前言
大一学习的 C 语言,现在回过头来发现已经忘的差不多了,正好趁着这个机会复习整理下,本文的目的偏向于整理备忘,讲解的部分会占很少。
目录及相关习题参考 《C程序设计(第四版)》谭浩强
1 算法表示
1.1 常见流程图
当型循环
直到型循环
1.2 NS 流程图
伪代码表示
2 数据类型
2.1 整型数据
1 | (1)普通整型(int),存储单元中使用反码形式存放 |
有符号数据 0 正 1 负,默认为有符号数据
2.2 字符型数据
一字节
1 | char c = '?'; |
==注意==
1 | 'A' 表示一个字符 |
2.3 浮点型数据
1 | 单精度浮点型(float),双精度浮点型(double),长双精度(long double) |
2.4 赋值过程中类型转换
因为 C 是强类型语言,如赋值语句两侧变量类型不相同则会进行转换
==注意==
1 | printf("%f\n", 1/3); //输出 0.000000,因为 1/3 结果为整型 0 |
2.5 强制类型转换
1 | (double)a |
3 C 语言注释
两种注释方式
- 块注释(block comment):以
/*
开始,*/
结束 - 行注释(line comment):以
//
开始
4 数据的输入输出
4.1 printf 输出数据
4.1.1 一般格式
语法:printf(格式字符, 输出变量);
example: printf("%d,%c\n",i,c); // 注意是双引号
4.1.2 格式字符
修饰字符
1 | %m.nf 指定数据的宽度和小数位数,m 包含小数点 |
4.2 scanf 输入数据
4.2.1 一般形式
语法:scanf(格式字符, 地址表列);
example: scanf("a=%f,b=%f,c=%f", &a, &b, &c); //1. 双引号 2. 注意是地址 &a
4.2.2 格式字符
==注意==
1 | (1) |
4.3 字符数据的输入输出
putchar 输出一个字符
1 | putchar(c); |
getchar 输入一个字符
1 | getchar(c); |
getchar 还可以获取屏幕上无法显示的字符,如控制字符
4.4 习题(第三章)
1 | //math 库 pow 函数应用 |
1 | //利息计算 |
==注意==
第二问,char 存储为一字节,按补码形式存储
==注意==
scanf 时,遇空格,回车,tab或遇到非法字符(如输入数字时遇到字符)则认为该数据结束
所以 71.82 和 Aa 之间不应有空格或回车
5 选择结构程序设计
5.1 if 语句实现选择结构
一般有两种形式
(1)
1 | if(a>b){ |
(2)
1 | if(number>500){ |
==注意==
1 | // 无花括号时,if 条件为真,只会执行之后的一条语句 |
5.2 关系运算符及优先次序
优先次序
5.3 逻辑运算符及优先次序
优先次序,!(非)最高
5.4 条件表达式
1 | ch=(ch>='A' && ch<='Z')?(ch+32):ch; |
5.5 switch 语句
1 | switch(grade){ |
5.6 习题(第四章)
1 | // (1)判断哪个等级方法(2)60一下输出E |
1 | #include <stdio.h> |
顺序排序
1 | #include <stdio.h> |
6 循环结构程序设计
6.1 while 实现循环
当型循环
1 | while(i<=100){ |
6.2 do……while 实现循环
直到型循环
1 | do{ |
6.3 for 实现循环
1 | for(i=1;i<=100;i++){ |
6.4 习题(第五章)
==重点==
1 | // 求解最小公倍数和最大公约数 |
1 | // if((c=getchar())!='\n') |
1 | //注意an的求法 |
1 | #include <stdio.h> |
==重点==
1 | //水仙花数 |
1 | //100以内的完数 |
1 | //斐波那契数列变形 |
1 | //牛顿迭代法求平方根 |
==重点==
1 | //图形输出问题 |
1 | //比赛排序问题 |
7 数组
7.1 一维数组
7.1.1定义方法
1 | int a[10]; |
==注意==
1 | (1)a[10] 下标从0开始到9 |
7.1.2 引用
1 | a[0] 或 a[2*3] |
7.1.3 初始化
- 全部初始化
1
int a[10]={0,1,2,3,4,5,6,7,8,9}; //注意大括号,逗号
- 只给一部分元素赋值
1
int a[10]={0,1,2,3,4}; // 前5个赋初值,后5个赋初值0
- 全部赋初值0可写成
1
int a[10]={0};
- 可以不指定数组长度
1
int a[]={0,1,2,3,4}; //数组长度自动为5
7.2 二维数组
7.2.1 定义方法
1
float a[3][4]; //可以理解成3行4列矩阵,内存中先顺序存储第一行,再存储第二行
7.2.2 引用
1
2
3
4int a[3][4]; //定义3×4二维数组
a[3][4]=3; //不存在a[3][4]元素
注意定义和数组下标范围的区别7.2.3 初始化
- 分别赋初值
1
int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; 大括号中嵌套大括号
- 可写在一个大括号内
1
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
7.3 字符数组
1
char c[10]="China";
7.3.1 字符串处理函数
#include <string.h>
- puts
1
2char str[]="China\nBeijing"
puts(str); - gets
1
gets(str);
- strcat - 连接字符串
1
2
3
4
5strcat(str1, str2);
注意:
(1)str1必须足够大,以便容纳连接后的新字符串
(2)连接前两字符串后面都有\0 - strcpy 和 strncpy - 字符串复制
1
2
3strcpy(str1,str2); // 将str2复制到str1
strcpy(str1,str2,n); //将str2最前面n个字符复制到str1中 - strcmp
1
2
3
4
5
6
7
8
9strcmp(str1,str2);
(1)如全部字符相同,则认为两个字符串相等
(2)若出现不相同字符,则以第一队不相同的字符的比较结果为准
函数值:
(1)相等,则返回0
(2)str1 > str2,返回正整数
(3)str1 < str2,返回负整数 - strlen
1
strlen(str); //字符长度,不包含\0
- strlwr - 小写,strupr - 大写
7.4 习题(第六章)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include <stdio.h>
#include <math.h>
int main()
{int i,j,n,a[101];
for (i=1;i<=100;i++)
a[i]=i;
a[1]=0;
for (i=2;i<sqrt(100);i++)
for (j=i+1;j<=100;j++)
{if(a[i]!=0 && a[j]!=0)
if (a[j]%a[i]==0)
a[j]=0;
}
printf("\n");
for (i=2,n=0;i<=100;i++)
{ if(a[i]!=0)
{printf("%5d",a[i]);
n++;
}
if(n==10)
{printf("\n");
n=0;
}
}
printf("\n");
return 0;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33#include <stdio.h>
int main()
{ int a[11]={1,4,6,9,13,16,19,28,40,100};
int temp1,temp2,number,end,i,j;
printf("array a:\n");
for (i=0;i<10;i++)
printf("%5d",a[i]);
printf("\n");
printf("insert data:");
scanf("%d",&number);
end=a[9];
if (number>end)
a[10]=number;
else
{for (i=0;i<10;i++)
{if (a[i]>number)
{temp1=a[i];
a[i]=number;
for (j=i+1;j<11;j++)
{temp2=a[j];
a[j]=temp1;
temp1=temp2;
}
break;
}
}
}
printf("Now array a:\n");
for (i=0;i<11;i++)
printf("%5d",a[i]);
printf("\n");
return 0;
}==重点:杨辉三角==1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23//一个数组中元素逆序
//以中间元素为中心,两侧元素互换即可
int main()
{ int a[N],i,temp;
printf("enter array a:\n");
for (i=0;i<N;i++)
scanf("%d",&a[i]);
printf("array a:\n");
for (i=0;i<N;i++)
printf("%4d",a[i]);
for (i=0;i<N/2;i++) //循环的作用是将对称的元素的值互换
{ temp=a[i];
a[i]=a[N-i-1];
a[N-i-1]=temp;
}
printf("\nNow,array a:\n");
for (i=0;i<N;i++)
printf("%4d",a[i]);
printf("\n");
return 0;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include <stdio.h>
# define N 10
int main(){
int i,j,a[N][N];
for(i=0;i<N;i++){
a[i][i]=1;
a[i][0]=1;
}
for(i=2;i<N;i++){
for(j=1;j<=i-1;j++){
a[i][j]=a[i-1][j]+a[i-1][j-1];
}
}
for(i=0;i<N;i++){
for(j=0;j<=i;j++)
printf("%6d", a[i][j]);
printf("\n");
}
return 0;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17//图形输出
int main()
{ char a[5]={'*','*','*','*','*'};
int i,j,k;
char space=' ';
for (i=0;i<5;i++)
{ printf("\n");
printf(" ");
for (j=1;j<=i;j++)
printf("%c",space);
for (k=0;k<5;k++)
printf("%c",a[k]);
}
printf("\n");
return 0;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25//非凯撒密码,对称密码
int main()
{int j,n;
char ch[80];
printf("input cipher code:\n");
gets(ch);
printf("\ncipher code:%s\n",ch);
j=0;
while (ch[j]!='\0')
{ if ((ch[j]>='A') && (ch[j]<='Z'))
ch[j]=155-ch[j];
else if ((ch[j]>='a') && (ch[j]<='z'))
ch[j]=219-ch[j];
else
ch[j]=ch[j];
j++;
}
n=j;
printf("original text:");
for (j=0;j<n;j++)
putchar(ch[j]);
printf("\n");
return 0;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18//strcat实现 不用strlen的方法
//s1[i++]=s2[j++]
int main()
{ char s1[80],s2[40];
int i=0,j=0;
printf("input string1:");
scanf("%s",s1);
printf("input string2:");
scanf("%s",s2);
while (s1[i]!='\0')
i++;
while(s2[j]!='\0')
s1[i++]=s2[j++];
s1[i]='\0';
printf("\nThe new string is:%s\n",s1);
return 0;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18//strcmp实现
int main()
{ int i,resu;
char s1[100],s2[100];
printf("input string1:");
gets(s1);
printf("\ninput string2:");
gets(s2);
i=0;
while ((s1[i]==s2[i]) && (s1[i]!='\0'))i++;
if (s1[i]=='\0' && s2[i]=='\0')
resu=0;
else
resu=s1[i]-s2[i];
printf("\nresult:%d.\n",resu);
return 0;
}1
2
3
4
5
6
7
8
9
10
11
12
13//strcpy实现 运用了strlen
int main()
{ char s1[80],s2[80];
int i;
printf("input s2:");
scanf("%s",s2);
for (i=0;i<=strlen(s2);i++)
s1[i]=s2[i];
printf("s1:%s\n",s1);
return 0;
}8 函数
8.1 定义函数
定义函数别忘了声明函数8.2 数组作为函数参数
数组名作为函数参数时,传递的是数组首元素的地址,也就是说形参的值改变,实参的值也改变1
2
3
4
5
6float score[10];
average(score);
float average(float array[10]){
……
}
8.3 局部变量和全局变量
8.3.1 局部变量
1 | (1)在一个函数内部定义即为局部变量 |
8.3.2 全局变量
在函数外部定义
为区别全局变量和局部变量,习惯将全局变量的第一个字母用大写表示
8.4 变量的存储方式和生存期
8.4.1 动态存储方式和静态存储方式
静态存储方式是指在程序运行期间由系统分配的固定的存储空间,动态存储方式是在程序运行期间根据需要进行动态分配
C 的存储类别包括四种:自动(auto),静态(static),寄存器(register),外部(extern)
8.4.2 局部变量存储类别
- 自动变量(auto 变量)
默认为自动变量,在调用该函数时,系统会给这些变量分配存储空间,在函数调用结束时就自动释放这些存储空间。 - 静态局部变量(static 局部变量)
局部变量的值在调用结束后不消失,下一次再调用该函数时,使用该值。
==注意==
1 | 虽静态局部变量在函数结束调用后仍存在,但其他函数不能调用它。 |
拓展外部变量的作用域:
- 在一个文件内拓展
1
2
3
4
5
6
7//将 A,B,C 使用范围拓展到定义之前
int main(){
extern int A,B,C;
……
}
int A,B,C - 拓展到其他文件
1
2
3
4
5
6
7
8
9file1:
int A;
int main(){
……
}
file2:
extern A;
…… - 将外部变量作用域限制在本文件中
1
2
3
4
5
6
7
8
9
10/// 添加static声明
file1:
static int A;
int main(){
……
}
file2:
extern A;
……8.5 内部函数和外部函数
8.6 习题(第七章)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23//函数递归应用
#include <stdio.h>
double P(int n,int x);
int main(){
int n,x;
double result;
printf("n,x:");
scanf("%d,%d",&n,&x);
result=P(n,x);
printf("%f",result);
}
double P(int n,int x){
if(n==0){
return 1;
}
else if(n==1){
return x;
}
else if(n>=1){
return (2*n-1)*x-P(n-1,x)-(n-1)*P(n-2,x)/n;
}
}
![](./C_C++_01/20200301143808.png)
1 |
|
9 指针
9.1 指针变量
- 定义
1
int *point_1, *point_2;
- 引用指针变量
1
2
3
4
5
6p=&a;
*p=1;
(1)& 取地址符
(2)* 指针运算符(或间接访问运算符),*p代表指针变量p指向的对象 - 指针变量作函数参数
实现了调用函数使变量的值发生变化,在main函数中就可以使用这些改变了的值
9.2 指针引用数组
- 数组元素的指针
1
2
3
4
5
6int *p;
int a[10]={0,1,2,3,4,5,6,7,8,9};
p=a; //将a数组首元素的指针赋给p
或
p=&a[0]; - 数组元素指针的计算
1
2p++; //指向下一个元素地址
p--; //指向前一个元素地址 - 指向多维数组
9.3 指针引用字符串
1 | char *string="I love China"; |
9.4 内存动态分配
1 |
- malloc
1
2或
malloc(100); //开辟100字节临时分配空间 - calloc
1
p=calloc(50,4); //分配50个4字节空间
- free
1
free(p); //释放空间
- realloc
1
relloc(p,50); //改变分配空间的大小
10 结构体
10.1 定义和使用
定义
1 | struct Student{ |
初始化和使用
1 | student1={11011,'M'}; |
10.2 结构体指针
1 | struct Student stu_1; |
引用结构体中变量三种方法:
1 | (1)stu.num |
10.3 共用体类型
共享一段内存的结构,后一个数据会覆盖前面的数据
1 | union Data{ |
10.4 枚举类型
一个变量只有几种可能的值
1 | enum Weekday{sun,mon,tue,wed,thu,fri,sat}; |
10.5 typedef声明新类型名
1 | 一般用法: |
11 文件输入输出
文件类型指针 stdio.h
11.1 打开与关闭文件
fopen打开文件
1 |
|
文件使用方式
fclose关闭文件
1 | fclose(fp); |
11.2 顺序读写文件
11.2.1 读写字符
1 | fgetc(fp); |
11.2.2 读写字符串
1 | fgets(str,n,fp); |
11.2.3 格式化读写文件
1 | fscanf(fp,"%d %f",&i,&f); |
11.2.4 二进制方式读写数据
1 | fread(&stud[i],sizeof(struct Student_type),1,fp); |
11.3 文件位置标记与随机读写
- rewind 使文件位置标记指向文件开头
1
rewind(fp1);
- fseek改变文件位置标记
- ftell测定当前文件标记位置
11.4 文件读写的出错检测
12 位运算
12.1 按位与(&)
代码
1 |
|
样例输出
1 | : The a & b(decimal) is 3 |
12.2 按位或(|)
代码
1 |
|
样例输出
1 | 63 : The a & b(decimal) is 63 |
12.3 异或(^)
同 0 异 1
代码
1 |
|
样例输出
1 | 4 |
12.4 取反(~)
代码
1 |
|
样例输出
1 | fffffff8 |
12.5 移位运算
代码
1 |
|
样例输出
1 | 1 |
常用C库函数
1. 数学函数
1 |
函数名 | 功能 | 函数原型 |
---|---|---|
abs | 绝对值 | int abs(intx); |
fabs | 绝对值 | double fabs(double x); |
exp | e^x | double exp(double x); |
floor | 不大于x的最大整数 | double floor(double x); |
log | lnx | double log(double x); |
log10 | lgx | double log10(double x); |
pow | x^y | douoble pow(double x, double y); |
sqrt | √x | double sqrt(double x); |
计算log2n,使用换底公式
1 | log(n)/log(2); |
2. 字符函数
1 |
函数名 | 功能 | 函数原型 |
---|---|---|
isanum | 判断是否数字 | int isanum(int ch); |
islower | 判断是否小写字母 | int islower(int ch); |
isupper | 判断是否大写字母 | int isupper(int ch); |
3. 字符串函数
1 |
1 |
|
4. 输入输出函数
1 |
5. 存储动态分配函数
运算符优先级
同一优先级的运算符,结合次序由结合方向所决定。
简单记就是:! > 算术运算符 > 关系运算符 > && > || > 赋值运算符