| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 31773 人关注过本帖, 12 人收藏
标题:[转载]给使用TC的初学者的一篇文章★★★
只看楼主 加入收藏
雨中飞燕
Rank: 3Rank: 3
等 级:禁止访问
威 望:8
帖 子:2200
专家分:0
注 册:2007-8-9
收藏
得分:0 
哦,那我改过来了,是讲的声明和返回值的问题
那个不是要说TC的缺点,而是说不能以一个编译器上的结果正确而认为逻辑上的正确
在不同编译上能得到不同结果的原因通常是因为不规范的代码导致的
然而很多初学者只使用TC的情况下,就很容易遗漏很多逻辑上的问题或者规范上的问题
2007-08-18 14:54
Knocker
Rank: 8Rank: 8
等 级:贵宾
威 望:47
帖 子:10454
专家分:603
注 册:2004-6-1
收藏
得分:0 

刚回到家,昨天的贴子是车上发,所以也没细说.除了百年不亮兄所说的,还有几点我的看法也有不同.

首先,我的观点:
TC过时了没有?
Tc过时了,相对现在绝大多数实际应用开发项目来说是一个绝对过时的工具.它本身就是一个dos系统下的C语言开发工具,你怎么要求它开发windows系统应用程式?从这点来说,现在已经没有或者很少有dos系统的应用开发了,所以,它过时了.

TC没过时,作为一个C语言学习工具来说,TC不过时,反而我的看法要提倡初学者就使用TC来学习C语言,原因有相对其它编译器,TC的IDE功能、设置要相对简单一点,几乎拿来就可以用,且小而精致。这里更提倡初学者使用wintc.这样可以避免初学者一开始就将大量的精力花费在如何使用IDE上,而且作为一个初学者根本用不到这些功能.
要知道,对于初学者来说语言学习是主要的,熟悉编译环境是次要的。语言学习的时间可能花费你几年时间,当你熟练掌握了C语言,想再熟悉一下另一种编译环境可能只需花费你几天时间。
再一个,以后你需要熟悉多种编译器多种语言怕是避免不了,所以一开始只需采用能满足学习所需的工具即,当然要选简单易用小巧的编译器.

以下是引用雨中飞燕在2007-8-17 20:27:53的发言:

给使用TC的初学者的一篇文章 —— 作者:雨中飞燕

本文源自雨中飞燕之家C/C++学习论坛[url]http://yzfy.org[/url],转载请注明出处。

前言:

“TC过时了”,我说。接着就一堆人问,“为什么过时啊?”,“TC不是很好用吗”,
“教材上也是用这个啊”,“二级考试不也是规定用的TC吗?”。
于是乎我已经无语了。


/----------------------------------------------------------------------/
一。头文件的问题

好了,来看个经典的TC2下在老潭的书的《C语言程序设计(第二版)》,
第4页的一段代码:
main( )
{
printf("This is a C program.\n");
}

好了,当时的TC2的确允许使用printf和scanf可以不加头文件,
也的确允许main()这样的声明。允许是允许了,可是你写成这样对你有好处吗?

打个比方,Basic语言知道吗?这种语言可以不声明变量就使用。
的确同样也是允许了,可是给我的话,我会要求编译器强制检查变量是不是声明了再使用。
为什么?如果你需要用名字是nlen这个变量,当中有一个不小心写成n1en,
不强制检查的话,编译器不告诉你错,但运行结果是错误的。但这种错误要是在很多行
代码里你怎么找?特别是'l'和'1'如此相似。

编译器虽然允许,但你别以为那样写就是好事。说回刚刚的C代码,TC2允许不加头文件,
于是不少初学的人习惯了从不写头文件,以为C语言不需要头文件似的。
好了,等到看到那本书的138页,那个字符输入输出,用了gets,
就突然多了一个#include <stdio.h>,仔细一看,那一页中间有100来字强调
了要用库函数,可是没有讲怎么用,下面多了的那一行初学者也可能会觉得奇怪,
要是不理解的人就跳过了,要是没留意的更不当一回事了,谁让之前书里一直都
没有那句呢。然后,当有的初学者用TC3.0打代码的时候,编译提示说scanf没有
声明(或者是用TC2的打了gets函数说gets没有声明),他们就郁闷了,
都是按照书的代码啊,都一模一样还会错?于是跑来论坛问。有跑来问的还好,
最怕的就是用TC2的,看了数组觉得难还跳了过去的,于是一直都不会写头文件,
成了习惯。要是随便换个环境,结果没写头文件的,错了,结果还说自己写C代码
写那么多,这里怎么就错了,然后就怀疑编译器是不是坏的。然后就借口说这个
用不习惯要换TC2。结果就是恶性循环,跳不出TC2,学不到新领域的东西。
论坛上这种代码绝不少见,随便翻一些提问帖子肯定找得到。其实早在TC3.0已经
不再允许scanf和printf不加头文件了,随后的所有C编译器也不再支持TC2的
这个特性了。
[color=black]本文源自雨中飞燕之家yzfy.org,作者雨中飞燕[/color]

//你的观点 :TC中充许printf等函数不加头文件是一种过时表现
//那么,我告诉你,使用BCB等等现代开发工具,程序员几乎用不着考虑头文件问题,IDE会处理.还有CodeCompletion技术在流行,目的仅仅都是为了方便程序员.TC中充许printf等常用I/O函数不需加头文件当时也基于方便程序员。

/----------------------------------------------------------------------/
二。main的声明与返回值

其实如果只是算潭书的第二版,这个无类型的main声明没有问题,只是直到C99标准
的出现,这个声明才彻底废除。其实也是同样一个问题,允许你不写,但这不是说你
这样用就是好事。不过,这个的后果有点不一样的就是,你忽略不写,很可能以为是
不需要返回的,或者是以为返回一个无类型的(void),接着就出现了main函数里不
写return 0;的问题。那本书就是从头到尾所有main函数一律没有return 0; 。好了,
等到学了函数那章,书上说,没有返回值的函数应该要用void来声明,好了,
void main就这样诞生了。不信就看看谭书的第三版,变成从头到尾的void main()。
不过话说回头,这样的问题对于初学者学习基本语法和结构方面和写写小程序的都不会
出现任何影响。在编译器上来说,这只是一个标准的问题,但对于你来说别小看了这么
一点点的变化。因为你习惯了main这种写法的话,必然会把这个习惯带到编写其它函数里
(这里暂且不讲main本身返回值的问题)。
举个简单例子,写以下代码:
#include <stdio.h>
factorial(int n)
{
if(n==1)return 1;
else if(n>1)return n * factorial(n-1);
}
int main(void)
{
int n;
while(scanf("%d", &n),n>=0)
{
printf("%d\n", factorial(n));
}
return 0;
}

看得出来是计算阶乘的(主要看那个子函数,main函数用回标准写法),
只不过少了int声明和最后一个必然的return而已,

//这个例子不用说,前面已百年不亮已说过了,是你的程序的逻辑有问题.与TC或C89标准都无关。

看看输入一个0进去会发生什么事吧:
TC2: 1 (结果居然是碰对了)
VC6: -858993460 (不确定的随机结果)
GCC: 0 (C99标准)
如果你用TC,那你还可能以为这份代码是正确的,
于是你就以为递归算阶乘就是这么写的。
于是还反过来问我:“喂,雨中飞燕,这个结果不就是正确的吗,还错什么啊?”
于是我无语了。。。然后你也就留下了一个你可能以后都不打算去检查的Bug。。。

现在我们再来看一个:
#include <stdio.h>
long Factorial(int n)
{
if(n==1)return 1;
else if(n>1)return n * Factorial(n-1);
return 1;
}
FactorialSum(int n)
{
float f = 0;
for(;n>0;--n)
{
f += 1.0/Factorial(n);
}
return f;
}
int main(void)
{
int n;
while(scanf("%d", &n),n>=0)
{
printf("%f\n", FactorialSum(n));
}
return 0;
}

这个是计算1/1! + 1/2! + 1/3! +...+ 1/n!的代码,Factorial的改好了,
然后加一个FactorialSum函数计算和。里面的变量f就是用来累加(喜欢用float来
保存浮点也是书上的一大不良特色),1写成1.0保证结果不是整数。似乎没错吧?
运行一下不就知道了嘛,输入1,输出0;输入2,输出0;输入5,输出0,
结果是输出全部是0。原因就是你省略类型埋的祸根,只需要在那个函数前面补上
一个float那结果就正确了。

//这个例子也同样是你错误运用C89标准的规则,与TC或C89标准都无关。
//上次的贴子,我主要就是指这两地方


[color=black]本文源自雨中飞燕之家yzfy.org,作者雨中飞燕[/color]
这个危害有多严重吗?在这里不算严重,因为在这里代码很短,相当容易看得出来。
要是换成大程序呢?上千代码甚至上万的代码,要是最后都懒得写一下return,
或者一个返回类型,那么错误还怎么找?你要是这个也省略那个也省略,
写了N多行代码的时候,一运行,这个结果也错那个输入也不行的时候,
你再看看你是不是被你自己的“习惯”给难住你自己吧。

其实说实在的,WIN-TC自带的一个tcsearch.exe文件,那个可以查函数用法和示例,
//怀疑一下,tcsearch.exe不是老吴写的吧?
上面的示例代码全部都是一样的风格: int main(void)
非常规范标准的写法,可是有多少人看了这个了呢?

/----------------------------------------------------------------------/
三。函数声明

经典的老代码:
int max(x,y)
int x,y;
{
return x>y ? x : y;
}

现在早已不是pascal时代了,这样的函数声明不但难读,并且现在C99标准已经不再
支持这种写法了。在老潭的书也仅仅用了半版不到的篇幅提到了一下,
其它地方并没有使用这种声明,这点做得还不错。不过很奇怪的是论坛上还时不时
能看见这种声明,这个到底是拜谁所赐呢?这我就不知道了,这里也不展开来讲了。


/----------------------------------------------------------------------/
四。代码风格

这个问题就非常严重了。现在的情况是,从代码风格,就可以知道你的大概水平了,
至少能知道你是不是菜鸟。那些代码缩进弄得乱七八糟的,不用看详细代码都知道
水平肯定高不到哪里去(当然不排除你可以故意弄乱)。因为要是作为一个新手,
要是写的代码乱,调试的时候或者自己看自己的代码的时候,要是你自己都觉得乱,
当代码有Bug,你要找出来的话,看你还头痛不头痛了。本来代码就有问题,再加上
格式乱,要是你自己看着都不舒服,那你还怎么去调试代码呢?自己不会看着头晕?
代码少的时候你可能不觉得,等你写了上百行代码的那再尝尝这种滋味吧。

更严重的问题是,DOS原版TC对缩进支持不好,
格式的控制相对其它的编辑器来说都要弱。
对于初学者,很容易弄出参差不齐的代码,
对于学习方面来说这是一个很不利的因素。
[color=black]本文源自雨中飞燕之家yzfy.org,作者雨中飞燕[/color]
再者,大括号的位置及变量声明位置的问题。看以下几种风格:
1.
int main(void) //潭氏风格
{int n,s;
while(scanf("%d", &n),n>=0)
{
s = factorial(n);
printf("%d\n", s);
}
return 0;
}

2.
int main(void) //视频教学风格?
{ int n,s;
while(scanf("%d", &n),n>=0)
{ s = factorial(n);
printf("%d\n", s);
}
return 0;
}

3.
int main(void) //不知道这风格的来源
{
int n,s;
while(scanf("%d", &n),n>=0)
{
s = factorial(n);
printf("%d\n", s);
}
return 0;
}

4.
int main(void){ //这种风格也有不少高手使用的
int n,s;
while(scanf("%d", &n),n>=0){
s = factorial(n);
printf("%d\n", s);
}
return 0;
}


5.
int main(void) //C Primer Plus 上的风格
{
int n;
while(scanf("%d", &n),n>=0)
{
int s = factorial(n);
printf("%d\n", s);
}
return 0;
}

我推荐的写法是第5种。第三种写法貌似较少见,雨中飞燕本人不好作出评论。
但对于1,2,4三种写法,都是有原因的。原因也很简单,减少占用的行数。
特别是纸版书,节省这点行数累积起来可以节约不少纸张,降低书的成本。
对于powerpoint演示,如果不节约行数,代码根本没办法显示完。
但你要注意,它这样写可能不是为了告诉你要这样写出这样紧密的代码。
但同样的问题出现在TC上。DOS窗口标准大小80*25,高度只能显示25行,
再加上TC菜单和最下面的输出窗口,你能同时看到最多20行,要是按第5种风格
来写代码,会看得很辛苦(因为TC2用不了鼠标 <谁告诉你的?>,TC3能用不过也麻烦),
于是造成N多紧缩型代码。如果你换成现在新的编辑软件,根本用不着这样。
Windows上的集成编辑软件一页下来就是三四十行,用鼠标滚轮滚一下就能上下拉,
一个代码块要是不想看还可以折叠起来,这些特性都是TC所无法比拟的,
都比TC方便得多。你还有什么理由抱着TC不放呢?还何必写紧缩型代码来为难
自己的那双眼睛呢?


/----------------------------------------------------------------------/
五。TC图形库

TC图形库这个可以说是TC一大特色,用TC2写出来的代码一般可以一眼看出,因为TC2
编译运行的时候,屏幕上原有的东西并不会清除,所以用TC的人一般会习惯在程序开头
写上clrscr()。当然,要是用Win-TC就不会发生这种情况。如果使用者本人知道这个
库是TC专有(好比是VC的MFC)的话,这倒问题不大。问题是如果使用者不知道的话,
屏幕输出用习惯了gotoxy,变得理所当然地认为C就应该支持这类函数的话,
那就糟糕了。论坛上跑来问VC6可不可以输出图形,或者问有没有gotoxy函数的人
不是一个两个人的问题了。

//?
[color=black]本文源自雨中飞燕之家yzfy.org,作者雨中飞燕[/color]

/----------------------------------------------------------------------/
六。越界检查

由于在DOS下,DOS系统根本不会去检查程序的访问越界问题,无论你要对内存的哪里
进行读写,都是允许的(只要不把自己程序的代码区改写了就没事)。但在Windows下,
尤其是WinXP,内存是分块的,对只读块写数据或者对不可读写块进行读数据都会引发
异常,如果程序不能够处理这个异常,那么这个程序就会被强制关闭。有了这个异常
机制,当然会使你更容易查出程序的错误。特别地,在VC6的Debug模式下,
堆里未被初始化的内存被0xCD字节模式填充,堆里释放的内存被0xDD字节模式填充。
于是一但发生越界的时候,很容易通过程序运行结果得知当中有错,为调试带来了方便。

//一,你所说好象不是“越界检查”问题
//二,如果你说的是"越界检查"问题,C99标准都不支持越界检查,我不用VC,VC支不持这个我到是不清楚了,如果支持,也只是VC对C标的扩展
然而TC则不然,不管你越界了多少,你都收不到任何的警告或者错误。
而且在多数情况下,TC下运行正常的越界代码换VC6上就会结果出错。
有初学者以为这是VC6编译器有问题,其实不然,而是TC给你掩盖了这个错误。
#include <stdio.h>
int main(void)
{
int n;
int num[8];
int sum[8] = {0};
for(n=1;n<=8;++n)num[n] = 1;
for(n=1;n<8;++n)sum[n] = num[n]+num[n+1];
for(n=1;n<8;++n)
printf("%d\n", sum[n]);
getchar();
return 0;
}


//从C标上看,无论是C89还是C99,这个错误都归属于程序员,越界检查是C程序员的事


这个程序的目的是给num数组全部给1,然后sum数组计算num相邻两个数的和。
有的初学者可能会说,这个程序没问题,如果他以为int num[8];的下标是从1至8的话。
然后,照样运行一下看看。TC的结果是7个2,结果正常。
VC6的结果是,什么都没有显示,然后你打开资源管理器查看一下进程,
你就会发现这个程序占用CPU高达90%以上。你不要以为这是编译器发生了问题,
原因正是因为这里的越界导致了一个死循环!如果是GCC或更高版本的VC编译器,
把for里的8改成11也会发生死循环。但即使改成11,在TC上运行的结果也非常正常,
TC里完全没有任何错误的征兆。这里不分析这个死循环产生的原因,这里只是想告诉你,
你在TC上运行结果无误的程序不一定就逻辑上正确了(包括VC和GCC)。特别是TC几乎
没有任何的越界检查,所以更要求程序员在TC上编写代码时候要十分谨慎和细心。
但现在问题是现在使用TC的大多是初学者,在没有什么经验的情况下,很大可能
会写出类似这样的越界访问代码。这种代码也许在TC上没有问题,可是只要换一个
编译环境,问题就马上暴露出来了。不信就看看下面的经典TC错误代码吧:
#include <stdio.h>
int main(void)
{
char *pstr;
gets(pstr);
puts(pstr);
getchar();
return 0;
}

(别告诉我说你不知道这代码错在哪里,你不知道错哪里的话那你平时一定是使用TC的)
[color=black]本文源自雨中飞燕之家yzfy.org,作者雨中飞燕[/color]

/----------------------------------------------------------------------/
七。结束语

现在再来回答文章一开头的内容:“为什么说TC过时”?
主要原因其实不是过时不过时的问题,主要是不适合现在初学C语言的学生们使用。
很容易因为TC过于宽松的一些语法,或者一些与C99标准不一样的语法,
让初学者养成不良习惯或者产生特定环境下的依赖性。这些都是对学习上不利的因素

//这点我同意,但是如果仅是因为这个,我的想法与你不同

//既然有C89与C99的区别,为什么不搞明白它?

所以我一般给别人推荐DevC++或者VC2005就是这个原因,借助编译器的强制能力,
迫使你使用较为规范的方式去写代码。新加坡的环境为什么好?不是因为公民素质高,
是因为有法律规定,随便扔垃圾或者破坏环境的都会有严重的法律后果。

归根究底,不让你用TC,就是不希望你有不良习惯,更何况有很多比TC优秀的编译器呢?
何必因为教材或者考试是TC,你就一定用TC呢?

知识是属于自己的,用来真正充实你自己的
考试是给别人看的,用来得到一时之虚荣的
你希望得到充实,还是一时之虚荣?

本文源自雨中飞燕之家C/C++学习论坛[url]http://yzfy.org[/url],转载请注明出处。



九洲方除百尺冰,映秀又遭蛮牛耕。汽笛嘶鸣国旗半,哀伤尽处是重生。     -老K
治国就是治吏。礼义廉耻,国之四维。四维不张,国之不国。   -毛泽东
2007-08-18 21:25
百年不亮
Rank: 3Rank: 3
等 级:新手上路
威 望:8
帖 子:789
专家分:0
注 册:2006-4-14
收藏
得分:0 

要说tc简单我同意,但是vc和dev-cpp也不是很复杂.

对于先接触tc后用vc的都说vc麻烦,我们学c时老师教过vc,学生记下新建文件的步骤就行了,对一个中学生或大学生来说记几个操作应该没问题吧.然后vc中编译执行,调试都可以用鼠标操作,符合我们日常用电脑的习惯,所以有人教还是用vc好.

先学vc后用tc到是感觉很麻烦,我见有的人总会时不时去摸鼠标.

或许时代变了,和Knocker
学c那个时代不同,我们学校现在都是开始就用vc.现在大学上课都用电脑加投影仪,老师讲程序时打开vc编译执行给我们看,有的时候还调试几步,再笨的学生每天都看老师用vc也该学会了.

2007-08-18 21:50
ioriliao
Rank: 7Rank: 7Rank: 7
来 自:广东
等 级:贵宾
威 望:32
帖 子:2829
专家分:647
注 册:2006-11-30
收藏
得分:0 

这个要看你用作什么用了,用其它的ide能在纯doc下运行吗?


/images/2011/147787/2011051411021524.jpg" border="0" />
2007-08-19 18:24
面朝大海
Rank: 1
等 级:新手上路
帖 子:28
专家分:0
注 册:2007-7-24
收藏
得分:0 

雨中飞燕是男是女啊?

2007-08-19 18:28
jun0325
Rank: 1
等 级:新手上路
帖 子:37
专家分:0
注 册:2007-8-8
收藏
得分:0 
楼主说得很好啊!佩服

数据结构+算法+程序设计方法+语言工具和环境=程序
2007-08-26 11:54
栖柏
Rank: 2
等 级:论坛游民
威 望:3
帖 子:1103
专家分:17
注 册:2007-8-23
收藏
得分:0 
我们学校有个机房里面的机子纯dos系统,没有鼠标,机器也是过去的

You have lots more to work on! Never give up!c language!
2007-08-26 11:58
Knocker
Rank: 8Rank: 8
等 级:贵宾
威 望:47
帖 子:10454
专家分:603
注 册:2004-6-1
收藏
得分:0 
dos系统也支持鼠标

九洲方除百尺冰,映秀又遭蛮牛耕。汽笛嘶鸣国旗半,哀伤尽处是重生。     -老K
治国就是治吏。礼义廉耻,国之四维。四维不张,国之不国。   -毛泽东
2007-08-26 12:08
栖柏
Rank: 2
等 级:论坛游民
威 望:3
帖 子:1103
专家分:17
注 册:2007-8-23
收藏
得分:0 
需要下载安装吧,也可自己编译一个程序吧(我做过这程序)
我说的是没有鼠标是没有鼠标那硬件
那个机房也不能联网
给学c人用的,还有参加我们学校竞赛用的
学校留的还是内存只有128m,好象是上个世纪80、90年代的机器

You have lots more to work on! Never give up!c language!
2007-08-26 12:20
福尔摩斯
Rank: 5Rank: 5
等 级:贵宾
威 望:12
帖 子:4011
专家分:370
注 册:2006-8-15
收藏
得分:0 
以下是引用Knocker在2007-8-26 12:08:51的发言:
dos系统也支持鼠标

dos下鼠标拿来做什么用?


自我放逐。。。
2007-08-26 12:53
快速回复:[转载]给使用TC的初学者的一篇文章★★★
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.068459 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved