这可能是一个愚蠢的问题,但是当您没有传递数组中元素的数量时,sizeof
运算符如何知道数组操作数的大小。我知道它不返回数组中的总元素数,而是以字节为单位的大小,但是它仍然必须知道数组何时结束才能得到这个结果。只是好奇这是如何工作的。
sizeof
在编译时被解释,编译器知道数组如何声明(因此知道所需的空间大小)。在动态分配的数组上调用 sizeof
可能不会产生您想要的结果,因为(正如您提到的那样)数组的结束点未指定。
sizeof
不会评估其操作数。操作数表达式只对编译器有意义,因此这真的是唯一可以实现它的地方。可变长度数组由编译器间接处理。编译器已经必须生成代码来计算为VLA分配多少空间(数组成员大小*某个变量),因此它可以重用该数字以用于对该VLA进行任何sizeof
调用。 - btadouble da[10]
是由10个double
组成的数组,而不是double*
,当你要求计算sizeof(da)
时,编译器肯定知道这一点。你不会对编译器知道sizeof(double)
感到惊讶吧?double da[10]
,然后在代码中稍后出现sizeof(da)
时,编译器会说:“啊哈,我知道da
是一个由10个double
组成的数组,因为我可以看到声明在第8行列出了数组的大小。”因此,编译器在编译源代码时从源代码本身推断出数组的大小。我明白了,谢谢! - Galaxywhile
循环内部使用a*b+c
或sizeof(arr)
在fgets
中是否最优,现在我知道了。谢谢。 - prometeusizeof
在编译时完成它的工作。在编译时,编译器跟踪对象的完整类型[编辑:无论如何,如果类型不完整以至于大小没有包括在内,尝试使用sizeof
将失败],sizeof
基本上只是将编译器中的一部分信息“导出”到正在编译的代码中,因此在生成的代码中成为常量。sizeof
。当应用于VLA时,sizeof
评估其操作数(否则它不会),并产生VLA的实际大小。在这种情况下,结果不是一个常量。
sizeof
。 - Potatoswattersizeof
只是请求编译器为您生成该值。Sizeof
是一个编译时操作符,它拥有与编译器相同的信息(显然编译器知道数组的大小)。
这就是为什么如果你对指针使用 sizeof
,你会得到指针的宽度,而不是指向该指针的数组的大小。
int a [5]; int * p = a; assert(sizeof(* p)== sizeof(int);
- Dennis ZickefooseSizeof 只能应用于完全定义的类型。编译器将能够在编译时确定大小(例如,如果您有像 int foo [8]; 这样的声明),或者它将能够确定它必须添加代码来跟踪变量长度数组的大小(例如,如果您有像 int foo [n + 3]; 这样的声明)。
与此处其他答案相反,请注意自 C99 开始,sizeof() 不一定在编译时确定,因为数组可能是可变长度的。
如果您在本地变量上使用sizeof
,它知道您声明了多少个元素。如果您在函数参数上使用sizeof
,它就不知道了;它将参数视为指向数组的指针,并且sizeof
会给出指针的大小。
sizeof
通常在编译时计算。值得注意的例外是 C99 的可变长度数组。
int main(int argc, char **argv)
{
if (argc > 1)
{
int count = atoi(argv[1]);
int someArray[count];
printf("The size is %zu bytes\n", sizeof someArray);
}
else puts("No");
}
来自维基百科的引用:
实现sizeof运算符是编译器作者的责任,必须针对特定的语言实现以正确的方式进行。sizeof运算符必须考虑底层内存分配方案的实现,以获取各种数据类型的大小。sizeof通常是一个编译时运算符,这意味着在编译期间,sizeof及其操作数将被替换为结果值。这在C或C++编译器生成的汇编语言代码中很明显。因此,尽管它的使用有时看起来像函数调用,但sizeof仍然是一个运算符。
sizeof operator会“知道”所有基本数据类型的大小,因为结构体、联合和数组只能通过组装基本类型来构建,所以很容易确定任何类型的数组的大小。它使用基本算术运算来确定复杂类型(在编译时)。
sizeof
是编译时运算符的人,-1 给所有说它在运行时跟踪指针所指向的数组大小的人。 - Billy ONealsizeof
需要评估其参数并产生一个运行时值以获得大小。因此,我为C++部分+1,为回答问题的C部分-1,总共给出0个赞。”请注意保持原意和尽量通俗易懂。我赞同那些说sizeof
也是编译时运算符的答案。但不幸的是,这个问题还涉及到C语言的VLAs,其中sizeof
需要在运行时计算其参数的大小。所以对于C++部分我点赞,而对于C的回答我则不予点赞,结果是我一共没有给出任何赞。 - Johannes Schaub - litbi
来写入int a[i]
,甚至没有考虑C99 - 他们认为这是老派的C语言。鉴于问题,我甚至不确定 @marchinram 是否知道区别,因此向他解释更加重要。 - Johannes Schaub - litb