本帖最后由 zzq宁静致远 于 2013-11-20 21:21 编辑
C语言技术公开课第三讲 const问题
昨天C语言技术公开课第三讲,有一个问题课后有人多次问到,const。既然大家问到,我就回答。朱兆祺ForARM要做的就是有问必答,不合理问题除外啊。 昨天的问题是: int main(int argc, char* argv[])
{
const int iNumber = 10 ;
printf(" iNumber = %d n" , iNumber) ;
int *ptr = (int *)(&iNumber) ;
*ptr = 100 ;
printf(" iNumber = %d n" , iNumber) ;
return 0;
} 我昨天上课给大家讲在VS2010编译器下答案为:10,10. 有人提出疑问: 1.这个程序不会报错吗? 2.答案应该是:10,100. 这个程序不会报错,其实答案是10,10还是10,100.这个跟编译器是否进行了优化是有关系的。我们一句一句来分析。首先iNumber是一个只读的变量,值为10.接下来使用ptr指向的地址(即为iNumber所在地址存放的值)为100.注意,iNumber所占的内存空间存放的值是100.在这里给大家举个例子,朱兆祺的办公室在201,所以每当有人问:“朱兆祺在哪个办公室”,答曰:“201”。有一天,朱兆祺被贬职了,在208了。有一天又有人问:“朱兆祺在哪个办公室”,前台答曰:“201”。因为没有人告诉了前台,朱兆祺搬过去了208.这就是VS2010编译器的效果,因为编译器进行了优化,直接取出了当初的赋值,如果没有进行优化,那么就应该直接取出*ptr赋值之后的地址的值。 不理解?没关系,朱兆祺就知道你会这么说,我是不会给你留下把柄的。再来。朱兆祺在*ptr赋值之前设定一个断点。 0a,也就是10.再单步运行: 64,也就是100,也就是说这个时候地址中的值已经改变,成为了100.201办公室已经换人了,不是朱兆祺了。但是为什么输出还是10呢,因为编译器进行了优化,直接还是输出了10.前台进行“条件反射”,故答曰:“朱兆祺在201”。不相信是这样,没事。再来。上汇编!!!我就不信你不死心。 认真看,仔细看。 汇编很醒目告诉你,直接输出的10.这就是前台为什么说“朱兆祺在201”,因为前台不知道朱兆祺换办公室了,公司没有告知前台。但是GCC编译器进行了没有进行优化这一步,前台得到了通知,所以前台知道“朱兆祺在208”。 如果这个程序加一个关键字:volatile。 volatile const int iNumber = 10 ;
这个关键字是告诉编译器,要进行优化iNumber这个只读变量。汇编的结果是这样: volatile的作用是告诉编译器不要进行优化,直接从地址从将值给我取出来。这下彻底死心了吧。 朱兆祺ForARM,下期更精彩。
|