sizeof 运算符在以下代码片段中的行为如何?
How does sizeof operator behaves in below code snippet?
请解释以下代码段的 OP:
int *a="";
char *b=NULL;
float *c='[=10=]' ;
printf(" %d",sizeof(a[1])); // prints 4
printf(" %d",sizeof(b[1])); // prints 1
printf(" %d",sizeof(c[1])); // prints 4
编译器将 a[1] 解释为 *(a+1),所以 a 有一些地址,现在它提前 4 个字节,然后它会有一些垃圾值,所以 OP 4 个字节如何,即使我做了 a[0] ,它仍然打印 4 ,虽然它是一个空字符串,那么它的大小为什么是 4 个字节?
在这里我们找出指针指向的变量的大小,所以如果我说 a[1] 的大小,它意味着 *(a+1) 的大小,现在 a 有 a 的地址字符串常量,它是一个空字符串,在我对该地址执行 +1 后,它向前移动 4 个字节,现在它在某个新地址,现在我们如何知道这个值的大小,它可以是整数、字符或float 什么的,怎么得出这个结论?
sizeof
运算符发生在编译时(VLA 除外)。它查看的是表达式的类型,而不是实际数据,所以即使是这样的东西也能工作:
sizeof(((float *)NULL)[1])
并给你一个浮点数的大小。在你的系统上是 4 个字节。
尽管这看起来非常糟糕,但它的定义很明确,因为实际上并没有发生取消引用。这是编译时对类型信息的所有操作。
sizeof()
基于数据类型,因此虽然它的大小超出了分配给变量的内存范围,但这并不重要,因为它是在编译时计算出来的,而不是 运行时间。
这一切都是静态完成的,即在运行时不会发生取消引用。这就是 sizeof
运算符的工作方式,除非您使用可变长度数组 (VLA),否则它必须在运行时工作。
这就是为什么您可以 sizeof
逃脱的原因:通过 NULL
指针和其他东西。
你应该还在为
找麻烦
int *a = "";
这毫无意义。我也真的不喜欢 c
初始化程序,但至少这是有道理的。
除一种情况外,sizeof 运算符不计算其操作数。
来自 C 标准(6.5.3.4 sizeof 和 alignof 运算符)
2 The sizeof operator yields the size (in bytes) of its operand, which
may be an expression or the parenthesized name of a type. The size is
determined from the type of the operand. The result is an integer.
If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the
result is an integer constant.
在此代码段中
int *a="";
char *b=NULL;
float *c='[=10=]' ;
printf(" %d",sizeof(a[1])); // prints 4
printf(" %d",sizeof(b[1])); // prints 1
printf(" %d",sizeof(c[1])); // prints 4
表达式a[1]
的类型是int
,表达式b[1]
的类型是char
,表达式c[1]
的类型是float
.
所以printf
调用输出对应4
,1
,4
.
但是调用中的格式说明符指定不正确。而不是 "%d"
必须有 "%zu"
因为 sizeof
运算符返回的值的类型是 size_t
.
来自 C 标准的同一部分
5 The value of the result of both operators is implementation-defined,
and its type (an unsigned integer type) is size_t, defined in
<stddef.h>
(and other headers).
请解释以下代码段的 OP:
int *a="";
char *b=NULL;
float *c='[=10=]' ;
printf(" %d",sizeof(a[1])); // prints 4
printf(" %d",sizeof(b[1])); // prints 1
printf(" %d",sizeof(c[1])); // prints 4
编译器将 a[1] 解释为 *(a+1),所以 a 有一些地址,现在它提前 4 个字节,然后它会有一些垃圾值,所以 OP 4 个字节如何,即使我做了 a[0] ,它仍然打印 4 ,虽然它是一个空字符串,那么它的大小为什么是 4 个字节?
在这里我们找出指针指向的变量的大小,所以如果我说 a[1] 的大小,它意味着 *(a+1) 的大小,现在 a 有 a 的地址字符串常量,它是一个空字符串,在我对该地址执行 +1 后,它向前移动 4 个字节,现在它在某个新地址,现在我们如何知道这个值的大小,它可以是整数、字符或float 什么的,怎么得出这个结论?
sizeof
运算符发生在编译时(VLA 除外)。它查看的是表达式的类型,而不是实际数据,所以即使是这样的东西也能工作:
sizeof(((float *)NULL)[1])
并给你一个浮点数的大小。在你的系统上是 4 个字节。
尽管这看起来非常糟糕,但它的定义很明确,因为实际上并没有发生取消引用。这是编译时对类型信息的所有操作。
sizeof()
基于数据类型,因此虽然它的大小超出了分配给变量的内存范围,但这并不重要,因为它是在编译时计算出来的,而不是 运行时间。
这一切都是静态完成的,即在运行时不会发生取消引用。这就是 sizeof
运算符的工作方式,除非您使用可变长度数组 (VLA),否则它必须在运行时工作。
这就是为什么您可以 sizeof
逃脱的原因:通过 NULL
指针和其他东西。
你应该还在为
找麻烦int *a = "";
这毫无意义。我也真的不喜欢 c
初始化程序,但至少这是有道理的。
除一种情况外,sizeof 运算符不计算其操作数。
来自 C 标准(6.5.3.4 sizeof 和 alignof 运算符)
2 The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.
在此代码段中
int *a="";
char *b=NULL;
float *c='[=10=]' ;
printf(" %d",sizeof(a[1])); // prints 4
printf(" %d",sizeof(b[1])); // prints 1
printf(" %d",sizeof(c[1])); // prints 4
表达式a[1]
的类型是int
,表达式b[1]
的类型是char
,表达式c[1]
的类型是float
.
所以printf
调用输出对应4
,1
,4
.
但是调用中的格式说明符指定不正确。而不是 "%d"
必须有 "%zu"
因为 sizeof
运算符返回的值的类型是 size_t
.
来自 C 标准的同一部分
5 The value of the result of both operators is implementation-defined, and its type (an unsigned integer type) is size_t, defined in
<stddef.h>
(and other headers).