【 C 】对左值与右值的一些个人思考

举报
李锐博恩 发表于 2021/07/15 23:54:36 2021/07/15
【摘要】 今天重温C语言的指针,看的书是《C和指针》,关于左值和右值以及指针表达式的内容看得甚是迷惑与煎熬,怎么会这么难理解,指针表达式又是作为左值又一会作为右值,而且二者有着不一样的含义,为什么当年学习C语言的时候没有遇到这些头疼的问题呢?这就是没有学好C的原因吧。 功夫不负有心人,认真思考,对比总结,竟有些头绪,记录下来吧。以免以后又忘了没有参考。 先谈谈左值与右值的定义吧。...

今天重温C语言的指针,看的书是《C和指针》,关于左值和右值以及指针表达式的内容看得甚是迷惑与煎熬,怎么会这么难理解,指针表达式又是作为左值又一会作为右值,而且二者有着不一样的含义,为什么当年学习C语言的时候没有遇到这些头疼的问题呢?这就是没有学好C的原因吧。

功夫不负有心人,认真思考,对比总结,竟有些头绪,记录下来吧。以免以后又忘了没有参考。


先谈谈左值与右值的定义吧。

左值就是那些能够出现在赋值符号左边的东西;因此,右值就是那些可以出现在赋值符号右边的东西。

举个例子:

a = b + 25;

a是一个左值,因为它标识了一个可以存储结果值的地点;b + 25是一个右值,因为它指定了一个值。

它们可以互换吗?也就是 b + 25 = a;

原先用作左值的a,此时也可以用作右值,因为每个位置包含一个值。然后 b + 25不能作为左值,因为它并未标识一个特定的位置。因此,这条赋值语句是错误的。

注意,当计算机计算b+25时,它的结果必然保存于机器的某个地方。但是,程序员并没有办法预测该结果会存储于什么地方,也无法保证这个表达式的值下次还会存储于那个地方。其结果是,这个表达式不是一个左值。基于同样的道理,字面值(常数)也都不是左值。


看了上面的总结,是不是有这样的感觉,变量可以作为左值,而表达式不能作为左值?

这是一种错觉,事实情况下并非如此,下面就专门总结这种情况。

第一个例子:


  
  1. int a[30];
  2. ...
  3. a[b+10] = 0;

[]是下表引用操作符,所以左边实际上是一个表达式,但它却是一个合法的左值,因为它标识了一个特定的位置,这个数组的某个特定的位置。

第二个例子:


  
  1. int a, *p;
  2. ...
  3. p = &a;
  4. *p = 20;

第一条赋值语句自然不必多说,指向整型变量的指针变量指定了一个特定的位置存放变量a的地址,p可以作为左值;

第二个赋值语句是需要重点分析的:

理解这个表达式作为左值之前,先了解一下*这个操作符。

*这是一个间接访问的操作符。

通过一个指针访问它所指向的地址的过程称为间接访问(indirection)或解引用指针(dereferencing the pointer)。

是不是有点难以理解?

下面直接给出上面的*p作为左值所表达的意义:*p作为左值代表的是指针变量p所指向的地址。

或者说,指针p的值是内存中某个特定位置的地址,*操作符使机器指向那个位置。当它作为左值使用时,这个表达式指定需要进行修改的位置。当它作为右值时,它就是提取当前存储于这个位置的值。

还不是太明白?那。。。

举个实际的例子:


  
  1. //下面是这些变量的声明
  2. int a = 112, b = -1;
  3. float c = 3.14;
  4. int *d = &a;
  5. float *e = &c;

d的值是a的位置(&a),假设为100;

当我们对d使用间接访问操作符时,它表示访问内存位置100并察看那里的值。

因此,*d的右值是112;而它的左值表示它指向的那个位置本身,因此是100本身。

我想举了这个实际的例子,大家已经明白了,左值与右值的含义了,不过还是免不了要愤怒。。。(真jr难理解,真jr麻烦!)哎,只能用熟能生巧来安慰自己了。


对于指针表达式,我下篇博文专门介绍一些有深度的内容,可谓是扑朔迷离,但是如果想深入掌握这门语言,还是要下功夫去研究。

本文参考《C和指针》这本书,但是里面画图的做法,我是真的接受不了,让我徒增迷惑。

 

文章来源: reborn.blog.csdn.net,作者:李锐博恩,版权归原作者所有,如需转载,请联系作者。

原文链接:reborn.blog.csdn.net/article/details/82154166

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。