关于指针左值和右值得问题!!!

aronchen2020 2013-08-29 10:36:16

int a=112;//假设a的地址为1000
int *p=&a;
*p的右值是112——位置1000的内容,它的左值是位置1000本身。(C与指针里的话)
这句话怎么理解???
...全文
633 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
大尾巴猫 2013-09-10
  • 打赏
  • 举报
回复
p是左值,没问题 &a是右值,也没问题 *p是左值吧,能放在等号左边的。 *p = 20 这个表达式也是左值吧,也能放在等号左边。 (*p = 20) = 10 vs2010编译通过。
lm_whales 2013-09-10
  • 打赏
  • 举报
回复
只怕作者的原意是 *p的值,是个左值, 左值可以当作右值使用,右值不能当左值用. 左值可以出现在=的任何一方, 出现在=右方的左值,是把左值当作右值使用,这是非常正常的. 右值,不能当作左值使用. 能够(单独)出现在=左方的是左值(实际是左右值,左值总是可以当作右值使用) 只能够出现在=右方的,是右值(纯粹的右值),不能当作左值使用. 左值代表地址单元,右值代表数据本身. 地址单元里的数据,是左值变量的右值的含义. 右值包括,纯数据,比如常数100,字符串常量"12345"等 以及地址单元中存储的数据.比如x ,这是左值当作右值使用代表的意义. 以及一些常变量(有确切地址的常量,可以象变量一样有个名字,其实就是变量,只是右值化了,不能当左值使用了)的含义. 左值代表存储器的一个单元. 这是一个物理概念,不仅仅是个地址(地址不过是个编号,是个数值而已),是个实实在在的东西. 右值代表数据,一个数值而已.
woshinia 2013-08-31
  • 打赏
  • 举报
回复
引用 8 楼 woshinia 的回复:
最简单的理解就是,在编译形成的符号表里,左值只会它的地址,而右值只会记录它的值。 “*p的右值是112——位置1000的内容,它的左值是位置1000本身。”这句话显然翻译的不够好,千万别迷信书中的一些读不通或者有歧义的话,尤其是翻译类的,那只是因为翻译的人水平不够,并不需要怀疑自己的理解力。爱因斯坦可以让一个老太太明白什么是相对论,而中国很多物理老师却无法告诉聪明的学生什么是相对论。 这句话的歧义在于:1,*p的右值,左值和右值都是一个名词,但这个“的”的存在,就表示了是*p产生的右值,那么*p只能理解成一个表达式,单目运算符*,解引用。这个我想很多人第一眼很难看出来,也是翻译差的一个表现。 2,解引用牵涉到的值有112(返回值),1000(p的值,即输入参数),那么理解起来就简单了,一般来说,一个表达式的右边就是右值,左边就是左值,显然,一个函数中的话,输入参数就是右值,返回值就是右值。 也符合那段话。 但原话很有问题,首先它的左值,它指代什么,当然由1中的分析,只能指代*p,但确实要更严谨一些,因为它之前出现了一个新的东西“位置1000的内容”,很可能就误解了。然后“位置1000本身”,不知道这里强调“本身”是什么意思,这个本身是指位置1000,还是*p,通过分析肯定只能指位置1000,因为右值不可能是*p,*p是表达式。一段简单的概念,需要柯南式的分析,我看译者也只是每个单词翻了下字典吧。
笔误,更正。 显然,一个函数中的话,输入参数就是右值,返回值就是左值。但这里却正好与原话中的结论,相反,为什么呢?那就要结合代码了,int *p=&a;既然原话是在解释这句的时候出现的,那么有理由相信,作者(不是译者)的意思是,“的右值”之前那个表达式应该是一个赋值操作,即p=&a。这个传入为变量a的值,返回为一个地址值(也可以看成是指针),按照左边是左值,右边是右值,那么就得到话中的结论:112为右值,地址1000为左值。但按照我的理解,“112为右值,地址1000为左值”完全是错的,p=&a这个表达式中,变量p是左值,a的地址1000是右值。 因为左值的属性就是可修改,a的地址可修改么?变量p的值才是能修改吧。 最悲剧的是,vs里的提示都是“Error:表达式必须是可修改的左值”,简化一下就是“表达式是左值”,难道程序员的语文都是数学老师教的,还是说只有我一个人怀疑这些句子。
woshinia 2013-08-31
  • 打赏
  • 举报
回复
最简单的理解就是,在编译形成的符号表里,左值只会它的地址,而右值只会记录它的值。 “*p的右值是112——位置1000的内容,它的左值是位置1000本身。”这句话显然翻译的不够好,千万别迷信书中的一些读不通或者有歧义的话,尤其是翻译类的,那只是因为翻译的人水平不够,并不需要怀疑自己的理解力。爱因斯坦可以让一个老太太明白什么是相对论,而中国很多物理老师却无法告诉聪明的学生什么是相对论。 这句话的歧义在于:1,*p的右值,左值和右值都是一个名词,但这个“的”的存在,就表示了是*p产生的右值,那么*p只能理解成一个表达式,单目运算符*,解引用。这个我想很多人第一眼很难看出来,也是翻译差的一个表现。 2,解引用牵涉到的值有112(返回值),1000(p的值,即输入参数),那么理解起来就简单了,一般来说,一个表达式的右边就是右值,左边就是左值,显然,一个函数中的话,输入参数就是右值,返回值就是右值。 也符合那段话。 但原话很有问题,首先它的左值,它指代什么,当然由1中的分析,只能指代*p,但确实要更严谨一些,因为它之前出现了一个新的东西“位置1000的内容”,很可能就误解了。然后“位置1000本身”,不知道这里强调“本身”是什么意思,这个本身是指位置1000,还是*p,通过分析肯定只能指位置1000,因为右值不可能是*p,*p是表达式。一段简单的概念,需要柯南式的分析,我看译者也只是每个单词翻了下字典吧。
发型不乱hy 2013-08-30
  • 打赏
  • 举报
回复
int *p = &a; 这句话与下边两句话是一样的意思: int *p; p = &a; *在你的那句话里是解引用操作符,p本身是一个int型指针,值为1000,*p就是取1000这个地址的值,也就是112,“*p的右值是112——位置1000的内容”这里*p应该是对p这个地址接引用的意思,而不是声明一个int型指针的意思,比如: int *p = &a; int c = *p;//这个时候c就是112 如果执行以下代码: printf("%d %d", *p, p); 会输出 112 1000
七擒关羽 2013-08-30
  • 打赏
  • 举报
回复
这个是一个浅拷贝,指针指向了原int常量 int a = 112;//有一个内存,内容是112,地址是1000 int *p=&a;//定义了一个指针,进行地址赋值,那么p为1000,*p为112 所以解释 *p的右值就是*p 112,*p的左值是p 1000地址本身
aronchen2020 2013-08-30
  • 打赏
  • 举报
回复
赵老湿,看你笑的这么猥琐,你能说点有用的不
BT_Dana 2013-08-30
  • 打赏
  • 举报
回复
引用 楼主 ckchenwei01 的回复:

int a=112;//假设a的地址为1000
int *p=&a;
*p的右值是112——位置1000的内容,它的左值是位置1000本身。(C与指针里的话)
这句话怎么理解???
a和p都是变量, 只不过一个是int型变量, 一个是指针变量而已. 变量a的地址是1000, 这个地址里的内容是112; 变量p的地址是xxxx, 这个地址里的内容是1000. 不知道这样解释够吗
xuechw5 2013-08-30
  • 打赏
  • 举报
回复
C语言 右值指定一个常量 左值指定一个地址 赋值就是把右值所示的常量放到左值所示的地址中 *p做右值时表示112 做左值时就表示*p的地址(&(*p)) 新手 勿喷
aronchen2020 2013-08-30
  • 打赏
  • 举报
回复
赵老湿,我跪了……
赵4老师 2013-08-30
  • 打赏
  • 举报
回复
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步对应汇编一行! VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。) 想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单! 指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认: 有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物; 而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。 这辈子不看内存地址和内存值;只画链表、指针示意图,画堆栈示意图,画各种示意图,甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗?本人深表怀疑! 这辈子不种麦不收麦不将麦粒拿去磨面;只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头,压面条,烤面包,……能从本质上理解面粉、理解面食吗?本人深表怀疑!! 提醒: “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 (Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。) 想要从本质上理解C指针,必须学习C和汇编的对应关系。” 不是一回事! 不要迷信书、考题、老师、回帖; 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实! 有人说一套做一套,你相信他说的还是相信他做的? 其实严格来说这个世界上古往今来所有人都是说一套做一套,不是吗? 不要写连自己也预测不了结果的代码! 电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址; 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息…… 十字链表交换任意两个节点C源代码(C指针应用终极挑战)http://download.csdn.net/detail/zhao4zhong1/5532495

69,336

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧