I have an int array and I need to find the number of elements in it. I know it has something to do with sizeof but I'm not sure how to use it exactly.
If you have your array in scope you can use sizeof to determine its size in bytes and use the division to calculate the number of elements:
#define NUM_OF_ELEMS 10
int arr[NUM_OF_ELEMS];
size_t NumberOfElements = sizeof(arr)/sizeof(arr[0]);
If you receive an array as a function argument or allocate an array in heap you can not determine its size using the sizeof. You'll have to store/pass the size information somehow to be able to use it:
void DoSomethingWithArray(int* arr, int NumOfElems)
{
for(int i = 0; i < NumOfElems; ++i) {
arr[i] = /*...*/
}
}
int a[20];
int length;
length = sizeof(a) / sizeof(int);
and you can use another way to make your code not be hard-coded to int
Say if you have an array array
you just need to:
int len = sizeof(array) / sizeof(array[0]);
I personally think that sizeof(a) / sizeof(*a) looks cleaner.
I also prefer to define it as a macro:
#define NUM(a) (sizeof(a) / sizeof(*a))
Then you can use it in for-loops, thusly:
for (i = 0; i < NUM(a); i++)
It is not possible to find the number of elements in an array unless it is a character array. Consider the below example:
int main()
{
int arr[100]={1,2,3,4,5};
int size = sizeof(arr)/sizeof(arr[0]);
printf("%d", size);
return 1;
}
The above value gives us value 100 even if the number of elements is five.
If it is a character array, you can search linearly for the null string at the end of the array and increase the counter as you go through.
In real we can't count how many elements are store in array
But you can find the array length or size using sizeof operator.
But why we can't find how many elements are present in my array.
Because when we initialise an array compiler give memory on our program like a[10] (10 blocks of 4 size) and every block has garbage value if we put some value in some index like a[0]=1,a[1]=2,a[3]=8; and other block has garbage value no one can tell which value is garbage and which value is not garbage that's a reason we cannot calculate how many elements in an array. I hope this will help you to understand. Little concept
Super easy.
Just divide the number of allocated bytes by the number of bytes of the array's data type using sizeof().
For example, given an integer array called myArray
int numArrElements = sizeof(myArray) / sizeof(int);
Now, if the data type of your array isn't constant and could possibly change, then make the divisor in the equation use the size of the first value as the size of the data type.
For example:
int numArrElements = sizeof(myArray) / sizeof(myArray[0]);
This way, the code is type agnostic and will function correctly no matter the data type of the array.
I used following code as suggested above to evaluate number of elements in my 2-dimensional array:
#include <stdio.h>
#include <string.h>
void main(void)
{
char strs[3][20] =
{
{"January"},
{"February"},
{""}
};
int arraysize = sizeof(strs)/sizeof(strs[0]);
for (int i = 0; i < arraysize; i++)
{
printf("Month %d is: %s\n", i, strs[i]);
}
}
It works nicely. As far as I know you can't mix up different data types in C arrays and also you should have the same size of all array elements (if I am right), therefore you can take advantage of that with this little trick:
count number of bytes with sizeof() function from whole 2d array (in this case 3*20 = 60 bytes)
count number of bytes with sizeof() function from first array element strs[0] (in this case 20 bytes)
divide whole size with size of one element what will give you number of elements
This snipped should be portable for 2d arrays in C however in other programming languages it could not work because you can use different data types within array with different sizes (like in JAVA).
The question is simple: given a C++ array (e.g. x as in int x[10]), how would you get the number of elements in it?
An obvious solution is the following macro (definition 1):
#define countof( array ) ( sizeof( array )/sizeof( array[0] ) )
I cannot say this isn’t correct, because it does give the right answer when you give it an array. However, the same expression gives you something bogus when you supply something that is not an array. For example, if you have
int * p;
then countof( p ) always give you 1 on a machine where an int pointer and an int have the same size (e.g. on a Win32 platform).
This macro also wrongfully accepts any object of a class that has a member function operator[]. For example, suppose you write
class IntArray {
private:
int * p;
size_t size;
public:
int & operator [] ( size_t i );
} x;
then sizeof( x ) will be the size of the x object, not the size of the buffer pointed to by x.p. Therefore you won’t get a correct answer by countof( x ).
So we conclude that definition 1 is not good because the compiler does not prevent you from misusing it. It fails to enforce that only an array can be passed in.
What is a better option?
Well, if we want the compiler to ensure that the parameter to countof is always an array, we have to find a context where only an array is allowed. The same context should reject any non-array expression.
Some beginners may try this (definition 2):
template <typename T, size_t N>
size_t countof( T array[N] )
{
return N;
}
They figure, this template function will accept an array of N elements and return N.
Unfortunately, this doesn’t compile because C++ treats an array parameter the same as a pointer parameter, i.e. the above definition is equivalent to:
template <typename T, size_t N>
size_t countof( T * array )
{
return N;
}
It now becomes obvious that the function body has no way of knowing what N is.
However, if a function expects an array reference, then the compiler does make sure that the size of the actual parameter matches the declaration. This means we can make definition 2 work with a minor modification (definition 3):
template <typename T, size_t N>
size_t countof( T (&array)[N] )
{
return N;
}
This countof works very well and you cannot fool it by giving it a pointer. However, it is a function, not a macro. This means you cannot use it where a compile time constant is expected. In particular, you cannot write something like:
int x[10];
int y[ 2*countof(x) ]; // twice as big as x
Can we do anything about it?
Someone (I don’t know who it is – I just saw it in a piece of code from an unknown author) came up with a clever idea: moving N from the body of the function to the return type (e.g. make the function return an array of N elements), then we can get the value of N without actually calling the function.
To be precise, we have to make the function return an array reference, as C++ does not allow you to return an array directly.
The implementation of this is:
template <typename T, size_t N>
char ( &_ArraySizeHelper( T (&array)[N] ))[N];
#define countof( array ) (sizeof( _ArraySizeHelper( array ) ))
Admittedly, the syntax looks awful. Indeed, some explanation is necessary.
First, the top-level stuff
char ( &_ArraySizeHelper( ... ))[N];
says _ArraySizeHelper is a function that returns a reference (note the &) to a char array of N elements.
Next, the function parameter is
T (&array)[N]
which is a reference to a T array of N elements.
Finally, countof is defined as the size of the result of the function _ArraySizeHelper. Note we don’t even need to define _ArraySizeHelper(), -- a declaration is enough.
With this new definition,
int x[10];
int y[ 2*countof(x) ]; // twice as big as x
becomes valid, just as we desire.
Am I happy now? Well, I think this definition is definitely better than the others we have visited, but it is still not quite what I want. For one thing, it doesn’t work with types defined inside a function. That’s because the template function _ArraySizeHelper expects a type that is accessible in the global scope.
I don’t have a better solution. If you know one, please let me know.
#include<stdio.h>
int main()
{
int arr[]={10,20,30,40,50,60};
int *p;
int count=0;
for(p=arr;p<&arr+1;p++)
count++;
printf("The no of elements in array=%d",count);
return 0;
}
OUTPUT=6
EXPLANATION
p is a pointer to a 1-D array, and in the loop for(p=arr,p<&arr+1;p++)
I made p point to the base address. Suppose its base address is 1000; if we increment p then it points to 1002 and so on. Now coming to the concept of &arr - It basically represents the whole array, and if we add 1 to the whole array i.e. &arr+1, it gives the address 1012 i.e. the address of next 1-D array (in our case the size of int is 2), so the condition becomes 1000<1012.
So, basically the condition becomes
for(p=1000;p<1012;p++)
And now let's check the condition and count the value
1st time p=1000 and p<1012 condition is true: enter in the loop, increment the value of count to 1.
2nd time p=1002 and p<1012 condition is true: enter in the loop, increment the value of count to 2.
...
6th time p=1010 and p<1012 condition is true: enter in the loop, increment the value of count to 6.
Last time p=1012 and p<1012 condition is false: print the value of count=6 in printf statement.
sizeof returns the size in bytes of it's argument. This is not what you want, but it can help.
Let's say you have an array:
int array[4];
If you apply sizeof to the array (sizeof(array)), it will return its size in bytes, which in this case is 4 * the size of an int, so a total of maybe 16 bytes (depending on your implementation).
If you apply sizeof to an element of the array (sizeof(array[0])), it will return its size in bytes, which in this case is the size of an int, so a total of maybe 4 bytes (depending on your implementation).
If you divide the first one by the second one, it will be: (4 * the size of an int) / (the size of an int) = 4; That's exactly what you wanted.
So this should do:
sizeof(array) / sizeof(array[0])
Now you would probably like to have a macro to encapsulate this logic and never have to think again how it should be done:
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
You need the parentheses enclosing all the macro as in any other complex macro, and also enclosing every variable, just to avoid unexpected bugs related to operators precedence.
Now you can use it on any array like this:
int array[6];
ptrdiff_t nmemb;
nmemb = ARRAY_SIZE(array);
/* nmemb == 6 */
Remember that arguments of functions declared as arrays are not really arrays, but pointers to the first element of the array, so this will NOT work on them:
void foo(int false_array[6])
{
ptrdiff_t nmemb;
nmemb = ARRAY_SIZE(false_array);
/* nmemb == sizeof(int *) / sizeof(int) */
/* (maybe ==2) */
}
But it can be used in functions if you pass a pointer to an array instead of just the array:
void bar(int (*arrptr)[7])
{
ptrdiff_t nmemb;
nmemb = ARRAY_SIZE(*arrptr);
/* nmemb == 7 */
}
void numel(int array1[100][100])
{
int count=0;
for(int i=0;i<100;i++)
{
for(int j=0;j<100;j++)
{
if(array1[i][j]!='\0')
{
count++;
//printf("\n%d-%d",array1[i][j],count);
}
else
break;
}
}
printf("Number of elements=%d",count);
}
int main()
{
int r,arr[100][100]={0},c;
printf("Enter the no. of rows: ");
scanf("%d",&r);
printf("\nEnter the no. of columns: ");
scanf("%d",&c);
printf("\nEnter the elements: ");
for(int i=0;i<r;i++)
{
for(int j=0;j<c;j++)
{
scanf("%d",&arr[i][j]);
}
}
numel(arr);
}
This shows the exact number of elements in matrix irrespective of the array size you mentioned while initilasing(IF that's what you meant)
we can find number of elements in array only if array is declared in this format
int a[]={1,2,3,4,5,6};
number of element in array is
n=sizeof(a) / sizeof(a[0]);
we should no able to calculate array size if it is declared like this int a[10]={1,2,3,4,5,6}
i mostly found a easy way to execute the length of array inside a loop just like that
int array[] = {10, 20, 30, 40};
int i;
for (i = 0; i < array[i]; i++) {
printf("%d\n", array[i]);
}
If we don't know the number of elements in the array and when the input is given by the user at the run time. Then we can write the code as
C CODE:
while(scanf("%d",&array[count])==1) {
count++;
}
C++ CODE:
while(cin>>a[count]) {
count++;
}
Now the count will be having the count of number of array elements which are entered.
Assuming you have an array with elements 1,3,4.
To know its length, you'd need to use the sizeof function as follows:
int myArray[] = {1,3,4};
int len = sizeof(myArray) / sizeof(myArray[0]);
You can check the number of elements by printing the output as follows:
cout<<"This array has " << len << " elements";
The full program would be as follows:
#include <iostream>
using namespace std;
int main()
{
int myArray[] = {1,3,4};
int len = sizeof(myArray) / sizeof(myArray[0]);
cout<<"The array has " << len << "elements";
return 0;
}
Actually, there is no proper way to count the elements in a dynamic integer array. However, the sizeof command works properly in Linux, but it does not work properly in Windows. From a programmer's point of view, it is not recommended to use sizeof to take the number of elements in a dynamic array. We should keep track of the number of elements when making the array.
Related
I am trying to write a function that prints out the elements in an array. However when I work with the arrays that are passed, I don't know how to iterate over the array.
void
print_array(int* b)
{
int sizeof_b = sizeof(b) / sizeof(b[0]);
int i;
for (i = 0; i < sizeof_b; i++)
{
printf("%d", b[i]);
}
}
What is the best way to do iterate over the passed array?
You need to also pass the size of the array to the function.
When you pass in the array to your function, you are really passing in the address of the first element in that array. So the pointer is only pointing to the first element once inside your function.
Since memory in the array is continuous though, you can still use pointer arithmetic such as (b+1) to point to the second element or equivalently b[1]
void print_array(int* b, int num_elements)
{
for (int i = 0; i < num_elements; i++)
{
printf("%d", b[i]);
}
}
This trick only works with arrays not pointers:
sizeof(b) / sizeof(b[0])
... and arrays are not the same as pointers.
Why don't you use function templates for this (C++)?
template<class T, int N> void f(T (&r)[N]){
}
int main(){
int buf[10];
f(buf);
}
EDIT 2:
The qn now appears to have C tag and the C++ tag is removed.
For C, you have to pass the length (number of elements)of the array.
For C++, you can pass the length, BUT, if you have access to C++0x, BETTER is to use std::array. See here and here. It carries the length, and provides check for out-of-bound if you access elements using the at() member function.
In C99, you can require that an array an array has at least n elements thusly:
void print_array(int b[static n]);
6.7.5.3.7: A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to
type’’, where the type qualifiers (if any) are those specified within the [ and ] of the
array type derivation. If the keyword static also appears within the [ and ] of the
array type derivation, then for each call to the function, the value of the corresponding
actual argument shall provide access to the first element of an array with at least as many
elements as specified by the size expression.
In GCC you can pass the size of an array implicitly like this:
void print_array(int n, int b[n]);
You could try this...
#include <cstdio>
void
print_array(int b[], size_t N)
{
for (int i = 0; i < N; ++i)
printf("%d ", b[i]);
printf("\n");
}
template <size_t N>
inline void
print_array(int (&b)[N])
{
// could have loop here, but inline forwarding to
// single function eliminates code bloat...
print_array(b, N);
}
int main()
{
int a[] = { 1, 2 };
int b[] = { };
int c[] = { 1, 2, 3, 4, 5 };
print_array(a);
// print_array(b);
print_array(c);
}
...interestingly b doesn't work...
array_size.cc: In function `int main()':
array_size.cc:19: error: no matching function for call to `print_array(int[0u])'
JoshD points out in comments below the issue re 0 sized arrays (a GCC extension), and the size inference above.
In c++ you can also use a some type of list class implemented as an array with a size method or as a struct with a size member(in c or c++).
Use variable to pass the size of array.
int sizeof_b = sizeof(b) / sizeof(b[0]); does nothing but getting the pre-declared array size, which is known, and you could have passed it as an argument; for instance, void print_array(int*b, int size). size could be the user-defined size too.
int sizeof_b = sizeof(b) / sizeof(b[0]); will cause redundant iteration when the number of elements is less than the pre-declared array-size.
The question has already some good answers, for example the second one. However there is a lack of explanation so I would like to extend the sample and explain it:
Using template and template parameters and in this case None-Type Template parameters makes it possible to get the size of a fixed array with any type.
Assume you have such a function template:
template<typename T, int S>
int getSizeOfArray(T (&arr)[S]) {
return S;
}
The template is clearly for any type(here T) and a fixed integer(S).
The function as you see takes a reference to an array of S objects of type T, as you know in C++ you cannot pass arrays to functions by value but by reference so the function has to take a reference.
Now if u use it like this:
int i_arr[] = { 3, 8, 90, -1 };
std::cout << "number f elements in Array: " << getSizeOfArray(i_arr) << std::endl;
The compiler will implicitly instantiate the template function and detect the arguments, so the S here is 4 which is returned and printed to output.
I am currently reading understanding pointers in c, am at the section were the author talks about passing arrays to functions. Out of all the bellow patterns which is best to use and why ? , does it have anything to do with optimisation ?
#include <stdio.h>
void passAsPointerWithSize(int * arr, int size) {
for ( int i = 0; i < size; i++ ) {
printf("%d\n", arr[i]);
}
}
void passAsPointerWithoutSize(int * arr) {
while ( *arr ) {
printf("%d\n", *arr);
arr++;
}
}
void passWithoutPointerWithSize( int arr [] , int size) {
for ( int i = 0; i <= size; i++ ) {
printf("%d\n", arr[i]);
}
}
void passWithoutPointerUsingWhile(int arr []) {
int i = 1;
while ( arr[i] ) {
printf("%d\n", arr[i++]);
}
}
int main() {
int size = 5;
int arr[5] = { 1, 2, 3, 4 , 5};
passAsPointerWithSize(arr, size);
passAsPointerWithoutSize(arr);
passWithoutPointerWithSize(arr, size);
passWithoutPointerUsingWhile(arr);
}
i compiled it with -std=gnu11 -O3
In the context of function parameters, int arr [] is the same as int *arr because when an array is passed as a function argument to a function parameter, it decays into a pointer to its first element.
So the following declaration:
void foo(int * arr, int size);
is equivalent to:
void foo(int arr[], int size);
When it comes to the question whether you need the size parameter, you need it in order to determine the length of the array, unless:
there is a special value stored in the array that act as an indicator for the end of array (the callee would be responsible for checking against this indicator).
the length of the array is already known to the caller.
Otherwise, how could you possibly know how many elements the array contains?
Out of all the bellow patterns which is best to use and why ?
With the points above in mind, the only thing you can always choose is whether to use the int * syntax or the int [] one for the function parameter.
Although both are equivalent (as explained above), some people may argue that using int * could suggest that there is at most one element, whereas int [] could suggest thet there there is at least one element and there could be more than one.
does it have anything to do with optimization ?
No, or at least, not directly, whether you need the size parameter is actually a matter of whether the size of the array is known by the caller or it can be obtained by means of a stored end-of-array indicator.
First see which one is correct! (based on what you posted)
void passAsPointerWithSize(int * arr, int size) {
for ( int i = 0; i < size; i++ ) {
printf("%d\n", arr[i]);
}
}
This is the one not invoking Undefined Behavior.
The ones using while won't stop unless they get an element having value 0. What if the array has no 0's ? Then it will access way beyond the memory (which is the case here). Perhaps this echos back to a time when strings used to be marked with zeros at their end, in any case, it's bad practice.
The other for loop is looping till index<=size accessing array index out of bounds when index = size, again, undefined behavior.
Now back to your question..
The syntax func(int arr[],..) is the same as func(int* arr,...) on the context of passing a 1D-array to a function. Arrays are passed as pointers - it doesn't matter how you specify the signature.
Looping? - it's just a matter of choice.
Typos and other things...
Typos are the <= or the i=1 initialization in one of the functions. did you not want to print the 0-th element? Well i=1 and then you start looping - it missed the 0-th element.
A compiler, when passed an array, deals with a pointer to the first element of the array no matter how you write it so the form doesn't matter
How do I know the size of the array passed?
In any of the cases - when you pass an array to a function as a pointer - there is no way to know the length of the array unless you have some placeholder which marks the end of the array. If that is not the case then you have to obviously somehow know the length of it - which is what you do when you pass a parameter named size in the function.
Readability + Choice + ...
Writing it as arr[] can be used to convey the meaning that it is an array when we will deal with that pointer. You may skim through the code and get an idea about what it is getting as arguments and what it will possibly do. One may argue that a comment can still serve that purpose - that's where choice comes into the picture.
Yeah, some of them won't work (what do you mean by the condition *arr for instance? are you trying to bring back null terminated strings? don't!)
But, actually the fastest one (barring some crazy compiler optimization which I for one have not seen in practice) if you don't care about order is iterating backwards
void passAsPointerWithSize(int *arr, int size) {
for ( int i = size - 1; i > 0; i-- ) {
printf("%d\n", arr[i]);
}
}
That's because it saves a whole CPU clock cycle every loop, since after you reduce i (i--) the answer of comparing to zero (i > 0) is already stored in the registers
Assume i have define structure which has one array. I have initialize the array in main program. But now how can i find the number of element initialized in the array. I have created arrays of struct object too.
#include <stdio.h>
#define noOfArray 10
struct Arrays
{
int data[100];
int size;
int discardArray; //1 for true and 0 for false
};
void main( )
{
int size=0,i,j;
struct Arrays arrayObject[10]={
{{1,2,3,4}},
{{1,3,5,6,3,4}},
{{1,6,7,8,9,10,11,43,4}}
};
size = sizeof arrayObject[0].data / sizeof arrayObject[0].data[0];
}
This size gives me 100 but i need total number of element present in arrayObject[0].data.
Event tried with
int arr[] = {1,2,3,4};
struct Arrays arrayObject[10] = {
{arr,sizeof arr/sizeof arr[0]},
{{1,3,5,6,3,4}},
{{1,6,7,8,9,10,11,43,4}}
};
But this doesn't compile: Near to sizeof start it is saying invalid initialization.
What I'm really looking for is any way to store n arrays, where the first array can be compared to other arrays. The element preset in the arrays with be of varying size.
Your compile time error is that you're trying to use arr as a value to initialize arrayObject to. However, C only allows values that are known at compile time to be used as initializers. arr is an address on the stack that won't be known until execution time, therefore it can't be used as an initializer.
You should be able to initialize to sizeof arr/sizeof arr[0], which will be the count of elements in the array, but you can't initialize to arr, sizeof arr/sizeof arr[0].
The flaw in what you're trying to do is the way you're trying to distinguish between initialized vs. uninitialized elements.
int a[100] = { 1, 2 };
Does initialize all 100 elements. The elements not mentioned in the initializer list are initialized to zero. You can't use sizeof(a)/sizeof(a[0]) to count initialized elements.
You could do something like
#define INIT_LIST { 1, 2, 111} // 257
#define ASIZE 100
int big_array[ASIZE] = INIT_LIST;
// this works with gcc -O1 / -Og, but dummy is there in the object file at -O0
static const char dummy[] = INIT_LIST;
int initialized_count = sizeof(dummy); // sizeof(char) is guaranteed to be 1, so no divisor is needed.
// Or even better, no dummy array in the object file even with -O0:
int initialized_count2 = sizeof((int[])INIT_LIST)/sizeof(int);
// This also avoids compiler warnings when constants in the initializer list don't fit in a char.
// in macro form: Be careful with very large initializers; this could compile slowly if you used it all over the place.
#define COUNT_INITLIST (x) (sizeof((long[])x)/sizeof(long))
// Even with optimization on, this will also compile away to just returning a constant
int initialized_in_big_array() {
// without optimization: dummy2 is there in the object file
// but still not copied to the stack, because of const
const char dummy2[] = INIT_LIST;
return sizeof(dummy2);
}
It turns out even at low optimization levels like -Og, compilers avoid emitting unused arrays entirely. So the inline-function isn't needed. Jens Gustedt's suggestion of casting the initializer list, so there is never an array, is the best.
One solution is to put a sentinel value at the end of the array. For example, if negative values are not normally allowed in the array, then you could use the value -1 to mark the end of the array.
struct Arrays arrayObject[10]={
{{1,2,3,4,-1}},
{{1,3,5,6,3,4,-1}},
{{1,6,7,8,9,10,11,43,4,-1}}
};
This allows you to use a simple for loop to count the number of valid entries in the array.
I have tried (sizeof(array)/sizeof(array[0])). Didn't work.
I wrote a simple function:
int length(int array[]){
int i=0;
while(array[i]) i++;
return i;
}
Worked one minute, didn't work the next.
Someone please help! I'm using Xcode as an IDE
The length of an array is not part of the array in C, so when passing an array as a parameter to a function you should pass its length as a parameter too. Here's an example:
#define ARRLEN(a) (sizeof(a)/sizeof (a)[0]) /* a must be an array, not a pointer */
void printarray(int* a, int alen)
{
int i;
for (i = 0; i < alen; i++)
printf("%d\n", a[i]);
}
main()
{
int a[] = { 3, 4, 5 };
printarray(a, ARRLEN(a));
return 0;
}
However, if your array is defined in such a way as to always end with a sentinel that isn't normal data, then you can traverse the elements until you encounter the sentinel. e.g.,
void printstrings(char** a)
{
int i;
for (i = 0; a[i]; i++)
printf("%s\n", a[i]);
}
main()
{
char* a[] = { "This", "should", "work.", NULL };
printstrings(a);
return 0;
}
Passing an array into a function is the same as passing a pointer to the array.
So sizeof(array)/sizeof(array[0]) does not work.
You can define a global macro:
#define A_LEN(a) (sizeof(a)/sizeof(a[0]))
Try this
main()
{
int a[10] ;
printf("%d\n", sizeof(a)/sizeof(int) ) ;
}
output : 10
See Why doesn't sizeof properly report the size of an array when the array is a parameter to a function? from the comp.lang.c FAQ to understand why the sizeof method doesn't work. You probably should read the entire section on arrays.
Regarding your length function, your "simple" function can work only if your array happens to have the semantic that it is terminated with an element that has the value of 0. It will not work for an arbitrary array. When an array has decayed into a pointer in C, there is no way to recover the size of the array, and you must pass along the array length. (Even functions in the C standard library are not immune; gets does not take an argument that specifies the length of its destination buffer, and consequently it is notoriously unsafe. It is impossible for it to determine the size of the destination buffer, and it therefore cannot prevent buffer overflows.)
There are several methods to get the length of array inside a function (can be in the same file or in different source file)
pass the array length as a separate parameter.
make array length as global extern so that function can directly access global data
I am trying to write a function that prints out the elements in an array. However when I work with the arrays that are passed, I don't know how to iterate over the array.
void
print_array(int* b)
{
int sizeof_b = sizeof(b) / sizeof(b[0]);
int i;
for (i = 0; i < sizeof_b; i++)
{
printf("%d", b[i]);
}
}
What is the best way to do iterate over the passed array?
You need to also pass the size of the array to the function.
When you pass in the array to your function, you are really passing in the address of the first element in that array. So the pointer is only pointing to the first element once inside your function.
Since memory in the array is continuous though, you can still use pointer arithmetic such as (b+1) to point to the second element or equivalently b[1]
void print_array(int* b, int num_elements)
{
for (int i = 0; i < num_elements; i++)
{
printf("%d", b[i]);
}
}
This trick only works with arrays not pointers:
sizeof(b) / sizeof(b[0])
... and arrays are not the same as pointers.
Why don't you use function templates for this (C++)?
template<class T, int N> void f(T (&r)[N]){
}
int main(){
int buf[10];
f(buf);
}
EDIT 2:
The qn now appears to have C tag and the C++ tag is removed.
For C, you have to pass the length (number of elements)of the array.
For C++, you can pass the length, BUT, if you have access to C++0x, BETTER is to use std::array. See here and here. It carries the length, and provides check for out-of-bound if you access elements using the at() member function.
In C99, you can require that an array an array has at least n elements thusly:
void print_array(int b[static n]);
6.7.5.3.7: A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to
type’’, where the type qualifiers (if any) are those specified within the [ and ] of the
array type derivation. If the keyword static also appears within the [ and ] of the
array type derivation, then for each call to the function, the value of the corresponding
actual argument shall provide access to the first element of an array with at least as many
elements as specified by the size expression.
In GCC you can pass the size of an array implicitly like this:
void print_array(int n, int b[n]);
You could try this...
#include <cstdio>
void
print_array(int b[], size_t N)
{
for (int i = 0; i < N; ++i)
printf("%d ", b[i]);
printf("\n");
}
template <size_t N>
inline void
print_array(int (&b)[N])
{
// could have loop here, but inline forwarding to
// single function eliminates code bloat...
print_array(b, N);
}
int main()
{
int a[] = { 1, 2 };
int b[] = { };
int c[] = { 1, 2, 3, 4, 5 };
print_array(a);
// print_array(b);
print_array(c);
}
...interestingly b doesn't work...
array_size.cc: In function `int main()':
array_size.cc:19: error: no matching function for call to `print_array(int[0u])'
JoshD points out in comments below the issue re 0 sized arrays (a GCC extension), and the size inference above.
In c++ you can also use a some type of list class implemented as an array with a size method or as a struct with a size member(in c or c++).
Use variable to pass the size of array.
int sizeof_b = sizeof(b) / sizeof(b[0]); does nothing but getting the pre-declared array size, which is known, and you could have passed it as an argument; for instance, void print_array(int*b, int size). size could be the user-defined size too.
int sizeof_b = sizeof(b) / sizeof(b[0]); will cause redundant iteration when the number of elements is less than the pre-declared array-size.
The question has already some good answers, for example the second one. However there is a lack of explanation so I would like to extend the sample and explain it:
Using template and template parameters and in this case None-Type Template parameters makes it possible to get the size of a fixed array with any type.
Assume you have such a function template:
template<typename T, int S>
int getSizeOfArray(T (&arr)[S]) {
return S;
}
The template is clearly for any type(here T) and a fixed integer(S).
The function as you see takes a reference to an array of S objects of type T, as you know in C++ you cannot pass arrays to functions by value but by reference so the function has to take a reference.
Now if u use it like this:
int i_arr[] = { 3, 8, 90, -1 };
std::cout << "number f elements in Array: " << getSizeOfArray(i_arr) << std::endl;
The compiler will implicitly instantiate the template function and detect the arguments, so the S here is 4 which is returned and printed to output.