已阅读5页,还剩14页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
白熊的C语言笔记0.0.1 前言要参加ACM比赛,从知识的要求上,至少的条件有三点:1. 一门程序设计语言,例如C2. 数据结构方面的知识3. 算法设计方面的知识但是很明显的,如果按照学校一直以来的教学进度的话,学完这三门课需要一年半的时间,对于一个真正想学点什么的人来说,太长了。为了能尽快的让同学们进入ACM这个技术竞赛,我们决定开办这个C语言的培训,但是因为对于你们学习进度以及对于老师授课的接受程度并不是很了解的原因,这次的培训,从整体上来说反应不是很好,主要的原因是因为我觉得你们已经上过课的话那这次就当做是复习,所以速度上有点太快,在此向所有同学致一声抱歉。经过研究后,我决定还是从实际出发,在实际的编程中增进对程序的理解,而对于C语言的知识,可能与我们手上的那本C语言设计(第二版)有着不同的顺序。换句话说,我们的课程进度将与学校的无关。当然,在实行的过程中有什么意见的话,欢迎随时向我反馈,或者告诉你们班的联系人让他转告,感谢。另外,培训的方式将改成一整天的以本文所讲的知识点为主的实战编程练习和讲解,希望大家能提前预习好本文的内容。白熊2009年10月19日1:21:080.0.2 推荐书目本来今晚是想写一下以C语言设计(第二版)为基础的教材的,但是越看越发现里面一些不合理以及非常规的地方,因此收回对这本书“中规中矩”的评价,但依然缺乏属于老谭的思想。在此,我推荐几本书,大家可以去找来看看。C by Dissection The Essentials of C Programming Fourth Edition(C语言解析教程(原书第四版)评价:一本相当不错的C语言入门书籍,我写的这个教程就是以这本书作为基础,针对我们需要用到的知识点做出来的,有兴趣的同学可以找原书来看。The C Programming Language评价:C语言学习的圣经,世界上公认的第一,但是内容相对比较深奥,建议有一定基础的同学自习。1 编写ANSI C程序1.1.1 准备编写第一个ANSI C程序编程的目的是用于指示计算机完成特定的任务或解决特定的问题。在这其中,步进式地完成所需任务的过程被称为算法(algorithm)。而编程是沟通算法与计算机的活动。我们用计算机语言给计算机下达指令,让它完成。就像我们叫某某人帮忙做某某事一样。但计算机无法容忍多义性,因此必须要用精确的语言不厌其烦地详述所有步骤。【多义性:一个语句可以被理解为多种意义。】【本文的注释和补充说明将采用【】符号括起来】编程过程可以分为四步:1. 描述任务2. 找出解决问题的算法3. 用C对算法进行编码4. 测试代码源代码(source code)是编写出来的C语言代码,而包含源代码的文件称为源文件(source file)。当程序员编写一个程序之后,他必须编译和测试他的程序。如果需要修改,就必须再次编辑源代码。这样,编程的过程由下述循环构成:当程序员对程序的性能感到满意之后,就结束这个循环。1.2. 第一个程序Hello World/*第一个C语言程序Hello World!*/#include int main (void)printf(Hello World!n);return 0;运行成功的话会出现Hello World!/*第一个C语言程序Hello World!*/这是一行注释,编译器会自动忽略/*和*/所括起来的字符,这是为方便阅读而存在的文档,一般来说源文件开头的注释会注明该文件中代码的作用、作者和日期等信息。#include 用#开始的行称为预处理指令,该指令用于与预处理器通信。#include指令使预处理器在代码当前位置加入标准头文件stdio的拷贝。【此项工作在编译开始之前】这个头文件是C系统提供的。尖括号指明该文件能在“通常的位置”找到。我们引入这个文件是因为其中包含了关于printf()函数的信息。【“通常的位置”根据编译环境而有所不同,在VC中,“通常的位置”指的是VC安装目录下的VC98Include文件夹】【stdio是Standard Input Output的缩写,即“标准的输入输出”】int main (void)每个程序都有一个命名为main的函数,程序从这里开始运行。main前面的int表明这个函数将返回一个int类型的值。main后面的圆括号()告诉编译器这是一个函数。圆括号中的void表明该函数没有参数。函数体【函数的主体部分】以左花括号开始,以相应的右花括号结束。我们的风格是每个括号单占一行,并靠左放置。【花括号也用于把语句组织在一起。】printf(Hello World!n);printf()是头文件stdio.h中包含的一个函数,作用是向屏幕输出。Hello World!n是一个字符串,在此作为printf函数的参数。也就是以单参数形式对printf进行调用。它控制了显示的内容。【printf()函数有多参数调用方式。】字符串尾部的n代表一个被称为“换行”的单字符,这是一个非打印字符,作用是把光标移动到下一行的开头。【注意本行以一个分号(;)结尾,C语言中所有的语句和声明都以分号结尾】return 0;main()函数向系统返回整数值0。0表示函数正常结束,而非零值表示函数没有成功。该右花括号与上面的左花括号相匹配,它代表函数main()的结束。Hello World的变形/*Hello World的第一种变形*/#include int main (void)printf(Hello );printf(World!n);return 0;这个程序的结果跟刚刚的Hello World是完全相同的,这证明了printf()函数的输出是在屏幕上连续的显示。只有读到换行字符n的时候,才会移动到一个新行。【当然,遇到窗口的边缘的时候也会自动换行,但是我们必须把它认为是在同一行。】【注意,第一个printf()函数中字符串的结尾有一个空格,如果没有这个空格的话,Hello跟World将会黏在一起。】接下来,我们尝试在Hello World中加上一行Hello Nilajor!/*Hello World的第二种变形*/#include int main (void)printf(Hello World!n);printf(Hello Nilajor!n);return 0;执行程序后我们可以看到结果:Hello World!Hello Nilajor!这就是用printf()语句逐行输出的效果。【可以将两个printf()语句用一个printf()语句代替】【printf(Hello World!nHello Nilajor!)】在标准库中,像printf()这样有用的函数的可用性是C的一个重要特征。虽然从技术角度上讲,标准库并不是C语言的一部分,但它是C系统的一部分,因为在标准库中的函数在C系统中随处可见,编写程序的时候经常要使用到它们。1.3 变量、表达式和赋值Hesperus1839年,在美国马萨诸塞州的诺曼的悲哀暗礁(Normans Woe),Hesperus船(金星号)发生了一起失事事件。暗礁在约7英寻的水下。编写程序把这个深度转为其他的测量单位。【1英寻(fathoms)=6英尺(feet),1英尺=12英寸(inches)】对于这个题目,我们可以想出如下的算法:1. 把英寻数赋给一个变量。2. 把英寻转换成英尺,并赋给另一个变量。3. 把英尺转换成英寸,并赋给第三个变量。4. 把不同测量单位的结果在屏幕上整齐的输出。【编写C代码的时候,我们必须选择一个适当的变量集。从本题看,很明显应该选择整型变量。因为我们必须保证转换表达式使用了正确的常量,并且输出也要便于阅读。】/*常量、赋值和表达式Hesperus问题*/#include int main (void)int inches, feet, fathoms;fathoms = 7;feet = 6 * fathoms;inches = 12 * feet;printf(Wreck of Hesperus:n);printf(Its desph at sea in different units:n);printf( %d fathomsn, fathoms);printf( %d feetn, feet);printf( %d inchesn, inches);return 0;执行程序后我们可以看到结果:Wreck of Hesperus:Its desph at sea in different units: 7 fathoms 42 feet 504 inchesint inches, feet, fathoms;第一行是一个声明。变量inches、feet和fathoms被声明为类型int,int是C的基本类型之一。类型为int的变量接纳整数值。在C程序中,所有变量在使用前都应该声明。【声明和语句都用分号结尾】fathoms = 7;这是一个赋值语句。等号(=)是C的一个基本运算符。等号右边的表达式的值被赋值给它左边的变量,此处右边的常量表达式是7,该值被赋给变量fathoms。feet = 6 * fathoms;inches = 12 * feet;这两个语句是赋值语句。因为1英寻等于6英尺,并要把给定的英寻数转换成等价的英尺数,所以我们必须要对其乘以6。星号(*)是乘法运算符。表达式6 * fathoms的值被赋给变量feet。因为变量fathoms的当前值是7,所以表达式6 * fathoms的值为42,该值被赋给变量feet。同理,为了转换成英寸,必须对feet乘以12。表达式l2 * feet的值被赋给变量inches。printf(Wreck of Hesperus:n);printf(Its desph at sea in different units:n);printf( %d fathomsn, fathoms);printf( %d feetn, feet);printf( %d inchesn, inches);这个printf()语句有两个参数,分别是%d fathomsn,和fathoms。【注意它们用逗号隔开。】函数printf()中的第一个参数总是一个称为控制串的串。在本例中,控制串含有转换说明%d。转换说明也称作格式。格式%d使得第二个参数中的表达式(本例为fathoms等)的值按十进制整数的格式显示。控制串中的一般字符,即不用于构成格式的字符,被简单地显示在屏幕上。【注意本例中的控制串用三个空格开始,这使得本行被缩进显示。只是为了美观。】变量在C中,所有的变量在被使用之前都必须声明。简单程序的一般形式为:预处理命令int main(void)声明语句在文件的顶部,可以有像#include这样的预处理命令行在main()体内,声明必须存在于语句前声明告诉编译器,什么类型的数据可以存在于那个变量中,这使得编译器能够留出适量的内存空间以用于保存数据。变量名变量名就是变量的名称,也称为标识符,由字母,数字和下划线组成,但不能用数字开头。标识符应该反映出他们在程序中的用途。提高程序的可读性。在声明变量后,我们就可以对其赋值或者在表达式中用到他们。关键字关键字是C语言中本身已经具有特定意义的一些字符,不能被用作变量名。例如:char、float、int等等【C系统中一些其他的名字,程序员也不应该将他们进行重定义,例如printf,一般不用作变量名,因为它是标准库中的一个函数名。】表达式通常表达式出现在赋值运算符的右边或作为函数的参数。表达式可以是以下形式:1. 单独的常量(例如Hesperus中的7)2. 单独的变量名3.运算符与变量和常量的有意义的组合运算符二元运算符作用在两个操作数上的运算符例如在表达式6 * fathoms中,运算符*作用于常量6和变量fathoms上,这两个数就被称为操作数。数学运算符+ 表示加法运算- 表示减法运算* 表示乘法运算/ 表示除法运算【除数不能为0】% 表示取模(求余)运算【操作数只能为正整数】简单的字符型关键字char代表字符,类型为char的常量和变量用于操纵字符。char型常量用单引号括起来/*char型数据的试验程序*/#include int main(void)char ch;ch = A;printf(%cn, ch);return 0;程序执行后输出:Achar ch;声明变量ch为char型ch = A;将char型常量A赋给chprintf(%cn, ch);利用格式%c,以字符的格式显示printf()函数的第二个参数ch简单的浮点型ANSI C中有三种浮点型,关键字分别为float、double和long double浮点型的常量和变量用于控制实数。/*float型数据试验程序x+y*/#include int main(void)float x, y;x = 1.0;y = 2.0;printf(The sum of x and y is %f.n, x+y);return 0;执行后输出的结果是:The sum of x and y is 3.000000.printf(The sum of x and y is %f.n, x+y);使用格式%f,按小数点后保留6位的浮点格式显示。【对于double型用格式%lf】【对于浮点型数据,不适用%运算符】赋值语句由等号、等号左边的变量、等号右边的表达式组成。常量、表达式不允许出现在等号左边。例如:a = b + c; (正确)b + c = a; (错误)2 = a;(错误)1.4 初始化在声明变量的同时给变量赋予一个初始值,称为初始化。例如在Hesperus程序中,我们可以将fathoms初始化:int inches, feet, fathoms = 7;但这样写是不被允许的:int inches, feet = 6 * fathoms, fathoms = 7;【变量不能在声明前使用。】1.5 #define和#include的用法在调用C编译器时,预处理器先工作:在进行编译之前,预处理器修改传递给编译器的源代码。例如,可能要引入文件,源代码中的指定字符串可能被转变成其他字符串。程序中向预处理器发命令的行被称为预处理指令,这样的命令用磅字符#始。常见的编程风格是把#写在页的左边。#include我们曾经使用过如下的预处理器指令: #include 使用这种模式可跨系统使用标准库。这样的代码是可复用的并且易于维护。#include 预处理器仅在标准的位置寻找文件,例如VC中我们提到过的文件夹,或者Unix平台的/usr/include文件夹。#include 文件名预处理器先在本文件夹(即与源文件同一个文件夹)中寻找文件,然后在其他系统相关位置寻找。#define例: #define LIMIT 100 #define PI 3.14159如果这些预处理指令出现在正在编译的文件的顶部,预处理器首先把出现的所有LIMIT变为100,PI变为314l59。字符串常量中的内容保持不变。这样预处理器把printf(PI = %fn, PI);变为printf(PI = %fn, 3.14159)。标识符PI在所出现的地方都被变为3.14l59它被称为符号常数。程序中符号常数的使用使程序更加易读。更重要的是,如果用#define功能把个常量用符号定义,那么就可以在整个程序中使用它,以后对它进行修改也是容易的(如有必要的话)。例如,如果我们写如下语句: #define LIMIT 100那么就可以在数干行的代码中用LIMIT表示常量100,这样以后改变代码也容易定义符号常量lIMI?为10 oo,我们所做的仅是把预处理指令改为: #define LIMIT 10000这样就自动地修改了所有的源代码。【#define可以出现在程序任何地方,但只影响其后的那些行。】【#define通常被放在文件的开始,#include的后面。】【按照惯例,#define定义的符号常数一般为大写。】1.6 printf()和scanf()的用法函数printf()用于显示格式化的输出。同样的,函数scanf()用于显示格式化的输入。这些函数存在于C标准库中,在C系统驻留的任何地方都可以调用它们。我们向printf()或者scanf()传递一个控制串和其他参数的参数列表。【控制串:一个包含一些转换说明的字符串,当然也可以纯粹由字符串或者转换说明构成】1.6.1 printf()的用法printf()函数用于输出一个字符串,在它的参数中,控制串中的格式说明了如何显示对应参数的值,因此在使用的过程中应该考虑用什么格式输出参数。【各个参数间用逗号隔开】例如:printf(Get set : %s %d %f %c%cn, one, 2, 3.33, G, O);第一个参数是控制串Get set : %s %d %f %c%cn,其中每个格式与对应位置的其他参数相匹配。第一个格式%s表示以字符串形式显示,对应除了控制串外的第一个参数one.第一个格式%d表示以整数形式显示,对应除了控制串外的第一个参数2.第一个格式%f表示以浮点形式显示,对应除了控制串外的第一个参数3.33.第一个格式%c表示以字符形式显示,对应除了控制串外的第一个参数G.第一个格式%c表示以字符形式显示,对应除了控制串外的第一个参数O.所以上面那个例子的输出应该是:Get set : one 2 3.33 GO【注:这个程序除了最后两个%c以外的其他格式中间都存在一个空格。】有时候,当printf()函数太长的话,我们可以把它写成几行,例如:printf(%s%sn,This Statement will print ,just a very long line on the screen.);【大家可以猜测或者实验一下这个语句的作用】对于格式中的转换字符,我们给出一个表方便大家记忆:printf()中的转换字符转换字符显示的方式c作为字符显示d作为十进制整数显示e作为科学计数法的浮点数f作为浮点数g作为e格式或者f格式中较短的一个s作为字符串域和域宽在显示一个参数时,所显示的参数位置被称为参数的域。域中字符的个数被称为域宽。格式中域宽能被表示为出现在和转换字符间的整数。因此,语句:printf(%c%3c%7cn, A, B, C);输出的结果是A B C【A跟B之间有2个空格,B跟C之间有6个空格】首先显示A,然后用3的宽度显示B,但是B本身只占一个位置,其他位置都是空格,所以B前面有两个空格,BC之间的空格同理。【如果待输出长度大于预定域宽则全部输出。】精度对于浮点值,我们不单能控制宽度,还能控制精度。精度即显示时小数点后数字的个数。在形式为%m.nf的格式中,m控制宽度而n控制精度,当然也可以单独用%.n的格式控制精度。从下面这段例句中可以看出一些精度的使用:printf(Some numbers: %.1f %.2f %.3f n, 1.0, 2.0, 3.0);【三个格式间有空格】printf(More numbers:%7.1f%7.2f%7.3fn, 4.0, 5.0, 6.0);【格式间无空格】输出:Some numbers: 1.0 2.00 3.000More numbers: 4.0 5.00 6.0001.6.2 scanf()的用法scanf()与printf()很相似,一个用于输入一个用于输出,但多了一个&符号,称为地址运算符。scanf(%d, &x);这个语句的作用是把键盘上输入的字符解释为十进制整数,并存到x所表示的内存空间中。我们先看一个表来了解scanf()中的转换方式scanf()的转换字符转换字符以什么形式解释c字符d十进制整数fFloat型浮点lfDouble型浮点LfLong double型浮点s字符串姓名与年龄/*scanf()应用示例*/#includeint main(void)char first, middle, last;int age;printf(Input your three initials and your age: );scanf(%c%c%c%d, &first, &middle, &last, &age);printf(nGreetings %c.%c.%c. %s %d.n, first, middle, last,Next year your age will be, age + 1);return 0;输出:Input your three initials and your age: 此时假设我们输入NAT 15则输出:Greetings N.A.T Next year your age will be 16.printf(Input your three initials and your age: );提示用户应该输入什么scanf(%c%c%c%d, &first, &middle, &last, &age);读入一个字符,送到first内存中读入第二个字符,送到middle的内存中读入第三个字符,送到last的内存中【scanf()的参数除了第一个控制串以外,都是内存的地址,所以我们用&取得变量所表示的内存地址,令输入的内容可以正确存储。】【scanf()读入数字的时候,会自动跳过其中包含的空格,但是在读入字符的时候,会把空格视为一个字符读入。】【因此,这段程序是不够健壮的,毕竟当用户输入姓名首字母的时候,程序应当接受夹杂的空白,这是根据一般习惯而定的。】圆的面积假设=3.141592653589793,编程完成以下任务:输入圆的半径,输出计算圆面积的过程。(的值要用#define预定义)#include#define PI 3.141592653589793int main(void)double radius;printf(n%snn%s,This program computes the area of a circle.,Input the radius: );scanf(%lf, &radius);printf(n%sn%s%.2f%s%.2f%s%.2fn%s%.5fnn,Area = PI * radius * radius, = , PI, * , radius, * , radius, = , PI * radius *radius);return 0;随提示输入2.333,程序输出:Area = PI * radius * radius = 3.14 * 2.33 * 2.33= 17.09934我们可以发现一个问题:3.14*2.33*2.33=17.046746,这跟最后得出的值不同。原因是因为PI跟radius的值虽然只保留2位小数输出,但在内存中还是精确的完整值。另外一点要注意的:我们在技制串中用了一个%lf 格式,即以double方式向scanf()读入,如果把变量从double改成float,我们必须把%lf改成%f。【printf()和scanf()函数是有返回值的。printf()返回显示的字符数。scanf()返回转换的字符数。都是以int类型返回的。】1.7 while语句题目:用while语句做从1到10的累加。/*110的累加,add_ten*/#includeint main(void)int i = 1, sum = 0;while(i = 10)sum = sum + i;i = i + 1;printf(Sum = %dn,sum);return 0;输出:Sum = 55int i = 1, sum = 0;声明变量i和sum为int型,并进行初始化,初值分别为1和0【变量i、j、k一般用作循环控制的变量名】while(i = 10)sum = sum + i;i = i + 1;这是一个完整的循环结构,首先计算括号中的表达式i = 10,若其值为真,则执行两个花括号中的语句,将i当前的值累加到sum上,再让i的值比原来增加1.完成一遍循环之后重新计算表达式i=10,若为真则循环重复执行这一过程,若为假则跳出循环,执行while语句的下一条语句。printf(Sum = %dn,sum);输出结果While语句的一般形式是:while(条件)语句其中条件可以是变量、常量或表达式,非0的结果视为真,而0视为假;花括号括起来的语句称为复合语句,在C语言中,复合语句可以出现在任何单语句出现的地方。1.8 问题求解:计算总和题目要求:编写一个重复累加用户从键盘上输入的数字的程序。根据题目的要求,我们可以得出一个算法,如下计算总和的算法1. 对变量cnt和sum初始化。2. 提示用户输入。3. 重复的读数据,对cnt加1.对sum进行累加4. 显示cnt和sum的值。【cnt表示count,计算累加的次数】/* Sums are computed.*/#include int main(void)int cnt = 0;float sum = 0.0, x;printf(The sum of your number will be computednn);printf(Input some numbers: );while (scanf(%f, &x) = 1)cnt = cnt + 1;sum = sum + x;printf(n%s%5dn%s%12fnn, Count:, cnt, Sum:, sum);return 0;这个程序运行后,输入若干个数,之间用回车确认,当输入为字符时,输出结果。scanf(%f, &x) = 1【符号=代表相等运算符。诸如a=b这样的表达式用于测试a的值是否等于b的值。如果是,则表达式为真;如果不是,则表达式为假。例如,l=l为真,2=3为假。】【scanf()函数用于读人用户输入的字符,把字符转换成类型为float的值,并存储到x中。若scanf()成功地做到这些,转换成功则该函数的返回值为1。若由于其他的原因,转换失败则返回值为0;若数据不再可用则返回值为1。】本句用于测试scanf()是否成功地完成了任务。如果是,那么表达式为真,否则为假。while (scanf(%f, &x) = 1)cnt = cnt + 1;sum = sum + x;我们可以把这个语句看做while(输入成功)。只要表达式scanf(%f, &x) = 1为真,while循环体就重复地执行。每次执行循环的过程:1. scanf()读入字符,把字符转换成数字,并把数字值存储到x中。2. 把cnt的值加1赋给变量cnt,把sum的值加上x赋给变量sum。【cnt保存到当前为止键入的数字个数,sum保存数字的总和。】什么时候这个过程结束?这要等到如下的两件事情之一发生。1. 用户键入了不能被转换成float类型的事物。例如,键入了一个不是数字的字符
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 沧州专业做课件
- 初中知识梳理课件
- 涉案陆生兽类形态鉴定
- 成长真好课件
- 口播教育行业分析报告
- 初中道德与法治七年级下册“做自尊的人”教学设计
- 高三地理教学设计:高考考前最后一课复习策略与思维升华
- 高中语文高三修辞手法复习教学设计
- 小学五年级科学下册当环境改变了教学设计
- 小学一年级道德与法治《课余生活真丰富-用好课间十分钟+我喜欢的课间游戏》教学设计
- 2026-2030中国PTC加热器行业市场发展趋势与前景展望战略分析研究报告
- 木龙骨隔墙施工工艺及施工方法
- 中医适宜技术在妇科疾病中的应用指南课件
- 2026工业自动化行业市场发展分析及前景趋势与投融资发展机会研究报告
- 国聘网笔试校招题库
- 实验室安全培训案例课件
- 2025-2026学年北京市文汇中学教育集团九年级(上)期中语文试卷
- 上海市郊野乡村风貌规划设计和建设导则二
- 产品开发TR5评审要素表
- 航天科工集团在线测评题
- GB/T 44211-2024消费品质量分级导则家具
评论
0/150
提交评论