0

I'm wondering if there any method to get the number of element in an Array like Array#size in ruby, so I come up with

int a;
int ary[] = {1,2,3,4,5,6};
int number_of_elements =sizeof(ary)/sizeof(a);
for(index = 0;index < number_of_element);index++){
    printf("the %d element of array is %d",index,*(ptr + index));
  }

it works, but I want a more elegant way to do this.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
mko
  • 21,334
  • 49
  • 130
  • 191

4 Answers4

3

Well, you can use this macro.

#define N_ELEM(t) (sizeof(t) / sizeof(*t))

Isn't it elegant ?

(Of course, it doens't work with dynamic arrays)

md5
  • 23,373
  • 3
  • 44
  • 93
  • Works for all *real* arrays, not only `static` ones. – Jens Gustedt Jul 23 '12 at 12:36
  • I don't speak english very well, I was speaking about "static arrays" to differentiate those arrays with dynamic arrays (nothing about static storage class/duration). – md5 Jul 23 '12 at 12:39
  • I think you just mean *array* in contrast to pointers, don't you? The fact that you can't know the size of an object that is pointed to by a pointer, has nothing to do with how and where the object has been allocated: `double A[3]; double *a = A;` then `sizeof` works well for `A` but not for `a`. – Jens Gustedt Jul 23 '12 at 12:47
  • 1
    You probably should read up a bit on the terminology, C has a well defined concept of what an "array" is and for all of these the `sizeof` operator works as expected. By dynamic array, you mean an object that you allocated by `malloc`? Don't call that array, this only adds up to the confusion. And don't mix up a pointer with the object it points to. – Jens Gustedt Jul 23 '12 at 13:51
2

No, there's no easy way to count the number of elements in an array in C unless you provide your own delimiter value to indicate the end of the array (similar as to how '\0' is used in strings.)

Levon
  • 138,105
  • 33
  • 200
  • 191
  • This is simply not true. `sizeof(arr)/sizeof(arr[0])` works quite well for staticially declared arrays, where the C compiler can infer the size from the declaration. Pretty easy, right? It does not work for arrays that have been passed around as pointers, or arrays allocated on the heap. – sfstewman Jul 23 '12 at 14:10
  • The question doesn't ask specifically about *statically* declared arrays, the question and title are asking about arrays (note the lack of qualifier). If the question was specific to static arrays, I'd agree with your comment. – Levon Jul 23 '12 at 14:18
  • You're making a categorical statement about all arrays, which isn't true for a subset of them (constant strings are in the subset, so it's a rather large subset, at that). – sfstewman Jul 23 '12 at 14:26
  • And you state that your suggested solution *"does not work for arrays that have been passed around as pointers, or arrays allocated on the heap"* (that's how arrays are used a lot of the times, no?) .. why are you trying to find a point to argue over? I didn't state anything incorrect given OP's question, and I said if it had been more specific I would agree with you. What else do you want? If you feel so strongly, why don't you just post your own answer and leave it at that? Seriously. – Levon Jul 23 '12 at 14:28
1

There might be a more elegant solution than this too.

#define number_of_elements sizeof(arr)/sizeof(arr[0])

or

const int number_of_elements = sizeof(arr)/sizeof(arr[0])

Also do look at: How to find the 'sizeof' (a pointer pointing to an array)?

Community
  • 1
  • 1
askmish
  • 6,464
  • 23
  • 42
1

There is no elegant or easy way, and even the sizeof trick has limits; when an array expression is passed to a function, what the function receives is a pointer value, not an array. So something like

void foo(int a[])
{
  size_t count = sizeof a / sizeof a[0];
  ...
}

won't work because in the context of a function parameter declaration, T a[] and T a[N] are identical to T *a; a is a pointer value, not an array, so you get the size of a pointer to int divided by the size of the first element, which is not what you want.

Basically, you have to keep track of the array's size yourself. You know how big it is when you create it, so you have to preserve that information and pass it with the array:

void foo(int *a, size_t asize)
{
   ...
}

int main(void)
{
   int arr[SOME_SIZE];
   ...
   foo(arr, SOME_SIZE);
   ...
}
John Bode
  • 119,563
  • 19
  • 122
  • 198
  • As I understood it, the only context where the C compiler does any kind of reasoning on the array is when it can determine the origin declaration of an array whose extent is statically defined. This can occur in a function parameter: `void foo(int a[3][2])`, but is more common as a global (or local-to-module) variable: `static int a[23][78]`. In all other cases, the array is treated as a pointer. – sfstewman Jul 23 '12 at 14:05
  • @sfstewman: [C 2011](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf), 6.7.6.2/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." – John Bode Jul 23 '12 at 14:21