`sizeof` 如何区分指针和数组?
How does `sizeof` distinguish a pointer from an array?
请注意,如果 a
是一个数组名称,那么 sizeof(a)
将产生整个数组的大小 a
而不是指向其元素之一的指针的大小。
所以比如sizeof
如何区分数组a
和指针b
?
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int a[4] = {1, 2, 3, 4};
int *b = a;
printf("sizeof\(a) = %ld\n", sizeof(a));
printf("sizeof\(b) = %ld\n", sizeof(b));
return EXIT_SUCCESS;
}
打印如下:
sizeof(a) = 16
sizeof(b) = 8
sizeof
is a compile-time operator. It is computed by the compiler (and is almost always a constant, VLA例外)。
编译器显然知道变量何时引用数组或指针,因为它必须知道每个变量的类型(数组类型与指针类型不同)。
请注意,在 C 中,数组可以 decay 变成指针(例如,当您将数组作为参数传递给例程时)。这是C语言最棘手的地方之一(看不懂就翻翻C编程书)。
编译器会密切关注您在代码中定义的每个名称(数组、整数、指针......)、地址和大小,并将其与其他信息一起保存在 table 中.因此,当您使用 sizeof
运算符时,编译器只是将表达式替换为该名称的大小,并使用硬编码数字编译您的程序,即:操作数的大小,这就是为什么您不能在 运行 时将 sizeof
与动态大小的结构一起使用。
因此,在您的示例中,编译器有一个 table like
name____address____size_____.....(其他)
a_____1000_____16_____.....(数组)<<<
b_____1016_____8_____.......
.._____1024_____.._____.......
当你使用像
这样的表达式时
printf("sizeof\(a) = %ld\n", sizeof(a));
编译器将(在其中一个翻译阶段)替换为
printf("sizeof\(a) = %ld\n", 16);
然后继续编译工作
请注意,如果 a
是一个数组名称,那么 sizeof(a)
将产生整个数组的大小 a
而不是指向其元素之一的指针的大小。
所以比如sizeof
如何区分数组a
和指针b
?
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int a[4] = {1, 2, 3, 4};
int *b = a;
printf("sizeof\(a) = %ld\n", sizeof(a));
printf("sizeof\(b) = %ld\n", sizeof(b));
return EXIT_SUCCESS;
}
打印如下:
sizeof(a) = 16
sizeof(b) = 8
sizeof
is a compile-time operator. It is computed by the compiler (and is almost always a constant, VLA例外)。
编译器显然知道变量何时引用数组或指针,因为它必须知道每个变量的类型(数组类型与指针类型不同)。
请注意,在 C 中,数组可以 decay 变成指针(例如,当您将数组作为参数传递给例程时)。这是C语言最棘手的地方之一(看不懂就翻翻C编程书)。
编译器会密切关注您在代码中定义的每个名称(数组、整数、指针......)、地址和大小,并将其与其他信息一起保存在 table 中.因此,当您使用 sizeof
运算符时,编译器只是将表达式替换为该名称的大小,并使用硬编码数字编译您的程序,即:操作数的大小,这就是为什么您不能在 运行 时将 sizeof
与动态大小的结构一起使用。
因此,在您的示例中,编译器有一个 table like
name____address____size_____.....(其他)
a_____1000_____16_____.....(数组)<<<
b_____1016_____8_____.......
.._____1024_____.._____.......
当你使用像
这样的表达式时printf("sizeof\(a) = %ld\n", sizeof(a));
编译器将(在其中一个翻译阶段)替换为
printf("sizeof\(a) = %ld\n", 16);
然后继续编译工作