漫谈:C语言 C++ 左值、右值、类型转换

初级代码游戏的专栏介绍与文章目录-CSDN博客

我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。

这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。


        编程不是自然语言,编程自有其内在逻辑。

目录

左值引起的BUG

左值是什么

为什么类型转换不是左值

类型转换究竟发生了什么

总结


左值引起的BUG

        编译器经常给出类似这样的BUG提示:

        “表达式必须是可修改的左值”

        “非常量引用的初始值必须是左值”

        看一下示例:

#include <iostream>

void f(int& x)
{}
int main()
{
    short a = 1;
	f((int)a);//非常量引用的初始值必须是左值
	(int)a = 5;//表达式必须是可修改的左值
	return 0;
}

左值是什么

        "左值"到底是什么啊?左值其实就是可以放在赋值(=)左边的东西,右值就是可以放在右边的东西。

        那什么可以放在赋值的左边呢?放在内存里的、有地址的东西都可以。

为什么类型转换不是左值

        那么为什么“(int) a”不可以呢?这就涉及到自然语言和编程的差异:自然语言讲概念,编程则必须落到实体:内存或者寄存器。

        自然语言的一个“数”是一个概念,有符号、无符号、存储长度都是没所谓的,只是概念上的一点限制。而对于编程,这些都要落实到具体的内存或寄存器上。

        从一个short到int,直觉上就是一个概念变化嘛,a还是那个a,但是实际呢?

        想一下,short和int长度都不一样,“(int)a”还能是原来那个a吗?

        所以“(int)a”发生了什么?发生了一个临时变量,长度是4个字节,放在寄存器里,没有内存地址,用完了就扔了。

        所以直接给“(int)a”赋值是没有意义的,程序的其他地方不可能引用这个只在寄存器里存在的对象(当然把寄存器里的临时变量赋值给一个有内存地址的变量是没问题的,这就是正常的赋值语句嘛)。

        引用参数为什么也不可以呢?因为用引用的目的是像指针一样操作外面的对象,传一个临时变量进去完全没有意义(把引用理解成指针的另一种形式是完全没有问题的)。

        即使是有符号、无符号转换,虽然长度不变,但逻辑上是一样的,都是生成一个临时对象。

类型转换究竟发生了什么

  •         整数长度增加的转换会根据是否有符号进行不同的扩展方式:

        无符号:前面扩展0

        有符号:扩展符号位

        效果:长度增加值不变。

  •         整数长度不变、仅仅是有符号、无符号改变:

        实际存储不变

        结果是负值变成很大的正数或很大的正数变成负值。

  •         长度变小的转换怎么做?

        疯了,没事别这么做。

  •         整数和浮点数转换:

        浮点数的格式和整数完全不一样啊,一定要经过专门的指令来转换

总结

  • 左值就是能赋值的对象
  • 类型转换是临时对象,不是左值


(这里是结束)

  • 26
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值