how and why sizeof(a)/sizeof(a[0]) in c is used to calculate the number of elements in an array

…衆ロ難τιáo~ 提交于 2019-12-06 15:15:54

According to the C Standard (6.5.3.4 The sizeof and alignof operators)

2 The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.

So if you have an array as for example

int a[N];

where N is some integer value then expression

sizeof( a )

yields the number of bytes occupied by the array. As the array has N elements and each element in turn occupies sizeof( int ) bytes then

sizeof( a ) == N * sizeof( int )

or what is the same

sizeof( a ) == N * sizeof( a[0] )

As result you can calculate N the following way

N = sizeof( a ) / sizeof( a[0] )

It is useful if you do not know the exact size of an array for example because its size depends on the number of initializers.

For example

int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const size_t N = sizeof( a ) / sizeof( *a );

Take into account that sometimes beginners make an error.

Let's assume that you have a function declaring an array as a parameter.

For example

void f( int a[10] );

and the function can be called like

int a[10];

f( a );

Beginners usually write in the body of the function the following expression

void f( int a[10] )
{
    size_t n = sizeof( a ) / sizeof( a[0] );
    //...
}

However it is a wrong code. The problem is that parameters declared like arrays are adjusted to pointers to the type of the array element. So the function declaration actually looks like

void f( int *a );

and within the function in expression

    size_t n = sizeof( a ) / sizeof( a[0] );

parameter a is pointer. That is it is equivalent to

    size_t n = sizeof( int * ) / sizeof( int );

Depending on the used system pointers occupies either 4 or 8 bytes. So you will get either 2 or 1 if sizeof( int ) is equal to 4.

You will not get the number of elements in the array that was used as the argument.

Pointers do not keep an information about whether they point to a single object or the first object of some array.

In this case you should declare the function with second parameter that specifies the number of elements in the array. For example

void f( int *a, size_t n );

meaning of sizeof(a) and sizeof(a[0])

sizeof(a) is the size (in bytes) of its operand, in this case, an array called a.

sizeof(a[0]) is the size (in bytes) of its operand, in this case, a single element of the array.

... to calculate the number of elements in an array.

Divide the size of the array by the size of an element. sizeof(a)/sizeof(a[0])

Why?

For easier code maintenance. Consider using

some_type a[N];
... code that visually separates the declaration and the below loop
for (i=0; i<N; i++) 
  foo(a[i])

versus

some_type a[N];
... lots of code
for (i=0; i<sizeof(a)/sizeof(a[0]); i++) 
  foo(a[i])

With the first method, after an update of some_type a[N]; to some_type a[N+1];, we need to search through code to also update the loop and other places that may need adjustment.

With the second method, after an update of some_type a[N]; to some_type a[N+1];, we are done.

sizeof returns the size of a variable in bytes. because of that, sizeof(a) where a is an array will return the size of the array, witch is the number of elements in the array times the size of one element.

sizeof(a[0]) will give you the size of one element in the array (we just chose the first).

so - sizeof(a) / sizeof(a[0]) = length of array * size of one element in the array / size of one element in the array = length of array.

in addition to what was said, the fact that sizeof( myarray ) works and returns the type multiplied by the number of elements I believe can be very compiler dependent. Some compilers will allow you to do this, others will not. This is one of the gotchya's in C programming if you are not careful. Try compiling and running this program to see for yourself.

# include <stdio.h>
# include <stdlib.h>


void Z1 ( int *z )
{
   printf(" size of z1 = %d\n", sizeof( z ) );
}

void Z2 ( int z[] )
{
   printf(" size of z2 = %d\n", sizeof( z ) );
}

void Z3 ( int z[10] )
{
   printf(" size of z3    = %d\n", sizeof( z ) );
   printf(" size of z3[5] = %d\n", sizeof ( z[5] ) );
}

int main ( int argc, char *argv[] )
{
   char a1;
   short int a2;
   int a3;
   long int a4;
   float a5;
   double a6;

   int myarray[10];


   for ( a3 = 0; a3 < 10; a3++ )
   {
      myarray[a3] = a3;
   }

   printf("\n");
   printf(" size of char      = %d\n", sizeof( a1 ) );
   printf(" size of short int = %d\n", sizeof( a2 ) );
   printf(" size of int       = %d\n", sizeof( a3 ) );
   printf(" size of long int  = %d\n", sizeof( a4 ) );
   printf(" size of float     = %d\n", sizeof( a5 ) );
   printf(" size of double    = %d\n", sizeof( a6 ) );

   printf(" size of myarray      = %d\n", sizeof( myarray ) );
   printf(" size of myarray[5]   = %d\n", sizeof( myarray[5] ) );

   printf("\n");

   Z1( myarray );
   Z2( myarray );
   Z3( myarray );
}

compiled in linux x86-64 using gcc version 4.3.4, the output i got was

 size of char      = 1
 size of short int = 2
 size of int       = 4
 size of long int  = 8
 size of float     = 4
 size of double    = 8
 size of myarray      = 40
 size of myarray[5]   = 4

 size of z1 = 8
 size of z2 = 8
 size of z3    = 8
 size of z3[5] = 4
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!