作者LoganChien (简子翔)
看板b98902HW
标题[讨论] 给学弟妹关於计程的建议
时间Fri Sep 18 12:02:57 2009
各位学弟妹大家好!
我是 b97 的学长 Logan。去年我当了半年的「伪‧强者」,在回答
同学的问题时,发现有不少人会犯一些常见的错误,所以一直想写一
篇文章介绍一些 DOs and DONTs,不过因为一些事情,所以拖稿拖到
今天。所以就发到你们的 hw 版,希望可以让新手少走一些错路,并
且学习 C 语言的道路可以更为平坦。
Logan 2009.9.18
--
首先我们先谈一些态度上的问题:
1. 作业早点写!
我个人强烈建议大家可以早点写作业。一般来说,没有学过程式不过
能力比较强的同学,至少要 3 个小时以上,而对一般人来说,要使用
的时间远远超过 3 个小时。所以不要把作业挤到最後一天才写。写
作业的人很累,帮助你的真强者也很累!想想看:如果你是真强者,
你希望同时有十几个同学问你问题吗?而且当真强者们同时要面对很
多人时,可能根本没有办法好好地向你解释你的 code 为什麽有问题,
只能告诉你哪里有问题,我认为这对你而言是一种损失。
2. 实际写 code 胜过空想解法
大部分刚学习 C 语言的同学最缺乏的是写 code 的经验,所以作业发
下来,不要空想三天三夜,等到有完整的想法才动工(而且你认为完整
的想法可能根本就是错的)。多花一点时间 try-and-error,未来你写
code 的时候就会有一种 sense 大概哪里会写错。
而且,我必需说:你实际上会遇到的难题可能和你想像的不太一样。这
就好比老师叫你去屠龙,你本来以为飞龙在天,所以花去很多时间在设
计飞行器,不过後来发现最大的问题是龙会喷火,那眼前的 0 就是逃
不掉的命运了!
3. 寻求帮助与帮助同学
原则上我是建议同学尽可能自力完成作业,尤其是 debug 不应该假他
人之手。Debug 也是一种经验的累积,为什麽强者们看到 code 大概
就知道错在哪,这就是所谓的「经验」!我去年在当伪强者的时候,有
些人少一个分号或大括弧的 syntax error 都拿来问我,我就会很不高
兴,这种问题我认为大家都应该有能力自行解决,编译器提供的 error
讯息用来对付这种问题已经很足够了!除非你认为你的程式是在逻辑面
有错误,不然不要轻易地问别人,不然你会丧失很多学习的机会。记住:
在上机考的时候,是没有人可以问问题或帮你 debug 的!
对於那些能力比较好的同学,我建议你可以多多帮助同学。有时候帮助
同学你会有一些意想不到的收获。例如我去年修物件导向程式设计的时
候,因为有人常常问我很有挑战性的问题,所以我知道了很多额外的东
西,这让我後来写考卷写得很顺利(我准备考试的时间相较其他同学也
变短了)!因为有时候你对一个东西只是一知半解,但是当你要解释给
别人听的时候,你就会被迫全盘地了解一个东西。我想教学相长大概就
是这个意思。
皆下来我们谈一些写 code 的问题:
1. 忘掉复制功能
在大多数的时间复制贴上都不是一个好主意!常见的问题是:有很多
程式码长得很像,所以就会有人直接复制之前的程式码,再稍做修改。
这有二个问题:(1) 在修改复制的程式码的时候常常会漏掉一些东西,
(2) 如果共同的程式码突然要再加上一些程式码就会东漏西漏。更重
要的是:除了你自己之外,不会有多少人想要看你的程式码,因为太
难读了,想像一下你的程式码上千行,而且常常用 if 去做例外处理,
我不认为有多少人愿意去看!
2. 变数命名
变数的命名基本上不要使用 a, b, c, d 或 r0, r1, r2 之类的变数
名称。应该尽可能用有意义的名字。试比较:
int a[100][100];
int b, c, d, e;
scanf("%d%d", &b, &c);
for (d = 0; d < b; ++d)
{
for (e = 0; e < c; ++e)
{
scanf("%d", &a[d][e]);
}
}
与下面这一个程式。
int matrix[100][100];
int height, width, r, c;
scanf("%d%d", &height, &width);
for (r = 0; r < height; ++r)
{
for (c = 0; c < width; ++c)
{
scanf("%d", &matrix[r][c]);
}
}
请问哪一个比较好读?哪一个比较容易了解?
注意,第二个程式的 r 与 c 也不是乱选的,r 是取自 row,c 是
取自 column,分别代表列与栏。这有什麽帮助呢?事实上他可以
帮助我们除错:例如你看到 r < width 把行拿来和宽度来比,十之
八九就是写错了!
另外,我个人建议如果你用到了 global variables,你在命名时,
就应该加上 g_,global variables 带来的问题太多了,不胜枚举!
3. 注解
注解是一个没人爱写但大家都想读的东西。有些人主张不要写注解,
不过理由绝对不是想要偷懒,而是主张一份良好的程式码应该是望
文生义,看程式码就像在读文件很好读。但是目前,一般同学写程
式的能力该都还没有到达那种境界,所以大家最好乖乖地加上注解!
注解的写作方式因人而异,不过,一些显而易见的事就不用特别写
注解:
int i = 10; /* i = 10 */
int j; /* declares j */
这种注解有跟没有一样,就不用花时间去写了!不过如果有时候会
使用一些特别的技巧,或是有个 global variables 会被多个函式
使用,在使用的同时最好好好写清楚使用的前提,与变数的变化。
/* g_storage, we can use:
* char *ptr = *g_storage_alloc++;
* to allocate a 1024 sized character array quickly. But, however,
* notice that you can only allocate 20 times, otherwise, overflow
* will occur.
*/
char g_storage[20][1024];
char (*g_storage_alloc)[1024] = g_storage;
4. 风格
C 语言的格式很自由,不过几年下来,已经有一些特定的写法,一
般来说,养成良好的 coding 习惯是很重要的,良好的 coding 习
惯也有助於减少 syntax error 与帮助 debug。我在这就介绍我自
己习惯的写法(基本上是 ANSI C Style)。
- 一定要缩排,一层 4 个空白,不使用 tab。
- {} 自己成为一行,缩排和之前的相同
- 每个变数自成一行,并且给定初始值
- if, for, while 之後总是加上 {}
- switch 的 case 之後总是加上 break
- 非必要不使用 goto Label。
int main()
{
int a = 0;
int b = 0;
int sum = 0;
scanf("%d%d", &a, &b);
if (a > b)
{
int tmp = a;
a = b;
b = tmp;
}
while (a < b)
{
sum += a;
++a;
}
printf("%d\n", sum);
return 0;
}
另外,命名时,我建议:
(1) 变数名用小写(与底线),3-8 个字为宜(global 例外),而且名
称要可以明确地表达变数的用途,而且多用「名词」。
(2) 函式名用小写(与底线),多用「动词」命名
(3) 巨集用大写(与底线),名字越长越好,这样才不会有名称冲突,
而且可以减少巨集的使用。
(4) Global variables 的名字也是越长越好!理由和巨集相同,你
应该减少 global variables 的使用。
当然我的建议不一定是最好的建议,如果你已经有特定习惯如 K&R C
就继续用下去,不过如果没有,你可以试着遵守我的建议!
另外,Dev C++ 的智慧缩排我强烈建议你把他关掉!愚笨者如我从来
看不懂他是怎麽缩排的。
以上大概是我过去半年的经验谈,希望对学弟妹们有所帮助。
--
LoganChien ----- from PTT2 个板 logan -----
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.112.247.159
1F:推 hrs113355:推 09/18 12:44
2F:推 ming1053:推这篇 不过 coding style 就看个人罗 09/18 13:06
3F:推 hsinfu8055:大推学长用心!! 09/18 16:46
4F:推 andy860106:该M文罗 09/18 16:48
5F:推 zenixls2:学长超强的!!看p2个版就知道!大推此文~ 09/18 19:58
※ 编辑: LoganChien 来自: 140.112.30.84 (09/18 20:15)
6F:推 telgniw:推 09/18 21:41
7F:推 sa072686:推,不过style看个人吧…强硬要求格式就不art了 09/18 22:49
8F:推 rock1246:超棒的文章 09/18 23:40
9F:推 xflash96:推 09/19 00:49
※ 编辑: LoganChien 来自: 140.112.247.159 (09/19 01:53)
※ 编辑: LoganChien 来自: 140.112.247.159 (09/19 02:05)
10F:推 scan33scan33:推 09/19 09:23
11F:推 godgunman:推 我也是觉得style 应该自由点~ 09/19 10:52
12F:推 s864372002:个人认为智慧型缩排很好用啊...... 09/19 11:40
13F:推 tomdavis:楼上真强者..... 09/19 16:24
14F:推 vanillaXleft:!+ 09/19 17:56
15F:推 comlcs:推 09/22 13:17
16F:推 spontrick:大推~看完後整个超甘心的~谢谢学长 09/28 19:02
17F:推 asdfghjkl202:超甘心。我也不惯用智缩,有啥规律呀? 10/07 15:50
18F:推 asdfghjkl202:可是我觉得/* i = 10 */好好笑喔XDD! 10/07 15:55