Executive summary:
int a[17];
size_t n = sizeof(a)/sizeof(a[0]);
Full answer:
To determine the size of your array in bytes, you can use the sizeof
operator:
int a[17];
size_t n = sizeof(a);
On my computer, ints are 4 bytes long, so n is 68.
To determine the number of elements in the array, we can divide the total size of the array by the size of the array element. You could do this with the type, like this:
int a[17];
size_t n = sizeof(a) / sizeof(int);
and get the proper answer (68 / 4 = 17), but if the type of
a changed you would have a nasty bug if you forgot to change
the sizeof(int) as well.
So the preferred divisor is sizeof(a[0]) or the equivalent sizeof(*a), the size of the first element of the array.
int a[17];
size_t n = sizeof(a) / sizeof(a[0]);
Another advantage is that you can now easily parameterize the array name in a macro and get:
#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
int a[17];
size_t n = NELEMS(a);
Answer from Mark Harrison on Stack Overflowc++ - Common array length macro for C? - Stack Overflow
C Program Length of Array
How to find the length of an array
How does C know the size of an array?
What is the length of an empty array in C?
Can I use sizeof() to get the length of an array inside a function?
Is sizeof(array) and sizeof(&array) the same?
Videos
Executive summary:
int a[17];
size_t n = sizeof(a)/sizeof(a[0]);
Full answer:
To determine the size of your array in bytes, you can use the sizeof
operator:
int a[17];
size_t n = sizeof(a);
On my computer, ints are 4 bytes long, so n is 68.
To determine the number of elements in the array, we can divide the total size of the array by the size of the array element. You could do this with the type, like this:
int a[17];
size_t n = sizeof(a) / sizeof(int);
and get the proper answer (68 / 4 = 17), but if the type of
a changed you would have a nasty bug if you forgot to change
the sizeof(int) as well.
So the preferred divisor is sizeof(a[0]) or the equivalent sizeof(*a), the size of the first element of the array.
int a[17];
size_t n = sizeof(a) / sizeof(a[0]);
Another advantage is that you can now easily parameterize the array name in a macro and get:
#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
int a[17];
size_t n = NELEMS(a);
The sizeof way is the right way iff you are dealing with arrays not received as parameters. An array sent as a parameter to a function is treated as a pointer, so sizeof will return the pointer's size, instead of the array's.
Thus, inside functions this method does not work. Instead, always pass an additional parameter size_t size indicating the number of elements in the array.
Test:
#include <stdio.h>
#include <stdlib.h>
void printSizeOf(int intArray[]);
void printLength(int intArray[]);
int main(int argc, char* argv[])
{
int array[] = { 0, 1, 2, 3, 4, 5, 6 };
printf("sizeof of array: %d\n", (int) sizeof(array));
printSizeOf(array);
printf("Length of array: %d\n", (int)( sizeof(array) / sizeof(array[0]) ));
printLength(array);
}
void printSizeOf(int intArray[])
{
printf("sizeof of parameter: %d\n", (int) sizeof(intArray));
}
void printLength(int intArray[])
{
printf("Length of parameter: %d\n", (int)( sizeof(intArray) / sizeof(intArray[0]) ));
}
Output (in a 64-bit Linux OS):
sizeof of array: 28
sizeof of parameter: 8
Length of array: 7
Length of parameter: 2
Output (in a 32-bit windows OS):
sizeof of array: 28
sizeof of parameter: 4
Length of array: 7
Length of parameter: 1
Here's a better C version (from Google's Chromium project):
#define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
It improves on the array[0] or *array version by using 0[array], which is equivalent to array[0] on plain arrays, but will fail to compile if array happens to be a C++ type that overloads operator[]().
The division causes a divide-by-zero operation (that should be caught at compile time since it's a compile-time constant expression) for many (but not all) situations where a pointer is passed as the array parameter.
See Is there a standard function in C that would return the length of an array? for more details.
There's a better option for C++ code. See Compile time sizeof_array without using a macro for details.
- What's the difference between those using array[0] and *array?
- Why should either be preferred?
- Do they differ in C++?
(1) No difference in C. No difference for an actual raw array in C++.
(2) No technical grounds to prefer one or the other, but newbies might be confused by the pointer dereference.
(3) In C++ you would normally not use the macro, because it's very unsafe. If you pass in a pointer instead of an actual raw array, code will compile but yield incorrect result. So in C++ you would/should instead use a function template, like …
#include <stddef.h>
typedef ptrdiff_t Size;
template< class Type, Size n >
Size countOf( Type (&)[n] ) { return n; }
This only accepts actual raw array as argument.
It's part of a triad of functions startOf, endOf and countOf that it's very convenient to define so that they can be applied to both raw arrays and standard library containers. As far as I know this triad was first identified by Dietmar Kuehl. In C++0x startOf and endOf will most probably be available as std::begin and std::end.
Cheers & hth.,
The following code prints 40, but I expect the output to be 10. Any ideas why?
I googled it and found (sizeof(a)/sizeof(a[0])) but in my use this always ended up being 4, what is an alternative way or how can i fix this method.
Code : https://pastebin.com/raw/7Qdw1fmz
A char array has the terminating \0 byte at the last index, so you can easily iterate through it. I can access the array by using it's address, stored in a pointer variable. The pointer is just a number, and by adding digits i can get any array index i want.
Integer arrays do not have a terminating byte and there is no information about the size in the pointer address. So how does for example free() know what to free?
C arrays do keep track of their length, as the array length is a static property:
int xs[42]; /* a 42-element array */
You can't usually query this length, but you don't need to because it's static anyway – just declare a macro XS_LENGTH for the length, and you're done.
The more important issue is that C arrays implicitly degrade into pointers, e.g. when passed to a function. This does make some sense, and allows for some nice low-level tricks, but it loses the information about the length of the array. So a better question would be why C was designed with this implicit degradation to pointers.
Another matter is that pointers need no storage except the memory address itself. C allows us to cast integers to pointers, pointers to other pointers, and to treat pointers as if they were arrays. While doing this, C is not insane enough to fabricate some array length into existence, but seems to trust in the Spiderman motto: with great power the programmer will hopefully fulfill the great responsibility of keeping track of lengths and overflows.
A lot of this had to do with the computers available at the time. Not only did the compiled program have to run on a limited resource computer, but, perhaps more importantly, the compiler itself had to run on these machines. At the time Thompson developed C, he was using a PDP-7, with 8k of RAM. Complex language features that didn't have an immediate analog on the actual machine code were simply not included in the language.
A careful read through the history of C yields more understanding into the above, but it wasn't entirely a result of the machine limitations they had:
Moreover, the language (C) shows considerable power to describe important concepts, for example, vectors whose length varies at run time, with only a few basic rules and conventions. ... It is interesting to compare C's approach with that of two nearly contemporaneous languages, Algol 68 and Pascal [Jensen 74]. Arrays in Algol 68 either have fixed bounds, or are `flexible:' considerable mechanism is required both in the language definition, and in compilers, to accommodate flexible arrays (and not all compilers fully implement them.) Original Pascal had only fixed-sized arrays and strings, and this proved confining [Kernighan 81].
C arrays are inherently more powerful. Adding bounds to them restricts what the programmer can use them for. Such restrictions may be useful for programmers, but necessarily are also limiting.