C语言复习提纲
第一章 C语言程序设计概述
一、Visual C++6.0开发环境
1、了解Visual C++6.0的安装过程;
2、了解Visual C++6.0的工作界面,菜单和工具栏的使用;
▲二、掌握C语言程序运行的过程
1、编辑:是指把按照C语法规则编写的程序代码通过编辑器(Visual C++ 6.0,Turbo C 3.0)输入计算机,并存盘。在存盘时,C源文件的扩展名为 .c
2、编译:将C语言源程序编译成目标程序,即对源程序进行编译,并将源程序转换为扩展名为.obj的二进制目标代码(即把已经编辑好的源程序翻译成二进制目标代码的过程)。
3、连接:将用户程序生成的目标代码文件(.obj)和系统提供的库文件(.lib)中的某些代码连接在一起,生成一个可执行文件(.exe)。
4、执行:执行生成的可执行代码,并输出结果。
5、调试:是将编制的程序投入实际运行前,用手工或编译程序等方法进行测试,修正语法错误和逻辑错误的过程。
▲三、结构化程序设计的基本概念
1、概念
以模块化设计为中心,将待开发的软件系统划分为若干个相互独立的模块,将原来较为复杂的问题化简为一系列简单模块的设计,任何模块都可以使用一些基本的结构来实现,任何复杂的程序,都可以使用这些基本结构按一定的顺序组合起来,这些基本结构的特点都是只有一个入口、一个出口,这样的程序设计方法称为结构化程序设计。
2、基本思想
结构化程序设计的基本思想是采用"自顶向下,逐步细化、模块化设计、结构化编码"的程序设计方法和"单入口单出口"的控制结构。
3、三种基本结构
⑴顺序结构 ⑵选择结构 ⑶循环结构
4、三种基本结构的特点
⑴只有一个入口 ⑵只有一个出口
⑶每一个基本结构中的每一部分都有机会执行到
⑷结构内不存在“死循环”
5、设计原则
⑴自顶向下 ⑶逐步细化 ⑶模块化设计
⑷结构化编码
▲四、C程序的基本组成:
C程序是由若干个函数构成的,至少有一个主函数main(),main()的位置可以任意,其他各函数在程序中的前后位置也是可以任意的。程序的执行总是从主函数开始,在主函数中结束。主函数是可以调用其他任何非主函数的函数,任何非主函数也可以调用其它任何非主函数。
C程序的基本组成:声明区、主程序区、函数定义区。
1、声明区
处在程序文件的所有函数的外部,一般包含:包含头文件、宏定义、类定义、结构体定义、函数声明、全局变量声明、条件编译等。
2、主程序区
主程序以main()函数开始,main()函数(主函数)是程序运行时的入口,包含局部变量的声明、函数调用、一般运算、结构控制、对象与结构的处理、文件处理等。
3、函数定义区
函数的定义包含函数说明和函数体两部分。
4、注释
//或/* */为注释,不能嵌套
不产生编译代码,不影响程序的执行效率。
▲五、标识符
1、标识符的定义:用来对变量、符号常量名、函数、数组、类型等命名的有效字符序列统称为标识符。
2、标识符的命名规则:由字母、数字或下画线组成,并且第1个字符必须为字母或下画线。
注意:标识符区分大小写,即大写字母和小写字母的通常意义不同,且不能与关键字重名。
练习1_1:下列变量标识符哪些是正确的,哪些是不正确的?
a3bc if a!bc _abc abc _3abc a_bc 3abc
3、标识符分类:关键字、预定义标识符、用户自定义标识符。
第二章 数据类型、运算符和表达式
▲一、C语言的数据类型

C语言中基本数据类型包括整型、实型、字符型、枚举类型,构造类型有数组、结构体、共用体等。
⑴、基本数据类型(见P17)
⑵、构造类型又称为组合类型,它是由基本类型按照某种规则组合而成的。
n 数组:是由具有相同数据类型的元素组成的集合。
n 结构体:是由不同的数据类型构成的一种混合的数据结构,构成结构体的成员的数据类型一般不同,并且在内存中分别占据不同的存储单元。
n 共用体:是类似于结构体的一种构造类型,与结构体不同的是构成共同体的数据成员共用同一段内存单元。
n 枚举:是将变量的值一一列举出来,变量的值只限于列举出来的值的范围内。
⑶、指针类型变量用于存储另一变量的地址,而不能用来存放基本类型的数据。它在内存中占据一个存储单元。
⑷、类是一种数据类型,它定义的是一种对象类型,由数据和方法组成,描述了属于该类型的所有对象的性质。
二、常量和变量
⑴、常量:在程序运行的整个过程中,其值始终保持不变的量。
n 整型常量:表示形式有十进制、八进制(以0开头)和十六进制(以0x或0X开头)。整型常量可以后缀字母L(或l)表示长整数,后缀字母U(或u)表示无符号整数。
n 实型常量(浮点型常量):表示形式有一般形式和指数形式。实型常量缺省为double型(双精度型),如后缀f或F,则为float型(单精度型)。
n 字符常量:用单撇号括起来的一个字符。如'A','*'等。
转义字符:用反斜杠引导的,具有特定含义的字符(见P22表2-4),如 '\n','\367','\x8a'。
注:C语言字符集中的任何一个字符均可用转义字符来表示。
n 字符串常量:用双撇号括起来的字符序列。如"student","广东广州"等。
n 布尔常量:false,true。
n 符号常量:
² #define 宏名 常数
⑵变量:指程序在运行时其值可改变的量。
n 变量应先定义(声明其类型和名称)后使用;
n 变量定义的一般形式为:
u < 数据类型 > <变名1>,<变名2>,…,<变名n>;
n 在定义一个变量的同时,也可以给它赋以初值。
▲三、运算符和表达式
1、算术运算符和算术表达式
注意:int i=1.2*3; //结果为3,而不是3.6。 int i=5/3结果为1。
表达式17/5的结果是3,表达式17%5的结果是2。
2、赋值运算符和赋值表达式
注意:
n 赋值运算符的结合性是从右至左的
n 复合赋值运算符:int a=12; a+=a-=a*=a;(a=a+(a=a-(a=a*a)),结果为0)
注意:
在C语言中,定义int a=b=c=3;是错误的,而定义int a,b,c; a=b=c=3;是正确的。
练习2_3设m=9,i=3,则执行运算m%=i+1后,m的值是多少?结果1。
m=m%(i+1)→m=9%(3+1)→m=1。
3、关系运算符和关系表达式
注意:
n 关系运算符的优先级低于算术运算符。例如:a+b>c 等价于 (a+b)>c,a!=b>c 等价于 a!=(b>c)
n “=”与“==”的区别
4、逻辑运算符与逻辑表达式
注意:
n 逻辑非的优先级最高,逻辑与次之,逻辑或最低
6、条件运算符
表达式1?表达式2:表达式3
注意:
n 结合性是自右向左。a>b?a:c>d?c:d相当于a>b?a:(c>d?c:d)
n 条件运算符的优先级别高于赋值运算符,低于关系运算符和算术运算符。如:
a>b?a-b:b-a相当于a>b?(a-b):(b-a)
7、位运算符
位运算符是对其操作数按其二进制形式逐位进行运算,参加位运算的操作数必须为整数。
注:在位运算中,操作数左移三位,其结果相当于操作数乘以8。
8、逗号运算符
表达式1, 表达式2, ……, 表达式n
注意:
自左至右,依次计算各表达式的值,“表达式n” 的值即为整个逗号表达式的值。如:a = 3 * 5, a * 4, a + 5的值为20。
▲四、运算符的优先级与结合性
1、所谓结合性是指,当一个操作数两侧的运算符具有相同的优先级时,该操作数是先与左边的运算符结合,还是先与右边的运算符结合。
自左至右的结合方向,称为左结合性。反之,称为右结合性。
结合性是C语言的独有概念。除单目运算符、赋值运算符和条件运算符是右结合性外,其它运算符都是左结合性。
2、表达式求值
n 按运算符的优先级高低次序执行。例如,先乘除后加减。
n 如果在一个运算对象(或称操作数)两侧的运算符的优先级相同,则按C语言规定的结合方向(结合性)进行。
例如,算术运算符的结合方向是“自左至右”,即:在执行“a – b + c”时,变量b先与减号结合,执行“a - b”;然后再执行加c的运算。
第三章 顺序结构程序设计
▲一、顺序结构程序设计——数据的输入和输出
1、格式化输出——printf()函数
n printf()函数的一般格式如下:printf("格式字符串" [,输出项表]);
² 输出项表:要输出的数据项(可以没有,有多个时以“,”分隔)
² 格式控制串:包含两种信息
格式说明: %[修饰符]格式字符 ,用于指定输出格式
如:格式控制字符“%c”表示的含义是输出一个字符型数据。
普通字符或转义序列:原样输出。
n 格式控制字符:

n 修饰符:

如:在C程序的格式输出中,%d表示输出十进制整数,%6.2f表示输出长度为6位,有2位小数的实数。printf("s=%-5.3s","student");的输出结果是s=stu 。
2、格式化输入——scanf()函数
scanf()函数的一般格式
scanf("格式字符串", 输入项首地址表);
注:
①格式输入函数scanf()可以从键盘上接收不同数据类型的数据。
②格式化输出函数(printf())和格式化输入函数(scanf())都包含在头文件“stdio.h”中。
n 格式字符串。格式字符串可以包含3种类型的字符:格式指示符、空白字符(空格、Tab键和回车键)和非空白字符(又称普通字符)。
格式指示符与printf()函数的相似,空白字符作为相邻2个输入数据的缺省分隔符,非空白字符在输入有效数据时,必须原样一起输入。
n 输入项首地址表──由若干个输入项首地址组成,相邻2个输入项首地址之间,用逗号分开。
输入项首地址表中的地址,可以是变量的首地址,也可以是字符数组名或指针变量。
变量首地址的表示方法: &变量名
其中“&”是地址运算符。
n 数据输入操作
² 如果相邻2个格式指示符之间,不指定数据分隔符(如逗号、冒号等),则相应的2个输入数据之间,至少用一个空格分开,或者用Tab键分开,或者输入1个数据后,按回车,然后再输入下1个数据。
例如,scanf("%d%d",&num1,&num2);
假设给num1输入12,给num2输入36,则正确的输入操作为:12□36↙
或者:12↙
36↙
注:使用“↙”符号表示按回车键操作,在输入数据操作中的作用是,通知系统输入操作结束。
² “格式字符串”中出现的普通字符(包括转义字符形式的字符),务必原样输入。
例如,scanf("%d,%d",&num1,&num2);
假设给num1输入12,给num2输入36,正确的输入操作为:12,36↙
第四章 选择结构程序设计
▲一、算法
1、算法的概念:算法是指为解决一个问题而采取的确定的、有限的方法和步骤。
2、算法的描述方法最常用的有自然语言、流程图、N-S流程图、PAD图和伪代码等。
▲二、顺序结构程序设计
顺序结构是结构化程序设计中最简单、最常见的一种程序结构。顺序结构中的语句是按照书写的先后次序执行的,并且每个语句都会被执行到。
▲三、选择结构程序设计
1、if语句
⑴、if语句的一般格式
if(表达式)
{语句组1;}
[else
{语句组2;} ]
n if语句中的“表达式”必须用“(”和“)”括起来。表示程序执行的条件,常用关系运算符、逻辑运算符等表示的条件表达式,其结果只有两个值“1”或“0”(成立或不成立)。
如:表示字符型变量ch是大写英文字符的C语言表达式是ch>='A'&&ch<='Z',要判断字符变量ch中的值是否为数字字符,则其表达式是ch>='0'&&ch<='9'。
n else子句(可选)是if语句的一部分,必须与if配对使用,不能单独使用。
n 当if和else下面的语句组,仅由一条语句构成时,也可不使用复合语句形式(即去掉花括号)。
⑵、if语句的执行过程
n 缺省else子句时
n 当“表达式”的值不等于0(即判定为“逻辑真”)时,则执行语句组1,否则直接转向执行下一条。
n 指定else子句时
n 当“表达式”的值不等于0(即判定为“逻辑真”)时,则执行语句组1,然后转向下一条语句;否则,执行语句组2。
⑶、if语句的嵌套与嵌套匹配原则
n if语句允许嵌套。所谓if语句的嵌套是指,在“语句组1”或(和)“语句组2”中,又包含有if语句的情况。
n if语句嵌套时,为避免嵌套的if-else语句的二义性,C语言规定:else总是与在其之前最近的未配对的if语句组成配对关系。
2.switch语句
⑴、switch语句的一般形式
switch(表达式)
{ case 常量表达式1:语句组;break;
case 常量表达式2:语句组;break;
......
case 常量表达式n:语句组;break;
[default:语句组;[break; ]]
}
⑵、执行过程
n 当switch后面“表达式”的值,与某个case后面的“常量表达式”的值相同时,就执行该case后面的语句(组);当执行到break语句时,跳出switch语句,转向执行switch语句的下一条。
n 如果没有任何一个case后面的“常量表达式”的值,与“表达式”的值匹配,则执行default 后面的语句(组)。然后,再执行switch语句的下一条。
⑶说明
n switch后面的“表达式”,可以是int、char和枚举型中的一种。
n 每个case子句后面的“常量表达式”的值,必须各不相同,否则会出现相互矛盾的现象(即对表达式的同一值,有两种或两种以上的执行方案)。
n case后面的常量表达式仅起语句标号作用,并不进行条件判断。系统一旦找到入口标号,就从此标号开始执行,不再进行标号判断,所以要退出switch语句,方法是使用break语句。
n 各case及default子句的先后次序,不影响程序执行结果。
n 多个case子句,可共用同一语句(组)
n 用switch语句实现的多分支结构程序,完全可以用if语句或if语句的嵌套来实现。
第五章 循环结构程序设计
▲一、循环程序设计
1、while语句
⑴、一般格式
while(循环继续条件)
{ 循环体语句组;}
⑵、执行过程
①求解“循环继续条件”表达式。如果其值为非0,转②;否则转③。
②执行循环体语句组,然后转①。
③执行while语句的下一条。
2、do-while语句(直到型循环)
⑴、一般格式
do
{ 循环体语句组; }
while(循环继续条件);/*本行的分号不能缺省*/
当循环体语句组仅由一条语句构成时,可以不使用复合语句形式。
⑵、执行过程
①执行循环体语句组。
②计算“循环继续条件”表达式。如果“循环继续条件”表达式的值为非 0(真),则转向①继续执行;否则,转向③。
③执行do-while的下一条语句。
⑶、do-while循环语句的特点是:先执行循环体语句组,然后再判断循环条件。
因此do......while语句不论条件是否成立,至少要执行一次循环体。
3、for语句
⑴、for语句的一般格式
for([变量赋初值];[循环继续条件];[循环变量增值])
{ 循环体语句组;}
⑵、for语句的执行过程
①求解“变量赋初值”表达式。
②求解“循环继续条件”表达式。如果其值非0,执行③;否则,转至④。
③执行循环体语句组,并求解“循环变量增值”表达式,然后转向②。
④执行for语句的下一条语句。
⑶、说明
①“变量赋初值”、“循环继续条件”和“循环变量增值”部分均可缺省,甚至全部缺省,但其间的分号不能省略。
②当循环体语句组仅由一条语句构成时,可以不使用复合语句形式。
③“循环变量赋初值”表达式,既可以是给循环变量赋初值的赋值表达式,也可以是与此无关的其它表达式(如逗号表达式)。
例如,for(sum=0;i<=100;i++) sum += i;
for(sum=0,i=1;i<=100;i++) sum += i;
④“循环继续条件”部分是一个逻辑量,除一般的关系(或逻辑)表达式外,也允许是数值(或字符)表达式。
如:while(!E)等价于while(0),while(E)等价于while(1)。
for语句最为灵活,不仅可用于循环次数已经确定的情况,也可用于循环次数虽不确定、但给出了循环继续条件的情况。
4、循环的比较
⑴、While和 for都是先判断后循环,而do-while是先循后判断。即do-while语句在条件不成立时循环体也要被执行一次。
⑵、while和do-while语句的条件表达式只有一个,只起到控制循环结束的作用,循环变量的初值等都用其他语句完成;for语句则有3个表达式,不仅能起到控制循环结束的作用,还可给循环变量赋初值。
5、循环的嵌套
⑴、循环语句的循环体内,又包含另一个完整的循环结构,称为循环的嵌套。循环嵌套的概念,对所有高级语言都是一样的。
⑵、for语句和while语句允许嵌套,do-while语句也不例外。
6、break语句与continue语句
⑴、一般格式: break;
continue;
⑵、功能
①break:强行结束循环,转向执行循环语句的下一条语句。
②continue:对于for循环,跳过循环体其余语句,转向循环变量增量表达式的计算;对于while和do-while循环,跳过循环体其余语句,但转向循环继续条件的判定。
⑶、说明
①break能用于循环语句和switch语句中,而continue只能用于循环语句中。
②break是终止整个循环的执行,而continue只是结束本次循环。
③循环嵌套时,break和continue只影响包含它们的最内层循环,与外层循环无关。
第六章 数组
数组是数目固定、类型相同的若干变量的有序集合。
▲一、一维数组
1、一维数组的定义:数据类型 数组名[常量表达式][, 数组名2[常量表达式2]……];
n “数据类型”是指数组元素的数据类型。
n 数组名,与变量名一样,必须遵循标识符命名规则。
n “常量表达式”必须用方括号括起来,指的是数组的元素个数(又称数组长度),它是一个整型值,其中可以包含常数和符号常量,但不能包含变量。
n 数组元素的下标,是元素相对于数组起始地址的偏移量,所以从0开始顺序编号。
n 数组名中存放的是一个地址常量,它代表整个数组的首地址。同一数组中的所有元素,按其下标的顺序占用一段连续的存储单元。
注:数组名能与其他变量名相同,数组名后是用方括号括起来的常量表达式,不能和圆括号。
2、数组元素的引用
引用数组中的任意一个元素的形式: 数组名[下标表达式]
n “下标表达式”可以是任何非负整型数据,取值范围是0~(元素个数-1)。
n 1个数组元素,实质上就是1个变量,它具有和相同类型单个变量一样的属性,可以对它进行赋值和参与各种运算。
n 在C语言中,数组作为1个整体,不能参加数据运算,只能对单个的元素进行处理。
⑶、一维数组元素的初始化
n 初始化格式:数据类型 数组名[常量表达式]={初值表}
n 如果对数组的全部元素赋以初值,定义时可以不指定数组长度(系统根据初值个数自动确定)。如果被定义数组的长度,与初值个数不同,则数组长度不能省略。
n “初值表”中的初值个数,可以少于元素个数,即允许只给部分元素赋初值。
3、数组元素的存储
数组元素在计算机内存中存储时,占据一片连续的存储空间,数组名代表数组元素占据的内存空间的首地址。由于数组各元素的数据类型相同,因此在数组中,每一个元素在内存里占用的存储单元数都是相同的。
二、二维数组
1、二维数组的定义:
数据类型 数组名[行常量表达式][列常量表达式][, 数组名2[行常量表达式2][列常量表达式2]……];
n 数组元素在内存中的排列顺序为“按行存放”,即先顺序存放第一行的元素,再存放第二行,以此类推。
n 设有一个m*n的数组x,则第i行第j列的元素x[i][j]在数组中的位置为:i*n+j(注意:行号、列号均从0开始计数)。
2、二维数组元素的引用
引用2维数组元素的形式为:
数组名[行下标表达式][列下标表达式]
n “行下标表达式”和“列下标表达式”,都应是整型表达式或符号常量。
n “行下标表达式”和“列下标表达式”的值,都应在已定义数组大小的范围内。假设有数组x[3][4],则可用的行下标范围为0~2,列下标范围为0~3。
n 对基本数据类型的变量所能进行的操作,也都适合于相同数据类型的2维数组元素。
3、二维数组元素的初始化
n 按行赋初值
数据类型 数组名[行常量表达式][列常量表达式]={{第0行初值表},{第1行初值表},……,{最后1行初值表}};
赋值规则:将“第0行初值表”中的数据,依次赋给第0行中各元素;将“第1行初值表”中的数据,依次赋给第1行各元素;以此类推。
n 按2维数组在内存中的排列顺序给各元素赋初值
数据类型 数组名[行常量表达式][列常量表达式]={初值表};
赋值规则:按2维数组在内存中的排列顺序,将初值表中的数据,依次赋给各元素。
如果对全部元素都赋初值,可以省略“行数”,但不能省略“列数”。注意:只能省略“行数”。
三、字符数组
1、字符数组的定义
n 1维字符数组,用于存储和处理1个字符串,其定义格式与1维数值数组一样。
n 2维字符数组,用于同时存储和处理多个字符串,其定义格式与2维数值数组一样。
2、字符数组的初始化
字符数组的初始化,可以通过为每个数组元素指定初值字符来实现。
3、字符数组的引用
字符数组的逐个字符引用,与引用数值数组元素类似。
n 字符数组的输入
除了可以通过初始化使字符数组各元素得到初值外,也可以使用getchar()或scanf()函数输入字符。
n 字符数组的输出
字符数组的输出,可以用putchar()或printf()函数。
四、字符串及其结束标志
所谓字符串,是指若干有效字符的序列。C语言中的字符串,可以包括字母、数字、专用字符、转义字符等。
C语言规定:以‘\0’作为字符串结束标志(‘\0’代表ASCII码为0的字符,表示一个“空操作”,只起一个标志作用)。因此可以对字符数组采用另一种方式进行操作了──字符数组的整体操作。
注意:由于系统在存储字符串常量时,会在串尾自动加上1个结束标志,所以无需人为地再加1个。
另外,由于结束标志也要在字符数组中占用一个元素的存储空间,因此在说明字符数组长度时,至少为字符串所需长度加1。
1.字符数组的整体初始化
字符串设置了结束标志以后,对字符数组的初始化,就可以用字符串常量来初始化字符数组。
2.字符数组的整体引用
n 字符串的输入
除了可以通过初始化使字符数组各元素得到初值外,也可以使用scanf()函数输入字符串。
n 字符串的输出
printf()函数,不仅可以逐个输出字符数组元素,还可以整体输出存放在字符数组中的字符串。
五、常用的字符串处理函数
字符串标准函数的原型在头文件string.h中。
1、输入字符串──gets()函数
①调用方式:gets(字符数组)
②函数功能:从标准输入设备(stdin)──键盘上,读取1个字符串(可以包含空格),并将其存储到字符数组中去。
③使用说明
n gets()读取的字符串,其长度没有限制,编程者要保证字符数组有足够大的空间,存放输入的字符串。
n 该函数输入的字符串中允许包含空格,而scanf()函数不允许。
2.输出字符串──puts()函数
①调用方式:puts(字符数组)
②函数功能:把字符数组中所存放的字符串,输出到标准输出设备中去,并用‘\n’取代字符串的结束标志‘\0’。所以用puts()函数输出字符串时,不要求另加换行符。
③使用说明
n 字符串中允许包含转义字符,输出时产生一个控制操作。
n 该函数一次只能输出一个字符串,而printf()函数也能用来输出字符串,且一次能输出多个。
3、字符串比较──strcmp()函数
①调用方式:strcmp(字符串1 ,字符串2)
其中“字符串”可以是串常量,也可以是1维字符数组。
②函数功能:比较两个字符串的大小。
如果:字符串1=字符串2,函数返回值等于0;
字符串1<字符串2,函数返回值负整数;
字符串1>字符串2,函数返回值正整数。
③使用说明
n 如果一个字符串是另一个字符串从头开始的子串,则母串为大。
n 不能使用关系运算符“==”来比较两个字符串,只能用strcmp() 函数来处理。
4、拷贝字符串──strcpy()函数
①调用方式:strcpy(字符数组, 字符串)
其中“字符串”可以是串常量,也可以是字符数组。
②函数功能:将“字符串”完整地复制到“字符数组”中,字符数组中原有内容被覆盖。
③使用说明
n 字符数组必须定义得足够大,以便容纳复制过来的字符串。复制时,连同结束标志'\0'一起复制。
n 不能用赋值运算符“=”将一个字符串直接赋值给一个字符数组,只能用strcpy()函数来处理。
5.连接字符串──strcat()函数
①调用方式:strcat(字符数组, 字符串)
②函数功能:把“字符串”连接到“字符数组”中的字符串尾端,并存储于“字符数组”中。“字符数组”中原来的结束标志,被“字符串”的第一个字符覆盖,而“字符串”在操作中未被修改。
③使用说明
n 由于没有边界检查,编程者要注意保证“字符数组”定义得足够大,以便容纳连接后的目标字符串;否则,会因长度不够而产生问题。
n 连接前两个字符串都有结束标志'\0',连接后“字符数组”中存储的字符串的结束标志'\0'被舍弃,只在目标串的最后保留一个'\0'。
6.求字符串长度──strlen()函数(len是length的缩写)
①调用方式:strlen(字符串)
②函数功能:求字符串(常量或字符数组)的实际长度(不包含结束标志)。
7.将字符串中大写字母转换成小写──strlwr()函数
①调用方式:strlwr(字符串)
②函数功能:将字符串中的大写字母转换成小写,其它字符(包括小写字母和非字母字符)不转换。
8.将字符串中小写字母转换成大写──strupr()函数
①调用方式:strupr(字符串)
②函数功能:将字符串中小写字母转换成大写,其它字符(包括大写字母和非字母字符)不转换。
第七章 函数
▲一、函数的定义与调用
1、函数的定义
任何函数(包括主函数main())都是由函数说明和函数体两部分组成。根据函数是否需要参数,可将函数分为无参函数和有参函数两种。
⑴、无参函数的一般形式
函数类型 函数名( void )
{ 说明语句部分;
可执行语句部分;
}
注意:在旧标准中,函数可以缺省参数表。但在新标准中,函数不可缺省参数表;如果不需要参数,则用“void”表示,主函数main()例外。
⑵、有参函数的一般形式
函数类型 函数名( 数据类型 参数[,数据类型 参数2……] )
{ 说明语句部分;
可执行语句部分;
}
有参函数比无参函数多了一个参数表。调用有参函数时,调用函数将赋予这些参数实际的值。
为了与调用函数提供的实际参数区别开,将函数定义中的参数表称为形式参数表,简称形参表。
⑶、说明
①函数定义不允许嵌套(但函数的调用可以嵌套)。
在C语言中,所有函数(包括主函数main())都是平行的。一个函数的定义,可以放在程序中的任意位置,主函数main()之前或之后。但在一个函数的函数体内,不能再定义另一个函数,即不能嵌套定义。
②空函数──既无参数、函数体又为空的函数。其一般形式为:
[函数类型] 函数名(void)
{ }
③在老版本C语言中,参数类型说明允许放在函数说明部分的第2行单独指定。
2、函数的返回值与函数类型
⑴.函数返回值与return语句
有参函数的返回值,是通过函数中的return语句来获得的。
①return语句的一般格式: return ( 返回值表达式 );
②return语句的功能:返回调用函数,并将“返回值表达式”的值带给调用函数。
注意:调用函数中无return语句,并不是不返回一个值,而是一个不确定的值。为了明确表示不返回值,可以用“void”定义成“无(空)类型”。
⑵.函数类型
函数的类型说明符指明了函数的类型,它实际上是函数返回值的类型。如果不要求函数有返回值,函数的类型说明符可以写为void,如果缺省,C语言函数返回类型的默认定义类型是int型。
在定义函数时,对函数类型的说明,应与return语句中、返回值表达式的类型一致。
如果不一致,则以函数类型为准。如果缺省函数类型,则系统一律按整型处理。
即:在C语言中,函数返回值的数据类型取决于在定义该函数时所指定的数据类型。
3、对被调用函数的说明和函数原型
在ANSI C新标准中,采用函数原型方式,对被调用函数进行说明,其一般格式如下:
函数类型 函数名(数据类型[ 参数名][, 数据类型[ 参数名2]…]);
C/C语言同时又规定,在以下3种情况下,可以省去对被调用函数的说明:
①当被调用函数的函数定义出现在调用函数之前时。因为在调用之前,编译系统已经知道了被调用函数的函数类型、参数个数、类型和顺序。
②如果在所有函数定义之前,在函数外部(例如文件开始处)预先对各个函数进行了说明,则在调用函数中可缺省对被调用函数的说明。
③当一个函数是int类型时,它与被调用者的前后位置关系可以忽略,可以省略对被调函数的说明。
4、函数的调用
一般形式为: 函数名([实际参数表])
切记:实参的个数、类型和顺序,应该与被调用函数所要求的参数(形参)个数、类型和顺序一致,才能正确地进行数据传递。
⑴、调用函数方式:
①函数表达式。函数作为表达式的一项,出现在表达式中,以函数返回值参与表达式的运算。
②函数语句。C/C语言中的函数可以只进行某些操作而不返回函数值,这时的函数调用可作为一条独立的语句。
③函数实参。函数作为另一个函数调用的实际参数出现。这种情况是把该函数的返回值作为实参进行传送,因此要求该函数必须是有返回值的。
⑵、说明:
①调用函数时,函数名称必须与具有该功能的自定义函数名称完全一致。
②实参在类型上按顺序与形参,必须一一对应和匹配。如果类型不匹配,C编译程序将按赋值兼容的规则进行转换。如果实参和形参的类型不赋值兼容,通常并不给出出错信息,且程序仍然继续执行,只是得不到正确的结果。
③如果实参表中包括多个参数,对实参的求值顺序随系统而异。有的系统按自左向右顺序求实参的值,有的系统则相反。Turbo C和MS C是按自右向左的顺序进行的 。
5、函数的形参与实参
⑴、函数的参数分为形参和实参两种,作用是实现数据传送。
形参出现在函数定义中,只能在该函数体内使用。发生函数调用时,调用函数把实参的值复制1份,传送给被调用函数的形参,从而实现调用函数向被调用函数的数据传送。
⑵、说明:
①实参可以是常量、变量、表达式、函数等。无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值,以便把这些值传送给形参。
②形参变量只有在被调用时,才分配内存单元;调用结束时,即刻释放所分配的内存单元。
因此,形参只有在该函数内有效。调用结束,返回调用函数后,则不能再使用该形参变量。
③实参对形参的数据传送是单向的,即只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。
④实参和形参占用不同的内存单元,即使同名也互不影响。
6、函数的嵌套调用和递归调用
⑴、函数的嵌套调用 指在执行被调用函数时,被调用函数又调用了其它函数。
如图所示:

⑵、函数的递归调用
函数的递归调用是指,一个函数在它的函数体内,直接或间接地调用它自身。
二、变量的作用域、局部变量与全局变量
变量的作用域是指变量在程序中的有效范围。C语言中的变量,按作用域范围可分为两种:局部变量和全局变量。
⑴、局部变量(内部变量)
在一个函数内部说明的变量是内部变量,它只在该函数范围内有效。只有在包含变量说明的函数内部,才能使用被说明的变量,在此函数之外就不能使用这些变量了。所以内部变量也称“局部变量”。 局部变量的作用域被限定在其所定义的局部范围中。
⑵、关于局部变量的作用域还要说明以下几点:
①主函数main()中定义的变量是内部变量,也只能在主函数中使用,其它函数不能使用。同时,主函数中也不能使用其它函数中定义的内部变量。因为主函数也是一个函数,与其它函数是平行关系。
②形参变量也是内部变量,属于被调用函数;实参变量,则是调用函数的内部变量。
③在同一个作用域中不可定义同名变量,但在不同的作用域中可以定义同名变量,因为它们代表不同的对象,分配不同的单元,互不干扰,不会发生混淆。
④在复合语句中也可定义变量,其作用域只在复合语句范围内。
⑶、全局变量(外部变量)
①在函数外部定义的变量称为外部变量。
外部变量不属于任何一个函数,其作用域是:从外部变量的定义位置开始,到本文件结束为止。
②外部变量可被作用域内的所有函数直接引用,所以外部变量又称全局变量。
三、变量的存储属性
1、静态存储变量和动态存储变量
从变量的生存期(即在内存中存在时间)来看,变量可分为静态存储变量和动态存储变量。
①静态存储变量:在系统编译程序时就分配存储单元,直至整个程序结束。
②动态存储变量:在程序执行过程中使用它时才分配存储单元,使用完毕立即释放。
2、变量的存储类型
变量存储类型是指变量在内存中的存储方式,分为静态存储和动态存储。
从变量的存储方式来看,变量分为auto(自动)变量、register(寄存器)变量、extern(外部变量)、static(静态变量)4种。
自动变量和寄存器变量属于动态存储方式,外部变量和静态变量属于静态存储方式。
①自动变量:类型说明符为auto(可以省略),缺省时,凡未加存储类型说明符的局部变量都有是自动变量。
自动变量属于动态存储方式,其作用域和生存期都局限于定义它的程序体内(函数或复合语句),因此不同的程序体中允许使用同名的变量而不会混淆。
②寄存器变量:类型说明符为register,存放在CPU的寄存器中,使用时不需要访问内存,而直接从寄存器中读写,这样可提高效率。
③外部变量:类型说明符为extern,又称为全局变量。
④静态变量:类型说明符为static,分为静态局部变量和静态全局变量。
四、编译预处理
所谓编译预处理是指,在编译之前处理,即在对源程序进行编译之前,先对源程序中的编译预处理命令进行处理;然后再将处理的结果,和源程序一起进行编译,以得到目标代码。
1、宏定义与符号常量
在C/C语言中,“宏”分为无参数的宏(简称无参宏)和有参数的宏(简称有参宏)两种。
⑴、无参宏定义
n 无参宏定义的一般格式
#define 标识符 语言符号字符串
其中:“define”为宏定义命令;“标识符”为所定义的宏名,通常用大写字母表示,以便于与变量区别;“语言符号字符串”可以是常数、表达式、格式串等。
n 使用宏定义的优点
①可提高源程序的可维护性
②可提高源程序的可移植性
③减少源程序中重复书写字符串的工作量
n 说明
①宏名一般用大写字母表示,以示与变量区别。但这并非是规定。
②宏定义不是C语句,所以不能在行尾加分号。
③宏定义命令#define出现在函数的外部,宏名的有效范围是:从定义命令之后, 到本文件结束。通常,宏定义命令放在文件开头处。
⑵、符号常量
在定义无参宏时,如果“语言符号字符串”是一个常量,则相应的“宏名”就是一个符号常量。
恰当命名的符号常量,除具有宏定义的上述优点外,还能表达出它所代表常量的实际含义,从而增强程序的可读性。
⑶、有参宏定义
n 带参宏定义的一般格式
#define 宏名(形参表) 语言符号字符串
n 带参宏的调用和宏展开
①调用格式:宏名(实参表)
②宏展开:用宏调用提供的实参字符串,直接置换宏定义命令行中、相应形参字符串,非形参字符保持不变。
2、文件包含
⑴、文件包含的概念
文件包含是指,一个源文件可以将另一个源文件的全部内容包含进来。
⑵.文件包含处理命令的格式
#include “包含文件名” 或 #include <包含文件名>
两种格式的区别仅在于:
①使用双引号:系统首先到当前目录下查找被包含文件,如果没找到,再到系统指定的“包含文件目录”(由用户在配置环境时设置)去查找。
②使用尖括号:直接到系统指定的“包含文件目录”去查找。一般地说,使用双引号比较保险。
⑶.文件包含的优点
一个大程序,通常分为多个模块,并由多个程序员分别编程。有了文件包含处理功能,就可以将多个模块共用的数据(如符号常量和数据结构)或函数,集中到一个单独的文件中。这样,凡是要使用其中数据或调用其中函数的程序员,只要使用文件包含处理功能,将所需文件包含进来即可,不必再重复定义它们,从而减少重复劳动。
⑷.说明
①编译预处理时,预处理程序将查找指定的被包含文件,并将其复制到#include命令出现的位置上。
②常用在文件头部的被包含文件,称为“标题文件”或“头部文件”,常以“h”(head)作为后缀,简称头文件。在头文件中,除可包含宏定义外,还可包含外部变量定义、结构类型定义等。
③一条包含命令,只能指定一个被包含文件。如果要包含n个文件,则要用n条包含命令。
④文件包含可以嵌套,即被包含文件中又包含另一个文件。
第八章 指针
▲一、指针和指针变量的概念
1、指针──即地址
一个变量的地址称为该变量的指针。取变量地址的运算符是&,通过变量的指针能够找到该变量。
2指针变量──专门用于存储其它变量地址的变量
▲二、指针变量的定义与应用
⑴、指针变量的定义:[存储类型] 数据类型 *指针变量[, *指针变量2……];
如float *p(缺省存储类型说明,表示指针变量p的存储类型是auto型)
⑵、取地址运算(&)和指针运算(*)
取地址运算的格式:&变量
指针运算(取内容运算)的格式:*指针变量(表示取指针变量所对应的目标变量的内容)
注:
①指针变量有自己的地址,它的内容也是一个地址。在C语言中,说p指向x,意味着变量p的内容是变量x的地址。
②由于指针的数据类型实际上是指定指针所能指向对象的数据类型,所以不同数据类型的指针变量不能相互赋值。
▲三、指针与数组
⑴指针和一维数组
数组名代表数组的首地址,是一个常量。
数组指针:就是指向数组元素地址的指针变量。
指向数组的指针变量可以与一个整型常量相加,或与一个整型常量相减。
⑵指针和二维数组
用数组名表示二维数组的行地址
数组元素三种形式引用:
⑴ a[i][j] 下标法
⑵ *(a[i]+j) 用一维数组名
⑶ *(*(a+i)+j) 用二维数组名
⑶指针数组
指针数组:数组的所有元素都是存放指针的数组称为指针数组。
即:指针数组中每一个元素(下标变量)都是指针变量。
指针数组的定义形式:
<存储类型> <数据类型> <*指针数组名>[数组长度][={地址列表}];
4、指针与字符串
⑴将字符串的首地址赋给指针,用字符指针变量来处理字符串。
⑵字符指针变量与字符指针数组
字符数组和字符指针变量都能实现字符串的存储与运算,但两者之间还是有区别的,主要包括以下几点:
①字符数组由若干元素组成,每个元素存放一个字符;
字符指针变量存放的是字符串的首地址。
②赋值方式不同:
不能用赋值语句给字符数组赋值。
char str[14];
str=“I love china!” 这是错误的。
字符指针变量可以采用下面的形式赋值:
char *p;
p=“china!” 这是正确的。
但要注意赋给指针变量p的不是字符串,而是字符串的首地址。
定义一个数组,在编译时分配存放n个元素的存储空间;
定义指针变量只分配存放一个地址的空间。
第九章 结构体、共用体与枚举类型
▲一、结构体
结构体是用户自定义的新数据类型,在结构体中可以包含若干个不同数据类型和不同意义的数据项(当然也可以相同),从而使这些数据项组合起来反映某一个信息。
1、定义一个结构体类型的一般形式为:
struct 结构体名
{
数据类型 成员名1;
数据类型 成员名2;
……
数据类型 成员名n;
};
例如:定义一个职工worker结构体如下:
struct worker
{ long number;
char name[20];
char sex; //sex是成员名
int age;
float salary;
char address[80];
char phone[20]; }; //注意分号不要省略
int sex=10; //sex是变量名
2、结构体类型变量的定义方法
n 先定义结构体类型再定义变量名:struct 结构体名 变量名
n 在定义结构体类型的同时定义变量。
注意:结构体的定义可以嵌套,即在结构体内还可以定义结构体。结构体中的成员也可以是一个结构体变量。
3、结构体变量的引用和初始化
n 结构体变量的引用:结构变量不能整体引用,只能引用其成员,一般形式为:结构体变量名.成员名。
n 结构体变量的初始化:struct 结构体名 变量名={初始数据表};
或
struct 结构体名
{
成员列表;
}变量名={初始数据表};
注意:
①结构体是一种构造数据类型,是数目固定,类型不同的若干有序变量的集合。
②结构体变量占据的内存空间大小等于所有成员占据的内存空间之和。
二、共用体
1、共用体的概念
在C语言中,不同数据类型的数据可以使用共同的存储区域,这种数据构造类型称为共用体,简称共用,又称联合体。
2、定义一个共用体类型的一般形式为:
union 共用体名
{
成员列表;
};
3、共用体变量的定义
n 先定义共用体类型再定义共用体变量:union 共用体名 变量名
n 在定义共用体类型的同时定义变量。
注意:
①共用体变量任何时刻只有一个成员存在。
②共用体变量定义分配内存,长度=最长成员所占字节数。
三、枚举
1、枚举的概念
枚举就是指将某一变量所有可能的取值一一列举出来。
2、枚举的定义:
enum 枚举类型名{枚举元素表}枚举变量名
3、枚举变量的定义
n 在定义枚举类型的同时,定义枚举类型的变量。
n 已定义过的枚举数据类型定义枚举变量,格式为:
enum 枚举名称 变量名表
注意:
①枚举元素是常量,不能在程序中用赋值语句再对它赋值 ;
②枚举元素作为常量是有值的,编译系统按定义时的顺序使它们具有顺序整数值:0,1,2,……;
③在定义枚举类型中,可在枚举数据时通过“=”来对枚举元素进行初始化(指定一个整型值),并影响后面的枚举元素的值,后继序号以此递增;
③枚举元素不是字符常量也不是字符串常量,不能直接输入输出,可在过程中通过判断和强制类型转换来实现输入输出;
④枚举变量只能取对应枚举类型的枚举元素表中的元素;
⑤枚举元素表中的元素有先后次序,可以进行比较。
四、类型定义typedef的使用
用typedef定义新的类型名代替已有的类型名。
⑴、格式:typedef 数据类型 新的名称
⑵、类型定义一般为大写,与原来的数据类型关键相区别
⑶、类型定义只是给已存在的数据类型增加一个类型名,并没有创造一个新的数据类型。
注意:
①使用typedef可以定义各种类型名,但不能用来定义变量;
②使用用typedef只是将已存在的类型用一个新的名称来代表,并不是定义了一种新的数据类型;
③使用typedef便于程序的通用。
第十章 文件
一、文件指针:
1、文件指针:C语言系统对文件的操作必须通过一个指向“FILE类型”的指针来实现,我们称这种指针为 “文件指针”。
二、文件位置指针
C语言规定:每一个文件都必须设置一个位置指针(文件指针)来控制文件的访问位置,其规律如下。
◆ 文件打开时指针自动指向文件的开始位置;
◆ 每读取一个单元内容文件位置指针自动顺序向后移动一定的偏移量(该偏移量的字节数由所读取单元的数据类型决定);
◆ 读到文件的结尾,则文件的位置指针指向一个特殊的位置——EOF。
◆ 对文件进行顺序写操作时,数据写入到文件位置指针所指向的位置。写入后文件位置指针自动向后移动到一个新的位置,等待下一次的写入操作。
◆ 可将文件位置指针移动到任何位置,实现对文件的随机读写访问。
三、文件的打开——打开文件函数fopen()
打开文件使用fopen()函数实现。打开文件格式为:
FILE *fp;
fp= fopen(文件名,使用方式);
文件名:为包含访问路径的文件名字符串。
在C语言中,对文件操作必须先打开文件。若执行fopen()时发生错误,则函数的返回值是NULL或0。
四、关闭文件函数fclose()
文件操作结束前,必须关闭文件。
关闭文件使用fclose()函数。格式如下:
fclose(文件指针) ;
其中的“文件指针”参数,就是保存打开文件操作时fopen函数返回值的FILE指针变量。
关闭文件的含义就是执行fclose()函数,先释放文件指针,后写缓冲区的数据到文件中。
当顺利执行了文件关闭操作时,fclose()返回值是0,否则返回-1。