这是在dev c ++ windows中编译的代码:
#include <stdio.h>
int main() {
int x = 5;
printf("%d and ", sizeof(x++)); // note 1
printf("%d\n", x); // note 2
return 0;
}
Run Code Online (Sandbox Code Playgroud)
x执行注释1后,我希望是6 .但是,输出是:
4 and 5
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么x在注1后没有增加?
pmg*_*pmg 520
从C99标准(重点是我的)
6.5.3.4/2
sizeof运算符产生其操作数的大小(以字节为单位),该操作数可以是表达式或类型的带括号的名称.大小由操作数的类型确定.结果是整数.如果操作数的类型是可变长度数组类型,则计算操作数; 否则,不评估操作数,结果是整数常量.
cod*_*ict 186
sizeof是一个编译时运算符,因此在编译时sizeof它的操作数被结果值替换.的操作数没有评估(除了当它是一个可变长度数组)在所有; 只有结果的类型才重要.
short func(short x) { // this function never gets called !!
printf("%d", x); // this print never happens
return x;
}
int main() {
printf("%d", sizeof(func(3))); // all that matters to sizeof is the
// return type of the function.
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
2
Run Code Online (Sandbox Code Playgroud)
作为short占据我的机器上2个字节.
将函数的返回类型更改为double:
double func(short x) {
// rest all same
Run Code Online (Sandbox Code Playgroud)
将8作为输出.
hug*_*omg 33
sizeof是一个编译时内置运算符,不是一个函数.在没有括号的情况下使用它会变得非常清楚:
(sizeof x) //this also works
Run Code Online (Sandbox Code Playgroud)
Sha*_*our 21
注意
这个答案是从一个副本合并而来,这解释了迟到的日期.
原版的
除了可变长度数组, sizeof不会评估其参数.我们可以从C99标准部分草案中看到这一点:6.5.3.4 运营商第2段的尺寸说:
sizeof运算符产生其操作数的大小(以字节为单位),该操作数可以是表达式或类型的带括号的名称.大小由操作数的类型确定.结果是整数.如果操作数的类型是可变长度数组类型,则计算操作数; 否则,不评估操作数,结果是整数常量.
评论(现已删除)询问是否会在运行时评估此类内容:
sizeof( char[x++] ) ;
Run Code Online (Sandbox Code Playgroud)
事实上,这样的事情也会起作用(看到它们都是现场的):
sizeof( char[func()] ) ;
Run Code Online (Sandbox Code Playgroud)
因为它们都是可变长度数组.虽然,我认为其中任何一个都没有多少实际用途.
注意,可变长度数组在草案C99标准部分6.7.5.2 数组声明符第4段中介绍:
[...]如果size是一个整型常量表达式,并且元素类型具有已知的常量大小,则数组类型不是可变长度数组类型; 否则,数组类型是可变长度数组类型.
更新
在C11中,VLA案例的答案发生了变化,在某些情况下,未指定是否评估了大小表达式.从部分6.7.6.2 数组声明符说:
[...]如果size表达式是sizeof运算符的操作数的一部分,并且更改size表达式的值不会影响运算符的结果,则无法指定是否计算size表达式.
例如在这样的情况下(见它):
sizeof( int (*)[x++] )
Run Code Online (Sandbox Code Playgroud)
Naw*_*waz 11
由于sizeof未评估运算符的操作数,您可以执行以下操作:
int f(); //no definition, which means we cannot call it
int main(void) {
printf("%d", sizeof(f()) ); //no linker error
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在线演示:http://ideone.com/S8e2Y
也就是说,f如果sizeof只使用它,则不需要定义函数.这种技术主要用于C++模板元编程,因为即使在C++中,操作数sizeof也不会被评估.
为什么这样做?它的工作原理是因为sizeof运算符不对值进行操作,而是对表达式的类型进行操作.因此,当您编写时sizeof(f()),它会根据表达式的类型进行操作f(),而这只是函数的返回类型f.返回类型总是相同的,无论函数在实际执行时返回什么值.
在C++中,你甚至可以这样:
struct A
{
A(); //no definition, which means we cannot create instance!
int f(); //no definition, which means we cannot call it
};
int main() {
std::cout << sizeof(A().f())<< std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然而,看起来sizeof,我首先A通过编写创建一个实例,A()然后通过写入调用f实例上的函数A().f(),但是没有这样的事情发生.
这是另一个解释其他一些有趣属性的主题sizeof:
| 归档时间: |
|
| 查看次数: |
28623 次 |
| 最近记录: |