免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: pmerofc
打印 上一主题 下一主题

[C] 《C解毒》征询意见帖 [复制链接]

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
201 [报告]
发表于 2012-05-29 15:12 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
202 [报告]
发表于 2012-05-29 15:12 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
203 [报告]
发表于 2012-05-29 15:15 |只看该作者

嗯 那就好。

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
204 [报告]
发表于 2012-05-29 16:25 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
205 [报告]
发表于 2012-05-29 21:20 |只看该作者
回复 205# pmerofc


    写完啦~呼,真累,看邮件去啦~


类型系统?表达式?副作用?——C的“易筋经”

    一本教材最应该做的事情,是应该培养一个人在某项技能中的“方向感”,用武侠的
话说,就是要能够内视,知道自己的位置和将要前进的方向。语言本质上是用来交流的,
一本语言的教材就更应该要给人一个大体的方向感,教你如何利用语言的概念去约束自己
,或是教导人获得新知的方法,而不是条条框框,那是语言手册,却绝对不是教材。

    就比如,C语言究竟是有什么基本元素组成的?这些元素之间有些什么样的规则?这
些规则又如何互相作用以达到编程者的目的?这些“穴道”一类的知识就应该是一本语言
教材需要交给大家的。一本好的语言教材,一定是《易筋经》一般的大体抽象,严谨精确
,它用抽象而实用的概念将穴道串联在一起,用名为逻辑思维的内力打通任督二脉。在这
个前提下教材去举例子打比方语言诙谐,才是有意义的。

    看看这一段对“if((a=b)>0) max=a; ”的描述:

   
先进行赋值运算(将b的值赋给a),然后判断a是否大于0


    我不知道一个只会外家拳法的所谓宗师如何去教人武功,也许大体上就是这样了:扔
给徒弟一堆穴道,然后根据自己的臆测,来猜想内力应该如何联系经脉,这样就算是不走
火入魔,也够你喝一壶的了。

    那么,我们来解释一下,究竟C语言版本的《易筋经》应该说明什么问题,应该怎么
去解释C语言的众多语法特性。我们再用学到的知识去解释if条件中的这个表达式,看看
好的教材如何教人内视。

    C是一门计算性的语言。大体上,有类型系统指定计算如何进行,有表达式负责值的
计算,有副作用进行状态的更改,有语句负责控制计算的步骤。语句不是今天的话题,我
们今天就谈谈表达式的那些事儿。

    什么是表达式呢?一系列的操作数,用操作符联系在一起,用于表达如何产生一个值
的式子就是表达式。表达式就是用来描述如何产生一个需要的值的,除了这个主要的目的
,表达式还可以用来做一些程序状态的更新,这些“私活”被称为表达式的副作用。为了
得到这个值,我们需要一系列的计算“工具”,它们就是前面提到的“操作符”,而被这
些计算工具当作“原料”来计算的,自然就是被称为“操作数”的一系列值了。操作数并
不一定是数字,这里仅仅是沿用旧的翻译而已。你可以认为它们仅仅是被操作的值就可以
了。

    我们知道,定义一个计算是很复杂的。数学里面有那么多的符号去做这件事,但计算
机语言的符号却是有限的。为了让一个符号能尽可能地表示更多的同类型的操作(注意,
用相似的符号去表达相似的工作,这就叫抽象,这是C区别于低级语言的重要特征),C引
入了类型系统,并且规定,一个符号所执行的操作,取决与这个符号作为运算符的操作数
的具体类型。

    有点晕了么?仔细看看这段话:一个运算符能做什么操作,是由其操作数的类型决定
的。比如,两个int型的值做+运算,那么这就是个int加法,而两个浮点型的值做+运算,
也许机器实际执行的操作就完全不一样了。一个值的类型就是描述这个值所有特征的一个
集合,当然如何运算也是值的特征之一了,所以由类型去决定计算,一点都不奇怪。

    现在我们知道了C语言可以做操作,并且这些操作是如何根据操作符和操作数来选择
的了,另外我们还必须知道操作符如何选择操作数——根据上面的说法,这直接决定了操
作符究竟会做什么具体操作。操作符是利用所谓“优先级”和“结合性”的方式去选择操
作数的。这一点我们之前已经探讨过了。我们需要探讨的最后一个问题是,这些运算会以
一个什么顺序去执行,这就是今天的主题了。

    在讨论这个问题前,我们要强调上面提过的一个事实:C语言的运算符其实并不止是
可以返回一个值的,他还可能会有一系列的副作用,这些副作用会造成程序执行环境的更
改。我们可以认为这是运算符在做运算的时候“顺带”去做的一些事情。也许这些事情对
我们来说才是主要的目的,但要记住,对C语言来说,这是顺带去完成的功能,这些功能
完成的时间是很灵活的,只需要满足一些约束条件就可以了。具体的约束条件,在“顺序
点”这个C语言知识点中做了完整的讲解。

    现在我么来看开头给出的这个表达式:(a = b) > 0,这个表达式是有两个子表达式
组成的,其中圆括号决定了由赋值操作符优先选择操作数——即a和b,而大于操作符的操
作数是赋值操作数的值,以及一个int型字面量0。这个表达式实际执行的操作要根据各个
变量的类型来决定,这里我们假设a和b都是int。

    那么,这个表达式是如何执行的呢?是不是真的就是按照谭老所说的,先赋值,再比
较呢?

    首先我们注意到,赋值操作符是有副作用的,这个副作用可以发生在任何时候。现在
我们不考虑这个副作用,我们只考虑“纯”的表达式。对于赋值运算符来说,他的值就是
如果按照一定的规则,a获得了b的值以后,a的那个值。你看,既然是一定规则,那么这
个值是可以预先算出来的,并不一定非要将b真的赋值给a我们才知道这个值是多少。表达
式的目的就是为了表达一个值的计算过程,在类型决定以后,这个计算过程也就决定了,
加上确定了的操作数,这个值也就决定了,并不会随着副作用是否发生而改变。

    我们得到的这个值又是比较操作符的操作数,于是比较操作符就可以用这个数字和0
比较,从而得出最终的结果。

    总的来说,顺序就是:

        1. 赋值运算符计算出一个结果。
        2. 这个结果交给比较运算符,得到第二个结果。
        3. 第二个结果就是整个表达式的值。

    这就是这个表达式的全部计算。

    还有副作用呢?哦,对了。赋值运算符其实还有一个副作用,副作用是将这个赋值表
达式的值保存到a变量中,让a变量的值变成赋值表达式的值。我们说过,副作用的发生是
很灵活的。在这里,这个副作用可以在任意时刻发生,可以是比较操作前,也可以是比较
操作后。我们说老谭的说法是错误的,就是由此得到的结论。

    老谭的错误在于,他混淆了“赋值表达式”这样一个静态的、用于描述一个值如何产
生的表达式和“赋值操作”这样一个动态的,会改变状态的操作。后者被称为“做了一次
赋值操作”,是会改变程序状态的,而前者只是计算出了一个值而已。这两者其实是不相
干的。既然不相干,就不会有任何顺序上的依赖关系,而仅仅是赋值表达式的值需要交给
下一个表达式去计算下一个表达式的值而已。

    怎么样?感觉到任督二脉通了吗?C语言的表达式具有众多知识点:变量类型、操作
符、优先级、结合性、副作用、顺序点等等。但是,如果按照这样的理解,要串起这些知
识点是很容易的事情,让内力顺着经脉流淌,就能一通百通,功力飞涨。这就是一本好的
内功教材需要做的事情。支离破碎的教条式的知识点,只会让初学者头大。只有将知识点
串联起来,以目的为导向,才能清晰说明问题。理解了C的表达式,基本上C的三国之一就
在你掌握之中了(剩下的两个所谓“国家”是类型系统和控制结构)。所谓指针的复杂性
,大多数也是因为表达式这个概念及某些表达式操作含混不清造成的。

    我们总结一下:

        - 表达式存在的目的是为了表达一个值的计算过程。
        - 除了直接依赖,否则值计算的顺序是不可预期的。
        - 除了计算值,表达式还可能会更改程序的状态,这叫“副作用”。
        - 副作用十分自由,可以(有限制地)发生在表达式执行过程中的任何时刻。
        - C只保证副作用一定会发生,却不保证会何时发生。

    一本好的教材就应该这样由上到下去慢慢剥离一个概念,去说透一个东西存在的意义
以及存在的规则,让读者养成按照严谨的思维去思考的习惯。做不到这一点的教材,实在
难称为一本好的教材。而如果作者本人都不知道这些概念,只会用臆想去误导他人的话,
那恐怕连合格的教材都难以胜任了。

论坛徽章:
2
技术图书徽章
日期:2013-09-04 15:21:51酉鸡
日期:2013-11-01 21:20:20
206 [报告]
发表于 2012-05-29 21:34 |只看该作者
starwing83 发表于 2012-05-29 21:20
回复 205# pmerofc


一门普通的计算机语言就是被这么忽悠成高难度的语言了。

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
207 [报告]
发表于 2012-05-29 21:35 |只看该作者
回复 207# mirnshi


    恩,奸商们是需要严谨滴态度滴~~~:wink:

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
208 [报告]
发表于 2012-05-29 21:37 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
2
技术图书徽章
日期:2013-09-04 15:21:51酉鸡
日期:2013-11-01 21:20:20
209 [报告]
发表于 2012-05-29 21:53 |只看该作者
starwing83 发表于 2012-05-29 21:35
回复 207# mirnshi


所以现在盛行忽悠风,老美忽悠恐怖分子,于是乎天天反恐,越反越恐。
在IT界,所有这一切都来自忽悠。忽悠的目的就是为了消费者兜里的币子。

防病毒是越防越多,不装防病毒,真的会非常危险吗?装了防病毒就高枕无忧?
机器是越来越闲置,低配置的机器,真的不能干活吗?高配置机器干起活来,真的省时省力?
教程书是越来越多,不读教程书,就不能写好程序?看了有个脑袋就写出来的书,就真的可以写出很好的程序?

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
210 [报告]
发表于 2012-05-29 22:00 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP