免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 11856 | 回复: 66
打印 上一主题 下一主题

[C] 学生为什么搞不懂C语言?不论是对于老师还是学生自己,这通常是一个谜 [复制链接]

论坛徽章:
11
摩羯座
日期:2013-09-16 11:10:272015亚冠之阿尔萨德
日期:2015-06-12 22:53:29午马
日期:2014-04-15 11:08:53亥猪
日期:2014-03-02 23:46:35申猴
日期:2013-12-06 22:07:00亥猪
日期:2013-11-28 12:03:13双鱼座
日期:2013-11-21 14:43:56亥猪
日期:2013-10-23 10:55:49处女座
日期:2013-10-17 18:15:43午马
日期:2013-09-27 17:40:4215-16赛季CBA联赛之青岛
日期:2016-06-22 00:45:55
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-11-30 13:40 |只看该作者 |倒序浏览
本帖最后由 Ager 于 2012-11-30 20:08 编辑

学生为什么搞不懂C语言?

不论是对于老师,还是对于学生自己,

这通常是一个谜 ……

C语言教学现场案例:关于for语句

以下叙述,以真实事件为蓝本,稍加整理和扩展。不知各位大虾在实际情况中,是否遇到过 ……

B弟: A大,不好了!我看了一夜的书,被C语言里这个for循环,彻底搞糊涂了 ……

A兄:(恐怕他是看了什么劣书,先来摸摸底:)你看的哪本书呀?

B弟: 《C Primer Plus 中文版》。

A兄: 不会吧,这本书应该不错的呀。你来说说你的问题吧 ……

B弟: 我昨天看到这么一个写法:
  1. int i;

  2. for (i = 1; i; i++){...}
复制代码
怎么在括号里的第二项,就一个i呀?不应该是一个范围的嘛?比如:
  1. for (i = 1; i <= 100; i++){...}
复制代码
这个我就能理解:这是给i设定了一个从1到100的范围。

A兄: 你不应该将“第二项”理解为“一个范围”,这里括号里的“第二项”应该叫做:括号里的第二个表达式。这个表达式,是用来判断for的语句体(循环体)是否要被执行的指标。

B弟: 这是什么意思呀?不懂耶。不应该是一个范围的嘛?

A兄: 呃 —— 是这样的 …… for语句对括号里的第二个表达式求值,如果值为0的话,那么整个for语句就结束了,语句体(循环体)将被跳过、不执行;如果该表达式的值不为0或者压根儿就没有这个表达式的话,那么,就执行for的语句体(循环体),之后,for再对括号里的第三个表达式(如果存在的话)求值,而求值一旦完成,所求得的值将被discard,尔后,for语句再次对括号里的第二个表达式求值。

B弟: 这是什么意思呀?不懂耶。第二个表达式不应该是一个范围的嘛?

A兄: 你不应该将第二个表达理解为“一个范围”。for语句在括号里的第二个表达式上,要的不是“一个范围”,它要的是一个值!这个值,要么是0,要么不是0或者不存在。

B弟: 这是什么意思呀?不懂耶。第二个表达式不应该是一个范围的嘛?

A兄: 那你的这个例子来说:
  1. for (i = 1; i; i++){...}
复制代码
for括号里的第一个表达式,是一个用来施行某种初始化的表达式:i=1这个表达式,也就是会被求值的,所求得的值是1,而且经由这个求值过程,一个副作用产生了,就是变量i被赋值以1了,所以,这个表达式也叫做“初始化分句”。接着,for对括号里的第二个表达式求值,因为变量i此时的值是1,即该值不是0,所以,for就要执行它的语句体(循环体)中的内容,执行完成之后,for再对括号里的第三个表达式“i++”求值,尔后,再次对括号里的第二个表达式求值。

B弟: 这是什么意思呀?不懂耶。第二个表达式不应该是一个范围的嘛?

A兄: 那不是什么“范围”啦!还是拿你这个例子来说,如果你想让变量i在某个“范围”(比如从1到100)里跑一趟的话,可以这么做:
  1. for (i = 1; i; i++) {
  2.         say ( i );
  3.         if  (i == 100) i = -1;
  4. }
复制代码
首先,在括号里的第一个表达式上,变量i被初始化以整数值1,接着,对括号里的第二个表达式求值,因为此时变量i的值为1,不是0,所以,for就执行它的语句体(循环体):先馈出i的值(1),然后做一个判断:如果此时变量i的值是100的话,则令其的值为-1(此时当然不会执行此事),此后,for再对括号里的第三个表达式求值,所求得的值是2,此值被求出后即被discard,但一个副作用产生了,即变量i的值被更新为2,尔后,for在对括号里的第二个表达式求值,此时该值是2,所以,继续执行for的语句体(循环体),这次,还是先馈出i的值(2),然后还是做那个判断 …… 如此循环往复,直到在语句体(循环体)中的变量值为100,那时,if对“i == 100”表达式求值,所求得的值为1,所以if就执行它的语句体,即对表达式“i = -1”求值,所求得的值为-1,此值被求出后即被discard,但一个副作用产生了,即变量i的值被更新为-1,此后,for再对括号里的第三个表达式求值,所求得的值是0,此值被求出后即被discard,但一个副作用产生了,即变量i的值被更新为0,尔后,for在对括号里的第二个表达式求值,此时该值是0,所以,for跳过它的语句体(循环体),整个for语句结束 —— 这样,就完成了将变量i从值0到100的馈出。

B弟: 这是什么意思呀?不懂耶。第二个表达式不应该是一个范围的嘛?

A兄: …… 你怎么还是认为有“范围”这么一回事儿呀 ……

B弟: 我觉得,for的括号里应该就是设定一个“范围”嘛 …… 比如在:
  1. for (i = 1; i <= 100; i++){...}
复制代码
的花括号里面,我就可以让程序显示i从1到100的值,这不就是因为:
  1. i = 1; i <= 100;
复制代码
这个设置,让i从1到100吗?

A兄: 之所以运行这段代码,让你觉得程序为变量i实现了一个“从1到100的范围”,其原理是:

变量i首先被初始化以整数值1,接着,for对对括号里的第二个表达式“i <= 100”求值,在变量i的值没有超过整数100的情况下,这个表达式的值一直为1,不是0,所以,for总是执行它的语句体(循环体),令变量i的值被馈出,此后,for再对括号里的第三个表达式“i++”求值,其果效为让变量i的值被加上整数1 …… 直到变量i的值为整数100的时候,语句体(循环体)执行完成之后,变量i的值,被括号里第三个表达式的求值过程更新为整数101,那么,尔后for对对括号里的第二个表达式“i <= 100”求值,此时,该值为0,所以,for不再执行它的语句体(循环体),那么,整个for语句结束。

B弟: 这是什么意思呀?不懂耶。第二个表达式不应该是一个范围的嘛?

A兄: …… 好吧……我这样来问你:

当变量i的值为整数1的时候,表达式“i <= 100”的值为什么?

B弟: 1。

A兄: 嗯,很好!那么:

当变量i的值为整数2的时候,表达式“i <= 100”的值为什么?

B弟: 2。

A兄: …… ※◎★@☆ ……

B弟: 这时,i是2,它仍然在从1到100的范围里,那么,它的值不就是2吗?

A兄: …… 你理解“i <= 100”这个表达式吗?

B弟: 理解呀,这是一个范围呀。

A兄: …… ※◎★@☆★※@※ …… 这个表达式叫做“关系表达式”,因为其中的操作符就是“<=”,这是一种关系操作符。如果关系操作符左右两边的操作数,满足前者所表征的某种关系,那么,这个表达式的值就为1,否则为0。所以,我们可以认为,这种表达式,起到了一种“判别真假”的作用,比如说:

当“i <= 100”这件事为真的时候,这个表达式的值就是1。

当“i <= 100”这件事为假的时候,这个表达式的值就是0。

B弟: 这是什么意思呀?不懂耶。“i <= 100”不应该是一个范围的嘛?

A兄: …… ※◎★@☆★※@※◆△◆※#&︿☆ …… 我用自然语言来说吧:

当变量i的值小于等于整数100的时候,“i <= 100”这个表达式的值就是1。

否则,这个表达式的值就是0。

B弟: “小于等于”是什么意思呀?



A兄: (…… 起灰 ——……)






论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
2 [报告]
发表于 2012-11-30 13:45 |只看该作者
这个B一根筋

论坛徽章:
154
2022北京冬奥会纪念版徽章
日期:2015-08-07 17:10:5720周年集字徽章-年
日期:2022-10-26 16:44:2015-16赛季CBA联赛之深圳
日期:2022-11-02 14:02:4515-16赛季CBA联赛之八一
日期:2022-11-28 12:07:4820周年集字徽章-20	
日期:2023-07-19 08:49:4515-16赛季CBA联赛之八一
日期:2023-11-04 19:23:5115-16赛季CBA联赛之广夏
日期:2023-12-13 18:09:34
3 [报告]
发表于 2012-11-30 13:50 |只看该作者
不知道为什么上课的时候也学不会,


但是回家把代码放到机器上一跑,再回过来看看表达式,左看看右看看,明白了

论坛徽章:
6
酉鸡
日期:2013-11-04 15:30:02巳蛇
日期:2014-01-23 10:36:23双鱼座
日期:2014-01-23 13:08:332015亚冠之鹿岛鹿角
日期:2015-09-03 14:36:002015亚冠之武里南联
日期:2015-09-18 10:48:1315-16赛季CBA联赛之山西
日期:2016-05-05 00:05:33
4 [报告]
发表于 2012-11-30 13:58 |只看该作者
啊!这么麻烦?

我记得当时学QBASIC的时候老师举了个罚我们到操场上跑圈的例子

跑一圈回来问她行不行,直到她说行了,就不用跑了

循环就结束了。。。。。。

论坛徽章:
11
摩羯座
日期:2013-09-16 11:10:272015亚冠之阿尔萨德
日期:2015-06-12 22:53:29午马
日期:2014-04-15 11:08:53亥猪
日期:2014-03-02 23:46:35申猴
日期:2013-12-06 22:07:00亥猪
日期:2013-11-28 12:03:13双鱼座
日期:2013-11-21 14:43:56亥猪
日期:2013-10-23 10:55:49处女座
日期:2013-10-17 18:15:43午马
日期:2013-09-27 17:40:4215-16赛季CBA联赛之青岛
日期:2016-06-22 00:45:55
5 [报告]
发表于 2012-11-30 14:01 |只看该作者
hellioncu 发表于 2012-11-30 13:45
这个B一根筋


他总是保持着“……是一个范围”的这种“一根筋”,这是一个谜。

最后,这个谜,终于被解开了:

他完全没有“小于等于”这个数学观念。

论坛徽章:
11
摩羯座
日期:2013-09-16 11:10:272015亚冠之阿尔萨德
日期:2015-06-12 22:53:29午马
日期:2014-04-15 11:08:53亥猪
日期:2014-03-02 23:46:35申猴
日期:2013-12-06 22:07:00亥猪
日期:2013-11-28 12:03:13双鱼座
日期:2013-11-21 14:43:56亥猪
日期:2013-10-23 10:55:49处女座
日期:2013-10-17 18:15:43午马
日期:2013-09-27 17:40:4215-16赛季CBA联赛之青岛
日期:2016-06-22 00:45:55
6 [报告]
发表于 2012-11-30 14:07 |只看该作者
本帖最后由 Ager 于 2012-11-30 14:08 编辑
Dannysd 发表于 2012-11-30 13:58
跑一圈回来问她行不行,直到她说行了,就不用跑了


这里问题的关键是:“问她行不行”是藉由“i <= 100”这个表达式来实现的。

然而,此案例中的学生,无法正确地理解这个表达式,在他的认知中,此表达式是一种范围的设定,即让i从1到100。

再归根结底,他完全没有领会“<=”这个关系操作符的正确含义 —— 因为,他没有“小于等于”这个数学观念。

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
7 [报告]
发表于 2012-11-30 14:20 |只看该作者
Ager 发表于 2012-11-30 14:07
这里问题的关键是:“问她行不行”是藉由“i



让他学其他语言吧,好多语言的for循环都是  from x to y,不像C这么灵活

论坛徽章:
11
摩羯座
日期:2013-09-16 11:10:272015亚冠之阿尔萨德
日期:2015-06-12 22:53:29午马
日期:2014-04-15 11:08:53亥猪
日期:2014-03-02 23:46:35申猴
日期:2013-12-06 22:07:00亥猪
日期:2013-11-28 12:03:13双鱼座
日期:2013-11-21 14:43:56亥猪
日期:2013-10-23 10:55:49处女座
日期:2013-10-17 18:15:43午马
日期:2013-09-27 17:40:4215-16赛季CBA联赛之青岛
日期:2016-06-22 00:45:55
8 [报告]
发表于 2012-11-30 14:24 |只看该作者
本帖最后由 Ager 于 2012-11-30 14:26 编辑
hellioncu 发表于 2012-11-30 14:20
让他学其他语言吧,好多语言的for循环都是  from x to y,不像C这么灵活


或者用Perl:
  1. for (1..100) {say; }
复制代码
没有任何显式的具名变量,连函数的参数都省了。。。。



论坛徽章:
1
白羊座
日期:2014-03-22 18:23:03
9 [报告]
发表于 2012-11-30 14:32 |只看该作者
的确是一根筋。。。。

论坛徽章:
78
双子座
日期:2013-10-15 08:50:09天秤座
日期:2013-10-16 18:02:08白羊座
日期:2013-10-18 13:35:33天蝎座
日期:2013-10-18 13:37:06狮子座
日期:2013-10-18 13:40:31双子座
日期:2013-10-22 13:58:42戌狗
日期:2013-10-22 18:50:04CU十二周年纪念徽章
日期:2013-10-24 15:41:34巨蟹座
日期:2013-10-24 17:14:56处女座
日期:2013-10-24 17:15:30双子座
日期:2013-10-25 13:49:39午马
日期:2013-10-28 15:02:15
10 [报告]
发表于 2012-11-30 15:07 |只看该作者
say for 1..100;
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP