C++
第一章 C语言基础知识
- C程序构成:预处理命令、语句、函数、注释
- 预处理命令以“#”开头,末尾没有分号,共有三种,分别是宏定义命令、文件包含命令及条件编译命令。
- 语句分为全局声明定义语句、局部声明定义语句和执行语句,都是以“;”结尾的语句。
- 函数由函数头和函数体构成。
- 行注释符:“//” 块注释符:“/……/”(可跨行)
标识符:由字母、数字和下划线“_”组成,但第一个字符必须是字母或下划线。
数据类型
1)基本数据类型
(1)整型:即整数
分类 | 类型说明符 | 取值范围 | 字节数 |
---|---|---|---|
有符号数 | short int 或 short | -32768~32767 | 2 |
int | -2147483648~2147483647 | 4 | |
long int 或 long | -2147483648~2147483647 | 4 | |
无符号数 | unsigned short | 0~65535 | 2 |
unsigned | 0~4294967295 | 4 | |
unsigned long | 0~4294967295 | 4 |
(2)浮点型:即含有小数部分的数据
分类 | 类型说明符 | 取值范围 | 有效数字 | 字节数 |
---|---|---|---|---|
单精度 | float | -3.4E+38 |
7位 | 4 |
双精度 | double | -1.7E+308 |
16位 | 8 |
长双精度 | long double | -1.7E+308 |
16位 | 8 |
(3)字符型:即字符
2)变量
(1)变量的定义
[存储类型] 数据类型 变量名列表;(变量名列表是使用逗号间隔的多个变量名)
(2)变量的赋值
数据类型 变量名 1=值 1,……,变量名 n=值 n;
3)常量
(1)整型常量
类型 | 组成要素 | 规则 | 实例 |
---|---|---|---|
十进制 | 数字0~9 | 非0数字开头 | 65535 -1627 |
八进制 | 数字0~7 | 0数字开头 | -0101 017775 |
十六进制 | 数字 0 ~ 9 ,字母 A ~ F (或 a ~ f ) | 0x或0X开头 | 0X2A -0Xa0 |
注:(1)八进制、十六进制是以数字0开头,而非字母O开头。
(2)在所有的整型常量末尾加上字母u或U,表示该数为无符号整数,加字母l或L表示该数为长整型数。
(2)实型常量
实型常量也称为实数或者浮点数,由两种形式。
- 小数形式
符号位 | 整数部分 | . | 小数部分 |
---|---|---|---|
— | 3 | . | 14159 |
- 指数形式
符号位 | 数码 | E | 符号位 | 阶码 |
---|---|---|---|---|
— | 0.314159 | e | + | 1 |
注:(1)小数形式中,小数点两侧若为零可省略,但是不能都省略。如0.0。
(2)指数部分的阶码,只能是整数,正整数的符号可省略。如2.1e5、—2.8e—2。
(3)浮点数常量默认是double型,末尾加上字母f或F,表示该数为 float 型,加字母l或L,表示该数为 long double 型。
(3)字符常量
字符常量是用单引号“ ’ ”括起来的一个字符。
注:
转义字符 | 含义 |
---|---|
\n | 回车换行 |
\t | 水平制表(Tab) |
\b | 退格 |
\r | 回车 |
\ddd | 1~3位八进制数 |
\f | 换页 |
\ | 反斜杠 |
\ ‘ | 单引号 |
\ “ | 双引号 |
\xhh | 1~2位十六进制数 |
常用转义字符
(4)字符串常量
字符串常量是由一对双引号“ ” “括起来的0个或多个字符。
字符常量与字符串常量的区别:
(1)字符常量由单引号” ‘ “括起来,字符串常量由双引号” “ ”括起来。
(2)字符常量只能是单个字符,字符串常量则可以含一个或多个字符。
(3)字符串常量占的内存字节数等于字符串中字节数加1,增加的一个字节的内存空间存放字符“\0”(ASCLL码为0)。
(5)常变量
在定义变量时,如果加上关键 const
,则变量的值在程序运行期间不能改变,这种变量成为常变量。
【语法格式】
1 | const 数据类型 常变量名 = 初始值; |
注:常变量初始化之后,不允许再被赋值。
- 二进制数的编码方式
(1)原码:将符号位数字化为0或1,数的绝对值与符号一起编码,即所谓“符号—绝对值表示”的编码,称为原码。
(2)反码:正数的反码与原码表示相同,负数的反码与原码的关系是其符号位保留不变(仍为1),其余各位取反(0变1,1变0)。
(3)补码:正数的补码与原码相同。负数的补码,符号位保留不变,其余位在反码的基础上,最末位加1。
- C程序的输入输出
1)printf函数
(1)语法格式
1 | printf(格式控制序列,输出表列); |
(2)
格式控制符 | 含义 | 实例 | 执行结果 |
---|---|---|---|
d,i | 整数(十进制) | int a=255;printf(“%d”,a); | 255 |
o | 整数(无符号八进制) | int a=255;printf(“%o”,a); | 377 |
x,X | 整数(无符号十六进制) | int a=255;printf(“%x”,a); | ff |
u | 整数(无符号十进制) | int a=255;printf(“%u”,a); | 4294967041 |
c | 单个字符 | char a=65;printf(“%c”,a); | A |
s | 字符串 | printf(“%s”,”ABC”); | ABC |
e,E | 浮点数(指数形式) | float a=567.789;printf(“%e”,a); | 5.677890e+002 |
f | 浮点数(小数形式) | float a=567.789;printf(“%f”,a); | 5670789000 |
g,G | 浮点数(e和f中较短一种) | float a=567.789;printf(“%g”,a); | 567.789 |
%% | 百分号本身 | printf(“%%”); | % |
printf()函数中的格式字符
(3)
修饰符 | 功能 |
---|---|
m | 输出数据域宽,数据长度<m,左补空格;否则按实际输出 |
.n | 对实数,指定小数点后位数(四舍五入) |
对字符串,指定实际输出位数 | |
对整数,n<=m时输出区域宽度为n,剩余域宽补空格,否则按域宽输出 | |
— | 输出数据在域宽内左对齐(缺省右对齐) |
+ | 指定在有符号整数的正数前显示正号(+) |
0 | 输出数值时指定左面不使用的空位置(域宽范围)自动填09 |
# | 在八进制和十六进制数前显示前导0,0x |
l,L | 在d,o,x,u前,指定输出精度为long型 |
在e,f,g前,指定输出精度为double型 |
printf()函数中的格式修饰符
2)scanf函数
(1)语法格式
1 | scanf(格式控制序列,地址表列); |
(2)
格式控制符 | 含义 |
---|---|
d | 读入整数(十进制) |
i | 读入十六进制,八进制,十六进制整数 |
o | 读入整数(无符号八进制) |
x,X | 读入整数(无符号十六进制) |
u | 读入整数(无符号十进制) |
c | 读入一个字符 |
s | 读入字符串,遇空格、制表符或换行符结束 |
f,F,e,E,g,G | 用来输入实数,可以用小数形式或指数形式输入 |
%% | 读%符号 |
scanf()函数中的格式字符
(3)
修饰符 | 功能 |
---|---|
h | 用于d,o,x前,指定输入为short型整数 |
l,L | 用于d,o,x前,指定输入为long型整数 |
用于e,f前,指定输入为double型整数 | |
m | 整型整数,指定输入数据宽度,遇空格或不可转换字符则结束 |
* | 抑制符,表示本输入项在读入后不赋值给相应的变量 |
scanf()函数中的格式修饰符
注:(1)使用空白字符会使scanf()函数一般以空格键、Tab键或Enter键作为 分隔符,当格式字符串中存在非格式字符时,输入时也需要一并输入。
(2)使用空白字符会使scanf()函数在读操作中略去输入中的一个或多个空白字符;使用非空白字符会使scanf()函数在读入是剔除掉与这个非空字符相同的字符。
(3)在用“%c”输入时,空格和转义字符均作为有效字符。
(4)输入数据时,遇以下三种情况则认为该数据结束:①遇空格键、Tab键、或Enter键;②有指定数据长度时,系统自动按长度截取;③遇非法输入。
(5)合法间隔符同样起作用。eg:int a,b; scanf(“%3d%*2d%2d”,&a,&b); printf(“a=%d,b=%d\n”,a,b); 输入123456789则输出a=123,b=67;输入12<空格>3456789则输出a=12,b=56。
3)putchar函数
(1)语法格式
1 | putchar(ch); //等同于printf("%c",ch). |
4)getchar函数
(1)语法格式
1 | char c; c=getchar(); //从键盘上读入一个字符,并显示到屏幕上。该函数等待输入直到按Enter键才结束,回车前的所有输入字符 |
都会逐个显示在屏幕上,但只有第一个字符作为函数的返回值。
5)标准输入流cin
(1)语法格式
1 | cin>>表达式1>>表达式2>>...>>表达式n; |
6)标准输出流cout
(1)语法格式
1 | cout<<表达式1<<表达式2<<...<<表达式n<<endl; //endl为回车换行 |
注:使用cin和cout函数需要导入头文件iostream.h。格式为:#include<iostream.h>
第二章 运算符与表达式
- 算术运算符
运算符 | 名称 | 示例 | 结果 | 优先级 | 结合性 | 对象数 |
---|---|---|---|---|---|---|
+ | 正号 | +a | —10 | 1 | 自右向左 | 单目 |
— | 负号 | —a | 10 | 1 | 自右向左 | 单目 |
* | 乘法 | a*5 | —50 | 2 | 自左向右 | 双目 |
/ | 除法 | a/5 | —2 | 2 | 自左向右 | 双目 |
% | 求余 | a%3 | —1 | 2 | 自左向右 | 双目 |
+ | 加法 | a+12 | 2 | 3 | 自左向右 | 双目 |
— | 减法 | a—2 | —12 | 3 | 自左向右 | 双目 |
注:(1)变量a的值为—10。
(2)“/”运算时,参与运算的两个数均为整型时,结果为舍去小数的整型数,如“15/4”结果为3,而不是3.75,要得到3.75,则应写成“15.0/4”、“15.0/4.0”或“15/4.0”。
(3)“%”要求参与运算的操作数均为整型,计算结果的符号与“%“左侧运算对象的符号相同,如”—7%4“的结果为—3。
(4)乘号”*“不能省略。
- 自增和自减运算符
运算符 | 名称 | 示例 | 功能 |
---|---|---|---|
++ | 自增(前缀形式) | ++i | 在使用变量i之前,先使i的值加1 |
—— | 自减(前缀形式) | ——i | 在使用变量i之前,先使i的值减1 |
++ | 自增(后缀形式) | ++i | 使用变量i之后,使i的值加1 |
—— | 自减(后缀形式) | ——i | 使用变量i之后,使i的值减1 |
注:”++“和”——“运算符只能用于整型变量,不能用于常量和表达式。
- 算术复合赋值运算符
运算符 | 名称 | 示例 | 运算规则 |
---|---|---|---|
+= | 加赋值 | a+=b*2 | a=a+(b*2) |
—= | 减赋值 | a—=b+3 | a=a—b+3 |
*= | 乘赋值 | a*=b+1 | a=a*(b+1) |
/= | 除赋值 | a/=b-1 | a=a/(b-1) |
%= | 模赋值 | a%=b+1 | a=a%(b+1) |
- 关系运算符
运算符 | 名称 | 示例 | 优先级 |
---|---|---|---|
> | 大于 | a>b | 优先级相同(较高) |
>= | 大于等于 | a>=b | |
< | 小于 | a<b | |
<= | 小于等于 | a<=b | |
== | 等于 | a==b | 优先级相同(较低) |
!= | 不等于 | a!=b |
注:真为1,假为0。
- 逻辑运算符
运算符 | 名称 | 示例 | 对象数 |
---|---|---|---|
! | 逻辑非 | !a | 单目 |
&& | 逻辑与 | a&&b | 双目 |
|| | 逻辑或 | a||b | 双目 |
注:(1)逻辑运算符的优先级从高到低为:”!”—>算术运算符—>关系运算符—>”&&”—>”||”—>赋值运算符
(2)运算符“&&”和运算符“||”都对操作数有“短路”计算。也就是说,对于“&&”来说,只有左边表达式的值为真时,才计算右边表达式的值;而对于运算符“||”来说,只有左边表达式的值为假时,才计算右边表达式的值
- 位运算符
操作符 | 名称 | 优先级 | 对象数 |
---|---|---|---|
~ | 按位取反 | 1 | .单目 |
<< | 按位左移 | 2 | 双目 |
>> | 按位右移 | 2 | 双目 |
& | 按位与 | 3 | 双目 |
^ | 按位异或 | 4 | 双目 |
| | 按位或 | 5 | 双目 |
- 位运算表达式
1)按位取反
(1)语法格式
1 | ~操作数 //对操作数的各二进制位按位取反,即1变0,0变1。 |
2)按位左移运算
(1)语法格式
1 | 操作数<<左移位数 //把操作数的各二进制位全部左移若干位(由右边的“左移位数:指定)。左移时,低位(右端)补0,高位(左端)移出部分舍弃。 |
注:若高位(左端)移出的部分均是二进制位数0,则每左移一位,相当于乘以2。
3)按位右移运算
(1)语法格式
1 | 操作数>>右移位数 //把操作数的各二进制位全部右移若干位(由右边的”右移位数“指定)。右移时,高位(左端)补0,低位(右端)移出部分舍弃 |
4)按位与运算
(1)语法格式
1 | 操作数 1 &操作数 2 |
5)按位异或运算
(1)语法格式
1 | 操作数 1 ^ 操作数 2 //计算结果的各个二进制位由操作数1和操作数2相应的位决定。相异为1,相同为0。 |
6)按位或运算
(1)语法格式
1 | 操作数 1 | 操作数 2 //计算结果的各个二进制位由操作数1和操作数2相应的位决定。有1为1,其余为0。 |
- 条件运算符与条件表达式
(1)语法格式
1 | 判定式 ?表达式 1 : 表达式 2 //若”“判定式”的值是非零,条件表达式的值取”表达式1“的值;若”判定式“的值为零,条件表达式的值取”表达式2“的值。 |
- 求字节运算符:sizeof()
(1)语法格式
1 | sizeof(类型名|变量名) //取出“类型名”或“变量名”的长度 |
- 数据类型转换
1)算术转换
高 long double
^ ^
| |
| double <— float
| ^
| |
| long
| ^
| |
| unsigned
| ^
| |
低 int <— char,short
注:在运行时,不同类型的数据先转换成同一类型,然后再进行运算
2)赋值转换
(1)实型(float、double)赋值给整型变量时,舍弃实数的小数部分。如: int i; i=123.456;//i值为123
(2)整型(short int、int、long int)赋值给实型变量时,数值不变,但以浮点数据形式存储到变量中,小数部分值为0。如:float f; f=123;//f值为123.000000
(3)字符型(char)赋值给整型(short int、int、long int)变量时,由于字符型只占1个字节,所以整型变量的低8位为字符的ASCLL码值,而高位则用char最高位来填充。如:char c=’k’; short int i; i=c;//由于字符’k’的ASCLL码值107(二进制值为0110 1011),高八位补0,即0000 0000 0110 1011,赋值给短整型变量i,因此i的值为107
(4)整型(short int、int、long int)赋值给字符型(char),只把低8位赋值给字符变量。如:short int i=353; char c; c=i;//由于整型i的二进制为0000 0001 0110 0001,截取低8位,即0110 0001,赋值给字符变量c,因此c的值为’a’
(5)整型(int、long int)赋值给短整型(short int)时,高位字节的数据将丢失,即赋值号右边的值不能超过左边变量的数值范围。如:long int j=32768; short int i; i=j;//由于j的二进制位为0000 0000 0000 0000 1000 0000 0000 0000,j赋值给i,去掉高位,低位不变,为1000 0000 0000 0000,即-32768补码表示形式,因此i的值为-32768
(6)有符号整型赋值给无符号整型变量时,把内存中存储的二进制数字原样复制,所以负数可能转换为整数。如:int j=-254; unsigned int i; i=j;//由于j的二进制补码为1111 1111 1111 1111 1111 1111 0000 0010,是无符号数4294967042的二进制形式,j赋给i,二进制数字原样复制,因此无符号整型i的值为4294967042
(7)无符号整型赋值给有符号整型变量时,把内存中存储的二进制数字原样复制。此时,若符号位为1,将按负数处理。如:unsigned short j=65535; short int i; i=j;//由于j的二进制为1111 1111 1111 1111 1111 1111 1111 1111,j赋给i,二进制数字原样复制,因此有符号整型i的值为-1
- 强制类型转换
(1)语法格式
(类型名)(表达式) //强制类型转换运算符将表达式的值转换成所需的数据类型。
注:类型名和表达式都必须加括号(单个变量可以不加括号)。
第三章程序的控制结构
- 顺序结构
1)表达式语句
(1)语法格式
1 | 表达式; |
2)复合语句
(1)语法格式
1 | { |
3)控制语句
(1)条件语句:if、switch
(2)循环语句:for、while、do-while
(3)转向语句:continue、break、goto、return
- 选择结构
1)if语句
(1)语法格式
1 | if(表达式) 语句 |
2)if-else语句
(1)语法格式
1 | if(表达式) 语句1 |
3)if-else嵌套
(1)语法格式1
1 | if(表达式1) |
(2)语法格式2
1 | if(表达式1) 语句1 |
注:else总是与它上面的最近的if配对。为了增强程序的可读性,通常把同层的if和else对其书写,但需要注意的是格式对编译器没有任何影响,即不是书写堆起来的if和else就一定配对为一条if语句
4)switch
(1)语法格式
1 | switch(整型表达式){ |
注:若无break,则一定会执行default后面的语句
- 循环结构
1)while
(1)语法格式
1 | while(表达式) |
2)do-while
(1)语法格式
1 | do |
3)for
(1)语法格式
1 | for(表达式1;表达式2;表达式3) |
- 其他控制语句
1)break
(1)语法格式
1 | break;//只能在循环语句和switch语句中使用,但当break出现在循环体中的switch语句内时,其作用只是跳出switch语句,并不能终止循环的进行 |
2)continue
(1)语法格式
1 | continue;//结束本次循环的进行,即不再执行continue语句之后的语句,转入下一次循环条件的判断和执行 |
3)goto
(1)语法格式
1 | goto 语句标号;//使程序的执行流程跳转到语句标号所在的地方;语句标号是由一个有效标识符(标号名)加冒号“:”组成,放在某个语句之前或单独一行 |
第四章构造数据类型
- 数组
1)数组
(1)一维数组
①语法格式
1 | 类型标识符 数组名[整型常量表达式] |
注:(1)数组下标是从0开始的
(2)系统不会自动检验数组元素的下标是否越界
②一维数组的引用语法格式
1 | 数组名[下标] |
注:不能整体引用一个数组
③初始化
Ⅰ语法格式
类型标识符 数组名[整型常量表达式]={常量1,常量2,……,常量n};
注:(1)初值的类型必须与所说明的类型一致
(2)可对数组部分元素赋初值,其他自动赋值为0。如:int a[10]={1,2,3,4,5}; 、 int b[10]={0};
(3)在初始化时,可以不指定数组元素的个数,此时数组元素的个数等于所赋初值数据的个数
(2)二维数组
①语法格式
1 | 类型标识符 数组名 [整型常量表达式1] [整型常量表达式2];//按行优先,从0开始 |
②二维数组引用的语法格式
1 | 数组名 [下标1] [下标2] |
③初始化
Ⅰ对全部元素赋初值
【1】分行赋值:数组的每一行元素初始值用花括号括起来,各元素之间用逗号“,”分开,最外层再加一对花括号
1 | int b [3] [4]={ { 1,2,3,4 } , { 5,6,7,8 } , { 9,10,11,12 } }; |
【2】按顺序赋值
1 | int b [3] [4]={1,2,3,4,5,6,7,8,9,10,11,12}; |
【3】省略第一维长度,但第二维长度不能省略。如果对全部元素都赋初值,则定义数组时对第一维长度可以不指定,但第二维的长度不能省略
1 | int b [] [4]={1,2,3,4,5,6,7,8,9,10,11,12}; |
或
1 | int b [] [4]={ { 1,2,3,4 } , { 5,6,7,8 } , { 9,10,11,12 } }; |
Ⅱ对部分元素赋初值
【1】分行赋值:可以对二维数组每一行的前面几个元素赋初值,对于后面没有赋初值的元素,系统将自动给该行后面的元素赋初值0
1 | int b [3] [4]={ { 7,8 } , { 2 } , { 0,3,9 } }; |
用分行赋值方式对部分元素赋初值时,也可以省略第一维的长度
1 | int b [] [4]={ { 7,8 } , { 2 } , { 0,3,9 } }; |
【2】按顺序赋值
1 | int b [3] [4]={12,9,5,2,6,10}; |
或
1 | int a [2] [3]={0}; |
按顺序赋值,也可以省略第一维的长度,设有n个初始数据,数组的第二维长度时m,则第一维的大小通常为(int)(n/m+1)
1 | int b [ ] [4]={12,9,5,2,6,10}; |
- 排序
1)冒泡排序
(1)工作原理
- 比较相邻的两个元素,如果前者比后者大(反之倒序),则交换。
- 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。
- 针对所有的元素重复以上的步骤。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
(2)代码
1 | #include<stdio.h> |
2)选择排序
(1)工作原理及排序流程
它的工作原理是每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。
选择排序算法通过选择和交换来实现排序,其排序流程如下:
- 首先从原始数组中选择最小的1个数据,将其和位于第1个位置的数据交换。
- 接着从剩下的n-1个数据中选择次小的1个元素,将其和第2个位置的数据交换
- 然后,这样不断重复,直到最后两个数据完成交换。最后,便完成了对原始数组的从小到大的排序。
(2)代码
1 | #include<iostream> |
3)插入排序
(1)工作原理
插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序。
插入算法把要排序的数组分成两部分:
- 第一部分包含了这个数组的所有元素,但将最后一个元素除外,
- 而第二部分就只包含这一个元素(即待插入元素)。
- 在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中。
(2)代码
1 | #include<iostream> |
- 字符数组和字符串
1)字符数组
(1)语法格式
1 | char 数组名 [整型常量表达式]; |
(2)初始化
①用字符常量逐个赋初值
1 | char c [10]={'C',' ','P','r','o','g','r','a','m','!'}; |
②用字符串常量逐个赋初值
1 | char s []={"C Program!"}; |
注:(1)字符常量用” ‘ “,字符串常量用” “ ”
(2)用scanf()函数输入字符串时,以空格、制表符或Enter符作为字符串间隔的符号。如:char s[20]; scanf(“%s”,&s); printf(“%s”,s); //若输入Visual Basic</回车>,但数组s中只有Visual
2)字符串处理函数
(1)字符串输入函数:gets()
①语法格式
1 | gets(字符数组名) //从终端输入一个字符串到字符数组,并且返回该字符数组的起始地址 |
(2)字符串输出函数:puts()
①语法格式
1 | puts(字符数组名) //将一个字符串(以‘\0'结束的字符序列)输出到终端 |
(3)字符串连接函数:strcat()
①语法格式
1 | stract(字符数组 1,字符数组 2) //连接两个字符数组中的字符串,把字符串2连接到字符串1的后面,把得到的结果放在字符数组1中 |
(4)字符串复制函数:strcpy
①语法格式
1 | strcpy(字符数组 1,字符数组 2) //把字符串2连同串结束标志’\0‘复制到字符数组1中,其中字符串2可以是字符数组或字符串常量 |
(5)字符串比较函数:strcmp()
①语法格式
1 | strcmp(字符串 1,字符串 2) //将字符串1和字符串2中的两个字符串自左向右按照各字符的ASCLL码值逐对进行比较,知道出现不同的字符或遇到'\0'为止。函数的返回值:①若字符串1=字符串2,则返回值为0;②若字符串1>字符串2,则返回值为正整数;③若字符串1<字符串2,则返回值为负整数 |
(6)求字符串长度函数:strlen()
①语法格式
1 | strlen(字符串) //测试字符串长度,即字符串中字符的个数,不包括'\0' |
(7)大写字母转化为小写字母函数:strlwr()
①语法格式
1 | strlwr(字符串) //将字符串中大写字母转换成小写字母 |
(8)小写字母转化为大写字母:strupr()
①语法格式
1 | strupr(字符串) //将字符串中小写字母转换成大写字母 |
注:使用字符串函数时应该在程序的开头用”#include<string.h>“
- 结构体
1)声明语法格式
1 | struct 结构体名 |
2)结构体定义
(1)先声明结构体类型,在定义结构体变量
1 | struct teacher |
语法格式
1 | struct 结构体名 变量名表; |
(2)在声明结构体类型的同时定义变量
1 | struct teacher |
语法格式
1 | struct 结构体名 |
(3)不指定结构体名而直接定义结构体变量
1 | struct |
语法格式
1 | struct |
3)结构体变量的初始化
在定义结构体变量的同时可以对其成员赋初值
1 | struct student |
4)结构体变量的引用
语法格式
1 | 结构体变量.成员名 |
例子
1 | student1.num=1001;//引用学生的学号 |
注:(1)”.”称为结构体成员运算符,其在C语言中的运算优先级是最高的
(2)对于多层嵌套结构体成员的使用,应按照从最外层到最内层的顺序逐层使用成员名,每层成员名之间用结构体运算符“.”隔开, 只能对最内层的成员进行存取及运算等操作
(3)可以引用结构体变量成员的地址,也可以引用结构体变量的地址
1 | scanf("%d",&student1.num); //输入student1.num的值 |
(4)同类型的结构体变量可以相互赋值
1 | student2=student1; |
- 位段
1)定义:在一个结构体中以位为单位指定其成员所占的内存长度,这种以位为单位的成员称为“位段”或“位域”
2)语法格式
1 | struct[结构体名] |
例子
1 | struct bf |
注:(1)常量表达式用来指定每个位段的宽度,即该位段占内存多少位
(2)省略位段名时,该位段称为无名位段;无名位段的作用是跳过不使用的某几位;当无名位段宽度为0时,将使下一个位段从下一 个存储单元开始存放
3)位段的引用
语法格式
1 | 位段类型变量名.位段名; |
例子
1 | x.a=3; |
注:(1)在赋值语句中,赋值表达式的值超出位段的宽度时,则自动取值的低位赋值。5的二进制数是101,而x.a只有2位,取101的低2 位,因此赋值后的x.a的值为1,而不是5
(2)不能对位段求地址,因此不能读入位段值,也不能用指针变量指向位段
(3)位段可以参加任何算术表达式的运算,系统自动将其转换成整型
- 共用体
1)定义:共用体变量的所有成员将占同一个存储空间
2)语法格式
1 | union 共用体名 |
3)共用体变量的定义
(1)先声明共用体类型,在定义共用体变量
1 | union ut |
(2)在声明共用体类型的同时定义共用体变量
1 | union ut |
(3)不指定共用体名而直接定义共用体变量
1 | union |
注:共用体成员所占空间的大小取决于占存储空间最大的那个成员,而不是各个成员的存储空间之和
4)共用体变量的初始化
共用体在定义的同时只能对第一个成员的值进行初始化
1 | union ut |
5)共用体变量的引用
语法格式
1 | 共用体变量名.成员名 |
注:(1)对共用体某一成员赋值,会覆盖其他成员原来的数据,原来成员的值就不存在了,因此。共用体变量中起作用的是最后一次 存入的成员变量的值
1 | x.a=10; |
(2)允许在两个类型相同的共用体变量之间进行赋值操作
- 枚举类型
1)语法格式
1 | enum 枚举名 |
注:(1)enum是C语言的关键字,是枚举类型的引导字,用于声明枚举类型
(2)方括号内的“=整型常量”可以省略。如果省略,编译程序按顺序给每个枚举元素一个对应的整数值,整数值从0开始,后续元素 顺序加1
2)枚举变量的定义
(1)先声明枚举类型,在定义枚举变量
1 | enum weekday |
(2)在声明枚举类型的同时定义枚举变量
1 | enum weekday |
(3)不指定枚举名而直接定义枚举变量
1 | enum |
3)枚举变量的引用
(1)枚举变量的赋值
在使用枚举变量时,只能取其相应枚举类型所列的枚举常量
1 | workday=Mon; //正确 |
不能把枚举常量对应的序号直接赋值给枚举变量
1 | workday=2; //这样赋值错误 |
但可以用强制类型进行转换
1 | workday=(enum weekday)(2); //相当于workday=Tue |
(2)枚举变量的输入和输出
枚举变量的值不能直接进行输入和输出,只能间接地实现输入和输出的操作
1 | int d; |
如果需要输出枚举型变量的值,可以利用以下形式实现输出操作
1 | switch(day) |
- 自定义类型名
语法格式
1 | typedef 类型名 新类型吗; |
例子
1 | //标准类型重命名 |
注:(1)“类型名”可以是标注类型,也可以是构造类型或已经定义过的类型名
(2)“新类型名“习惯上用大写字母表示,以便于系统提供的关键字或预处理标识符相区别
第五章 函数
- 函数的定义与调用
1)函数的定义
(1)语法格式
1 | 类型标识符 函数名(形式参数表) |
2)函数的返回
C语言提供了返回语句return,其作用是返回调用它的函数,同时可以向调用函数送回计算结果(函数返回值)
(1)不返回函数值
1 | return; |
(2)返回函数值
1 | return 表达式; |
3)函数的声明
1 | 类型标识符 函数名(形式参数表) |
例子
1 | #include<stdio.h> |
注:(1)声明语句中形式参数表有两种,分别为
1 | 类型 形参1,类型 形参2,……,类型 形参n, |
或
1 | 类型,类型,……,类型 |
(2)当函数的定义与函数的调用出现在同一个程序文件,且函数的定义位于函数调用的位置之前时,可以省略函数声明
1 | #include<stdio.h> |
4)函数的调用
(1)有参函数调用语法格式
1 | 函数名(实际参数表) |
(2)无参函数调用语法格式
1 | 函数名() |
5)函数的递归调用
一个函数在它的函数体内调用其自身称为递归调用
一个函数能设计成为递归函数,必须具备以下两个因素:
- 递归模式:构成原问题的子问题与原问题在结构上相似,也称为结构自相似
- 递归出口:确定递归何时终止,一般用if语句来控制
1 | #include<stdio.h> |
6)函数调用经典例题:汉诺塔
![dasd jsdj](D:\blog\source_posts\C\dasd jsdj.jpg)
问题分析:
考虑将柱A上的n个盘子借助于柱B的帮助(如果需要的话)移动到C这样一个一般的汉诺塔问题以hanoi(n,a,b,c)表示,a、b和c各自表示A、B和C3跟柱子的一根。该问题通过循环结构来构造线求解是非常困难的,可把它当作递归问题来进行分析。
当n=1时,只要将编号为1的圆盘从柱子A直接移到柱子C上即可。
当n>1时,就需要借助另外一根柱子来移动。将n个圆盘由A移到C上可以分解为以下几个步骤:
- 将A柱子上的n-1个圆盘借助C柱子移到B柱子上;
- 把A柱子上剩下的一个圆盘从A柱子移到C柱子上;
- 最后将剩下的n-1个圆盘借助A柱子从B柱子移到C柱子上。
1 | #include<stdio.h> |
- 变量的作用域和生存期
1)变量的作用域
变量的作用域是指变量的有效性范围,既可以引用变量的区域,可以分为局部变量和全局变量
(1)局部变量
局部变量是指在任何一个复合语句中定义的变量,只能在定义它的代码块内使用;在一个代码块内定义的变量,对另一个代码块是隐蔽的
(2)全局变量
全局变量是指在函数外部定义的变量
2)变量的生存期
(1)定义:变量的生存期是指变量值在程序运行过程中存在的期限,即从系统为变量分配存储单元开始到将存储单元回收为止
(2)语法格式
1 | 存储类型 类型标识符 变量名列表 |
- 变量的存储类型
1)局部变量的存储类型
(1)自动变量
1 | auto int a,b; //等价于 int a,b; |
注:定义自动变量时,如果没给自动变量赋值,变量的初值是不确定的。如果赋初值,则每次调用时执行一次赋值操作
(2)静态变量
1 | static int a; |
注:静态局部变量在整个程序运行期间占用存储空间不释放,在函数调用结束后仍然保存在内存中,即其所占用的存储空间不释放,下次再调用该函数时,变量的值就是该函数上次调用后的值
(3)寄存器变量
1 | register int a; |
注:访问寄存器变量的速度比访问内存中的变量速度快,但寄存器变量只能是字符型变量、整型变量和指针类型的变量
2)全局变量的存储类型
(1)外部变量
外部变量是定义再函数外部的全局变量,如果外部变量不在文件开头定义,则只限于定义处到文件结束范围内使用该变量,如果要在作用域范围外使用全局变量,则可以使用extern关键字来声明外部变量,扩展其作用域,一种情况是在一个文件内扩展外部变量作用域到定义之前,另一种是将外部变量的作用域扩展到其他文件
1 | extern 类型标识符 变量名列表 |
(2)静态全局变量
静态全局变量的作用域限制在定义该变量的源文件内,同一个源程序中的其他源文件不能使用它
1 | static 类型标识符 变量名列表 |
- 宏定义
宏定义是指将一个标识符(又称为宏名)定义为一个字符串
1)无参宏定义
即定义一个没有参数的宏
语法格式
1 | #define 标识符 字符串 |
注:(1)宏名一般习惯用大写字母表示,以便于变量名相区别,但这并非规定
(2)在进行宏定义时,可以引用已定义的宏定义
(3)宏定义不是C程序语句,不必在行末加分号
2)带参宏定义
语法格式
1 | #define 宏名(形参表) 字符串 |
例子
1 | #include<stdio.h> |
注:(1)在带参宏定义中,宏名与其后的左括号”(”之间不应加空格,否则将变成无参宏定义
(2)在带参宏定义中,一般应将字符串及字符串中的形参用圆括号括起来
第六章 指针
- 指针与指针变量
1)定义:变量的地址就是变量的指针
2)指针变量的定义
(1)语法格式
1 | 类型标识符 *标识符 |
注:(1)标识符是指针变量名,标识符前加“*”号表示该变量是指针变量,用于存放地址
(2)一个指针变量只能指向类型相同的变量,因此一个指向整型变量的指针变量不允许指向实型变量
(2)指针变量的赋值
①通过地址运算符“&”赋值
1 | float f,*p; |
②指针变量的初始化
③通过其他指针变量赋值
1 | int i,*p1=&i,*p2; |
④用NULL给指针变量赋空值
1 | p=NULL; |
⑤开辟动态存储单元并给指针变量赋值
Ⅰnew运算符
语法格式
1 | new 类型名; //new运算符在内存中创建一个对象并分配存储空间,返回所创建对象的首地址 |
Ⅱdelete运算符
语法格式
1 | delete 变量名 //delete运算符删除new所创建并释放所分配的存储空间 |
注:在程序中为了防止错误地使用指针来存取数据,常常在指针未使用之前,先赋值为NULL,因为NULL可以赋值给指向任何类型的指针变量
- 指针与数组
1)一维数组
1 | int a[100],*p=a //等同于p=&a[0] |
注:*指针运算符“”与自增运算符“++”均为单目运算符,运算优先级相同,结合方向是“自右向左”**
2)二维数组
1 | a……二维数组的首地址,即第0行的首地址 |
- 指针与结构体
语法格式
1 | struct 类型名 *指针变量名; |
注:“->”是指向运算符
第七章 文件
- 文件的打开与关闭
1)文件打开函数
(1)语法格式
1 | FILE *fp; |
注:文件名:要打开的文件的路径和文件全名(文件名.扩展名),可以是字符串常量或字符数组,如“C:\Welcome.txt”
(2)
方式 | 说明 |
---|---|
”r”或”rt” | 以只读方式打开一个文本文件,此文件必须存在,只允许读 |
“w”或”wt” | 以只写方式建立并打开一个文本文件。若文件已存在,则打开时清空原内容,只允许写 |
“a”或”at” | 以追加方式打开一个文本文件,并将写入的内容添加到文件的末尾。若文件不存在,则新建一个文本文件 |
“rb” | 以只读方式打开一个二进制文件,此文件必须存在,只允许读 |
“wb” | 以只写方式建立并打开一个二进制文件。若文件已存在,则打开时清空原内容,只允许写 |
“ab” | 以追加方式打开一个二进制文件,并将写入的内容添加到文件的末尾。若文件不存在,则新建一个二进制文件 |
“r+”或”rt+” | 以读/写方式打开一个文本文件,此文件必须存在,允许读和写 |
“w+”或”wt+” | 以读/写方式建立并打开一个文本文件。若文件已存在,则打开时清空原内容,允许读和写 |
“a+”或”at+” | 以读/追加写方式打开一个文本文件,并将写入的内容添加到文件的末尾。若文件不存在,则新建一个文本文件 |
“rb+” | 以读/写方式打开一个二进制文件,此文件必须存在,允许读和写 |
“wb+” | 以读/写方式建立并打开一个二进制文件。若文件已存在,则打开时清空原内容,允许读和写 |
“ab+” | 以读/追加写方式打开一个二进制文件,并将写入的内容添加到文件的末尾。若文件不存在,则新建一个二进制文件 |
文件打开方式
2)文件关闭函数
(1)语法格式
1 | fclose(文件指针); |
- 文件的读写
1)字符读写函数
(1)fputc()函数
语法格式
1 | fputc(ch,fp); //ch:要写入到磁盘的字符;fp:文件的指针 |
(2)fgetc()函数
作用与fputc()函数相反,它是从一个文件里读取一个字符,这个文件必须是以读或读写方式打开的
语法格式
1 | ch=fgetc(fp); |
注:文件结束标志是EOF,当遇到时则返回文件结束标志(-1)。在C语言中,为了判读文件是否结束,常常使用的函数是feof(),其语法格式如下
1 | feof(fp); |
附录
附录ASCll码表
二进制 | 十进制 | 十六进制 | 字符/缩写 | 解释 |
---|---|---|---|---|
00000000 | 0 | 00 | NUL (NULL) | 空字符 |
00000001 | 1 | 01 | SOH (Start Of Headling) | 标题开始 |
00000010 | 2 | 02 | STX (Start Of Text) | 正文开始 |
00000011 | 3 | 03 | ETX (End Of Text) | 正文结束 |
00000100 | 4 | 04 | EOT (End Of Transmission) | 传输结束 |
00000101 | 5 | 05 | ENQ (Enquiry) | 请求 |
00000110 | 6 | 06 | ACK (Acknowledge) | 回应/响应/收到通知 |
00000111 | 7 | 07 | BEL (Bell) | 响铃 |
00001000 | 8 | 08 | BS (Backspace) | 退格 |
00001001 | 9 | 09 | HT (Horizontal Tab) | 水平制表符 |
00001010 | 10 | 0A | LF/NL(Line Feed/New Line) | 换行键 |
00001011 | 11 | 0B | VT (Vertical Tab) | 垂直制表符 |
00001100 | 12 | 0C | FF/NP (Form Feed/New Page) | 换页键 |
00001101 | 13 | 0D | CR (Carriage Return) | 回车键 |
00001110 | 14 | 0E | SO (Shift Out) | 不用切换 |
00001111 | 15 | 0F | SI (Shift In) | 启用切换 |
00010000 | 16 | 10 | DLE (Data Link Escape) | 数据链路转义 |
00010001 | 17 | 11 | DC1/XON (Device Control 1/Transmission On) | 设备控制1/传输开始 |
00010010 | 18 | 12 | DC2 (Device Control 2) | 设备控制2 |
00010011 | 19 | 13 | DC3/XOFF (Device Control 3/Transmission Off) | 设备控制3/传输中断 |
00010100 | 20 | 14 | DC4 (Device Control 4) | 设备控制4 |
00010101 | 21 | 15 | NAK (Negative Acknowledge) | 无响应/非正常响应/拒绝接收 |
00010110 | 22 | 16 | SYN (Synchronous Idle) | 同步空闲 |
00010111 | 23 | 17 | ETB (End of Transmission Block) | 传输块结束/块传输终止 |
00011000 | 24 | 18 | CAN (Cancel) | 取消 |
00011001 | 25 | 19 | EM (End of Medium) | 已到介质末端/介质存储已满/介质中断 |
00011010 | 26 | 1A | SUB (Substitute) | 替补/替换 |
00011011 | 27 | 1B | ESC (Escape) | 逃离/取消 |
00011100 | 28 | 1C | FS (File Separator) | 文件分割符 |
00011101 | 29 | 1D | GS (Group Separator) | 组分隔符/分组符 |
00011110 | 30 | 1E | RS (Record Separator) | 记录分离符 |
00011111 | 31 | 1F | US (Unit Separator) | 单元分隔符 |
00100000 | 32 | 20 | (Space) | 空格 |
00100001 | 33 | 21 | ! | |
00100010 | 34 | 22 | “ | |
00100011 | 35 | 23 | # | |
00100100 | 36 | 24 | $ | |
00100101 | 37 | 25 | % | |
00100110 | 38 | 26 | & | |
00100111 | 39 | 27 | ‘ | |
00101000 | 40 | 28 | ( | |
00101001 | 41 | 29 | ) | |
00101010 | 42 | 2A | * | |
00101011 | 43 | 2B | + | |
00101100 | 44 | 2C | , | |
00101101 | 45 | 2D | - | |
00101110 | 46 | 2E | . | |
00101111 | 47 | 2F | / | |
00110000 | 48 | 30 | 0 | |
00110001 | 49 | 31 | 1 | |
00110010 | 50 | 32 | 2 | |
00110011 | 51 | 33 | 3 | |
00110100 | 52 | 34 | 4 | |
00110101 | 53 | 35 | 5 | |
00110110 | 54 | 36 | 6 | |
00110111 | 55 | 37 | 7 | |
00111000 | 56 | 38 | 8 | |
00111001 | 57 | 39 | 9 | |
00111010 | 58 | 3A | : | |
00111011 | 59 | 3B | ; | |
00111100 | 60 | 3C | < | |
00111101 | 61 | 3D | = | |
00111110 | 62 | 3E | > | |
00111111 | 63 | 3F | ? | |
01000000 | 64 | 40 | @ | |
01000001 | 65 | 41 | A | |
01000010 | 66 | 42 | B | |
01000011 | 67 | 43 | C | |
01000100 | 68 | 44 | D | |
01000101 | 69 | 45 | E | |
01000110 | 70 | 46 | F | |
01000111 | 71 | 47 | G | |
01001000 | 72 | 48 | H | |
01001001 | 73 | 49 | I | |
01001010 | 74 | 4A | J | |
01001011 | 75 | 4B | K | |
01001100 | 76 | 4C | L | |
01001101 | 77 | 4D | M | |
01001110 | 78 | 4E | N | |
01001111 | 79 | 4F | O | |
01010000 | 80 | 50 | P | |
01010001 | 81 | 51 | Q | |
01010010 | 82 | 52 | R | |
01010011 | 83 | 53 | S | |
01010100 | 84 | 54 | T | |
01010101 | 85 | 55 | U | |
01010110 | 86 | 56 | V | |
01010111 | 87 | 57 | W | |
01011000 | 88 | 58 | X | |
01011001 | 89 | 59 | Y | |
01011010 | 90 | 5A | Z | |
01011011 | 91 | 5B | [ | |
01011100 | 92 | 5C | \ | |
01011101 | 93 | 5D | ] | |
01011110 | 94 | 5E | ^ | |
01011111 | 95 | 5F | _ | |
01100000 | 96 | 60 | ` | |
01100001 | 97 | 61 | a | |
01100010 | 98 | 62 | b | |
01100011 | 99 | 63 | c | |
01100100 | 100 | 64 | d | |
01100101 | 101 | 65 | e | |
01100110 | 102 | 66 | f | |
01100111 | 103 | 67 | g | |
01101000 | 104 | 68 | h | |
01101001 | 105 | 69 | i | |
01101010 | 106 | 6A | j | |
01101011 | 107 | 6B | k | |
01101100 | 108 | 6C | l | |
01101101 | 109 | 6D | m | |
01101110 | 110 | 6E | n | |
01101111 | 111 | 6F | o | |
01110000 | 112 | 70 | p | |
01110001 | 113 | 71 | q | |
01110010 | 114 | 72 | r | |
01110011 | 115 | 73 | s | |
01110100 | 116 | 74 | t | |
01110101 | 117 | 75 | u | |
01110110 | 118 | 76 | v | |
01110111 | 119 | 77 | w | |
01111000 | 120 | 78 | x | |
01111001 | 121 | 79 | y | |
01111010 | 122 | 7A | z | |
01111011 | 123 | 7B | { | |
01111100 | 124 | 7C | | | |
01111101 | 125 | 7D | } | |
01111110 | 126 | 7E | ~ | |
01111111 | 127 | 7F | DEL (Delete) | 删除 |
附录B运算符和结合性
优先级 | 运算符 | 名称或含义 | 结合方向 | 说明 |
---|---|---|---|---|
1 | [] | 数组下标 | 左到右 | |
() | 圆括号 | |||
. | 成员选择(对象) | |||
-> | 成员选择(指针) | |||
2 | - | 负号运算符 | 右到左 | 单目运算符 |
(类型) | 强制类型转换 | 单目运算符 | ||
++ | 自增运算符 | 单目运算符 | ||
– | 自减运算符 | 单目运算符 | ||
* | 取值运算符 | 单目运算符 | ||
& | 取地址运算符 | 单目运算符 | ||
! | 逻辑非运算符 | 单目运算符 | ||
~ | 按位取反运算符 | 单目运算符 | ||
sizeof | 长度运算符 | 单目运算符 | ||
3 | / | 除 | 左到右 | 双目运算符 |
* | 乘 | 双目运算符 | ||
% | 余数(取模) | 双目运算符 | ||
4 | + | 加 | 左到右 | 双目运算符 |
- | 减 | 双目运算符 | ||
5 | << | 左移 | 左到右 | 双目运算符 |
>> | 右移 | 双目运算符 | ||
6 | > | 大于 | 左到右 | 双目运算符 |
>= | 大于等于 | 双目运算符 | ||
< | 小于 | 双目运算符 | ||
<= | 小于等于 | 双目运算符 | ||
7 | == | 等于 | 左到右 | 双目运算符 |
!= | 不等于 | 双目运算符 | ||
8 | & | 按位与 | 左到右 | 双目运算符 |
9 | ^ | 按位异或 | 左到右 | 双目运算符 |
10 | | | 按位或 | 左到右 | 双目运算符 |
11 | && | 逻辑与 | 左到右 | 双目运算符 |
12 | || | 逻辑或 | 左到右 | 双目运算符 |
13 | ?: | 条件运算符 | 右到左 | 三目运算符 |
14 | = | 赋值运算符 | 右到左 | 双目运算符 |
/= | 除后赋值 | 双目运算符 | ||
*= | 乘后赋值 | 双目运算符 | ||
%= | 取模后赋值 | 双目运算符 | ||
+= | 加后赋值 | 双目运算符 | ||
-= | 减后赋值 | 双目运算符 | ||
<<= | 左移后赋值 | 双目运算符 | ||
>>= | 右移后赋值 | 双目运算符 | ||
&= | 按位与后赋值 | 双目运算符 | ||
^= | 按位异或后赋值 | 双目运算符 | ||
|= | 按位或后赋值 | 双目运算符 | ||
15 | , | 逗号运算符 | 左到右 |