4

让我们考虑 int array[] = {2,33,4,56,7,8}; //案例A

如果 sizeof() 检查 '\0' 作为 char[] 数组的结尾!sizeof(array) 检查什么作为标记值以查找 int 数组的结尾,因此在案例 A 中数组的大小?

如果我要实现 sizeof (intArray) ,就没有访问标记值信息的自由吗?

4

3 回答 3

14

sizeof不检查任何东西。它只是看起来像一个函数调用,但它实际上是一个运算符,一个编译器技巧,用于在编译时插入编译器已知的大小。

以下是sizeof与 C 数组交互的方式:当您声明一个数组时,您将其大小指定为常量、运行时整数表达式,或者通过提供一定数量的值放入数组中来隐式指定。

当在编译时知道元素的数量时,编译器将替换sizeof(array)为实际数量。当直到运行时才知道元素的数量时,编译器会准备一个特定于实现的特殊存储位置,并将大小存储在那里。正在运行的程序将需要此信息来清理堆栈。编译器还让实现的运行时部分知道这些隐藏信息,sizeof以返回正确的值。

于 2013-10-19T02:08:58.953 回答
6

我认为您将'\0'最后带有(空终止符)的字符串文字与一般的数组混淆了。数组具有编译器1已知的编译时长度。sizeof是一个运算符,它根据数组长度和数组的基本类型给出大小。

因此,当有人这样做时int a[] = {1, 2, 3};,最后没有添加空终止字符,并且编译器将元素的数量推导出为 3。在sizeof(int)= 4 的平台上,您将得到sizeof(a)12。

混淆是因为对于char b[] = "abc";,元素计数将是 4,因为所有字符串文字都有一个'\0'自动放置的即它们自动以空值终止。不是sizeof操作员对此进行检查;它只是给出,4 * sizeof(char)因为对于sizeof所有重要的是编译时数组长度,即 4 = 1 + 由于 C 中字符串文字的性质而在字符串文字中明确说明的字符数。

但是,不是由字符串文字初始化但具有字符文字的字符数组没有这个怪癖。因此 if char c[] = {'a', 'b', 'c'};,sizeof(c)将返回 3 而不是 4 因为它不是字符串文字并且没有空终止字符。再次 sizeof 运算符(不是函数)在编译时执行此推导2

最后,如何实现 sizeof 运算符本身来执行此操作,是标准未规定的实现细节。标准谈论条件和结果。它们是如何通过实现实现的,与标准无关(或除实现它的开发人员之外的任何人)。


1 C99 引入了可变长度数组 (VLA),它允许数组具有动态大小。

2 仅对于 VLA,sizeof运算符及其操作数在运行时进行评估

于 2013-10-19T02:16:18.123 回答
2

sizeof不是一个函数,而是一个编译时运算符,它被替换为变量的大小。在真正的数组(不是指针)的情况下,它被替换为数组内容的字节大小,因为它在编译时就知道了;

尝试以下方法来说服自己:

void print_size(int[] array)
{
  printf("%u\n", sizeof(array)); //Prints 4 (= sizeof(int*))
                                 //May print 8 on 64b architectures
}

int main()
{
  int array[] = {2,33,4,56,7,8};
  printf("%u\n", sizeof(array)); //Prints 24 (= 6*sizeof(int))
  print_size(array);
  return 0;
}

这是因为,在 内部main,编译器知道 array 是一个 6int的数组,而函数print_size可以用任何数组调用,所以它的大小是事先不知道的:它被当作 int* 处理(除了我不确定它是否是左值)

于 2013-10-19T02:19:33.087 回答