*注:所有加粗仅代表个人角度
文章中可能有的指针部分星号与变量之间有空格,可自行删除,因为我在编辑时发现可能会识别成斜体或加粗,所以我就加了空格
如内容有问题,欢迎给我留言,我会及时更改
部分PPT上的代码没有放上来,可以百度一下相关标题或者自行查看PPT
我整理的教材资源
第一章 C语言基础知识
计算机系统的基本组成
包括计算机硬件和计算机软件。
硬件指构成计算机系统的元器件、部件和设备,其中包括运算器、控制器、存储器、输入和输出设备,运算器和控制器是计算机的核心部分,人们将它们称为中央处理器(CPU)。
软件是用户操纵计算机的接口界面,通常,按照应用层次可以将软件划分成系统软件、支撑软件和应用软件三个层次。
程序设计
是指设计、编写和调试程序的方法与过程,大致经历了以下几个阶段。
1)面向计算机的程序设计
2)面向过程的程序设计
3)面向对象的程序设计
程序设计语言
程序设计语言是用于编写计算机程序的语言。按照语言级别可以将它分为两个类别:低级语言和高级语言。
低级语言是一种与特定计算机体系结构密切相关的程序设计语言,主要包括机器语言和汇编语言。
高级语言是一类采用接近数学语言,并力求与具体机器无关的程序设计语言形式,它具有描述能力强,便于阅读理解,易于修改维护等特点。C语言支持结构化程序设计,C++语言和Java语言支持面向对象程序设计。
C语言本身比较简单,具有简明的数据定义和流程控制机制。开发者可以通过模块的组合来构造结构化的复杂程序,并且允许软件系统不同程序模块的分别开发。C语言支持底层程序设计。
C程序是由若干个函数组成的,每个函数用于描述一项操作的具体实现过程。
任何一个完整的C程序都必须有且仅有一个名为main的主函数。
当程序运行后,系统将率先自动调用主函数。
运行C程序的基本过程
基本数据类型与数据的表示
整型int:用4字节(32位二进制位)表示,包括1位符号,有效位数为31位
实型:常用的实型是双精度型,用double表示。8字节(64位二进制位)表示,包括1位符号,11位指数和52位尾数
字符型char:一对单引号括起来,并且每个字符对应一个ASCII编码,用1个字节(8位二进制位)表示。
Long4字节
Short2字节
Unsigned4字节
(以上三项为个人查阅,有问题不负责)
常量:常量是指在程序运行过程中始终不发生变化的量。
整型常量
实型常量:指数形式:1.87E+10表示1.87×1010
字符常量:一对单引号(‘’)括起来,其内部存储表示是相应字符的ASCII编码。转义符是指用一个反斜杠(\)后跟一个特定字符或一个八进制或十六进制数值表示的字符。例如:\n, \101
字符串常量:字符串常量用一对双引号(“”)括起来。
变量:变量是指其值可以改变的量,每个变量代表了不同的存储单元。
C语言规定:程序中的每一个变量,必须先定义后使用
定义变量的语法格式为:
<数据类型> <变量名>[,<变量名>[,<变量名>…]];
例如:int count;
C语言规定:变量名用标识符表示。标识符是由字母、数字和下划线(_)组成的字符序列,其中第1个字符必须是字母,字母需要区分大小写。
变量的赋值
变量定义之后并没有一个确切的初始值,变量赋值就是将变量所属数据类型的某个数值(介于取值范围之中)放入系统为这个变量分配的存储空间中的操作。
在定义变量的同时为变量赋予一个初始值。
<数据类型> <变量名> = <常量表达式>;
例如:int data = 100;
通过赋值操作为变量赋值。
<变量名> = <表达式>
例如: x = 64;
基本的输入输出
字符的非格式化输入 getchar( )
字符的非格式化输出 putchar( )
格式化输入 scanf( )
scanf(<格式控制字符串>,<变量地址>,<变量地址>… );
例如:scanf(“%d%d%f%f”, &x, &y, &f1, &f2);
常用的格式控制说明符由“%”后跟一个特定字符或字符序列组成“%d”表示这个位置应该输入一个十进制整型数值;“%c”表示这个位置应该输入一个字符;“%f”表示这个位置应该输入一个实型数值,“%ld”表示这个位置应该输入一个长整型数值
<变量地址>是准备用来存放输入数据的变量地址。例如,&a、&value分别表示变量a、value的存储地址
格式化输出 printf( )
printf(<格式控制字符串>,<表达式>,<表达式>…);
例如: printf(“This value is %d\n”, x);
printf( )函数的基本功能是将每个表达式的结果按照格式控制说明符的规则显示到标准输出设备——显示器上。格式控制说明符需要与将要输出的表达式一一对应。
人们希望能够更加准确地控制每个数值输出时所占据的列数,为此,C语言提供了相应的功能。其格式为:%m 和 %m.n
m表示数值输出时在屏幕上占据的列数,又称为场宽,n表示输出实型数值时小数点后的位数
算术运算符
加(+)、减(-)、乘(*,不能省略 )、除(/)、取余(%)
% (求余) 运算对象只能是整型
整型/整型 相当于取整,一个为实型即为除法
C语言允许char类型的变量或常量参与各种算术运算,但在运算时,它将被看成一个整型数值,其值为字符对应的ASCII编码。例如:‘A’+32等于用大写字符’A’的ASCII编码65与32相加结果为97
自增、自减运算符 + + 、- -
a = 10; b = ++a; 表达式的值取修改后的值 先加再赋值
a 为 11 ,b为11
a=10; b=a++; 表达式的值取修改前的值 先赋值再加
a 为 11 ,b为10
算术表达式
算术表达式是指仅包含算术运算符或自加(++)、自减(–)运算符的表达式。算术表达式的结果一定是数值类型的,即整型或实型
C语言规定,在书写表达式时,应该遵循下列规则:
(1)所有内容都必须写在一行上,例如:必须写成7/8
(2)在表达式中只允许使用圆括号。为了确保表达式中的每个运算符能够按照所期望的顺序进行计算,应该适当地添加括号。
(3)表达式中的乘号不允许省略,例如:(a+1)(a-1) 必须写成 (a+1)*(a-2)
第二章 C语言的基本控制结构
顺序结构
顺序结构是指按照语句的书写顺序依次执行每条语句的语句结构。
选择结构
选择结构是指根据某些数据的取值或计算结果选取不同操作的处理方式。
选择结构的描述由两个基本部分组成,一是对选择条件的描述;二是对处理分支的描述。
关系运算与逻辑运算
关系运算符
逻辑运算符
对于数学表示形式 0 < a < 10,不能直接地采用这种方式书写,而需要将它分解成两个关系运算,即分解成0小于a并且a小于10,并按照下列格式书写: 0 < a && a < 10
对于逻辑表达式 x >= 0 && y++ ,如果x小于0,将不计算y++。
if语句
if ( <条件表达式> ) <真分支语句> else <假分支语句>
多路选择和switch语句
switch ( <表达式> ) {
case <常量> : <语句序列>
case <常量> : <语句序列>
…
case <常量> : <语句序列>
default : <语句序列>
}
执行的基本过程:首先计算充当开关角色的表达式;然后,根据计算结果进行控制的转移,即用开关值与下面每个case语句中的常量进行比较;如果开关值等于某个常量,则执行该case语句中的语句序列;如果不存在等于开关值的case常量,则执行default语句中的语句序列。
所有的case常量不允许重复。
经常将break语句作为每个case分支的语句序列的最后一条语句,以表示该分支的计算结束,并随后跳出switch语句,终止switch语句的继续执行。
循环结构
while 语句
语法格式:
while ( <条件表达式> ) <语句>
for 语句
语法格式:
for ( <初值表达式>; <条件表达式>; <增量表达式> ) <语句>
do while 语句
语法格式:
do <循环体语句> while ( <条件表达式> ) ;
第三章 计算机算法初步
算法
利用计算机求解问题的一般过程
(1)问题分析阶段
(2)数据结构设计阶段
(3)算法设计阶段
(4)编码与调试阶段
算法描述
一种是自然语言的描述方法。鉴于自然语言本身过于灵活且又缺乏严谨性,所以容易产生理解上的歧义。
还有一种算法的图形描述方式——流程图。它采用一些标准的图形符号描述算法的操作过程,从而避免了人们对非形式化语言的理解差异。
常用流程图符号
穷举法
核心在于明确问题的所有可能性,并针对每种可能情况逐个进行判断,最终找出正确问题的答案。
素数的判断
假设给定的整数用x表示,则判断过程就是确认x不能整除以2到x-1 之间的任何整数。这就需要一一列举出2到x-1之间的每个整数进行排查。
百钱买百鸡
公鸡、母鸡和小鸡的数量是有限的,都不会超过100。通过对不同数量的公鸡、母鸡和小鸡进行组合,可以计算出购买这些鸡所用的花费,但这个题目要求找出那些花费正好100枚且鸡的总数也为100只的情况。因此,可以采用穷举法,将不同的公鸡、母鸡和小鸡的数量枚举一遍,找出那些符合题目要求的解。
递推与迭代法
递推常用于序列数据的计算。其基本策略是用已知结果和特定关系(递推公式)计算中间值。
采用递推法进行问题求解的关键在于找出递推公式和边界条件。
迭代也是计算机数值计算的一种基本算法,其基本策略是从初值出发,不断计算问题的近似解。
等比数列求和
等比数列的递推公式为:
itemi = itemi-1 * ratio 后项等于前项乘以比例值
sumi = sumi-1 + itemi 前i项之和等于前i-1项之和加当前项
由于在重复上述递推计算之前,需要将第1项的值累加到sum中,所以,需要先将item存入sum中。
求圆周率π
圆周率π的计算公式为:
π = 4 – 4/3 + 4/5 – 4/7 +4/9 – 4/11 + …
圆周率是通过将数列4、-4/3、4/5…求和得到的。在这个数列中,每个数据项的取值与前一项及该项的序号存在着一定的关系。
可以通过迭代,逐个计算出每一个数据项,再将它们累加起来。
为了满足要求的精度,可以通过检查数据项的大小来控制循环的终止。由于数据项的绝对值是递减的,且相邻项的符号不同,如果第n个数据项的绝对值已经小于精度值,则前n项之和一定已经满足精度要求了。
第四章 数据的组织结构(一)
数组类型
同时存在若干个用来描述同一性质且不同个体的数据。
只有将这些数据组织在一起形成批量数据,共同参与处理,很多操作才具有实际意义。
一维数组类型的定义
定义格式:
<元素类型> <数组变量名>[<元素数量>];
例如: int vote[10];
C语言规定:数组的下标从0开始,因此,表示这10个数据的下标为0~9
在C程序中,系统将会为每个数组型变量分配一片连续的存储空间,所需要分配的存储空间总数将取决于包含的元素个数和每个元素需要的存储空间。
一维数组的初始化
基本格式为:
<元素类型> <数组变量名>[<元素数量>]={<元素初值1>,<元素初值2>,…,<元素初值n>};
例如:double score[5] = {9.2, 9.1, 8.7, 9.1, 8.5};
float score[ ] = {9.2, 9.1, 8.7, 9.1, 8.5};
int letter[26] = {10, 9, 8, 7};
它的执行结果是:将10、9、8、7分别赋予letter数组中下标为0、1、2、3的元素,后面的所有元素赋予初值0。
int vote[10] = {0};将数组型变量中的每一个元素赋予初值0。
一维数组元素的引用及基本操作
数组元素的引用
<数组变量名>[<下标表达式>]
数组的赋值
利用赋值语句为数组赋值
for (i=0; i<10; i++){
vote[i] = 0;
}
调用标准输入函数为数组赋值
for (i=0; i<13; i++) {
scanf(“%f”, &score[i]);
}
数组的输出
for (i=0; i<10; i++) {
printf(“%5d”, vote[i]);
}
使用一维数组组织数据的应用实例
查找问题
查找是指根据某个给定的条件,在一组数据中搜索是否存在满足该条件的数据的过程。
已知一个按非递减有序排列的整型数列(12,23,30,45,48,50,67,82,91,103)。请编写一个程序,查找其中是否存在与给定key相等的数值。
#include <stdio.h>
#define NUM 10
main( )
{
int value[NUM] = {
12, 23, 30, 45, 48, 50, 67, 82, 91, 103}; /* 非递减整型数列 */
int low, high, mid, key;
printf("\nEnter a key:"); /* 输入查找的数值 */
scanf("%d", &key);
low = 0; high = NUM-1;
while (low<=high) {
mid = (low+high)/2;
if (value[mid]==key) break;
if (value[mid]<key)
low = mid+1;
else
high = mid-1;
}
if (low<=high)
printf("\n%d is found at %d.", key, mid); /* 确认break出口 */
else
printf("\n%d is not found.", key); /* 确认循环正常出口 */
}
排序问题
选择排序
将一组无序的数列重新排列成非递减或非递增的顺序是一种经常需要的操作。
首先从n个数据中选择一个最小的数据,并将它交换到第1个位置;然后再从后面n-1个数据中选择一个最小的数据,并将它交换到第2个位置;以此类推,直至最后从两个数据中选择一个最小的数据,并将它交换到第n-1个位置为止,整个排序操作结束。
字符串的组织
字符串的组织形式
字符串是指一个有限长度的字符序列 ,字符串常量用一对双引号(“”)括起来。
字符串中所包含的字符个数被称为字符串长度。
字符串的初始化
char str[ ] = “C program”;
char str[ ] = {‘C’, ‘ ’, ‘p’, ‘r’, ‘o’, ‘g’, ‘r’, ‘a’, ‘m’, ‘\0’};
对于这种初始化形式,系统将其视为字符操作,而不是字符串操作,因此不会在尾部添加结束符‘\0’。
“C program”的存储状态
字符串的输入
1、gets(str);
gets 以换行符作为输入结束标记,但不保存换行符。
2、scanf(“%s”, str);
scanf 以空格、换行符或制表符作为结尾。
字符串的输出
1、puts(str);
puts将字符串的内容显示到标准输出设备——屏幕上,并换行。
2、printf(%s”, str);
字符串处理函数及应用实例
字符串标准函数
在C语言的标准函数库中,提供了30余种与字符串处理有关的标准函数,从而大大地提高了字符串处理的能力,降低了字符串处理的复杂程度。
计算字符串长度
strlen(str);这个函数的功能是返回字符串中所包含的字符个数,即字符串长度。字符串结束标志‘\0’不计算在内。
字符串比较
strcmp(str1, str2);两个字符串进行比较时将依据每个字符对应的ASCII编码决定其大小。
字符串拷贝
strcpy(str1, str2);其中str2是将要被拷贝的字符串,str1是用于存放拷贝结果的存储区域。
字符串连接
strcat(str1, str2);其中str1和str2是两个字符串。这个函数的功能是:将str2连接在str1之后,并在结束处添加一个字符串结束符‘\0’
字符串转换成数值类型
atof(str);
atoi(str);
atol(str);
其中str是一个字符串。atof() 的返回类型是double,它可以将字符串str转换成一个双精度数值;atoi() 的返回类型是int,它可以将字符串str转换成普通整型;atol() 的返回类型是long,它可以将字符串str转换成长整型(long)。
大小写转换
strlwr(str);
strupr(str);
str是一个字符串。标准函数strlwr( ) 可以将字符串str中出现的所有大写字母转换成小写字母;标准函数strupr( ) 可以将字符串str中出现的所有小写字母转换成大写字母。
二维数组
二维数组的定义
定义格式:
<元素类型> <数组变量名>[<元素数量1>][<元素数量2>];
例如: int value[5][4];
value数组的每个元素类型为int,包含5行4列共20个元素
一旦定义了一个二维数组型变量,系统就会立即为其分配相应的存储空间用于存放数组中的每个元素。存储空间的数量取决于数组元素的类型和所定义的行数、列数,即存储空间数量=每个元素所占用的字节数量×行数×列数,并按照行列顺序依次排列 。
二维数组的初始化
int a[4][3]={
{12,11,10},{9,8,7},{6,5,4},{3,2,1}};
int a[4][3]={12,11,10,9,8,7,6,5,4,3,2,1};
int a[][3]= {12,11,10,9,8,7,6,5,4,3,2,1};
如果只对二维数组变量中的部分元素进行初始化,可以使用下面两种形式。
int array1[4][3]={
{},{1},{1,2},{1,2,3}};
int array2[4][3]={10,9,8,7,6,5};
二维数组元素的引用及基本操作
数组元素的引用
<数组变量名>[<下标表达式1>][<下标表达式2>]
数组的赋值
for (i=0; i<ROWS; i++)
for (j=0; j<COLS; j++)
value[i][j] = i+j;
数组的输入
for (i=0; i<ROWS; i++)
for (j=0; j<COLS; j++)
scanf(“%d”, &value[i][j]);
数组的输出
for (i=0; i<ROWS; i++){
for (j=0; j<COLS; j++)
printf(“%4d”, value[i][j]);
putchar(‘\n’);
}
判断给定方阵是否为对称矩阵。
对于一个给定的NN矩阵array,如果矩阵中的每个元素都满足array[i][j]=array[j][i],则称这个矩阵为对称矩阵。
在判断一个给定的矩阵是否为对称矩阵时,只需要用下三角部分的每个元素与对应的上三角元素进行比较。如果每一对元素都相等,这个矩阵就是对称矩阵,否则,就是非对称矩阵。
#include <stdio.h>
#define NUM 5 矩阵行列数
main( )
{
int m[NUM][NUM]; /定义二维数组变量/
int i, j;
/* 输入矩阵 */
printf("\Enter %d rows %d cols datas for the maxtrix:\n",NUM,NUM);
for (i=0; i<NUM; i++)
for (j=0; j<NUM; j++)
scanf("%d", &m[i][j]);
/* 显示矩阵 */
for (i=0; i<NUM; i++){
for (j=0; j<NUM; j++)
printf("%4d", m[i][j]);
printf("\n");
}
/* 判断矩阵是否对称并输出相应的结果 */
for (i=0; i<NUM; i++)
for (j=0; j<i; j++)
if (m[i][j]!=m[j][i]) {
printf("\nThe matrix isn't symmetrical.");
return 0;
}
printf("