C_and_CPP 板


LINE

※ 引述《ttucse ((((>( ̄▽ ̄)<))))》之铭言: : 我只有学过java : c跟c++学得很烂 : 现在都写java : 所以我指标也很烂 : 我在BSD UNIX的作者Bill Joy的演讲 : 看到这个*p++ = *q++ : 图在这里 : http://i.imgur.com/3QSwcbZ.jpg : https://youtu.be/rByrD_R9Vuo
: 影片的19分44秒左右投影片上的程式码 : 所以想问*p++ = *q++ : 是什麽意思 : 还是这个写法不好 : 可是这个是BSD UNIX作者给的 : 让我很想知道这个的意思 : 谢谢大家 这是经典的写法,也算半个时代的眼泪了 这段程式码最着名的出处不是别的, 正是大名鼎鼎的K&R C 换句话说,对现在五六十岁的资工系教授那一辈的人 这个应该是教科书等级的写法 XD https://meee.com.tw/jWInyox 截图是K&R中译版的相关内容,我手上这本是蔡文能副教授翻的 小弟也算有幸在他退休前跑去旁听他的计科概,不过这是题外话:P 对大多数人比较舒服的写法可能会像推文里面说的 用一个index i去处理递增动作: int i = 0; while(s[i]!='\0'){ t[i] = s[i]; i++; } 那为什麽K&R要在一本基础教学书秀这种要一点功底才能懂的写法? (K&R甚至比影片内的更凶残,它是放在while的判断条件里) 除去它更加简练,或是可以展现C语言语法的综合应用这种理由以外 其实我猜更大的原因应该是Dennis Ritchie的私心XD 如果对电脑的发展史有一点理解的话 应该知道上面影片讲的PDP-11、Unix跟C语言是大约同一个时代出现的产物 而PDP-11的手册不知道哪个老教授留的, 总之现在还可以在mit cs的网页挖到: https://pdos.csail.mit.edu/6.828/2005/readings/pdp11-40.pdf 其中的第三章就在介绍PDP-11的addressing mode 跟多数人(比方说我)比较熟悉的x86/x64架构比的话, 你会发现他有一个很特别的东西 叫做autoincrement-addressing mode 简单的说PDP的指令集允许你设定指令中的某几个bit 把要操作的register作为记忆体位置看待 然後在你对记忆体位置上的东西做完该做的操作之後 他会自动去把register的值+1 (或是-1) 随便举个例子: r0 = 0x1234->"Foo" r1 = 0x5678->"Bar" movb (r1)+ , (r0)+ (注:(rn)+代表autoincrement-addressing mode) 上面这行组语做完後 记忆体位置0x1234上的第一个byte会被0x5678上的值盖过去 0x1234->"Boo" 0x5678->"Bar" 并且: r0 = 0x1235->oo r1 = 0x5679->ar 你稍微想一下就会发现 *s++=*t++; 跟上面这行组语不能说很像,只能说做的事情一模一样 换句话说在PDP-11上面, 这个看起来很复杂的expression可以直接被一行组语干掉 (如果再考虑当年的compiler没现在那麽威的分析能力 这没准还会是同语意下唯一可以只编成一行的写法...) K&R C的第一版成书於1978年 1978年的另一件大事,叫做Intel推出8086处理器 也就是现代x86_64处理器的开山鼻祖,後来的事情大家都知道了 作为几乎可以跟PC划上等号的指令集架构 x86并没有支援这麽fancy的addressing mode 同一行程式码在x86上应该是要编两个mov + 两个inc来做这件事 不管你把++拆开来写还是塞在同一行都一样 所以这段code自然就只剩下精简程式码的功能,而失去了最佳化的能力 (当然现代x64有SIMD跟一些针对连续记忆体处理的指令,那就是後话了) 但说是这麽说 工程师就是会对自己搞出来的得意之作念念不忘的生物 就像高老爷子非得在他的TAOCP里面塞磁带的外部排序算法一样 K&R C的第二版於1989年出版,也就是我现在手上拿的这个版本 1989年我想应该已经没PDP-11什麽事情了 但K&R还是选择展示这段程式码作为strcpy的实作 也许多少有缅怀那个年代的意义在吧 --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 123.192.202.202 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1769621660.A.99D.html
1F:推 ttucse: 感谢讲解。 01/29 02:00
2F:推 lc85301: 推好文 01/29 09:25
3F:推 hongsiangfu: 推 01/29 14:38
4F:推 james732: 推 01/29 15:43
5F:推 goldie: 推 01/29 19:49
6F:推 if4: 推好文 01/29 20:16
7F:推 Richun: 原来还有这段历史 01/29 20:23
8F:推 agogoman: 推 01/30 15:50
9F:推 LPH66: 推 01/30 16:44
10F:→ LPH66: x86 其实是有一个老组语指令 MOVS 有类似的效果啦 01/30 16:52
11F:→ LPH66: MOVS 把 ds:esi 搬到 es:edi 之後把 esi 和 edi 都递增/减 01/30 16:53
12F:→ LPH66: (易记指令是 Move String 搬字串,因为加 REP 可以搬一串) 01/30 16:54
13F:→ LPH66: 但它是限定只能用这组暂存器,不像 PDP-11 能用其他暂存器 01/30 16:55
14F:→ LPH66: 所以在已经很有压力的 x86 暂存器数量下不容易最佳化出它来 01/30 16:56
15F:→ LPH66: 然後 REP MOVS 因为是数量先行指定 (REP 用 ecx 倒数计数) 01/30 17:00
16F:→ LPH66: 所以应该只有例如 memcpy 这种有指定数量的能生出 REP MOVS 01/30 17:01
17F:→ LPH66: 零结尾字串用的 strcpy 用 MOVS 应该没有省到什麽东西 01/30 17:02
18F:推 mihonisizumi: 好文推 02/01 05:56
19F:推 HolyBugTw: 总是有真正的高手解惑,受益良多 02/03 14:08
20F:推 chuegou: 好像在不知道哪家的小众dsp看过类似的指令 一样是带+1 02/04 18:43
21F:推 F04E: 推 02/10 14:04







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:Gossiping站内搜寻

TOP