简体   繁体   English

sizeof运算符如何在下面的代码片段中表现?

[英]How does sizeof operator behaves in below code snippet?

Please explain the OP for below code snippet : 请解释以下代码片段的OP:

int *a="";
char *b=NULL;
float *c='\0' ; 
printf(" %d",sizeof(a[1])); // prints 4 
printf(" %d",sizeof(b[1])); // prints 1
printf(" %d",sizeof(c[1])); // prints 4

Compiler interprets a[1] as *(a+1) , so a has some address , now it steps 4 bytes ahead , then it will have some garbage value there so how is the OP 4 bytes , even if I do a[0] , still it prints 4 , although it is an empty string , so how come its size is 4 bytes ? 编译器将[1]解释为*(a + 1),所以a有一些地址,现在它前进4个字节,然后它会有一些垃圾值那么OP 4字节如何,即使我做了[0]虽然它是一个空字符串,但仍打印4,那么它的大小是4字节呢?

Here we are finding out the size of the variable the pointer is pointing to , so if I say size of a[1] , it means size of *(a+1), Now a has the address of a string constant which is an empty string , after I do +1 to that address it moves 4 bytes ahead , now its at some new address , now how do we know the size of this value , it can be an integer , a character or a float , anything , so how to reach to a conclusion for this ? 这里我们找出指针所指向的变量的大小,所以如果我说a [1]的大小,则表示*(a + 1)的大小,现在a具有字符串常量的地址,这是一个空字符串,在我对该地址+1后,它前移4个字节,现在它在某个新地址,现在我们怎么知道这个值的大小,它可以是整数,字符或浮点数,任何东西,所以如何得出结论呢?

The sizeof operator does not evaluate its operand except one case. 除一种情况外,sizeof运算符不会计算其操作数。

From the C Standard (6.5.3.4 The sizeof and alignof operators) 来自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. 2 sizeof运算符产生其操作数的大小(以字节为单位),可以是表达式或类型的带括号的名称。 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 . 否则,不评估操作数,结果是整数常量

In this code snippet 在此代码段中

int *a="";
char *b=NULL;
float *c='\0' ; 
printf(" %d",sizeof(a[1])); // prints 4 
printf(" %d",sizeof(b[1])); // prints 1
printf(" %d",sizeof(c[1])); // prints 4

the type of the expression a[1] is int , the type of the expression b[1] is char and the type of the expression c[1] is float . 表达式a[1]的类型是int ,表达式b[1]的类型是char ,表达式c[1]的类型是float

So the printf calls output correspondingly 4 , 1 , 4 . 所以printf调用输出相应的414

However the format specifiers in the calls are specified incorrectly. 但是,调用中的格式说明符指定不正确。 Instead of "%d" there must be "%zu" because the type of the value returned by the sizeof operator is size_t . 而不是"%d"必须有"%zu"因为sizeof运算符返回的值的sizeofsize_t

From the same section of the C Standard 来自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). 5两个运算符的结果值是实现定义的, 其类型(无符号整数类型)是size_t ,在<stddef.h> (和其他标题)中定义。

This is all done statically, ie no dereferencing is happening at runtime. 这都是静态完成的,即在运行时不会发生解除引用。 This is how the sizeof operator works, unless you use variable-length arrays (VLAs), then it must do work at runtime. 这是sizeof运算符的工作方式,除非您使用可变长度数组(VLA),然后它必须在运行时工作。

Which is why you can get away with sizeof :ing through a NULL pointer, and other things. 这就是为什么你可以逃脱sizeof :通过NULL指针和其他东西。

You should still be getting trouble for 你应该仍然会遇到麻烦

int *a = "";

which makes no sense. 这毫无意义。 I really dislike the c initializer too, but at least that makes sense. 我真的不喜欢c初始化器,但至少这是有道理的。

sizeof operator happens at compilation (except for VLA's). sizeof运算符在编译时发生(VLA除外)。 It is looking at the type of an expression, not the actual data so even something like this will work: 它正在查看表达式的类型,而不是实际数据,所以即使是这样的东西也会起作用:

sizeof(((float *)NULL)[1])

and give you the size of a float. 并给你一个浮子的大小。 Which on your system is 4 bytes. 你的系统上有4个字节。

Live example 实例

Even though this looks super bad, it is all well defined, since no dereference ever actually occurs. 即使这看起来非常糟糕,但它都是明确定义的,因为实际上并没有实现解除引用。 This is all operations on type information at compile time. 这是编译时对类型信息的所有操作。

sizeof()基于数据类型,因此虽然它的大小超出了分配给变量的内存范围,但它并不重要,因为它在编译时而不是运行时计算出来。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM