我是编程的初学者,我不知道sizeof(a)和sizeof(a [0])的确切含义来计算数组中元素的数量。为什么在何处使用此功能?划分它们的目的是什么。
根据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 );
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];
之后,我们完成了。
sizeof
返回变量的大小(以字节为单位)。因此,sizeof(a)
其中a是一个数组将返回该数组的大小,witch是该数组中元素的数量乘以一个元素的大小。
sizeof(a[0])
将为您提供数组中一个元素的大小(我们只是选择了第一个)。
so-sizeof(a) / sizeof(a[0])
=数组的长度*数组中一个元素的大小/数组中的一个元素的大小=数组的长度。
除了所说的,sizeof(myarray)有效并返回类型乘以我认为可以非常依赖于编译器的元素数量的事实。一些编译器将允许您执行此操作,而其他编译器则不允许。如果您不小心,这是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