令人纠结的两行代码
来源:互联网 发布:了不起的盖茨比知乎 编辑:程序博客网 时间:2024/06/04 19:59
我的主力博客:半亩方塘
以下内容系原创,转载请务必注明地址
主要参考资料:我在 Stackoverflow 上提的问题 Why the first is right but the second is wrong ?
这令人纠结的两行代码如下:
const char *cval = "nothing"; // 正确int *ival = {1, 2, 3, 4}; // 错误
为什么第一行代码正确第二行代码错误呢?既然 "nothing" 在内存中是以数组的形式存储的,那么,为什么可以定义一个 cval 指向它而不能对应地定义一个 ival 指向下面的数组呢?这确实是一个很让人纠结的问题,看下面的分析吧:
首先我们来看第一行代码:
const char *cval = "nothing";
赋值运算符右侧是一个 字符串字面值常量 ,编译器将字符串字面值常量放在内存空间中的一段连续的地址单元进行存储,且 存储的类型为 const char[] ,存储的形式是: {'n', 'o', 't', 'h', 'i', 'n', 'g', '\0'}
,这一点很重要,将赋值运算符右侧的字符串字面值赋给左侧的运算对象时,const char[] 类型将向 const char* 进行转换,由于数组名本身就是一个指针,因此这种转换是合理的,合法的,所以这部分代码是正确的;
再来看看以下的这部分代码:
int *ival = {1, 2, 3, 4};
这部分代码怎么是错的了?这是因为,编译器不允许单独将 {1, 2, 3, 4} 存储到内存中,而必须将其拷贝到某一个对象对应的连续的地址单元,显然,赋值运算符右边只是一个指向 int 的指针类型,不具备存储 {1, 2, 3, 4} 的条件,所以,这部分代码是错误的。
由于在 C 语言中,从 C99 以后,有一个称之为 compund literal 的特性,所以对于第 2 行的代码,在 C 中我们可进行如下修改使其正确:
int *ival = (int []) {1, 2, 3, 4};
上面的这行代码在 C++ 中是不成立的,有错误产生,想想为什么呢?这是因为 C 和 C++ 的语言特性是不一样的,在 C 中,上面代码中的赋值运算符右侧是一个持久的值,是一个常量对象,它被创建的时候有着持久的地址,但是,在 C++ 中,右侧运算对象只是一个临时对象,不具备持久的地址,在
(int []) {1, 2, 3, 4}
这个表达式结束时地址已经消亡,我个人认为,这是 C 和 C++ 语言 右值 规范上的差别,对于这点理由欢迎提供不同参考意见。 0 0
- 令人纠结的两行代码
- 令人纠结的英语啊!
- 令人纠结和不淡定的R14寄存器
- 令人纠结的面试题-集锦
- 令人纠结的面试题-答案
- JS中令人纠结的this
- 令人头痛的代码
- 讨论了半天结果还是令人纠结的
- 令人纠结无比的a[i++]=i++
- 纠结的libpq代码 PQexecParams
- 令人吐血的高手代码
- 通俗|令人拍案叫绝的Wasserstein GAN 及代码(WGAN两篇论文的中文详细介绍)
- C++ Primer_数组与指针_那些令人纠结的const
- 一个令人纠结的弹窗问题,鼠标放上去显示div,鼠标离开div消失
- 深度解析Windows最令人迷惑的两大进程
- 深度解析Windows最令人迷惑的两大进程
- 深度解析Windows最令人迷惑的两大进程
- 深度解析Windows最令人迷惑的两大进程
- POJ 3468 A Simple Problem with Integers 树状数组 区间修改 区间查询
- maximo序列自动修复
- 屈博老师带你浅谈Java中的对象
- c/c++成长之捷径
- spring MVC3.0.5搭建全程
- 令人纠结的两行代码
- Surface Pro 3 今夜见,Surface Mini 将缺席
- MVC中的扩展点:ActionResult
- 记忆里总有着各种各样的故事
- ORACLE数据库的备份恢复(5)
- net start telnet的问题
- 企业微信的公众账号要怎么推广呢?
- ORACLE数据库的备份恢复(6)
- 16、从头学Android之Service初步一