目录
第1~8章_基础篇(数据类型、运算符、输入输出、流程控制、数组字符串、函数、指针。)
第9~12章_技术篇(结构体、链表、位运算、宏定义。)
第13~15章_提高篇(文件处理、调试、绘图函数。)
第16~18章_实践篇(俄罗斯方块、Ping测试、学生成绩管理系统。)
C语言的设计目的是取代汇编语言,结构式语言:代码和数据分离。
第2章_算法和数据类型
(算法的概念和表示、数据类型、常量和变量、初始化、类型转换)
程序的两个部分:数据结构、算法。
数据结构:指定数据的类型和数据的组织形式。
算法:为解决一个问题而采取的方法和步骤。
计算机算法分为两类:数值运算、事务管理。
闰年的两个判断条件:能被4整除但不能被100整除、能被100和400整除。
流程图的3种结构:顺序结构、选择结构、循环结构。
C语言数据类型4大类:基本数据类型、构造数据类型、指针类型、空类型。
基本类型:整型(int)、实型(float、double)、字符型(char)、枚举型(enum)。
构造数据类型:数组、结构体、共用体。
指针的值用来表示变量在内存中的地址。
函数的返回值可以为空类型。
数据类型的取值范围有两种:常量、变量。
#define预处理命令可以放于源代码的任何位置。
关键字const定义常量,常量初始化表达式不能包含函数。
sizeof(int)不是函数,是基本操作符。
DevCpp中char的大小是1Byte,int的大小是4Byte,float的大小是4Byte,double的大小是8Byte。
short是2Byte,long是4Byte。
静态变量static和常量const的区别?
寄存器变量register、外部变量extern。
整数的表示形式:8进制以0为前缀、16进制以0x为前缀、10进制无前缀。
int类型整数的取值范围为-32768——+32767。
无符号整数的后缀为u,长整数的后缀为L。
实数的两种十进制表示形式:十进制小数形式、指数形式(-2.8×10-2=-2.8E-2)。
Float型数据在计算时先转换为double类型的。
字符常量使用单引号,如:’a’。
转义字符:\n,\t,\b,\r,\f,\\,\’,\”,\a,\ddd,\xhh。
\r:移动到本行的行首,\n:移动到下一行的行首。
字符串常量用双引号,如:”hello”。
字符常量’a’占1Byte,字符串常量”a”占2Byte,其中包含结束符’\0’。
字符常量放入字符变量中,是将字符所对应的ASCII码值放入存储单元。
字符可以以字符形式输出,也可以以整数形式输出。
大小写字母的ASCII码相差32。
变量的初始化定义中不允许连续赋值。
数据类型的转换有两种:自动类型转换、强制类型转换。
赋值号右边量的类型转换为左边量的类型。丢失部分按四舍五入向前舍入。
第3章_运算符和表达式
(运算符的种类。)
10类运算符:算术运算、关系运算、逻辑运算、位操作、赋值、三目运算符、逗号运算符、指针、求字节、下标。
算术运算符是左结合性、赋值运算符是右结合性。
运算符优先级分为15级。
i++先运算后自增,++i先自增后运算。
将小写字母变成大写字母,用x+’A’-’a’来计算。
将大写字母变成小写字母,用x+’a’-A’来计算。
复合赋值运算符的好处:简化程序,提高编译效率。
复合赋值运算符右边的表达式是一个运算“整体”,不能分开。
如:a*=b+1等价于a=a*(b+1)
赋值表达式:a=2,计算a+=a-=a*a。
首先计算a=a-a*a=-2,然后计算a=a+a=-2+(-2)=-4。
判断x和y是否相等-->判断x与y的差的绝对值是否在一定误差范围内。
即fabs(x-y)<1.06E-6
括号里的逗号表达式的值。
良好的编程习惯:注释、嵌套层数、控制语句的选择、合理的命名规则。
注释:注释变量名、函数名、函数作用。精简的主函数和少量的函数调用。
第4章_数据的输入输出
(gets()。)
语句是一条完整的指令。
变量说明时不允许连续给多个变量赋初值,赋值语句允许连续赋值。
scanf( )、printf( )、getchar( )、putchar( )、gets( )、puts( )。
格式字符串的一般格式:%[标志][输出最小宽度][.精度][长度]格式字符。
在printf函数中的格式控制字符串中用连续两个%%来输出字符’%’。
对于输入语句:scanf(“%4d%4d”,&a,&b);如果输入12345678,则a=1234,b=5678。
对于输入语句:scanf(“%d,%d,%d”,&a,&b,&c);如果格式控制字符串中有非格式字符,则在输入时也要输入该非格式字符。
输入的字符过多会造成gets( )函数的缓冲区越界。
第5章_流程控制
顺序结构、选择结构、循环结构。
switch( )语句中可以省略default字句。
尽量避免使用goto( )语句。
main( )函数结束时,隐式调用exit( )函数。
程序员的职业发展:产品经理、项目经理、技术架构师。
第6章_数组和字符串
当数组下标为小数时、编译器自动取整。
C语言中,二维数组是按行排列的。
杨辉三角。
字符数组的初始化赋值:char c[]={‘c’,’ ‘,’p’,’r’,’o’,’g’,’r’,’a’,’m’};
Char c[]=”C program”;
字符串处理函数:strlen( )计算除字符串结束标记外的所有字符的个数。
strupr( ),strlwr( ),strcpy( ),strcmp( ),strcat( ),atoi( ),atol( ),atof( )。
第7章_函数
函数的分类:库函数、用户自定义函数。是否有返回值、是否有参数。
编译系统不会为形参数组分配内存,数组名作函数参数,传送的是地址。
形参数组与实参数组共用一段内存空间。
形参数组和实参数组的长度可以不同。
多维数组名作为参数,第一维的长度可以省略,第二维和其他更高维的长度不可以省略。
对称矩阵的转置,最大公约数(辗转相除法)和最小公倍数。
函数的嵌套调用和递归调用。
小程序:输出句子中最长的单词、弦截法求方程的根、汉诺塔问题:可视化处理,表示成矩阵。
已知直线上的两点(ax,ay)、(bx,by),则直线与x轴交点的横坐标为x=(axby-aybx)/(by-ay)
给定自变量x的范围,步长为1,求出因变量y的取值范围,再确定根的区间。
用柱子的长度表示柱子上盘子的个数,用盘子的编号来表示盘子的大小
每个柱子都是一个数组、数组头部开始存放盘子的编号。从数组末端向下打印。
按行打印,柱子A中数组末端盘子的大小,制表符,柱子B中数组末端盘子的大小。
柱子上盘子的显示函数。
递归调用会降低程序的运行效率。
局部变量、全局变量、文件变量。
主函数中定义的变量只能在主函数中使用。
使用外部变量增加函数的返回值。
局部变量与外部变量同名时,局部变量屏蔽外部变量。
变量的生存期和作用域。
静态存储变量和动态存储变量。
C语言中的四种变量存储类型。
auto:自动变量。register:寄存器变量。extern:外部变量。static:静态变量。
自动变量和寄存器变量属于动态存储方式、外部变量和静态变量属于静态存储方式。
C语言中变量的默认存储类型为自动变量。
静态变量:局部变量中的值在函数调用结束后能保留原值。
静态变量存放在内存中的静态存储区,编译系统为其分配固定的存储空间。
静态函数会被自动分配在一个一直使用的存储区,直到退出应用程序实例,避免调用函数时压栈出栈,提高速度。
内部函数又被称为静态函数。函数的作用域仅限于本文件。
外部静态变量(静态外部变量)只能在本文件中使用。
静态局部变量的特点:
函数内的静态局部变量,生存期为整个源程序,作用域中函数内。
系统自动为静态变量赋初值。
非静态全局变量的作用域是整个源程序,在各个源文件中都有效。
静态全局变量的作用域局限于一个源文件内。
寄存器变量register加快存取时间,提高程序执行效率。(循环控制变量、循环体内反复使用的变量)
静态函数:函数的作用域仅限于本文件。
声明的作用是把函数的属性通知给编译器,以便在调用该函数时系统按此进行对照检查。
函数声明中也可以不写形参名,而只写形参的类型。
模块化设计:求解复杂问题时采用逐步分解、分而治之的方法。
模块划分是一个自上而下的过程,各模块具有相对的独立性和完整性。
主要明确模块的基本功能、输入、输出、数据结构、模块间的关系、接口参数、公共数据。
第8章_指针
变量的指针就是变量地址,指针变量存放变量的地址。
指针变量的声明格式:指针类型 *指针名称;
指针变量只能指向对应类型的变量地址。
指针类型可以强制转换,同类型的指针可以相互赋值。
常量指针是指向常量的指针。
把数组的首地址赋给指针变量:int a[5],*ptr;ptr=a;
把字符串的首地址赋给指针变量:char *ptr;ptr=”hello world!”;
把函数的入口地址赋给指针变量:int (*ptr)();int func(int a,int b);ptr=func;
数组下标是一种运算符,是一种计算地址和引用内存单元的方法。
定义指针变量时应初始化为空:int *p=null;
静态指针长期占用内存,不随函数的执行结束而释放。不能将动态变量的地址赋值给静态指针变量。
不能将寄存器变量赋值给指针变量。
指向一维数组的指针变量的定义:指针类型 (*指针名)[一维数组长度]。
三层for循环实现矩阵的乘法运算。
8.5_指针和字符串
8.5.1_指针访问字符串
用指针访问字符串(strcpy函数的实现),表达式while((*pa=*pb)!=‘\0’)的用法。
进一步优化:while((*pa++=*pb++)!=‘\0’)。
8.5.2_字符串指针作为函数参数
使用函数调用实现字符串的复制。
while(a[i]!=‘\0’){b[i]=a[i];i++;} b[i]=‘\0’;
8.5.3_使用字符串指针变量与字符数组的区别
字符数组只能逐个元素赋值。
数组可以在变量定义时整体赋初值:char str[20]={“This is a car.”};
8.6_指针数组和多级指针
指针数组中的每个变量都是指针变量。
8.6.1_指针数组
1_指针数组的定义:指针类型 *指针名[长度];
2_指针数组元素的引用
8.6.2_多级指针的定义和应用
二级指针的定义:指针类型 **指针名;
二级指针的赋值:int c,*p,**ptr;p=&c;ptr=&p;
字符串排序。
8.6.3_指向指针的指针
单级间址、二级间址。
8.6.4_main函数的参数
C语言规定:main函数的第一个参数必须是int类型的参数,int argc。
第二个参数必须是指向字符串的指针数组char *argv[ ]。
第一个参数表示命令行中参数的个数,文件名本身也算一个参数。
8.7_指针函数和函数指针
指针函数的返回值是int型,int * 指针函数名(函数形参列表)
函数指针是指向函数地址的指针。
在C语言中,用函数名称代表函数的首地址。
函数指针可以作为函数参数。
第二篇_核心技术篇
第9章_结构体、共用体和枚举
9.1_结构体
结构体成员可以是基本数据类型,也可以是构造类型。
9.1.1_定义结构体类型
Struct关键字 结构体名{ 成员列表};最后的分号不可以省略。
9.1.2_结构体类型变量的定义
C语言中所有数据类型遵循“先定义后使用”的原则。
结构体类型变量定义的三种方式:先定义结构体后定义变量、定义类型同时定义变量、直接定义变量。
9.1.3_结构体变量的引用
结构体与数组的差异:数组名是一组元素存放区域的起始位置,是地址量;
结构体变量名只代表一组成员,它不是地址量而是一种特殊变量。
1_结构体变量中成员的引用
结构体变量的地址可以作为函数参数,传递结构体地址。
2_结构体变量作为整体的引用
仅限于赋值。
9.1.4_结构体变量的初始化
基本数据类型成员变量的初始化默认值:int(0)float(0.0)double(0.0)
Char(‘\0’)char str[n](“”)int xyz[n](0,0,···,0)
9.2_结构体数组
结构体数组中的所有元素均为结构体变量。
9.2.1_结构体数组定义
结构体数组的三种定义方法:
先定义结构体类型再定义结构体数组、定义结构体类型时定义结构体数组、直接定义结构体数组。
9.2.2_结构体数组的初始化
9.2.3_结构体数组的引用
1_数组元素的引用
2_数组的引用
9.3_结构体指针
9.3.1_结构体指针变量的定义
结构体指针变量定义的三种格式。
9.3.2_结构体指针变量的初始化
9.3.3_结构体指针变量的引用
9.3.4_指向结构体变量的指针
9.3.5_指向结构体数组的指针
9.4_结构体和函数
9.4.1_结构体变量和结构体指针作为函数参数
结构体指针作为函数参数,可以减少传送结构体中成员数组的时间和空间,降低开销,提高程序效率。
9.4.2_返回结构体类型值的函数
9.5_共用体
共用体中的成员在内存中占用同一段存储单元。
9.5.1共用体和共用体变量的定义
使用关键字union标识共用体类型
9.5.2_共用体变量的引用与初始化
共用体成员不能同时使用。
共用体不能作为函数参数,也不能作为函数的返回值。
9.5.3_结构和共用体的区别
9.6_枚举
描述有限个元素的集合。
9.6.1_定义枚举类型
关键字是enum。
9.6.2_定义枚举变量
先定义枚举类型,再定义枚举变量。
定义枚举类型,同时定义枚举变量。
9.6.3_枚举变量的引用
9.7_用typedef定义类型
Typedef的目的是为已知数据类型增加新名称,并没有引入新的数据类型。
第10章_链表
10.1_动态内存分配
10.1.1_为什么用动态内存分配
10.1.2_如何实现动态内存分配及其管理
4个专用函数malloc、calloc、realloc、free
10.2_链表
链表由一系列节点组成,每个节点包括两部分:数据域、指针域。
10.2.1_链表概述
链表的建立:逐个定义节点,并逐个连接。
10.2.2_单向链表
链表基本操作:创建、插入、删除、遍历。
10.2.3_创建链表
链表中的每个数据对象称为节点Node。
10.2.4_删除整个链表
从第一个节点开始逐个删除。
10.2.5_在链表中插入节点
头插法、尾插法、指定位置插入。
10.2.6_在链表中删除节点
10.2.7_双向链表
三种基本操作:查找、插入、删除。
10.2.8_循环链表
最后一个节点的指针指向第一个节点或表头节点。
表尾判断条件是指针域是否是头节点。
第11章_位运算
11.1_位运算符和位运算
C语言出现之前,使用汇编语言操作硬件,汇编程序体积小,运行速度快。
6种位运算:&、|、^、~、<<、>>。
11.1.1_按位与运算
用途:清零、获取指定位、保留特定位。
11.1.2_按位或运算
用途:设定指定位。
11.1.3_按位异或运算
用途:定位翻转、数值交换。
11.1.4_取反运算
11.1.5_左移运算
高位丢弃,低位补0,二倍乘运算。
11.1.6_右移运算
无符号数,低位丢弃,高位补0,除数为2的整除运算。
11.1.7_符合位运算符
&=、>>=、<<=、^=
11.2_位域
1_位域的定义和位域变量的说明。
位域的长度不能大于1字节。
位域的本质是结构体,但其成员按二进制位分配。
2_位域的使用
第12章_预编译处理
加快处理效率
12.1_预处理概述
预编译处理命令,用于规范和统一不同编译器的指令集合。
3类主要预编译指令:宏定义、文件包含、条件编译。
12.2_宏定义
编译预处理时,用宏定义中的字符串代换程序中所有出现的宏名。
宏定义由源程序中的宏定义命令完成。宏代换由预处理程序自动完成。
12.2.1_不带参数的宏定义
通常将反复使用的表达式进行宏定义处理。
宏代换不检查语法,编译时检查语法。
可以使用宏定义终止命令“#undef”结束先前定义的宏名。
12.2.2_带参数的宏定义
宏定义增长源程序,函数调用不增长源程序。
宏替换占编译时间,函数调用占运行时间。
12.2.3_字符串化运算符
12.2.4_并接运算符
12.3_文件包含
文件包含命令的两种格式:双引号与尖括号。
双引号:查找顺序首先为当前目录,然后是系统指定的“包含文件目录”。
尖括号:直接到系统指定的“包含文件目录”中去查找。
12.4_条件编译
12.4.1_#ifdef……#else……#endif
12.4.2_#if defined……#else……#endif
12.4.3_#ifndef……#else……#endif
12.4.4_#if!defined……#else……#endif
12.4.5_#ifdef……#elif……#elif……#else……#endif