如何以及为什么使用 c 中的 sizeof(a)/sizeof(a[0]) 来计算数组中的元素数

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

我是编程初学者,我不知道sizeof(a) 和sizeof(a[0]) 的确切含义来计算数组中的元素数。 为什么以及在哪里使用此功能? 以及划分它们的目的是什么。

sizeof returns 变量的大小(以字节为单位)。因此,sizeof(a) 其中 a 是一个数组将 return 数组的大小, 是数组中元素的数量乘以一个元素的大小。

sizeof(a[0]) 会给出数组中一个元素的大小(我们只选择了第一个)。

so - sizeof(a) / sizeof(a[0]) = 数组长度 * 数组一元素大小 / 数组一元素大小 = 数组长度。

根据 C 标准(6.5.3.4 sizeof 和 alignof 运算符)

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.

所以如果你有一个数组,例如

int a[N];

其中 N 是某个整数值然后表达式

sizeof( a )

yields 数组占用的字节数。由于数组有 N 个元素,每个元素依次占用 sizeof( int ) 个字节,因此

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

或相同之处

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

因此,您可以按以下方式计算 N

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

例如,如果您不知道数组的确切大小,这很有用,因为它的大小取决于初始化器的数量。

例如

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

考虑到初学者有时会犯错误。

假设您有一个将数组声明为参数的函数。

例如

void f( int a[10] );

函数可以像

那样调用
int a[10];

f( a );

初学者通常在函数体中写下如下表达式

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

然而这是一个错误的代码。问题是像数组一样声明的参数被调整为指向数组元素类型的指针。所以函数声明实际上看起来像

void f( int *a );

并在表达式中的函数内

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

参数a为指针。即相当于

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

根据使用的系统指针占用 4 或 8 个字节。因此,如果 sizeof( int ) 等于 4,您将得到 2 或 1。

您不会获得用作参数的数组中元素的数量。

指针不保留有关它们是指向单个对象还是某个数组的第一个对象的信息。

在这种情况下,您应该使用指定数组中元素数量的第二个参数来声明函数。例如

void f( int *a, size_t n );

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

sizeof(a) 是其操作数的大小(以字节为单位),在本例中,是一个名为 a.

的数组

sizeof(a[0]) 是其操作数的大小(以字节为单位),在本例中为数组的单个元素。

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

用数组的大小除以元素的大小。 sizeof(a)/sizeof(a[0])

Why?

便于代码维护。考虑使用

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

对比

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

第一种方法,在some_type a[N];更新为some_type a[N+1];后,我们需要翻遍代码,将循环等可能需要调整的地方也更新一下。

使用第二种方法,将 some_type a[N]; 更新为 some_type a[N+1]; 后,我们就完成了。

除了所说的, sizeof( myarray ) 起作用的事实和 returns 类型乘以元素数量我认为可能非常依赖于编译器。有些编译器允许你这样做,有些则不允许。 如果您不小心,这就是 C 编程中的陷阱之一。 尝试编译并 运行 这个程序以供您自己查看。

# 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 );
}

使用 gcc 版本 4.3.4 在 linux x86-64 中编译, 我得到的输出是

 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

我尽量用通俗易懂的话来解释:

看看如果我们知道 1 个元素的大小是 4,数组的总大小是 20,那么它们在数组中有多少个元素。

4 * X = 20

X = 20/4

Here also, we are doing same thing 
number of elements in array =
 
sizeof(Array) / sizeof 1 element of Array(sizeof(A[0]))