7815

帖子

56

TA的资源

裸片初长成(中级)

41
 
为什么 * (地址)解运算符 是 运行时的行为 和 强制转换 是 编译时行为

首先,这里解释一下 * 这个东东。
和很多C元素一样,同一个东西,因为出现的位置和组合的不同,经常会出现多义。
比如 *

在四则运算里,它自然是我们熟悉的 乘法。
而如果它跟了一个,我不太想说什么 左值结合性之类地破玩意。
因为这俩玩意都太理论性。
对于左值我还稍微比较能说得清楚,但是对结合性我就仨字: 懒得记。
这里简单的说,(听说这也经过修改现在比较被接受的一种解释方式)

左值,怎么理解呢?把他理解成一个容器,或者说一个洞。
一个什么洞,一个可以往里面填东西的洞。
这个洞当然是内存上的一个洞。
其实说白了,就是所有可以引用到内存上一段特定空间,可以对它进行赋值或者操作的 东东,都可以称为 左值。

容器,甚至 是对象(前面那个 东东,我是故意用 东东 ,而不是 对象的)
因为在编程里,,一谈对象就很容易变成 面向对象这种东西。
而我作为一个没啥文化的码农,真心表示不懂面向对象,所以我从来不谈对象(当然我谈结婚对象!!)

所以,我有意避免使用这种模棱两可的术语。
因为我和free叔叔不同,我不懂c++,似乎可预见时间里也没打算去学习c++,所以,俺不太习惯像free叔叔前面说的那样
他在提到 *的时候,他用的术语是  reference。这个其实就是引用的意思吧。

好了不扯远了,我们回到正题。

*和&,当它们后面跟着的是一个左值,我们可以说,这是一个地址,或者一个变量神马的时候。
*的专业名字叫 解地址运算符——你们老实交代,有多少人和我一样,脑子里就是记着,把这个写到一个指针前就可以取出指针地址值指向的内存的内容的?
&的专业名字叫 取地址符。

这俩玩意,和 四则运算一样,是一对 互逆操作。
当然了,它们具体是干嘛的,你当然知道了,我也就不废话了。

在这里我罗罗嗦嗦写了这么多左值内存的东西,只想说明一点。
它们跟的操作符,都是内存上的一个地址。
而它们本身又是运算符,运算符是神马意思。

显然就是要计算一下用的东西嘛.......

虽然操作数可以是一个字面量(常数),但运算这种东西,必然是可以在运行中,用来操作随时变化的变量的。
因此,我就是这么蛮力地理解了,*解地址运算是一个 运行时行为的。
严格来说,任何一个运算,都应该是 运行时行为。

否则,运算(operate)还有什么存在的意义?

接下来是,那为什么转换是一个 编译时行为。

首先我们要回想起两个重要细节:
1.其实严格来说,对于运算符来说,它是要求所有操作数都是同一数据类型的,而且是严格的一致的。
比如说,我们人可以很无所谓的 计算 0.34+10.
但机器不行,因为 不同数据类型的数,连存储格式都不一致。
不要说 浮点数用的是 指数形式 和 整型 不是一回事。
就是同样都是整型,也因为机器字长不同,而不能实现直接运算。

比如4字节数和 2字节数相加,得到的结果,如果你付给一个2字节数,就不行,为什么?因为结果可能超出2字节所能表达的最大值。

所以,编译器在编译时,编译这个行为,除了我们鲜为人知的所谓朗朗上口的把高级语法翻译对应的机器码以外,还涉及很多地址上的安排,内存的分配行为。
计算机其实很蠢,它不是人,你不能指望它这么智能。
如果你不把一切安排好,它就会捣乱——

这一点其实也是我非常不喜欢看到的一个现象:
一个普通大众可以要求计算机像人一样贴心,但一个专业的程序员不应该。尤其是,你明明更理解计算机的缺陷所在和根本原理性的原因。

下面这句话对于所有技术都适用:
如果我们希望一个技术实现我们想要的效果,那我们至少应该按照这个技术所期待的输入,去给我们想要的输出。
对人甚至也通用。
不要对自身之外的任何东西心存太多理所当然的假设。

好了,回到这个问题。
因此,为什么一门编程语言会这么“没人性地”设置这么多种不一样的数据类型?
这其实就是为了保证它的存储和运算行为是正确无误的。

而转换这种东西,分为显示和隐式。
显式就是你强行或者说明确无误的告诉编译器。
在执行一个2字节和4字节相加时,我就是要那么作孽的把4字节转化成2字节。
那么最后结果出来了是错的,你不能怪它,因为这是你要他这么干的。
C语言领域,最常说的一句话就是;
其实没有什么事情是不能做的,前提是你要知道自己在干什么。

但如果你偷懒,你发自内心的希望计算机人性点,让你可以尽可能的偷懒:
那么,编译器就会给你自动进行转换,这个过程不是你明确提出来的,是它自动干的,所以称为隐式转换。

关于隐式转换,其实是一套相当复杂的规则。
复杂到很容易记错和忽略,所以很多过来人都建议你:强制显式按照你想要的方式去转换,不要让编译器去猜。

比如著名的华为编程规范就这么说过。

这是因为,编译器本身也是一个人造软件,它,也是有可能出错的。
当然更多的时候,并不是它出错,只是它的实现方案造成对你的一个特定表达式进行的转换非你所愿。
这其实不是什么奇怪的事情,甚至不需要搬出一堆的技术理论去解释。
你只要回忆一下你和别人讨论事情的时候,明明你说的是这个意思,可别人听了却是那个意思,你就可以理解了。

这也是为什么我也非常赞同,不要让人猜,就算我辛苦点,我也要明确无误地告诉别人我要什么的原因。

扯远了,收住。

在这里,我想表达的是,偷懒不算一种原罪,但是,请你下次偷懒的时候,稍微站在另一个角度考虑问题,而不是一味为自己找理由和借口。
恩,说的就是你,水果君。
此帖出自编程基础论坛
个人签名

强者为尊,弱者,死无葬身之地

 

回复

7815

帖子

56

TA的资源

裸片初长成(中级)

42
 
以上,关于free叔叔的看法。

虽然我本来说要接着往下阐述这个帖子里出现的其他答案,但没想到一写就写了个把小时,乖乖。
歇会歇会。

而且,俺真心不想做一个这么 批判性 的人,即使在技术圈子里也不愿意。

那样会找不到女朋友。
但反正,我就是一个要精确控制到bit的男人,就是那么任性!
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

350

帖子

0

TA的资源

纯净的硅(中级)

43
 
好久不见,老哥还是那么啰嗦哈哈。
此帖出自编程基础论坛
 
 
 

回复

88

帖子

0

TA的资源

一粒金砂(中级)

44
 
好贴,受教!
此帖出自编程基础论坛
 
 
 

回复

7815

帖子

56

TA的资源

裸片初长成(中级)

45
 
终极菜鸟 发表于 2016-2-25 14:03
好久不见,老哥还是那么啰嗦哈哈。

宝宝心里委屈,但是宝宝不说!
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

2

帖子

0

TA的资源

一粒金砂(中级)

46
 

时隔几年,再看看,结果发现好像争吵了一个无意义的东西。具体环境用具体方法,不要总想着大一统,避免自己掉坑,也避免后继者掉坑

此帖出自编程基础论坛
 
 
 

回复

209

帖子

3

TA的资源

一粒金砂(高级)

47
 

看似平常的代码,细究起来还是有许多知识点的,平常不会有人注意,而仅仅是在于编程逻辑。其实学透一门编程语言,弄懂细节,还是很重要的。可以避免编程时出现莫名其妙的错误。也有助于提高解决问题的能力。谢谢楼主细心分享。

此帖出自编程基础论坛
 
 
 

回复

44

帖子

0

TA的资源

一粒金砂(中级)

48
 

此帖出自编程基础论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表