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

时间:2016-01-26 17:53:35

标签: c arrays sizeof

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

4 个答案:

答案 0 :(得分:10)

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

  

2 sizeof运算符产生其操作数的大小(以字节为单位)   可以是表达式或类型的带括号的名称。大小是   根据操作数的类型确定。结果是整数。如果   操作数的类型是可变长度数组类型,操作数   被评估;否则,不评估操作数和结果   是一个整数常量。

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

int a[N];

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

sizeof( a )

产生数组占用的字节数。由于数组具有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 );

答案 1 :(得分:1)

  

sizeof(a)和sizeof(a [0])

的含义

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

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

  

...计算数组中元素的数量。

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

  

为什么?

为了更轻松地维护代码。考虑使用

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];后,我们就完成了。

答案 2 :(得分:0)

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

sizeof(a[0])将为您提供数组中一个元素的大小(我们只选择了第一个元素)。

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

答案 3 :(得分:0)

除了所说的, sizeof(myarray)工作并返回类型的事实乘以我认为可能非常依赖于编译器的元素数量。有些编译器会允许你这样做,有些则不会。 如果你不小心,这是C编程中的gotchya之一。 尝试编译并运行此程序以便自己查看。

# 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