c语言 字符输出要加 吗,最后的printf为什么要加&,他不是输出字符串吗

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

+FAQ

为什么要特别反对“把数组名当成指针”这种调调?

因为这是严重的误导,还不止一个。

为什么这是误导?有好几个原因,只提重点。

最显然地,这不合 C 的语言规则。这根本就不是 C 语言的内容。

鼓吹这种伪规则,会让用户自认为“学会了”的错觉。这样的用户,实际只是冒牌货——他们会的,充其量是自以为是的不存在规格说明的臆想非主流方言;这些方言之间因为臆想程度的不同还可能各不兼容。

即便 C 这样的语言在这方面已经非常混乱而欠缺在新项目中应用的价值,维护成本不给市场添乱仍然应该是自觉,否则不要怪利益相关者拿冒牌货 C 用户出气。

(C++ 同理,但是因为其它语言规则足够复杂而容易使自以为是现世报,所以阻碍了这种错觉的合理性和莫名其妙的自信。)

第二,这是学习方法论上的普遍错误。

所谓“把数组名当成指针”,技术上来讲,这是一种 AOT(ahead-of-time) 意义上的语法变换(syntatic transformation) 。而这里的目的是保持含义的等价,本质上是语义的。

使用语法变换(“当成”)来处理等价的语义变换,主要动机是简化实现(包括用在语言设计和解释器上,提供宏这样的机制来提升性能的技巧)。这可能是合理的。

但问题是不是所有的语法变换都能处理语义变换。C 语言中存在不能把数组名当成指针的上下文相关的反例,就是一个实例。

决定语义等价变换是否适用,必须确保上下文一致性这个前提。这是最基本的功课。如果在最一开始就把这个省略了,后面只会 garbage in garbage out ,了解的自然不可能是什么正确的规则。

更何况反例已经证明这种规则是普遍上不靠谱。去记忆这种的规则,必须在使用时重新判断前提才能确保正确。否则,就和依赖未定义行为是基本是同等的愚蠢。

——那为什么不一开始就学习清楚正确的规则?

(类似的不靠谱问题也存在于关于声明语法的所谓“右左法则”之类的规则中。这是不靠谱的,因为至少隐含依赖确定哪些标识符是未声明的上下文信息——要例子可以考虑自己推断一下标准库的 signal ;而想要靠谱,老实看 ISO C 的声明文法一条条怼。觉得麻烦?那就对了,C 在这里确实就是充斥了不必要的复杂性,设计得就是那么烂,不服不要玩。)

最后,就危害程度来讲实质上应该更重要的问题,是关于理论计算机科学意义上的反智主义。

如果用户是从 Lisp 或者 Forth 之类的语言入门,或许还有机会自己理解到 apply/eval (所谓计算机科学中的 Maxwell's equations )这样基础的语义变换的重要性,甚至可能自己发明出来。

但以 ALGOL-like 特别是其中的“静态语言”入门的用户,老实说,以绝大多数人的天赋,是没什么机会在严格的理论训练前认知到这种基本理论常识的。

为什么这是重要的?因为这根本上要求用户反思自己方法论意义上的需求:具体来说,为什么需要语法变换?

往大了说,想清了这个问题,历史上的大部分“新”程序设计语言根本就不用存在,很多问题都是原地踏步罢了。

另一方面看,滥用“静态”的语法变换已经导致了很多问题。语法变换损失了原始的上下文,使用户难以推测出原始结构的意图,而造成了许多实际场合的不便甚至不可行。

影响嘛……举个例子,根正苗红的“静态语言”的可扩展性问题(比如现在 C++ 死活想加上的翻译时反射),都一定程度上对应了原始设计中对这个问题的考虑不足。

可能这样的例子太大而比较抽象,再举一些可比的影响:

比如,对递归的偏见。(注意,递归和递归调用不是一回事。)这个问题现在还没有纠正,并且还被许多 ALGOL-like 语言的用户以教条主义遵循。这在工业界已经带起了盲流,例如许多厂商以技术上可笑的理由拒绝实现 ECMAScript 的 TCO ——尽管这些技术决策者在复读标准以外十有八九都说不清楚什么叫 TCO 。这些人要有点常识就该清楚 [Clinger98] 之类才是这类问题的核心,但是他们受到的毒害大概已经不足以支撑这样的学习精神了。

再如,通用目的语言中缺乏一等函数的局促设计。好在新的语言基本都纠正了这个缺陷,不过至少 C 语言是个显著的反例。

很遗憾,历史上的绝大多数用户恰恰都欠缺这样的常识(说白了这里一开始没什么理论,John McCarthy 都承认 Lisp 很多地方的设计都是偶然),其中还包括了很多“工业”语言的设计者;他们的局限性使大多数基础设施的设计中充斥了特设的(ad-hoc) 的鸡肋设计,浪费时间,而鼓励更多的用户学习不通用的具体知识。这就是一种具体的反智表现。

其实 Lisp 在这里也是不怎么合格的。虽然有 eval ,但 eval 始终是二等的。历史上有 FEXPR ,但却没能给出一个 non-trivial equational reasoning 的方法,反而让人往死胡同里走([Wand98])。而滥用语法变换背后的根本致命问题恰恰是容易导致 trivialilty 而削弱语言设计的抽象能力。

引用文献略。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值