sizeof如何知道操作数数组的大小?

mar*_*ram 31 c c++ sizeof

这可能是一个愚蠢的问题,但是当你没有传入数组中的元素数量时,sizeof运算符如何知道数组操作数的大小.我知道它不会返回数组中的总元素,而是以字节为单位返回大小,但为了得到它,它仍然必须知道数组何时结束.只是好奇这是如何工作的.

bta*_*bta 45

sizeof在编译时解释,编译器知道数组是如何声明的(因此它占用了多少空间).调用sizeof动态分配的数组可能无法达到您想要的效果,因为(如您所述)未指定数组的结束点.

  • @xaxxon:标准没有*明确*说它在编译时被评估,但它确实说`sizeof`不评估它的操作数.操作数表达式仅对编译器有意义,因此它实际上是唯一可以实现它的地方.VLA由编译器间接处理.编译器必须生成代码来计算为VLA分配多少空间(数组成员大小*某个变量),因此它可以为该VLA上的任何`sizeof`调用重用该数字. (2认同)

sbi*_*sbi 23

你理解这个问题的根本问题可能是因为你混淆了数组和指针,正如许多人所做的那样.但是,数组不是指针.A double da[10]是十个数组double,而不是a double*,当你要求它进行评估时,编译器肯定知道它sizeof(da).编译器知道你会不会感到惊讶sizeof(double)

数组的问题在于它们在许多上下文中自动衰减指向它们的第一个元素(比如它们传递给函数时).但仍然,数组是数组,指针是指针.

  • +1用于解释这里常见误解的根源. (2认同)

Jer*_*fin 14

除了一个案例,sizeof它是编译时的事情.在编译时,编译器会跟踪对象的完整类型[编辑:嗯,它知道关于对象类型的所有内容 - 无论如何 - 如果类型不完整,那么不包括大小,尝试使用sizeof将失败],并且sizeof基本上只是将一条信息从编译器"导出"到正在编译的代码中,因此它在结果代码中基本上成为一个常量.

例外情况是sizeof应用于可变长度数组(VLA)1时.应用于VLA时,sizeof计算其操作数(否则不会),并生成VLA的实际大小.在这种情况下,结果不是常数.


1.在V99中,VLA正式成为C的一部分,但在此之前,一些编译器支持它们.虽然不是C++的正式部分,但是一些编译器(例如,g ++)也包括VLA作为C++的扩展.

  • 编译器会跟踪完整类型...除非它没有,因为类型不完整.在这种情况下,不能使用`sizeof`. (3认同)

Dav*_*eas 10

编译器知道应用程序中每种类型的大小,并且sizeof只是请求编译器为您生成该值.


Bil*_*eal 9

Sizeof是编译时运算符; 它拥有与编译器一样多的信息.(显然编译器确实知道数组的大小).

这就是为什么如果调用sizeof指针就得到指针的宽度,而不是指针所指向的数组的大小.

  • 如果取消引用指针,则会获得对数组存储的对象的引用,而sizeof将返回该指针.`int a [5]; int*p = a; assert(sizeof(*p)== sizeof(int);` (2认同)

ngr*_*oot 5

Sizeof只能应用于完全定义的类型.编译器要么能够在编译时确定大小(例如,如果你有一个类似int foo [8]的声明;),或者它将能够确定它必须添加代码来跟踪变量的大小-length数组(例如,如果你有一个像int foo [n + 3];)的声明.

相反,这里其他的答案,请注意,作为C99的,sizeof()会必然在编译时决定,因为阵列可以是可变长度.