为什么sizeof在未设置元素时返回值?

时间:2012-08-31 13:21:45

标签: c

#include <stdio.h>

int main(void) {

int TEST_HB[10]; 
memset(TEST_HB,'9', sizeof( TEST_HB));

printf("%c\n",TEST_HB[9]);

printf ("TEST_HB[10]=%d\n",sizeof( TEST_HB[40]));   // shows 4
printf ("Arraysize=%d\n",(sizeof(int)*10));     // gets the expectected results
return 0;

} 

我相信sizeof(myArray)应该以字节为单位返回数组的总大小。但是,为什么sizeof( TEST_HB[40])在未定义时会返回4?

4 个答案:

答案 0 :(得分:7)

TEST_HB[40]是一个类型为int的表达式(如果进行求值,则为未定义的行为,因为40对于数组来说太大了)。因此,sizeof(TEST_HB[40])是您实施时int的大小:4是典型的。

重要的是,sizeof不会评估其操作数,除非它是VLA - 它只是使用该类型。因此,即使没有TEST_HB[40]这样的对象,您的代码也会定义行为。

实际上,我说它已经定义了行为,但是sizeof评估为键入size_t,而不是%d。在可用的地方使用%zu或查阅编译器文档。你已经离开了它,因为你已经很幸运地使用了varargs调用约定,而且size_t与你实现中的int大小相同,或者你的实现是little-endian,或者两者。

sizeof不评估操作数这一事实的一个相当普遍的用法是写这样的东西:

struct Foo *foo = malloc(sizeof(*foo) * number_of_foos_required);

sizeof(*foo)sizeof(struct Foo)相同,但对于某些人来说,“显然”使用的尺寸更合适。在分配内存之前,foo未初始化,因此sizeof实际上并未使用foo的值。

不太常见的用法,用于演示sizeof

的行为
int i = 0;
printf("%d\n", i);
printf("%d\n", (int)(sizeof(i++))); // i++ is not executed
printf("%d\n", i);

答案 1 :(得分:2)

sizeof( TEST_HB)

是数组的大小(int[10]的大小)

sizeof(TEST_HB[40])

是数组元素的大小(int的大小)。

请注意,数组中不存在元素TEST_HB[40](您的数组只有10个元素),但由于sizeof不评估其操作数,它仍然有效。

答案 2 :(得分:1)

sizeof运算符产生其操作数的大小。如果要获得数组的大小,则应使用sizeof TEST_HB代替(不需要括号)。 TEST_HB[40]的确属于int,而TEST_HB的类型为int[10]。请注意,除了可变长度数组之外,sizeof运算符的操作数未被计算,因此不会导致未定义的行为。

  

C11§6.5.3.4sizeof和_Alignof运算符

     

sizeof运算符产生其操作数的大小(以字节为单位)   可以是表达式或类型的带括号的名称。

此外,使用非常量大写标识符被视为错误的C编程风格。

答案 3 :(得分:0)

sizeof( TEST_HB[40])返回int数组位置40中int的大小,因此大小为4个字节。