1.C语言基础
1.1. 数据类型
基本类型
整型 短整型 short 整型 int 长整型 long
实型 单精度型 float 双精度型 double 构造类型 数组 结构型 struct 共用体 union 枚举类型 enum 指针类型
空类型 void
1.2.常量
常量定义:程序运行时指不能改变的量(既常量)。 分类:
符号常量: 直接常量: 用标识符代表常量。 整型常量 格式:#define 符号常量,常量 实型常量 一般用大写字母可以做到“一改全改” 字符常量 是宏定义的预处理命令,不是C语句(不用+;结尾) 字符串常量
1.2.1 整型常量(整常数)
表现形式 十进制整数 由数字0~9和正负号表示 八进制整数 由数字0开头,后跟数字1~7表示 十六进制整数 由0x开头后跟0~9,a~f,A~F表示
整型常量的类型:
根据其值所在范围确认数据类型
在整常量后+l/L认为他是long int 型常量
1.2.2 实型常量
表现形式 十进制整数形式 必须有小数点
0.123,.123 实际都为0.123,123.0,123.都为123.0指数形式 e或E钱必须有数字,指数必须为整数
3E-6合法 e-5,123E3.5 不合法
实型常量的类型:
默认double。
在实型常量后+f/F认为他是float类型。
规范化的指数形式:
在字母e/E后的位数部分中,小数点左边应有一位且仅有以为非零的数字。
%e控制指数形式输出是,按规范化的指数形式输出。
1.2.3 字符常量
定义:用单引号括来的单个普通字符或转义字符。
字符常量的值:是该字符的ASCII码值。
转义字符:反斜线后面跟一个字符或一个代码值表示转义字符及其含义。
常见的ASCII码值:
转义字符 含义 转义字符 含义 \n 换行 \t 水平制表 \v 垂直制表 \b 退格 \r 回车 \f 换页 \a 响铃 \\ 反斜线 \* 单引号 \** 双引号 \ddd 3位8进制数代表的字符 \xhh 2位16进制数代表的数字
1.2.4 字符串常量
定义:用双引号括起来的字符序列。
存储:每个字符串尾部自动添加一个‘/0’作为字符串的结束标志。
"hello"实际存储为“hello/0”
字符串常量与字符常量不同。
1.3.变量
定义:用老表示变量、常量、函数等的字符序列。
组成:
只能由字符,数字,下换线组成,切第一个必须是字母或下划线。
大小写敏感。
不能使用关键字作为用户标识符。
长度:一般计算机系统规定,取前八个有效字符,Turbo C中规定最长32字符。
命名原则:
见名知意。
不宜混淆,如大写I和小写L,大写O与小写o。
1.3.1 变量的定义
概念:
值可以改变的量。
变量名与变量值:
变量名定义后不可改变,变量值可以改变。
变量定义的一般格式:
数据类型 变量1[,变量2,....,变量n];
变量初始化:
定义时赋初值,如果不赋初值,且开辟的内存被使用过,那么变量会是一个随机的。
变量的使用:先定义,后使用。
变量定义的位置:
一般放在函数的开头。
根据变量的类型,检查运算是否合法。
1.3.2 整型变量
1.3.2.1 分类
整型变量的分类:
整型变量的基本类型符是int。
C语言允许程序员在定义整型变量时,在int前面增加两类修饰符:
一类是控制变量是否有符号,包括:signed和unsigned,不设置默认有符号。
另一类控制整型变量的值域范围,包括short和long。
比如,可以这样定义一个整型变量:unsigned long int
这样就形成了6类整型变量:
数据
类型符有无
符号最高位是否
参与数值的计算值域 占用
内存有符号的
基本整型int
sigredint有 否 -2^15 ~
2^15-12 无符号的
基本整型unsigredint
unsigred无 是 0~2^16-1 1 有符号的
短整型short int
short有 否 -2^15 ~
2^15-12 无符号的
短整型unsigred short int
unsigred short无 是 0~2^16-1 2 有符号的
长整型long int
long有 否 -2^31
~2^31-1'4 无符号的
长整型unsigred long int
unsigred long无 是 0~2^32-1 4
1.3.2.2 内存中的存放
证书的数值在内存中用补码表示,比如:
整数14的二级制位1110,在内存中的存放形式为:
0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 -14为14的源码取反
+1后成为补码
1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 数据溢出问题:当达到最大值后,再次+1就会变成最小值。
1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0
1.3.3 实型变量
1.3.3.1 存放形式
实数在内存中的存放形式
实数按照指数形式存放
通常一个实数需要4个字节(32位)的内存。计算机将这4个字节分为3个部分,最高位是符号位,剩下的31位,有一部分存放实数的小数部分,另一部分存放实数的指数部分。
小数部分占的位(bit)数愈多,数的有效数字愈多,精度愈高。指数部分占的位数愈多,则能表示的数值范围愈大。
1.3.3.2 分类和定义
名称 数据类型符 内存占用 例 单精度实型 float 4个字节(32位)内存 float f-2.14,F; 双精度实型 double 8个字节(64位)内存 double x,y; 长双精度实型 long double 16字节(128位)内存 long double x,y:
1.3.3.3 实型的误差
由于实型变量是由有限的存储单元组成的,因此能提供的有效数字总是有限的,在有效位以外的数字将被舍去。由此可能会产生一些误差。
1.3.4 字符型变量
·字符变量的定义:字符型变量用来存放字符常量,只能放一个字符,如:
char c1,c2:字符变量在内存中的存放形式:
存放字符ASCII码char与int数据间可进行算术运算
1.4. 数据类型转换
1.5. 运算符和表达式
C运算符 算数运算符 + - * / % ++ -- 关系运算符 < <= == > >= != 逻辑运算符 ! && || 位运算符 << >> ~ | ^ & 赋值运算符 = += -= *= /= %=
<<= >>= &= ^= |=条件运算符 ? : 逗号运算符 , 指针运算符 * & 求字节数 sizeof 强制类型转换 (类型) 分量运算符 , -> 下表运算符 [ ] 其他 ( ) -
学习运算符应注意:
运算符功能
与运算量关系
要求运算量个数
要求运算量类型运算符优先级别
结合方问
1.5.1 基本算数运算符
+ - * /
结合方向:从左向右。
优先级:-(2)====》*/%(3)====》+-(4)
说明:
“-”可为单目运算符时,右结合性
两整数相除,结果为整数
%要求两侧均为整型数据
在将一个数学式子改写成C语言表达式时应注意以下几点:
1.乘号不能省。如:ab应写成 a*b
2.所有符号写成一行。
3.C语言中只有圆括号,可以嵌套使用,但左、右括号必须匹配。
4.避免两个运算符并置如:a*b/-c应写为:a*b/(-c)
5.由于两个整数相除结果仍为整数,所以要转换成实数运算。
如 5/12应该写成5.0/12或5/12.0
1.5.2 强制类型转换
一般形式: (类型名)(表达式)
例
(int)(x+y)
(int)xly
(double) (3/2)
1.5.3 赋值运算符和表达式
1.5.3.1简单赋值运算符
符号:=
恪式:变量名=表达式作用:将一个数据(常量或表达式)赋给一个变量
1.5.3.2 符合赋值运算符
符号:+= *= /= %= 《= 》= &= ^= |=
意义:简化程序,使程序精炼。提高编译效率。
说明:
结合方向:自右向左
优先级:14
左侧必须是变量,不能是常量或表达式赋值转换规则:使赋值号右边表达式值自动转换成其左边变量的类型,按存储单元中的存储形式直接传送。
赋值表达式的值与变量值相等,且可嵌套。
1.5.4 自增 自减
作用:使变量值加1或减1
种类:
前置 ++i,--i(先执行i+l或i-1,再使用i值)后置 i++i--(先使用i值,再执行i-1或i-1)
说明:
++,--不能用于常量和表达式,如5++,(aHb)++++--结合方向: 自右向左
优光级:--++-------->*/%----->+ -
1.5.5 关系运算符
种类:< <= >= >
结合方向:自左向右
优先级别: == != 优先级为7,其他优先级为6关系表达式的值:是逻辑值“真"或“假”,用1和0表示
1.5.6 逻辑运算符
种类:! && ||
逻辑运算真值表 a b !a !b a&&b a||b true true false false true true true false false true false true false true true false false true false false true true false false 短路特性:逻辑表达式求解时,并非所有的逻辑运算符都被执行,只是在必须执行下一个逻辑运算符才能求出表达式的解时,才执行该运算符。
1.5.7 条件运算符与表达式
一般形式:expr1 ? expr2 : expr3
执行过程
必功能:相当于条件语句,但不能取代一般if语句优先级:13
结合方向:自右向左
1.5.8 逗号运算符和表达式
形式:表达式1,表达式2.…….表达式n
结合方向:从左向右
优先级: 15
逗号表达式的值:等于表达式n的值用途:常用于循环for语句中
例题:
a=15,表达式值60/a=15.表达式值20a-3*5.a*4 a+5例 x(a=3,6*3)//赋值表达式,表达式值18,x-18x-a-3.6*a//逗号表达式,表达式值18.x-3
例a=3*5,a*4 a=15.表达式值60
a-3*5,a*4,a+5 a=15,表达式值20
x=(a-3,6*3) 赋值表达式,表达式值18,x=18
x=a=3,6*a 逗号表达式,表达式值18,x=3
2.程序设计
2.1 C语句概述
C语句:以“;”作分隔符,编译后产生机器指令
C语句分类
必表达式语句:表达式加分号构成必空语句: ;
程序控制语句(9种):
复合语句:用{..}括起来的一组语句
分支
if~else switch 循环
for while do~while 辅助控制
continue break goto return
2.2 赋值语句
赋值语句是由赋值表达式加上一个分号构成,是程序设计中最常用的语句之一
格式: 变量名=表达式;
例如:t=a;
2.3 输入,输出函数
C语言无I/O语句,IO操作由函数实现
#include <stdio.h>
2.3.1 字符输出函数(putchar)
格式:putchar(ch )
参数:ch可以是字符变量或整型变量
功能:把字符ch输出到显示器上
说明:在程序中使用putchar()函数时,该程序的开头必须用一条预编译命“#include<stdio.h>”
2.3.2 字符输入函数(getchar)
格式:getchar()
功能:接收从终端输入的1个字符,没有参数。
函数值:从输入设备得到的字符。
2.3.3 格式输出函数(printf)
格式:printf(“格式控制串”,输出表)
功能:按指定格式向显示器输出数据
输出项表:要输出的数据(可以没有,多个时以“”分隔)输出项可以是合法的常量、变量和表达式。
格式控制串:包含两种信息格式
说明:
%[修饰符] 格式字符,用于指定输出格式
普通字符或转义序列:原样输出
格式字符 格式字符 含义 代码 结果 d i 十进制整数 int a=567;printf( “od .a): 567 c 单一字符 char a=65:print“ooc”.a). A s 字符串 printf( os . “ ABC”): ABC e e 指数形式浮点小数 float a=567.789,printf(“ce .a) 5.677890e+02 f 小数形式浮点小数 float a=567.789,print("'f .a); 567.789000 说明
格式字符要用小写
格式字符与输出项个数应相同,按先后顺序一一对应附加格式说明符(修饰符)
修饰符 功能 m 输出数据域宽,数据长度<m,左补空格:否则按实际输出 .n 对实数,指定小数点后位数(四舍五入) 对字符串,指定实际输出位数 l 在d,o,x,u前,指定输出精度为long型 在e,f,g前,指定输出精度为double型
2.3.4 格式输入函数(scnaf)
格式:scanf(“格式控制串”,地址表)
功能:按指定格式从键盘读入数据,存入地址表指定的存储单元中,并按回车键结束
地址表:变量的地址,常用取地址运算符&
格式字符:d,c,s,f
修饰符 功能 l 用于d,o,x前,指定输入为long型整数 用于e,f前,指定输入为double型实数 m 指定输入数据宽度,遇空格或不可转换字符则结束 输入分隔符的指定:
一般以空格、TAB或回车键作为分隔符
其它字符做分隔符:格式串中两个格式符之间的字符
说明:
用“%c”格式符时,空格和转义字符作为有效字符输入
3 选择结构分支
3.1 if语句
3.1.1 if语句的三种形式
if(表达式) 语句。
if(表达式) 语句1 else 语句2
if(表达式1) 语句1 else if(表达式2) 语句2 ..... else 语句n
说明:
(1)if后面的“表达式”一般为逻辑表达式或关系表达式,系统对表达式的值进行判断,若为0按“假”处理,若为非0,按“真”处理。因此,表达式的类型不限于逻辑表达式,可以是任意的数值类型(包括整型,实型,字符型,指针型数据)
(2)后面两种形式的if语句中,每个else前面有一个分号,不要错认为是两个语句。
(3)if和else后面可以使用复合语句,即用“{}”将n个 语句括起来。
4.1.2 if内嵌
在if语句中又包含一个或多个if语句称为 if语句的嵌套。
if(表达式1){ if(表达式2){ }else{ } }else{ }
说明:
应注意 if与 else 的对应关系,else总是与它上面最近的i配对,若试与else的数目不一致,可以加{}来确定配对关系。
为明确匹配关系,避免匹配错误,强烈建议:将内嵌的if语句,一律用花括号括起来。
3.2 switch语句
3.2.1 一般形式
switch (表达式){ case 常量表达式1: 语句1 case 常量表达式2: 语句2 case 常量表达式n: 语句n default: 语句n+1
说明:
(1)switch后面括弧内的“表达式”,可以是任意类型的表达式。
(2)当表达式的值与某一个case后面的常量表达式的值相等时,就执行此case后面的语句,若所有的case 中的常量表达式的值都没有与表达式的值匹配的,就执行detault后面的语句(3)每一个case 的常量表达式的值必须互不相同,否则就会出现互相矛盾的现象。
(4)各个case的出现次序不影响执行结果!
(5)多个case可以供用一组执行语句。如:
caseA case 'B' case 'c ':printf(">60\n");
(6)执行完一个case后面的语句后,流程控制转移到下一个case 继续执行。“case常量表达式”只是起语句标号的作用,并不是在该处进行条件判断。
注意:
break语句可以使流程跳出switch结构,继续执行switch语句下面的语句
switch (表达式){ case 常量表达式1: 语句1; break; case 常量表达式2: 语句2; break; case 常量表达式n: 语句n; break; default: 语句n+1;
4.循环控制
4.1 while语句
1.形式 : while(表达式)语句
2.作用 :实现“当型”循环, 当表达式成立时,执行语句
3.特点:先判断表达式,后执行语句4.执行过程:
(1)首先判断表达式的值是真是假。
(2)若为真,则执行一次循环体,并转向(1)。(3)若为假,则转向循环体之后的语句执行。
注意:
1、循环体只能是单条语句。若有多条,须用台括起来。如上面程序中删除{}
2、在循环体中应改变循环控制变量的值,以逐步结束循环。
4.2 do~while语句
1.形式:Do
循环体语句while(表达式);
2.特点:先执行语句,后判断条件,当表达式成立时执行。直到表达式不成立为止。3.作用:可以实现“直到型”循环,但要注意表达式的结束条件
4.3 for语句
for(i=1;i<=10;H++)sum=sum+i;
2.执行过程:1)计算表达式1,给循环变量赋初值
2)计算表达式2,判循环条件是否成立;
当表达式2成立时(非0),转3);
当表达式2不成立时(0),转5);
执行语句;
4)计算表达式3,循环变量增值,返回2)
5)结束循环3.说明:
1)表达式1可省,但分号不能省.2)若表达式2省略,循环条件永远为真;
3)表达式3也可省略,但应设法保证循环正常结束;
4)可只给循环条件,这时与 while 语句等同;
5)三个表达式都可省;for(;;) 相当于 while (1);
6)表达式1和表达式3可以是逗号表达式;
7)表达式2一般为关系表达式或逻辑表达式,但也可以是数值表达式或字符表达式,只要其值为非零就执行循环体如:for( ;(c=getchar( ))!='n';)
8)注意循环结束时,循环变量的值
4.4 循环嵌套
1.概念 :一个循环体内又包含另一个完整的循环结构 。
2.说明:
1)嵌套可以是多层的;2)一个循环体必须完完整整嵌套在另一个循环体内,不能出现交叉;
3)三种循环可以互相嵌套。
4.5 break,continue
一、break语句
1)从循环体内跳出循环体,即提前结束循环接着执行循环下面的语句;2)break语句只能用于循环语句和 swvitch 语句
二、continue 语句
1.作用:结束本次循环,即跳过循环体中下面尚未执行的语句,接着执行下一次是否执行循环的判定。
三、区别
1.break语句和continue语句的区别是1)contimnue 语句只结束本次循环,不终止整个循环的执行;
2.break 语句是终止整个循环的执行,不再进行条件判断。
5. 数组
5.1 一维数组
一维数组的定义
1.定义方式:
类型说明符数组名[整型常量表达式1例:int a[10];
2.说明:
1)数组名的定名规则和变量名相同,遵循标识符定名规则。
2)数组名后的常量表达式用[]括起来。3)常量表达式表示数组元素的个数,即数组长度。
4)常量表达式中可以包括常量和符号常量,不能包含变量,即定义时必须确定数组的大小。
二、一维数组元素的引用
数组必须先定义,然后使用。C语言规定只能逐个引用数组元素而不能一次引用整个数组。
1.冒泡排序算法: 用冒泡法对10个数排序
5.2 二维数组
一、二维数组的定义
类型说明符数组名[常量表达式][常量表达式]例:foat a[3][4],b[5][10];
说明:
1)可以把二维数组看作是一种特殊的一维数组。2)二维数组在内存中按行存放
3)多维数组定义方式与二维数组类似int x[3]14l[2];
二、二维数组的引用引用形式为:
数组名[下标】[下标]
注:下标可以是整型表达式,但应在已定义的数组大小的范围内。
三、二维数组的初始化
1.分行给二维数组赋初值。int a[3][4]= {{1,2 3,4},{5,6,7,8},{910,11,12}}2.可以将所有数据写在花括弧内,按数组排列的顺序对各 元素赋初值。
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}.3.可以对部分元素赋初值,不赋的为0。如:
int a[3][4]={{1},{5},9}}int a[3][4]={{1},{0,6},{0,0,11}}}
4..如果对全部元素都赋初值,则定义数组时对第一维的长 度可以不指定,但第二维的长度不能省。
5.3 字符数组
一、字符数组的定义
char 字符数组名[整型常量表达式]例:char c[10], d[2][3];
二、字符数组的初始化
例:char c[10]={'I' ,'a','m',’','h','a','','p','y'];
char c[3][2]={{'','*',{'*',''},{'','*'}};注:对静态字符数组未被赋值的元素系统自动将其赋值为空("0”)。
三、字符数组元素的引用同简单变量
四、字符串和字符串结束标志
在C语言中,用字符数组来处理字符串,同时,C语言规定以字符"0'(null)作为字符串结束标志。对字符数组初始化,可以用字符串常量来使字符数组初始化。
如:
char c[]={“I am happy”};(可以不指定数组长度,其c[]=“【am happy”; 长度由系统检测+1确定char c [14]={“I am happy”};(也可以指定数组长度char但应保证其长度至少比其字符个数+1要大,多余部分自动赋予null(/0)
五、字符数组的输入输出
1.输入输出控制字符有两种"%c"和"%s'逐个字符输入/输出%e0/s一次输入/输出整个字符串
2.输出应注意的问题用"%s"格式输出字符时,输出遇"0'时结束,printf函数中的输出项是字符数组名,而不是数组元素.
3.输入时应注意:在使用scanf函数时,若用"%s"格式输入字符串,则后面跟数组名,且不带"&"符号,数组名指向该数组的起始地址。
注:用函数scanf输入(格式字符%s)无法输入空格,必须用字符串处理函数完成。
六、字符串处理函数所有函数都包含在头文件"string.h"中
1.字符串输出函数puts
格式:puts(字符数组)
向显示器输出字符串(输出完,换行)功能:
说明:字符数组必须以'\0’结束
2.字符串输入函数gets
格式:gets(字符数组)
功能:从键盘输入一以回车结束的字符串放入字符数组中,并自动加'\0’
说明:输入串长度应小于字符数组维数3.strcat(字符数组1,字符数组2)连接两个字符数组中的字符串,把字符串2接到字符串1的后面,结果放到字符数组1中,函数调用后得到一个函数值一字符数组1的地址。
说明:
① 字符数组1必须足够大,以便容纳连接后的新字符串。
②连接时,自动取消数组1后的"0’,只在新串最后保留一个"0'4.strcpy(字符数组1,字符串2)作用:将字符串2拷贝到数组1中去。说明:
①字符数组1必须足够大,以便容纳被拷贝的字符串。② “字符数组1”必须写成数组名形式,“字符串2”可以是字符数组名,也可以是一个字符串常量。
③拷贝时连同字符串后面的"0’一起拷贝到字符数组1中
④不能用赋值语句将一个字符串常量或字符数组直接赋给一个字符数组。(str1=str2;str1={“HELLo”})
⑤ 可以用strcpy函数将字符串2中前面若干个字符拷贝到字符数组1中去。
strepy(str1,str2,2)(有些系统不支持)拷贝str2的前2个字符,然后再加一个"05.strcmp(字符串1,字符串2)
作用:比较字符串1和字符串2
对两个字符串自左至右逐个相比,直到出现不同的字符或遇到“0’为止,如全部字符相同,则认为相等;若出现不相同的字符,则以第一个不相同的字符的比较结果为准,比较的结果由函数值带回。(以字符的ASCI码为准)
字符串1==字符串2,函数值为0字符串1>字符串2,函数值为一正整数
字符串1<字符串2,函数值为一负整数
6.strlen(字符数组)
测试字符串长度的函数,函数的值为字符串的实际长度,不包括“0’在内。Stren(“Chim”)函数返回值是5。
6. 函数
6.1 函数的概述
说明:
1.一个 ℃ 程序由一个或多个函数组成;从 main0)开始,调用其它函数后,回到 main() 结束;
2.分类:
1)用户使用角度:库函数和用户白定义函数2)调用关系:主调用函数和被调用函数3)函数形式:无参函数 和 有参函数
6.2 函数的定义
6.2.1 函数定义格式
形式:
类型标识符 函数名(形式参数表列){
函数声明部分
函数语句部分}
说明:若不带回函数值,或返回一个int类型数据,则类型标识符也可以不写
6.2.2 函数调用
函数调用的一般形式函数名(实参表列)
说明:
1.无参函数,括号不能省;2.实参表列中,各实参与形参在 个数、顺序、类型上-一对应,参数间用逗号分隔。
6.2.3 被调函数的声明
1.被调函数必须存在!
2.若使用库函数:用#include命令包含有关库函数:
3.若使用用户自定义函数:
被调用函数在主调函数前定义,这样在主调函数中可以不对调用函数类型进行声明。否则在主调函数中必须对调用函数类型进行声明
函数声明的形式:
函数类型 函数名(参数类型1,参数类型2,.);
函数类型 函数名(参数类型1 参数名,参数类型2 参数名2,…);
6.3 参数和返回值
一、形式参数 和 实际参数
形式参数:定义函数时,括号中说明的变量名;
实际参数:调用函数时,括号中给定的表达式。
二、函数的返回值
说明:
函数的返回值
1.通过 return 语句获得返回值; 如: return(z)
2.定义函数时指定函数返回值的类型;不加类型说明的,按整型处理。(即函数返回值为整型时,可不加类型说明。)
3.为了明确表示“不带回值”,可以用“ void ”定义“无类型”。(如:void print0 )
6.4 函数的嵌套
6.4.1 普通嵌套
6.4.2 递归调用
在调用一个函数的过程中又出现直接或间接地调用该函数本身,称为函数的递归调用。
递归问题的特点
1.把一个问题转化为一个新问题,新问题与原问题解法相同,只是所处理的对象有所不同,随着问题的转化,问题的规模有规律的递增或递减
2.可以通过转化过程使问题得到解决。
3.必须有一个明确的结束递归的条件。
6.5 变量作用域
6.5.1 作用域
若某个变量仅能在源程序正文的某个范围内被使用,则称源程序正文的这个范围为该变量的作用域。
6.5.2 局部变量
在一个函数内部定义的变量,不能在此函数外使用这些变量。只在函数内有效的变量。
说明:
1.每个函数中定义的变量,只在定义它的函数中有效;2.不同函数可以使用相同名字的变量,但意义不同;
3.形式参数是局部变量;
4.可以在复合语句中定义变量,但它们只在本复合语句中有效 。
6.5.3 全局变量
1.外部变量:在函数之外定义的变量;
2.外部变量是全局变量;
3.作用范围:从定义变量的位置开始到本源文件结束4.说明:
(1)作用:提供一种函数问数据联系与共亨的方法;(2)全局变量与局部变量同名时,局部变量屏蔽外部变量
(3)不要过多使用全局变量;
1)占内存
2)易产生副作用
6.6 变量存储类别
6.6.1 动态存储变量与静态存储变量
1.静态存储变量:
程序运行期间始终占有固定的存储空间,存放全局变量或静态局部变量(static)。2.动态存储变量:根据需要动态分配存储空间.
1)动态局部变量(auto)
2)寄存器变量(register)
6.6.2 局部变量存储方式
1.动态局部变量(自动变量):([auto])
1)函数调用后,值不予保留,即释放存储空间
2)再次调用时,原值不能引用
2.静态局部变量: (static )
1)函数调用后保留原值,即不释放所占存储空间:
2)再次调用时,原值在本函数内仍可使用
说明 :
1.若静态局部变量定义时不赋初值,编译时自动赋初值0;
2.虽然静态局部变量在函数调用结束后仍然存在,但不能被其它函数引用
6.6.3 全局变量存储方式
1.用extern声明全局变量
1)在函数外部定义
2)允许其他文件中的函数引用,需要用extern作说明
2.用static声明全局变量只能被本文件中的函数引用
7.编译预处理命令
对源程序编译之前,要对程序做一些处理。
种类
宏定义 #define
文件包含 #include
条件编译 #if--#else--#endif
格式:
# 开头
占单独书写行
语句尾不加分号
7.1 宏定义
不带参数宏定义
一般形式:#define 宏名 宏体宏展开:预编译时.用宏体替换宏名---不作语法检查
如#define YES 1
#define NO 0
#define PI 3.1415926
#define OUT printf('******\n');宏定义可嵌套
#define WIDTH 80
#define LENGTHI WIDTH+40
var=LENGTH*2:
宏展开:
var= 80+40 *2;宏定义中使用必要的括号
#define WIDTH 80
#define LENGTH (WIDTH+40)var=LENGTH*2:
宏展开:
var=(80+40)*2;
带参宏定义
7.2 文件包含
功能:一个源文件可将另一个源文件的内容全部包含进来
一般形式: #include“文件名’或 #include <文件名>
处理过程:预编译时,用被包含文件的内容取代该预处理命令,再对“包含”后的文件作一个源文件编译被包含文件内容:源文件(*.c)头文件(*.h)
文件包含可嵌套
8. 指针与数组
8.1 指针和地址的概念
一个数据在内存中的首地址称为该数据的指针
一个变量在内存中的首地址称为该变量的指针
8.2 指针和与指针变量
指针:一个数据或变量在内存中的首地址
指针变量:专门存放地址的变量
8.2.1 指针变量的定义格式
【格式】基本类型标识符: *指针变量名列表。
例如:
int *pointer 1,*pointer 2float *pointer_3
char *pointer_4;
1)在定义指针变量时,变量名前的*表示该变量的类型为指针变量,指针变量的命名规则与基本变量的命名规则相同.
2)在定义指针变量时必须指定其基本类型
8.2.2 指针变量的引用
指针变量定义后,必须先赋值,再使用
指针变量赋值有两种方法:
1、将某个已经定义了的普通变量的首地址赋给指针变量;
2、调用C语言的动态内存分配函数为指针变量在内存的动态存储区找到一个可用区域。
方法1.
指向变量的指针
&取地址运算符
*指针运算符直接访问:使用普通变量名来访问某个数据。如:ij间接访问:使用指针变量名来访问某个数据。如:*p1
使用指针变量的一般步骤为:
1)先定义指针变量和同类型的普通变量如:int *p,x;
2)使用取地址运算符“&”将指针变量指向普通变量,
如:p=&x;3)此后,使用*p即可取代变量x
方法2.内存的动态分配
使用动态内存分配函数,在内存中找到一个连续可用空间,将该空间的首地址赋给一个指针变量,然后直接通过该指针变量,对该内存空间进行读写操作。1)malloc函数
void *malloc(unsigned int n);功能:调用该函数将在内存分配一个长度为n的连续空间
若调用成功,该函数将返回一个指向所分配空间的首地址:
若调用失败,该函数将返回一个空指针 {NULL)
2)calloc函数
void *calloc(unsigned m, unsigned n);功能:该函数将在内存分配m个长度为n的连续空间
若调用成功,该函数将返回一个指向所分配空间的首地址:
若调用失败,该函数将返回一个空指针(NULL)
3)free 函数
void free ( void *p);功能:释放指针变量p所指向的内存空间此函数无返回值
指针变量的使用
1、将指针变量所指向的内存单元的值作为函数的参数
2、将指针变量作为函数的参数
3、使函数返回多个函数值的一般方法
9.2.3 使函数返回多个函数值的一般方法
1)在主程序设置n个普通变量x1、x2、x3.......和n个指针变量p1、p2、p3...
2)将n个指针变量指向这n个普通变量。即:pl-&x1;p2-&x2,
3)然后将这n个指针变量作为实参,将其地址传递给所调用的自定义函数的形参。
4)在自定义函数中,除了接受主函数传递运算数的"个形参外,再设置n个指针变量作形参,用来接受由主函数main传递来的n个地址,这样,在自定义函数中,可以通过改变自定义函数中所定义的这些形参指针变量所指向的内存单元的值,来改变主函数中变的值。量x1、x2、x3......
8.3 指针和数组
1、数组名是表示数组首地址的地址常量
2、一个数组的各个元素在内存中是顺序存放的
访问数组元素的方法:
下标法
数组名计算地址法
指针变量法特别强调:数组名a是一个地址常量,因此,类似于 a++或à+=i是非法的。
指针变量的运算
如果p指向数组a的首元素(p=a):
p++的功能
指针加1的功能.不是地址的具体值加1,而是将指针指向与之相临的下一个数据。
*p++的功能
语句 x=*p++;等价于: x=*p; p++;
(*p)++的功能
将p所指向的内存单元的值加1。
8.4 指针与字符串
在C语言中,用字符数组来处理字符串
1.字符串的定义char sl10];
2.字符串的结束标志 '\0',字符串的长度≠字符数组的长度
3.字符串的访问:下标、指针
指针变量的关系运算
若p1和p2指向同一数组,则
p1<p2 表示p1指的元素在前
p1>p2表示p1指的元素在后
p1==p2 表示p1与p2指向同一元素若p1与,2不指向同一数组,比较无意义
9.结构体
9.1 结构体定义
结构体是一种构造数据类型
用途:把不同类型的数据组合成一个整体
结构体类型标识符的定义
struct 结构体类型标识符{ 类型标识符1 成员名1; 类型标识符1 成员名2; 类型标识符n 成员名n; }
方法一:
先定义结构体类型,再定义结构体变量·一般形式:
struct 结构体类型标识符{ 类型标识符1 成员名1; 类型标识符1 成员名2; 类型标识符n 成员名n; } struct 结构体名称 变量名表
方法二:
定义结构体类型的同时定义结构体变量一般形式:
struct 结构体类型标识符{ 类型标识符1 成员名1; 类型标识符1 成员名2; 类型标识符n 成员名n; }变量名表1,变量名表2
方法三:
直接定义结构体变量
struct { 类型标识符1 成员名1; 类型标识符1 成员名2; 类型标识符n 成员名n; }变量名表1,变量名表2
说明:
结构体类型与结构体变量概念不同结构体类型:不分配内存;
结构体变量:分配内存
结构体类型:不能赋值、存取、运算:结构体变量:可以赋值、存取、运算
结构体成员名与程序中变量名可相同
9.2 结构体变量引用
引用规则结构体变量一般不能整体引用,只能引用成员
引用方式:结构体变量名.成员名
可以将一个结构体变量赋值给另一个结构体变量
9.3 结构体变量初始化
9.4 结构体数组定义
9.5 结构体和指针
10 文件
10.1 C文件概述
1.文件:存储在外部介质上数据的集合.是操作系统数据管理的单位
2.文件分类
按数据的组织形式:
1)文本文件: ASCI文件,每个字节存放一个字符的ASCI码
2)二进制文件:数据按其在内存中的存储形式原样存放
使用数据文件的目的
1、数据文件的改动不引起程序的改动--程序与数据分离2、不同程序可以访问同一数据文件中的数据--数据共享
3、能长期保存程序运行的中间数据或结果数据
10.2 文件类型指针
文件结构体FILE缓冲文件系统为每个正使用的文件在内存开辟文件信息区文件信息用系统定义的名为FⅡE的结构体描述FILE定义在stdio.h中
10.3 文件打开和关闭
10.4 文件的读写