第一章–引言
1.1、C 语言的基本概念
- C语言是由函数组成的(包括系统函数和用户自定义的函数)
- C程序有且只有一个main()函数,程序从main函数开始运行,main函数结束,则程序结束。
1.2、程序与程序设计语言
- 计算机程序:是人们为了解决某种问题用计算表及可以识别的代码编排的一系列的数据处理步骤。
- 程序在计算机中是以0,1组成的指令码来表示的,即,程序是0,1组成的序列。
1.2.2、程序设计语言的 功能
- 程序设计语言必须有数据表达和数据处理(或者成为控制)的能力。
- 数据表达:
- 数据类型:就是对有些具有共同特点的数据集合的总称。包括数据类型的定义域、操作。
- 基本数据类型:整型、实型(浮点型)、字符型等。
- 基本数据类型在程序中有两种表现形式:常量和变量。
- 常量:常量值在程序中不变,例如整型常量123
- 变量:变量是在程序中存储数据的地方,其值可以通过操作改变。由类型名和变量名组成:int i = 0;
- 其他复杂数据类型:数组、结构、文件、指针等
- 流程控制:
- C语言的设计方法:将程序划分为若干个互相独立的模块,使完成每个模块的工作变得单纯而明确。也就是结构化的程序设计方法。模块既可以是语句也可以是一段程序或者一个函数。
- C语言的三种控制结构:顺序、分支结构、循环结构。
- 顺序:一个模块完成后自动执行下一个模块
- 分支结构:又称为选择结构,根据不同的条件来选择执行的模块
- 循环结构:有条件的重复执行某些模块,如果条件满足则就执行该模块。
1.2.3、程序设计的语言
C语言的主要语法要素:
- 标识符:由数字、字母、下划线组成,第一个字符必须是字母或者下划线。
- 标识符又包括保留字和用户自定义标识符
- 保留字:又称为关键字,是有特殊含义专门用途的标识符。包括数据类型相关(int ,float,char,typedef)以及语句相关(if,else,while,for,break)等。
- 用户自定义标识符:用户自定义的变量名,数据类型名,函数名和符号常量。
- 表达式:运算符与运算对象的有意义组合 2+3*4
- 语句:是程序最基本的执行单位,一般以分号结尾
- 输入输出:C语言没有输入输出语句,依靠函数完成输入输出功能,printf()、scanf()
1.3、C语言的 发展和历史特点
- 优点:功能强、语句表达简练、数据结构丰富灵活、程序时空开销小,既有通用程序设计语言的特点又有高级语言没有的低层操作能力;不但可以编写系统软件又可以编写应用软件。
- 特点:
- **C语言是一种结构化语言;**函数是C语言的基本结构模块,程序操作有不同功能的函数完成,C语言提供了一套完整的控制语句和构造构造数据类型机制,使程序具有良好的结构性。
- **C语言语句简洁紧凑,使用灵活方便;**C语言一共有32个保留字,九种控制语句,程序书写形式自由,压缩了一切不必要的成分;例如++ --表示加一减一,三目运算符可以表示if语句,一行可以书写多个语句,一个语句也可以书写在不同行上。
- **C语言程序易于移植;**C语言将于硬件有关的因素从语言主体上分离,通过库函数调用实现。例如不把输入输出作为语句,而是作为库函数调用,极大提高了可移植性。
- **C语言有强大的处理能力;**C语言引入了结构指针、地址、位运算、寄存器等功能,提高了语言处理能力。
- 生成的目标代码质量高,运行效率高;
- 不足:
- 数据类型检查不合格
- 表达式出现二义性
- 不能自动检查数据越界
C语言程序编写步骤:
- 编辑代码,生成源程序(后缀为 .c)
- 编译,生成二进制目标程序(.obj)
- 连接库函数,生成可执行程序(.exe)
- 运行与调试
第二章-----用C语言编写程序
2.1、变量,常量,数据类型
-
变量:其值可以改变的量
-
常量:其值不可以改变的量
-
变量使用:必须先定义后使用,
定义格式为: 类型名 变量名
-
数据类型:int ,char,double(双精度浮点型),float(单精度浮点型)
-
double型:数据占用空间大,精读更高,取值范围更大。
常量是程序里直接写出的数据,包括各种整数,浮点数,字符和字符串
-
整数常量
通常由一串数字组成,其中根据类型可以分为八进制十进制和十六进制整数;
-
浮点数常量
由一组数字一个小数点和另一组数字组成
科学计数法表示:浮点数常量+e+整数 1.4E-2 == 1.4*0.01
-
字符常量:
是指单个字符,用单引号括起来
-
字符串常量
有一对双引号括起来的0个或多个字符组成,以\0结尾
2.2、算数运算和赋值运算
算数运算:
- 整数 / 整数 还是整数
- 取余运算只能用于整型数据,不能用于实型
- 双目运算符两侧数据类型要相同,否则会进行类型转换
赋值运算:
- 赋值运算左边必须是变量
- 过程
- 先计算右边表达式的值
- 将右边表达式的值复制给左边的变量
2.3、格式化输出函数printf()
-
C语言中输出是通过调用函数实现的。
-
printf是系统提供的库函数,在stdio.h中声明。
-
格式:
printf(格式控制字符,输出参数1,输出参数2·····);
-
格式控制符:以%开头,按照指定格式输出数据
int --%d, float,double----%f.
-
输出参数必须和格式控制符相对应,并且位置、类型、个数要一一对应。
2.4、格式化输入语句scanf()
-
C语言中输出是通过调用函数实现的。
-
系统提供的库函数,在stdio.h中声明。
-
格式:
scanf(格式控制字符串,输入参数1,输入参数2······);
格式控制符表示输入的格式,输入参数是变量地址前面需要加&。
-
格式控制说明:以%开头,按指定格式输入数据。
int — %d, float — %f, double — %lf
-
输出参数必须和格式控制符相对应,并且位置、类型、个数要一一对应。
2.5、常用数学函数
调用数学函数需要加入#incluide<math.h>
- 平方根函数 sqrt(x)
- 绝对值函数 fabs(x) | x |
- 幂函数 pow(x,n) x 的 n 次方 x ^ n
- 指数函数 exp(x) e 的 x 次方 e ^ x
- 以e为底的对数函数 log(x) lnx
2.6 C语言的注释风格
- /* */ 多行注释
多行注释可以跨越多行,但是不允许套用嵌套,即使前面有多个 /* 在遇到第一个*/的时候就会结束注释。
- // 单行注释
第三章 ---- 分支结构
1、字符型数据
- 字符型常量:
- 单个字符
- 用单引号括起来
- 每个字符都有唯一的ASCII码
- 字符型变量:
- 定义: char a;
2、字符型数据的输入输出
- 可以使用 scanf(),printf()和getchar(),putchar()
- scanf(),printf() 字符数据格式控制符为 %c
- 字符输入函数getchar():
- 调用格式:ch = getchar();
- 每次只能读入一个字符,多次输入就得多次调用,一般再循环中使用。
- 字符输出函数putchar():
- 调用格式:putchar(ch);
- 功能是输出字符型变量或者常量
第四章 – – 循环结构
1、for while do-while 三种循环的区别:
-
for循环:
- 形式 : for(表达式;表达式2;表达式3){循环体}
- 流程:先计算表达式1,然后判断表达式2,进入循环体,计算表达式三;
-
while循环:
- 形式: while(表达式){ 循环体}
- 流程: 判断表达式是否为真,然后进入循环体,直到表达式为假。
- 注意:表达式避免永真或者永假。
-
do-while循环:
- 形式:do {循环体} while (表达式);
- 流程:先进入循环体,执行,然后判断表达式真假,真则继续执行,直到为假退出。
-
三种循环的区别:
- for 和 while 运行机制一样,选判断表达式真假,在进入循环体执行。do-while 则是现进入循环体执行一次,在判断表达式的值。
- 指定循环次数用for更清晰,没有指定 多用为while。
break用于跳出一个循环体或者完全结束一个循环,不仅可以结束其所在的循环,还可结束其外层循环。
注意:
(1)只能在循环体内和switch语句体内使用break。
(2)不管是哪种循环,一旦在循环体中遇到break,系统将完全结束循环,开始执行循环之后的代码。
(3)当break出现在循环体中的switch语句体内时,起作用只是跳出该switch语句体,并不能终止循环体的执行。若想强行终止循环体的执行,可以在循环体中,但并不在switch语句中设置break语句,满足某种条件则跳出本层循环体。
2、continue语句的作用是跳过本次循环体中剩下尚未执行的语句,立即进行下一次的循环条件判定,可以理解为只是中止(跳过)本次循环,接着开始下一次循环。
注意:
(1)continue语句并没有使整个循环终止。
(2)continue 只能在循环语句中使用,即只能在 for、while 和 do…while 语句中使用。
第五章 — 函数
-
函数是一个完成特定工作的独立程序模块,包括库函数,和自定义函数
-
一般形式:
函数类型 函数名(形式参数) ------ 函数头部
{
函数过程 --------- 函数体
}
-
函数首部:函数首部由函数类型,函数名,形参表组成,位于函数的第一行,后边不加分号,函数名是韩式的成为或者名字,函数类型,是指函数的返回类型,一般与后面return返回语句的类型一致。形参表格式为: 类型 形参 ,其类型不可省略。
-
函数的调用:
调用库函数只需要在程序的最前面用#include导入即可
使用自定义函数,程序中需要有与调用函数相对应的函数定义,
调用过程:先从主函数开始运行,遇到函数调用就进入该函数知道return返回结果,执行完之后进入主函数继续执行。
通常将主函数称为主调函数,被调用的函数称为被调函数。
-
参数传递:
函数定义时,位于其首部的参数称为形参,主调函数的参数称为实参。
实参可以是,常量,变量,表达式。形参为变量
实参与形参,一一对应,数量相同类型一致。,调用时,实参的值传给形参。
实参 ----形参传输过程是单向的,只允许将实参传递给形参。
函数中return语句的作用:结束函数的运行,返回结果。return语句只能返回一个值。
-
函数声明:
C语言要求先定义后调用。
目的主要是说明,函数的类型和参数的情况,以保证程序编译时能判断调用是否正确。
函数声明格式与函数定义的第一句相同。
函数定义语句后边不加分号,函数声明需要加分号。
结构化的程序设计思想
结构化的程序设计强调,程序设计的风格和程序结构的规范化,提倡清晰地结构,七基本思路是将一个复杂的问题求解过程划分为若干个阶段。每个阶段分别去处理不同问题。
-
自顶向下分析问题的方法
就是把大的复杂的问题分解成小问题后在解决
-
模块化设计
需要将米快组织成良好的层次系统。顶层模块调用其下层的模块以实现程序的完成功能。
原则:
- 一个模块只完成一个指定的功能
- 模块之间值通过参数进行调用
- 一个模块只有一个出口和入口
- 模块内慎用全局变量
在C语言中,模块一般通过函数来实现,一个函数对应一个一个模块
-
结构化编码主要原则
- 经模块化设计后,每一个模块都可以独立编码。
- 对变量、函数、常量等命名时,要见名知义,有助于对变批含义或函数功能的理解。
- 在程序中增加必要的注释,增加程序的可读性
- 要有良好的程序视觉组织, 利用缩进格式,一行写一条语句, 呈现出程序语句的阶梯方式,使程序逻辑结构层次分明、结构清楚、错落有致、更加清晰。
- 程序要清晰易懂,语句构造要简单直接。
- 程序有良好的交互性,输入有提示,输出有说明,并尽量采用统一整齐的格式。
全局变量和局部变量:
-
局部变量:
C语言中把定义在函数内部的变量成为局部变量,局部变量的有效范围局限于函数内部,,,形参就是局部的变量
-
全局变量:
定义在函数外部不属于所有函数的变量称为全局变量。
变量的生存周期:
变量从定义 开始分配存储单元,到运行结束存储单元被回收,整个过程称为变量的生存周期。全局变量的生存周期为整个程序的执行周期。
静态变量 static
静态变量存放在静态存储区,声明周期持续到程序结束,静态变量定义时没有赋值,系统将自动自动赋值0。静态局部变量受变量作用范围限制,不能用于其他函数。
第七章 — 数组
- 数组:
数组时最基本的构造类型,他是一组相同类型数据的有序集合。数组中的元素在内存中连续存放,每个元素都属于同一种数据类型,用数组名和下标可以唯一确定数组元素。
- 数组的的定义:
形式:
类型名 数组名 [数组长度]
类型名为数组中元素的数据类型,数组名是数组的名称,是一个合法的C语言标识符;数组长度是一个整型常量的表达式,表示数组的大小。
其中数组名是一个地址常量,表示首地址,不允许更改。
- 数组的引用:
C语言规定,只能引用单个数组元素,而不能一次引用整个数组。
形式:
数组名 [下标]
其中数组下标从0开始,不能越界,取值范围(0----数组长度-1)
- 二维数组的定义:
C语言支持多维数组,最常见的就是二维数组,常用于表示二维表和矩阵
定义形式:
类型名 数组名 [行长度] [列长度]
int a [3] [3]
- 二维数组的引用:
形式:
数组名 [行下标] [列下标]
取值范围均为 (0----长度-1)
- 二维数组中的特殊定义:
对角线 : i == j
上三角: i <= j
下三角: i >= j
副对角线: i+j = N-1 (N行N列)
一维字符数组:
一维字符数组用于存放字符型数据,在定义初始化引用与其他的类型一致
char c [30]
字符串:
字符串常量就是用一对用双引号括起来的字符序列,即一串字符,以‘\0’为结束标志,处理‘\0’是结束字符以外,其余的字符称为有效字符
字符串的长度就是有效字符的个数
C语言将字符串作为一个特殊的一维字符数组来处理、
将字符放入数组时,由于有一个结束符号,所以数组长度至少是字符串的有效程度+1
第八章 — 指针
指针:
C语言中把专门存放变量地址的的变量称为指针变量,简称指针。
指针变量的定义:
类型名 * 指针变量名 int *p
注:定义多个指针变量时,每一个指针变量前面都必须加上*
指针变量也要先赋值在使用
参数传递:
C语言中实参和形参的数据传递为单向的“值传递”,调动函数不能改变实参变量的值,
指针变量也遵守这一原则,调用函数无法实现改变实参变量的值,但是可以改变实参指针变量所指向的值,。
这样的机制被称为引用调用。
采用引用调用机制,需要在函数定义时将指针变量作为函数的形参,调用时把变量的地址作为实参。
指针和数组:
相似之处:
指针名和数组名都代表着内存地址
不同之处:
指针名是一个变量,数组名是一个常量。,指针名所代表的的地址是可以改变的,而数组一旦被定义后,内存空间就被分配不能改变。
数组名本身就是一个地址也就是指针
字符串:
字符串是一种特殊的char型一维数组,字符串常量是用一对双引号括起来的字符序列,与基本数据类型常量相似。
由于字符串是一串字符,通常被看成特殊的一维数组,其中所有字符在内存中连续存放,
字符串常量实质上就是一个指向该字符串首字符的指针常量
如果定义了一个字符指针接受字符串常量的值,该指针就指向字符串的首字符。
常用的字符串处理函数:
字符串输入输出:
gets()、puts()
printf()、scanf();
gets(s):
参数S是字符数组名。函数从输入得到一个字符串,遇到回车结束,自动将输入的数据和‘\0’,送入数组中。采用getS函数输入的字符串允许带空格。
puts(s):
参数S可以是字符数组名或者字符串常量,输出时遇到‘\0’自动将其转换为’\n’,即输出之后自动换行。
区别:
printf和puts的区别:
在于puts函数输出后自动换行。
scanf和gets函数的区别:
scanf()函数遇到空格会自动结束输入,gets()函数遇到回车结束输入。
scanf()函数只能输入不带空格的字符串,而后者却没有这个限制
字符串复制函数 strcpy(str1,str2);
该函数将字符串2的内容复制到字符串1,知道遇到字符串的‘\0’停止。字符串1要有足够的空间容纳字符串2,且字符串1的内容被覆盖,函数返回的是字符串1,其中参数1,必须是字符型数组基地址,参数2可以是字符数组名或者字符串常量。
字符串连接函数 strcat(str1,str2);:
参数1必须为字符数组基地址,参数2可以是字符数组名或者字符串常量。函数将字符串2接到字符串1的后边,此时参数1的结束符‘\0’被放置到连接后的结束位置上。
字符函比较函数strcmp(str1,str2):
函数中参数1和参数2可以是字符数组名或者字符串常量,函数返回一个整数:
str1 = str2 …,返回0;
str1 > str2 …返回正数
str1 < str2 … 返回负数;
第九章 — 结构
结构:
是一种特殊的数据类型,可以把不同的数据类型汇聚成一个整体使其相互关联,同时结构也是一个变量的集合。
一般形式:
struct 结构名{
类型名 结构成员名1;
类型名 结构成员名2;
};
其中结构成员业绩也叫结构分量;
在定义嵌套的结构时,需要先定义成员结构的类型,在定义主结构类型。
结构的定义:
struct 结构名{
类型名 结构成员名1;
类型名 结构成员名2;
}结构变量表名;
结构变量成员的引用:
结构变量名.结构成员名
第十章 — 函数与程序结构
结构化程序设计方法原则:
- 自顶向下:设计程序是应该先考虑总体步骤,然后考虑步骤的细节;先考虑全局,在考虑局部;
- 逐步求精:对于复杂的问题,其中大的操作步骤应该再将其分解为一些子步骤,逐步实现程序;
- 函数实现:根据逐步求精,把函数很为一个个的子步骤,每个子步骤的最终目标就是用一个个的函数来处理问题;
函数可以是问题解决过程局部化,函数 设计应注意以下的问题:
- 限制函数长度:一个函数语句不宜太多,便于阅读,理解,方便调试以及后期维护;
- 避免函数间功能重复:应当将函数封装成一个个独立的功能,达到一处定义,多处使用。
- 减少区局变量的使用:函数应该尽量使用局部变量,通过蚕食与返回值与外部进行交互,只有多个函数需要共享数据时才时使用全局变量
宏定义:
#define
格式:
#define 宏名 宏定义字符串
宏名通常由大写字母组成,宏名与宏定义之间用空格分开,在程序编译时,所有出现宏名的地方,都会用宏定义字符串替换,所以宏也叫宏替换。
文件包含:#include
包含的作用是把指定的文件模块插入到程序中,文件包含头为#开头,表示为编译预处理。因此include不算是真正意义上的c语言语句;
格式分为#include<> 和#include“”两种形式,如果使用尖括号,将会使用C语言的标准头文件,由编译程序到c系统中设置好的include文件中到指定的文件包含进来;
如果使用双引号,则编译程序首先到当前文件夹寻找被包含的文件,若找不到,再到系统文件中查找,一般适用于编程者自己的头文件使用;
编译预处理:
编译预处理是C语言编译程序的组成部分,它用于解释处理C语言源程序的中的个种预处理命令,以#开头,不属于C语言的语句,但是增强了C语言的编程功能,改进了C语言程序设计环境,提高了编程效率。
程序、程序文件模块、函数的关系 :
一个大的程序由多个程序文件模块组成,一个程序文件模块由多个函数组成,程序文件模块只是韩式书写的载体;
外部变量:
声明格式:
extern 变量名表;
他只起到说明作用,不会分配存储单元,对应的存储单元在去全局变量定义时 分配;
静态全局变量:
作用:用于限制全局变量作用域的扩展;
第十二章 — 文件
在操作系统中,,文件是指驻留在外部介质中的一个有序数据集,可以是源文件、目标程序文件、可执行文件,也可以是待输入的原始数据,或是一组输出的结果。
源文件,目标文件和可执行文件可以成为程序文件
输入输出的数据可称为数据文件,数据文件还可分为各种类型,如文本文件,图像声音文件等;
在C语言中,按照数据存储的编码形式,数据文件可以可以分为文本文件和二进制文件。
文本文件是存储ASCLL码的编码文件,其文件内容就是字符,
二进制文件是存储二进制数据的文件。
C语言的源程序是文本文件,其内容由ASCLL码组成
C语言的目标文件和可执行文件是二进制文件,由机器代码组成
缓冲文件系统:
在进行文件操作时,系统会自动为每个文件分配一块文件内存缓冲区,c程序对文件的所有操作就通过对文件缓冲区的操作来完成。
文件类型指针:
FILE文件结构,其成员指针指向文件的缓冲区,通过移动指针来实现对文件的定位操作。
格式:
FILE *fp
其中FILE是文件类型定义符,fp是文件类型的指针变量;
用C语言编写文件操作的程序的步骤:
- 定义文件指针;
- 打卡文件:文件指针指向磁盘文件缓冲区;
- 文件处理:文件读写操作;
- 关闭文件;
打开文件:
fopen(“文件名”,"文件打开方式’');
执行标准函数fope(),计算机完成以下步骤:
- 在磁盘中找到指定文件;
- 在内存中分配保存一个file类型结构的单元
- 在内存中分配文件缓冲区单元
- 返回FILE结构地址
关闭文件:
fclose(文件指针);
该函数返回一个整数,如果返回值为0,那么表示正常关闭文件
操作完成时应及时关闭文件:
- 确保数据完整写入文件
- 及时释放不用的文件缓冲单元
常用的文件操作函数:
-
字符方式文件读写函数fgetc() 和fputc()
fgetc()函数实现从fp所指示的磁盘文件读入一个字符到ch
ch = fgetc(fp);
fputc()函数实现把一个字符ch写到磁盘文件上
fputc (ch,fp)
-
字符串方式文件读写函数fgets()和fputs()
fgets()函数实现从文本文件中读取字符串
fgets(s,n,fp)
s是字符数组名或者字符指针,n是指定读入字符的个数,fp是文件指针
fputs()函数实现向指定文本文件写入一个字符串
函数实