This question already has answers here:
How do I determine the size of my array in C?
(24 answers)
Closed 1 year ago.
So what's this line means? int n = sizeof(arr) / sizeof(arr[0])
Why are we dividing arr with arr[0] and whats the use of n here?
#include <iostream>
using namespace std;
int search(int arr[], int n, int x)
{
int i;
for (i = 0; i < n; i++)
if (arr[i] == x)
return i;
return -1;
}
// Driver code
int main(void)
{
int arr[] = { 2, 3, 4, 10, 40 };
int x = 10;
int n = sizeof(arr) / sizeof(arr[0]);
// Function call
int result = search(arr, n, x);
(result == -1)
? cout << "Element is not present in array"
: cout << "Element is present at index " << result;
return 0;
}
From the C++ 14 Standard (5.3.3 Sizeof)
1 The sizeof operator yields the number of bytes in the object
representation of its operand...
If you have an array declared for example like this
int arr[] = { 2, 3, 4, 10, 40 };
then the expression
sizeof( arr )
yields the size of the memory occupied by the whole array.
The expression
sizeof(arr[0])
is the size of each element of the array because all elements of an array has the same size. As the type of array elements is int then you could write also
sizeof( int )
instead of
sizeof( arr[0] )
So the expression
sizeof( arr ) / sizeof( arr[0] )
yields the number of elements in the array.
Here is a demonstrative program.
#include <iostream>
int main()
{
int arr[] = { 2, 3, 4, 10, 40 };
size_t size_of_array = sizeof( arr );
std::cout << "The size of the memory occupied by the array is "
<< size_of_array << '\n';
size_t size_of_element = sizeof( arr[0] );
std::cout << "The size of the memory occupied by each element of the array is "
<< size_of_element << '\n';
std::cout << "The number of elements in the array is "
<< size_of_array / size_of_element << '\n';
return 0;
}
The program output is
The size of the memory occupied by the array is 20
The size of the memory occupied by each element of the array is 4
The number of elements in the array is 5
Pay attention to that the value of the expression has the type size_t instead of the type int.
If your compiler support C++ 17 then you can use standard function std::size declared in the header <iterator> instead of the expression sizeof( arr ) / sizeof( arr[0] ) like for example
#include <iterator>
//...
size_t n = std::size( arr );
As for the function search then it should be declared and defined like
size_t search( const int arr[], size_t n, int x )
{
size_t pos = 0;
while ( pos < n && arr[pos] != x ) ++pos;
return pos;
}
and in main you should write
size_t pos = search(arr, n, x);
( pos == n )
? cout << "Element is not present in array.\n"
: cout << "Element is present at index " << pos << '\n';
That line determines the size of the array. In C/C++ arrays (in contrast to Java) the size is not available. Since an array of n elements uses n times the size of a single element, you can calculate the number of elements like this.
This makes more sense when using templates where the actual size of an array element is unknown at compile time.
Related
Completely new to C++. Programmed selection sort on 1D array of arbitrary length. Want to allow user to keep inputting integers into console to make an array of desired length, to be subsequently sorted.
Can only seem to make arrays of length 2 using a while loop for adding elements. Code and example of erroneous result when inputting 6, 2, 3, and 9 shown below.
Script:
// Preprocessor directives and namespace declaration
#include <iostream>
#include <vector>
using namespace std;
// Function
void SelectionSort(int *arr, int len)
{
// Loop through index j in arr
for (int j = 0; j < len; j++) {
// Assume element j is minimum, and initialise minIndex
int min = arr[j];
int minIndex = j;
// Loop through comparisons to determine actual minimum
// (of elements after and including j)
for (int i = j; i < len; i++)
{
if (min > arr[i])
{
min = arr[i];
minIndex = i;
}
}
// Swap minimum with element j
int temp = arr[j];
arr[j] = min;
arr[minIndex] = temp;
}
// Display resulting array
for (int i = 0; i + 1 < len; i++)
{
cout << arr[i] << ", ";
}
cout << arr[len - 1] << endl;
}
// Main
int main()
{
// Explain program to user
cout << "Sort 1D array of user-inputted length/contents" << endl;
cout << "To finish array, enter -999" << endl;
// Initialise dynamic array
vector<int> vDyn (1);
vDyn[0] = 0;
cout << "Enter first element of array: ";
int firstElement = 0;
cin >> firstElement;
vDyn[0] = firstElement;
// Loop to define elements until desired length reached
bool keepGoing = true;
while (keepGoing == true)
{
cout << "Enter another element: ";
int newElement = 0;
cin >> newElement;
if (newElement != -999)
{
vDyn.push_back(newElement);
} else
{
keepGoing = false;
}
}
// Convert vector to array (dynamic to static)
int* v = &vDyn[0];
// Get array length
int len = sizeof(v) / sizeof(v[0]);
// Run SelectionSort function
SelectionSort(v, len);
return 0;
}
Terminal:
Sort 1D array of user-inputted length/contents
To finish array, enter -999
Enter first element of array: 6
Enter another element: 2
Enter another element: 3
Enter another element: 9
Enter another element: -999
2, 6
This declaration
int len = sizeof(v) / sizeof(v[0]);
is equivalent to the declaration
int len = sizeof( int * ) / sizeof( int );
because the variable v is declared like
int* v = &vDyn[0];
The size of a pointer is equal usually to 4 or 8 bytes. So the variable length will have the value either 1 or 2 and does not depend on the number of elements stored in the vector..
Instead you should use for example
size_t len = vDyn.size();
You could declare the function like
void SelectionSort(int *arr, size_t len);
and call it like
SelectionSort( vDyn.data(), vDyn.size() );
Also as in C++ there is standard function std::swap declared in the header <utility> then instead of this code snippet
// Swap minimum with element j
int temp = arr[j];
arr[j] = min;
arr[minIndex] = temp;
you could just write
if ( j != minIndex ) std::swap( arr[j], arr[minIndex] );
And the inner for loop could look like
for ( size_t i = j + 1; i < len; i++)
^^^^^
In fact your function SelectionSort is a C function. A C++ function should be more general and use iterators. In this case it could sort arrays along with other containers.
Here is a demonstration program that shows a more general function called for an array based on a vector.
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
template <typename ForwardIterator>
void SelectionSort( ForwardIterator first, ForwardIterator last )
{
for ( ; first != last; ++first )
{
auto current_min = first;
for ( auto next = std::next( first ); next != last; ++next )
{
if ( *next < *current_min ) current_min = next;
}
if ( current_min != first )
{
std::iter_swap( current_min, first );
}
}
}
int main()
{
std::vector<int> v = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
for ( const auto &item : v )
{
std::cout << item << ' ';
}
std::cout << '\n';
SelectionSort( v.data(), v.data() + v.size() );
for ( const auto &item : v )
{
std::cout << item << ' ';
}
std::cout << '\n';
}
The program output is
9 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9
In general you need also to write an overloaded function that accepts also a comparison function.
// Convert vector to array (dynamic to static)
int* v = &vDyn[0];
This line doesn't convert the array to anything. You merely take address of the first element in the vector.
If you want to take an underlying c-array from std::vector you are supposed to use data property of it.
Also, since the array is decayed into a pointer, it no longer contains data of its size. You should rely on std::vector properties (i.e. std::vector::size) to pass this information forward
I am took two arrays and then merged those two arrays to a newly created third array and it worked but when I output the size of the array, I was getting the size as '1'. I don't understand why the size of that array was '1' even though there are 5 elements in it.
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int arr1[] = { 1,2,3 };
int arr2[] = { 9,4 };
int size1 = sizeof(arr1) / sizeof(int);
int size2 = sizeof(arr2) / sizeof(int);
int *arr = new int[size1 + size2];
//merging the two arrays by transferinng the elements into the third array
for (int i = 0; i < size1; i++)
{
arr[i] = arr1[i];
}
for (int i = size1; i < (size1 + size2); i++)
{
arr[i] = arr2[i - size1];
}
//sorting the array
sort(arr, arr + (size1 + size2));
cout << endl;
//finding the size of newly merged array
int mergeSize = sizeof(arr) / sizeof(int);
cout << "The size of the array is " << mergeSize << endl; //why am I getting the size of the array as '1'
return 0;
}
sizeof(arr) gives you the size of the pointer arr, which does not depend on the number of elements you allocated for it.
Avoid the problem by using std::array. It doesn't have the overhead of std::vector and it's easier to use than C-style arrays.
int main()
{
array<int, 3> arr1 = { 1, 2, 3 };
array<int, 2> arr2 = { 9, 4 };
array<int, arr1.size() + arr2.size()> arr;
//merging the two arrays by transferinng the elements into the third array
for (int i = 0; i < arr1.size(); i++)
{
arr[i] = arr1[i];
}
for (int i = 0; i < arr2.size(); i++)
{
arr[i + arr1.size()] = arr2[i];
}
//sorting the array
sort(arr.begin(), arr .end());
cout << endl;
//finding the size of newly merged array
int mergeSize = arr.size();
cout << "The size of the array is " << mergeSize << endl; //why am I getting the size of the array as '1'
return 0;
}
arr is not an array, it's a pointer, Using sizeof on a pointer gives the size of the pointer not the size of the dynamic array it's pointing at. The sizeof a pointer is usually 4 or 8, depending on whether you have a 32 bit or 64 bit system.
You can avoid these problems by using vectors instead of arrays. Vectors have a size method which always gives the actual size. Arrays are quite poor in C++.
I have a function to which I need to pass an array.
But I don't want to pass the entire array (e.g., valid indices from array[0] to array[size-1]), but a subarray (e.g., valid indices starting at array[5] to array[size-1]).
Is there a way to do that in C++?
You can transfer array to function parameter below
void Foo(int* arr, int length);
//call Foo
Foo(&a[0], length); //or
Foo(a, length);
you can also transfer a certain range of array.
Foo(&a[1], length);
Foo(a + 1, length);
Just, simple code.
#include <iostream>
void Print(int* arr, int length)
{
for(int i=0; i < length; i++)
{
std::cout << *(arr + i) << ", ";
}
std::cout << std::endl;
}
int main()
{
int a[5] = {1,2,3,4,5};
//type A
Print(&a[0], sizeof(a)/sizeof(int)); //print all element of a
Print(&a[1], 3); //print 2,3,4
//type B
Print(a, sizeof(a)/sizeof(int)); //print all element of a
Print(a + 1, 3); //print 2,3,4
getchar();
return 0;
}
Quoted comment by n.m.:
You cannot pass an array to a function. When you try to, you actually pass the address of the first element of the array. If you need a subarray that starts at 5, you just pass the address of the fifth elements. You shouldn't be using C-style arrays anyway. Use std::vector and iterators, this is the C++ way.
As indicated, you can add an offset to the array base pointer (and subtract from the passed arraysize accordingly).
Or pass begin and end (one past the end) pointers of the array to the function to achieve an "iterator-style" implementation.
But as you are programming C++, please consider to use std::vector.
Example:
#include <iostream>
void foo(int arr[], int size) {
for (int i = 0; i < size; i++)
std::cout << arr[i] << ' ';
}
void bar(int* begin, int* end) {
while (begin != end)
std::cout << *begin++ << ' ';
}
int main() {
int arr[] = {0,1,2,3,4,5,6,7,8,9};
int size = sizeof(arr)/sizeof(*arr);
// pass entire array
foo(arr, size);
//bar(arr, arr+size);
std::cout << '\n';
// pass array starting at index 5
foo(arr+5, size-5);
//bar(arr+5, arr+size);
std::cout << '\n';
}
The output is:
$ g++ test.cc && ./a.out
0 1 2 3 4 5 6 7 8 9
5 6 7 8 9
I have written some code that prints 25 random numbers between 3 and 7 and puts them into an array, and then its reverse array. How would I now subtract the first number in the array minus the last number in the array? Here is my code so far. I have the function call and prototype made; just not sure what to put in the definition exactly:
#include <time.h>
#include <iostream>
#include <stdlib.h>
using namespace std;
// Function prototypes
void showArray ( int a[ ], int size ); // shows the array in the format "int a [ ] = { 3, 7, 4, ... ,5, 6, 3, 4, 7 } "
void showBeforeIndex( int a [ ], int size, int index); // shows all array values before a specified index
int firstMinusLast ( int a[ ], int size );
// **************************************************************************************************************************************
int main ()
{
// Array and reverse array
srand((int)time(NULL));
int i=0;
const int SIZE = 25;
int randvalue[SIZE];
cout << "Making an array of 25 random integers from 3 to 7!" << endl;
for(; i < SIZE; i++)
{
randvalue[i] = rand () % 5 + 3; // random number between 3 to 7
}
cout << "Original array a [ ] = {";
showArray(randvalue, SIZE);
cout << "}" << endl;
int j = SIZE-1;
i = 0;
while( i <= j)
{
swap(randvalue[i], randvalue[j]);
i++;
j--;
}
cout << "Reversed array a [ ] = {";
showArray(randvalue, SIZE);
cout << "}" << endl;
// *******************************************************************************************************
// Function call for FIRST - LAST
int returnFirstLast = firstMinusLast (randvalue, 25);
cout << "The difference between the first and and last array elements is " << returnFirstLast << endl;
//********************************************************************************************************
return 0;
}
// Function definition for ARRAY
void showArray ( int a[ ], int size )
{
int sum = 0;
for(int i = 0; i < size; i++)
cout << a[i];
}
// Function definition for FIRST - LAST
int firstMinusLast ( int a[ ], int size )
{
int fml;
return fml;
}
In C/C++ arrays are indexed beginning with 0. So the first element is at index 0. Given that the first element of an array is at index 0, then the last element of an array is at an index equal to the size of the array minus 1. So as code:
The first element is a[0]
The last element is a[SIZE - 1]
So to get their difference:fml you simply write: fml = a[0] - a[SIZE - 1]
This seems pretty simple for a function so perhaps you are expecting something bigger or different.
Do you need the absolute value of the difference? The magnitude of change without the sign? If so, just use the absolute value function.
fml = abs(a[0] - a[SIZE-1]);
If you meant to say that you want first minus last before the reverse, then simply do this:
fml = a[SIZE-1] - a[0];
If it needs the abs then it doesn't matter which way you do the subtract.
If you already have the size of the array, and you know the array is fully populated:
int firstMinusLast ( int a[ ], int size ){
return a[0] - a[size - 1];
}
This question already has answers here:
Why isn't the size of an array parameter the same as within main?
(13 answers)
Closed 8 years ago.
Trying to pass an int array of consecutive numbers starting with 1 but assuming the function receiving this array does not know it's length. When trying to calculate the length inside the function it just gives me 1 since it only finds the first element when calculating sizeof(arrayName).
#include <iostream>
using namespace std;
int Sum(int intArray[]) {
int n = sizeof(intArray) / sizeof(*intArray);
cout << "Array size in function: " << n << endl;
return n * (n + 1) / 2;
}
int main() {
int anArray[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int arraySum = Sum(anArray);
cout << "Array size in main: " << sizeof(anArray) / sizeof(*anArray) << endl;
cout << "Sum is: " << arraySum;
int a;
cin >> a;
return 0;
}
Your function is taking a pointer to int. All size information is lost as you pass the array into the pointer. But you can use a function template to instantiate functions that match the right array size:
template <size_t N>
int Sum(const int (&intArray)[N])
{
cout << "Array size in function: " << N << endl;
return std::accumulate(std::begin(intArray), std::end(intArray), 0);
}
This Sum function will accept plain arrays or size known at compile time. However, it makes more sense to use std::array for these cases, or std::vector for cases when the size is chosen at runtime.
Note that the call to std::accumulate is just an example that solves the sum problem. It does not require knowledge of N, and could replace the function entirely. The size is taken care of by std::begin and std::end. You would need headers <numeric> and <iterator> for accumulate and begin/end respectively.
In this function declaration
int Sum(int intArray[]);
array passed to it as an argument is implicitly converted to the pointer to the first element of the array. So this declaration is equivalent to
int Sum( int *intArray );
And the expression
int n = sizeof(intArray) / sizeof(*intArray );
is equivalent to
int n = sizeof( int * ) / sizeof( int );
if sizeof( int * ) is equal to sizeof( int ) then n will be equal to 1.
If you declare the parameter such a way as you did then you should also declare a second parameter that will accept the number of elements in the array. So I would rewrite the function the following way
int Sum( int intArray[], size_t n )
{
int sum = 0;
for ( size_t i = 0; i < n; i++ ) sum += intArray[i];
return sum;
}
and in main I would call the function the following way
int arraySum = Sum( anArray, sizeof( anArray ) / sizeof( *anArray ) );
}
Also functions ususally are written to perform some general algorithms. It is a bad idea to write a function only for arrays that has sequantial values from 1 to some N.