轻松学习C语言的技巧
轻松学习C语言的技巧(实用)
C语言是一门通用计算机编程语言,应用广泛。那么在C语言的学习过程中会有哪些技巧呢?下面小编为大家带来轻松学习C语言的技巧,希望对您有所帮助!
轻松学习C语言的技巧
1,任何语言都是为应用服务的。这里的应用主要在测试方面。首先应该明确这一点。
2,C语言能不能速成因人而异,大学里一般C语言一般60课时左右(40_60=2400分钟=100小时=4天左右)。所以合理分配时间,加上学习上没有什么障碍的话,2周左右是可以略有所成的。
3,还有一些客观原因制约学习,如果是第一次接触语言,那么一些语法规则和一些“约定俗成”的东西需要一段时间来消化。从我个人经历来看,学习C语言以后,Java我几乎没有学习过,只是边学边用而已。所以可见第一门语言的学习如何重要。所以没有什么特殊情况,尽量放下脚步。
4,无论你打算怎么制定学习计划,实践的比重一定要最大。在你学习中你可能就会发现,好多要点能在实践中获取,大大提高学习效率。举个简单例子:与其背 , , ,%s,%o等等是什么意思,不如在程序中调用一下,看看输出结果最为直观。
5,根据应用,个性化学习语言。C语言提供的头文件中有大量可供调用的函数,但并不是都有很高的利用价值。根据你实际的测试用例的安排,或测试的方法来使用这些函数即可。有时候,一段系统提供的函数和你编的一段代码肯能会实现同意个目标,但系统函数可能只需要一行,而你的代码要几十行,所以多了解系统函数的利用价值,对你快速应用很有帮助。
6,切忌学习是一个循序渐进的过程,都有周期性的。每一个阶段都会有止步不前的时候。适当的找人提供帮助是初学者必须做到的,单凭自学,有些时候会错过一些技巧性的东西,既浪费时间,又未有所得。
7,下面说学习过程:
(1)了解和使用一个函数,比如一个10几行的函数。要做到了解每一句话的作用。每个函数的.参数的意义。然后尝试自己默写这段程序,运行,调试。看自己错误在那里。然后用函数中出现的知识,来扩展这段程序,哪怕扩展的都是打印语句。注意:数据类型等一些知识可以遇到多少学多少,慢慢积累。
(2)掌握3种程序结构,能学会3种结构间并列、嵌套的使用。理解条件、循环结构的意义和目的。
(3)知道以上这些内容,就可以大胆的参考材料,尝试阅读或改写书中提供的小程序了。例如求斐波那锲数、阶乘一类的,这些几乎是在练习程序的结构,使用熟练度。
(4)第一次深入学习:数组。学完数组后,可以补充一些数据结构的知识,然后就可以做很多的排序、查找的程序了。这时候可以做一个小型的管理系统,来检验所学。
(5)第二次深入学习:指针。指针学习最好紧跟数组,因为他们向来是拿到一起做比较的,因此这样安排有利于对数组和指针应用时的取舍。
(6)以上学习后,C语言基本成型,可以把侧重点都放在实践上,比如用指针内容改写用数组知识编写的管理系统。
8,好好学肯定有斩获。
C语言编程建议和技巧
介绍
Kernighan和Plauger编写的《The Elements of Programming Style》,是一本很重要而且公认有很大影响力的书。但有时候我觉得对于书中的简洁规则,可以看做是一种好的烹饪方法,而不是想简洁的表达一种哲学思维。倘若这本书声称应该有意义地选择变量名称,那么难道他们文章中对变量的命名更好?难道MaximumValueUntilOverflow比maxval更好吗?我不这么认为。
下面是一篇简短的文章,总体上鼓励在编程时应有清晰的哲学思维,而不是给予硬性规则。我并不希望你们能认可所有的东西,因为它们只是观点,观点会随着时间的变化而变化。可是,如果不是直到现在把它们写在纸上,长久以来这些基于许多经验的观点一直积累在我的头脑中。因此希望这些观点能帮助你们,了解如何规划一个程序的细节。(我还没有看到过一篇讲关于如何规划整个事情的好文章,不过这部分可以是课程的一部分)要是能发现它们的特质,那很好;要是不认同的话,那也很好。但如果能启发你们思考为什么不认同,那样就更好了。在任何情况下,都不应该照搬我所说的方式进行编程;要用你认为最好的编程方式来尝试完成程序。请一以贯之而且毫不留情的这么做。
欢迎您的评论。
排版问题
程序是一种出版物。意味着程序员们会先阅读(也许是几天、几周或几年后的你自己阅读),最后才轮到机器。机器的快乐就是程序能编译,机器才不在乎程序写的有多么漂亮,可是人们应该保持程序的美观。有时人们会过度关心:用漂亮的打印机呆板地打印出漂亮的输出,而这些输出只是将所有介词用英文文本以粗体字体凸显出来,都是些与程序无关的细节。虽然有很多人认为程序就应该像 Algol68 所描述的一样(有些系统甚至要求照搬该风格编写程序),可清晰的程序不会因为这样的呈现而变得更清晰,只会使糟糕的程序变得更可笑。
对于清晰的程序来说,排版规范一向都是至关重要的。当然,众所周知最有用的是缩进,但是当墨水遮盖了意图时,就会控制住排版。因此即便坚持使用简单的旧打字机输出,也该意识到愚蠢的排版。避免过度修饰,比如保持注释的简洁和灵活。通过程序整齐一致地说出想表达的。接着往下看。
变量命名
对于变量名称,长度并不是名称的价值所在,清晰的表达才是。不常用的全局变量可能会有一个很长的名称,像maxphysaddr。在循环中每一行所使用的数组索引,并不需要取一个比i更详尽的名字。取index或者elementnumber会输入更多的字母(或调用文本编辑器),并且会遮盖住计算的细节。当变量名称很长时,很难明白发生了什么。在一定程度上,这是排版问题,看看下面
for(i=0to100)
array[i]=0;
vs.
for(elementnumber=0to100)
array[elementnumber]=0;
现实例子中的问题会变得更糟。所以仅需把索引当成符号来对待。
指针也需要合理的符号。np仅仅只是作为指针 nodepointer 的助记符。如果一贯都遵从命名规范,那么很容易就能推断出 np 表示“节点指针”。在下一篇文章中会提到更多。
同时在编程可读性的其它方面,一致性也是极其重要的。假使变量名为 maxphysaddr,则不要给同级关系的'变量取名 lowestaddress。
最后,我倾向于「最小长度」但「最大信息量」的命名,并让上下文补齐其余部分。例如:全局变量在使用时很少有上下文帮助理解,那么它们的命名相对而言更需要令人易懂。因此我称 maxphyaddr (不是 MaximumPhysicalAddress)作为一个全局变量名,对于在本地定义和使用的指针来说 np 并不一定是 NodePoint。这是品味的问题,但品味又与清晰度相关。
我避免在命名时嵌入大写字母;在我经验丰富的双眼中,它们的阅读舒适性太别扭了,像糟糕的排版一样令人心烦。
指针的使用
C 语言不同寻常,因为它允许指针指向任何事物。指针是锋利的工具,像任何这样的工具一样,使用得当可以产生令人愉悦的生产力,但使用不当也可以造成极大的破坏(在写这篇文章的前几天,我把木工凿插到拇指里了)。指针在学术界的名声不太好,因为它太危险了,莫名其妙地就变得糟糕的不行。但我认为它是强大的符号,它可以帮助我们清楚地自我表达。
思考:当有指针指向对象时,对于那个对象,确切地说它只是名称,其它什么也不是。听起来很琐碎,但看看下面的两个表达式:
np
node[i]
第一个指向一个 node(节点),第二个计算为(可以说)同一个 node。但第二种形式是不太容易理解的表达式。这里解释一下,因为我们必须要知道 node 是什么,i是什么,还要知道i和 node 与周围程序之间相关(可能不是很详细)的规则是什么。孤立的表达式并不能说明i是 node 的有效索引,更不用提是我们想要元素的索引。如果i、j和k都是 node 数组中的索引将很容易出差错,而且连编译器都不能帮助找出错误。当给子程序传参数时,尤其容易出错:指针只是一个单独的参数;但在接收的子程序中必须认为数组和索引是一体的。
计算为对象表达式本身,比该对象的地址更不易察觉,而且容易出错。正确使用指针可以简化代码:
parent->link[i].type
vs.
lp->type.
如果想取下一个元素的 type 可以是
parent->link[++i].type
或
(++lp)->type.
i前移,但其余的表达式必须保持不变;用指针的话,只需要做一件事,就是指针前移。
把排版因素也考虑进来。对于处理连续的结构体来说,使用指针比用表达式可读性更好:只需要较少的笔墨,而且编译器和计算机的性能消耗也很小。与此相关的问题是,指针类型会影响指针正确使用,这也就允许在编译阶段使用一些有用的错误检测,来检查数组序列不能分开。而且如果是结构体,那么它们的标签字段就是其类型的提示。因此
np->left
是足以让人明白的。如果是索引数组,数组将取一些精心挑选的名字,而且表达式也会变得更长:
node[i].left.
此外,由于例子变得越来越大,额外的字符更加让人恼火。
一般来说,如果发现代码中包含许多相似并复杂的表达式,而且表达式计算为数据结构中的元素,那么明智地使用指针可以消除这些问题。考虑一下
if(goleft)
p->left=p->right->left;
else
p->right=p->left->right;
看起来像利用复合表达式表示p。有时这值得用一个临时变量(这里的 p)或者把运算提取成一个宏。
过程名称
过程名称应该表明它们是做什么的,函数名称应该表明它们返回什么。函数通常在像if这样的表达式使用,因此可读性要好。
if(checksize(x))
是没有太大帮助的,因为不能推断出 checksize 错误时返回 true,还是非错误时返回。相反
if(validsize(x))
使这点能清晰表达,并且在常规使用中将来也不大可能出错。
注释
这一个微妙的问题,需要自己体会和判断。由于一些原因,我倾向于宁可清除注释。第一,假如代码清晰,并且使用了规范的类型名称和变量名称,应该从代码本身就可以理解。第二,编译器不能检查注释,因此不能保证准确,特别是代码修改过以后。误导性的注释会非常令人困惑。第三,排版问题:注释会使代码变得杂乱。
但有时我会写注释,像下文一样仅仅只是把它们用于介绍。例如:解释全局变量的使用和类型(我总是在庞大的程序中写注释);作为一个不寻常或者关键过程的介绍;或标记出大规模计算的一节。
糟糕注释风格,有一个典型的例子:
i=i+1;/_ Add one to i _/
还有更烂的做法:
/__________________________________
__
_Add one to i_
__
__________________________________/
i=i+1;
先不要嘲笑,等到在现实中看到再去吧。
或许除了诸如重要数据结构的声明(对数据的注释通常比对算法的更有帮助),这样至关重要部分之外,需要避免对注释的“可爱”排版和大段的注释;基本上最好就不要写注释。如果代码需要靠注释来说明,那最好的方法是重写代码,以便能更容易地理解。这就把我们带到了复杂度。
复杂度
许多程序过于复杂,比需要有效解决的问题更加复杂。这是为什么呢?大部分是由于设计不好,但我会跳过这个问题,因为这个问题太大了。然而程序往往在微观层面就很复杂,有关这些可以在这里解决。
规则 1:不要断定程序会在什么地方耗费运行时间。
瓶颈总是出现在令人意想不到的地方,直到证实瓶颈在哪,不要试图再次猜测并加快运行速度。
规则 2:估量(measure)
在没有对代码做出估量之前不要优化速度,除非发现最耗时的那部分代码,要不也不要去做。
规则 3:当 n 很小时(通常也很小),花哨的算法运行很慢。
花哨算法有很大的常数级别复杂度。在你确定 n 总是很大之前, 不要使用花哨算法。(即使假如 n 变大,也优先使用规则 2).例如,对于常见问题,二叉树总比伸展树高效。
规则 4:花哨的算法比简单的算法更容易有 bug,而且实现起来也更困难
尽量使用简单的算法与简单的数据结构。
以下几乎是所有实际程序中用到的数据结构:
数组
链表
哈希表
二叉树
当然也必须要有把这些数据结构灵活结合的准备,比如用哈希表实现的符号表,其中哈希表是由字符型数组组成的链表。
规则 5:以数据为核心
如果选择了适当的数据结构并把一切都组织得很有条理性,算法总是不言而喻的。编程的核心是数据结构,而不是算法。(参考 Brooks p. 102)
规则 6:就是没有规则 6
数据编程
不像许多 if 语句,算法或算法的细节通常以紧凑、高效和明确的数据进行编码。眼前的工作可以编码,归根到底是由于其复杂性都是由不相干的细节组合而成。分析表是典型例子,它通过一种解析固定、简单代码段的形式,对编程语言的语法进行编码。有限状态机特别适合这种处理形式,但是几乎任何涉及到对构建数据驱动算法有益的程序,都是将某些抽象数据类型的输入“解析”成序列,序列会由一些独立“动作”构成。
也许这种设计最有趣的地方是表结构有时可以由另一个程序生成(经典案例是解析生成器)。有个更接地气的例子,假如操作系统是由一组表驱动,这组表包含连接 I/O 请求到相应设备驱动的操作,那么可以通过程序“配置“系统,该程序可以读取到某些特殊设备与可疑机器连接的描述,并打印相应的表。
数据驱动程序在初学者中不常见的原因之一是由于 Pascal 的专制。 Pascal 像它的创始人一样,坚信代码要和数据分开。因而(至少在原始形式上)无法创建初始化的数据。与图灵和冯诺依曼的理论背道而驰,这些理论可都是定义存储计算机的基本原理。代码和数据是一样的,或至少可以算是。还能怎样解释编译器的工作原理呢?(函数式语言对 I/O 也有类似的问题)
函数指针
Pascal 专制的另一个结果是初学者不使用函数指针。(在 Pascal 中没有把函数作为变量) 用函数指针来处理编码复杂度会有一些令人感兴趣的地方。
指针指向的程序有一定的复杂度。这些程序必须遵守一些标准协议,像要求一组都是相同调用的程序就是其中之一。除此之外,所要实现的只是完成业务,复杂度是分散的。
有个协议的主张是既然所有使用的功能相似,那么它们的行为也必须相似。这对简单的文档、测试、程序扩展和甚至使程序通过网络分布都有帮助——远程过程调用可以通过该协议进行编码。
我认为面相对象编程的核心是清晰使用函数指针。规定好要对数据执行的一系列操作,以及对这些操作响应的整套数据类型。将程序合拢到一起最简单的方法是为每种类型使用一组函数指针。简而言之,就是定义类和方法。当然,面向对象语言提供了更多更漂亮的语法、派生类型等等,但在概念上几乎没有提出额外的东西。
数据驱动程序与函数指针的结合,变成了一种表现令人惊讶的工作方法。根据我的经验,这种方法经常会产生惊喜的结果。即使没有面向对象语言,无需额外的工作也可以获得 90% 的好处,并且能更好地管理结果。我无法再推荐出更高标准的实现方式。我所有的程序都是由这种方式组织管理,而且经过多次开发后都相安无事——远远优于缺少约束的方法。也许正如所说:从长远来看,约束会带来丰厚的回报。
包含文件
简单规则:包含(include)文件时应该永远不要嵌套包含。
如果声明(在注释或隐式声明里)需要的文件没有优先包含进来,那么使用者(程序员)要决定包含哪些文件,但要以简单的方式处理,并采用避免多重包含的结构。多重包含是系统编程的祸根。将文件包含五次或更多次来编译一个单独的 C 源文件的事情屡见不鲜。Unix 系统中 /usr/include/sys 就用了这么可怕的方式。
说到 #ifdef,有一个小插曲,虽然它能防止读取两次文件,但实际上经常用错。#ifdef 是定义在文件本身中,而不是文件包含它。结果是常常导致让成千上万不必要的代码通过词汇分析器,这是(优秀编译器中)耗费最大的阶段。
只需遵从以上简单规则。
C语言学习攻略
一、C语言学习中存在的问题
(一)基础薄弱,无法适应
C语言学习的课程通常安排在大一,这个时候,学生们刚刚进入高校这个新环境,经过高考后的长达3个月的“放羊”,学生们在学习方面的兴趣有所回落,而且新的学习习惯还未养成,因此,对于一门完全陌生的学科,肯定是无法好好适应的。虽然C语言是计算机编程类的最基础的入门课程,但是,对于学生而言,它属于一个全新的领域,学生们不知道该如何去学习,特别是在进行上机实验的时候,就显得更加不知所措。用C语言编程的时候,要求百分百的正确率,否则,就“差之毫厘,失之千里”,编写的程序无法正常运行,学生们容易产生挫败感,从而降低学习C语言的热情。
(二)课时少,学习压力大
由于C语言对于很多非计算机专业的学生来说,只是一门公共基础课,因此,安排的课时相对较少,这样导致教师在每节课的讲授内容就非常大,学生的学习压力非常大。特别是在刚开始学习C语言的时候,都是些理论知识和语法知识,面对枯燥的理论和大量需要记忆的繁琐的语法知识,学生很难在短期内消化吸收,需要一个过程,而现有的课时安排不够的情况下,使得学生每节课的学习压力增大,一旦前面的内容没有完全掌握,对于后面的学习就无法跟上,从而使得学生会对其产生厌烦心理。
(三)学习方法不当,学习效率低下
面对这样一个新的学科,要想学好,学习方法是十分重要的。而对于经历了长期的应试教育磨练的大学新生们来说,学习的知识都只是为了应付考试,而不知道真正的如何去学以致用。而学习C语言的`最终目的,就是为了编程,反过来说,能够证明学好了C语言的唯一方式就是能够编写出优秀的程序。初学者们在学习之初,带着过去传统的学习方法来进行C语言的学习,注重语法的记忆,可是,到了上机实践的时候,连最简单的模仿都不能做好,就更不用说自己自主设计编写程序了。
二、改进C 语言学习的措施
(一)选择好的学习工具
“工欲善其事,必先利其器。”初学者在学习之初,一定要选择最好的学习工具。学校配备的教材不一定是业界公认最优秀的,因此,学生们可以去请老师推荐,或是通过网络查找,配备一两本被业界认可的最好的入门书籍。另外,在实践方面,选择的编程工具也要是最合适的,现在被普遍广泛使用的是Visual C++ 6.0。
(二)使用好的学习方法
学习的过程都是一个循序渐进的,因此,我们要针对不同的学习阶段使用不同的学习方法。
具体而言,在初期阶段,即刚开始接触C语言的阶段,我们一定要了解它,正所谓“知己知彼,百战不殆”。首先,我们需要对C语言的来龙去脉有非常细致的了解,我们得知道它是怎么产生,经历了怎样的发展阶段,它的主要贡献是什么,它对科学的发展有什么帮助,我们学习它会有哪些好处,学习它的难点在哪,怎样学习才更加高效。在有了这些全方位的了解之后,我们就要让自己喜欢上C语言,要让自己从内心深处渴望学习C语言,那么如何才能做到呢?这就需要培养对C语言的兴趣。“兴趣是最好的老师”,一旦让自己对C语言产生了浓厚的兴趣,在正式学习阶段,我们就有了更强的动力。从心理学角度来看,人们通常对一些很有意思或很有作用的东西产生兴趣,因此,我们就需要去发掘C语言的有意思的地方和有作用的地方。C语言本身虽然看似枯燥,但它有着神奇的魔力,我们使用C语言的时候,虽然是一系列复杂的代码,但确能给我们变出我们想要的程序,通过这些程序,能够给我们带来巨大的便利。其实,教师在教学过程中,也会在这一方面下很大功夫,例如,教师会在教学过程中,现场演示一些比较简单而且很有趣味的小程序,使学生产生羡慕之情,使学生萌发出自己也要试一试的想法,从而“引诱”学生主动积极学习。对于学生来讲,在课堂上,一定要和老师形成良好的互动,要明确老师的教学方法和教学策略,并很好的与之配合。
在中期阶段,即正式学习阶段,这一阶段,最好的学习方法就是模仿――依葫芦画瓢,这也是教师在课堂教学中最常用到的。教师通过挑选一些最经典的例题,然后对其全方位解读,包括问题的产生、问题的分析、方案的设计、方案的实施以及最后问题的解决。通过这种全方位的示范之后,教师再给出相似的例题,让学生自己进行解决。这种教学方法也是非常好的一种自学方法,学生自己可以进行反复的模拟练习,从而掌握对某一类型的问题的解决方法。学生通过这种自己模仿的方法,不断提高自己的能力,而且让自己在解决问题的过程中,增强了自信,从而提升自己的学习兴趣。当然,单纯的模仿肯定是不够的,特别是在上机实验的时候,容易出现一些无法通过模范解决的问题,这个时候就需要耐心细致的进行比对,要善于发现问题所在,不能因为遇到困难就退缩,要积极进取,主动寻找解决问题的方法。
后期阶段,即学习展示阶段,通过对C语言的学习之后,老师也要检验自己的教学成果,学生要检验自己的学习成果。对于这种实践操作型的学科,是非常容易检验成果的。当然,检验的目的不仅仅是看学的效果,更加重要的在于发现学生的不足之处,从而进行改进。检验的方式也有很多,但是“任务驱动法”是最值得提倡的,通过用任务帮助学生们运用所学的知识去解决实际问题,实现从理论到实际应用的跨越。
(三)培养学生自学能力,打造良好学习环境
大学所需要培养的最重要的能力之一就是自学能力,在如今的信息爆炸时代,知识的更新速度是非常惊人的,因此,我们需要掌握自学的能力,从而帮助自己随时进行知识的更新。前文提到过,现在的大学课堂里,C语言的学习课时有限,因此,学生们需要在课外花功夫,而且C语言属于一个实践工具,要想灵活运用其编写实用程序,必须经过大量的课外编程实践。为了培养良好的自学习惯,可以建立学习兴趣小组,小组成员之间互相帮助,互相监督。在小组中,可以自己开展一些编程项目,大家一起分析问题,解决问题,这样更加能够培养学生的学习兴趣。
三、小结
C语言是计算机学习的一门重要的基础课程,也是各专业解决问题的重要工具,因此,学生们都需要很好地将其掌握,希望学生在今后的学习中,选择好的学习工具,改善学习方法,加大自主学习力度,真正培养对C语言的学习兴趣。