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

+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 而削弱语言设计的抽象能力。

引用文献略。

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

  1. C语言阅读程序输出星号井号,C语言字符

    在实际开发中,程序员很少用单个字符来表示数据,字符的意义主要作为数组的时候可以形成一个字符串.在本章节中,我们重点介绍字符与整数之间的关系和ASCII码的相关知识. 字符类型char,只能用单引号' ...

  2. C语言中 %md 的输入输出使用(还有printf函数的 %0格式控制符的使用)

    今天在牛客网中做了一道题,这道题需要使用%m进行格式控制 下面来讲一下%md 的输入输出的用法 1.%md在输入语句中的使用 通过scanf函数的%m格式控制可以指定输入域宽,输入数据域宽(列数), ...

  3. C语言字符数组与字符串的使用及加结束符‘\0‘的问题

    1.字符数组的定义与初始化 字符数组的初始化,最容易理解的方式就是逐个字符赋给数组中各元素. char str[10]={ 'I',' ','a','m',' ','h','a','p','p','y ...

  4. c语言在数组输出字母,c语言字符数组与字符串的使用详解

    1.字符数组的定义与初始化字符数组的初始化,最容易理解的方式就是逐个字符赋给数组中各元素. char str[10]={ 'I',' ','a','m',' ','h','a','p','p','y' ...

  5. C语言字符和字符串的输入与输出

    C语言 一.输入单个字符 1.scanf函数输入单个字符 C语言scanf输入时缓冲区问题 scanf函数是标准输入流(从键盘接收数据),接收的数据放入输入缓冲区中,其中就包括在键盘输入的空格.回车这 ...

  6. C语言字符数组的输入和输出

    字符数组的输入输出有两种方法: (1)逐个字符输入输出.用格式符"%c"输入或输出一个字符.例如 int main() {char c[6]; //定义一个字符串for (int ...

  7. C语言字符5,c语言总览5:字符输入和输出

    c语言的库函数中提供了一些基本的字符输入和输出函数.其实,不管输入或输出的文本来自哪里,都是作为文本流来处理的.一个文本流包含一些字符,它们被换行符分成不同的行.当我们使用这些函数的时候,只需要考虑文 ...

  8. c语言函数前加long的作用,C语言中longlong型数据怎么输出,能详细说明一下long与long long的区别吗?...

    导航:网站首页 > C语言中longlong型数据怎么输出,能详细说明一下long与long long的区别吗? C语言中longlong型数据怎么输出,能详细说明一下long与long lon ...

  9. c语言用getchar函数输入两个字符c1,c语言:用getchar函数读入两个字符给c1,c2,用putchar和printf输出。思考问题...

    用getchar函数读入两个字符给c1,c2,分别用putchar和printf输出这两个字符.思考以下问题: (1)变量c1和c2定义为字符型还是整型?或二者皆可? (2)要求输出c1和c2的ASC ...

最新文章

  1. 2018.08.04 cogs2633. [HZOI 2016]数列操作e(线段树)
  2. ORACLE 将SQL的执行脚本返回值传给SHELL
  3. 前端学习(576):margin无效情形之内联特性导致无效
  4. 基于yolo5工地安全帽和禁入危险区域识别系统,附数据集
  5. 比特大爆炸为啥老显示服务器满,《有可能是史上最长停服维护公告》
  6. java string 数组 个数,Java - 定义一个接收String的方法,并返回一个整数数组,其中包含每个元音的数量...
  7. cass有坐标文件生成里程文件_【视频】南方cass9.0进阶教程74.3生成里程文件3
  8. 计算机网站之TCP报文结构
  9. 智慧养殖系统方案云平台功能
  10. win7文件共享服务器搭建,Win7下搭建web服务器实现数据共享的简单步骤
  11. c语言水仙花数7位数,C语言水仙花数的实现
  12. 用虚拟串口实现串口数据收发
  13. Autorun风暴专杀工具
  14. java苹果沙盒验证参数问题_java -苹果支付凭证校验
  15. HDU6438 Buy and Resell
  16. 《大明王朝》掠之于官
  17. 如何在CentOS 7上安装指定版本的PHP
  18. 【100%通过率】华为OD机试真题 Python 实现【最接近最大输出功率的设备 /查找充电设备组合】
  19. 使用virt-install创建虚拟机
  20. HTML 六十二 实例

热门文章

  1. Trie Tree 介绍
  2. (原) 我要地图 pk Google地图
  3. python关于类和对象说法正确的是_关于类和对象,下面说法正确的是?
  4. Object转Map
  5. transactionscope mysql_c# – 嵌套的TransactionScope在测试中失败
  6. s3c4510 烧写flash
  7. 深聊性能测试,从入门到放弃之:通过这几点获取性能需求,BOSS再也不担心用户投诉了。
  8. Lua Python及Shell语法异同点
  9. 微信公众平台域名设置
  10. 360replugin导入demo