转义符:
| 转义字符 | 含义 |
|---|---|
| n | 换行 |
| t | 向后移动 |
| b | 退格 |
| r | 回车 |
| f | 换页 |
| 显示 | |
| ’ | 显示、 |
| " | 显示“ |
单引号与双引号的是不一样的
单引号表示字符,双引号表示字符串;
字符型:
| 数据类型 | 存储单位数 |
|---|---|
| char | 1 |
数据类型大概:
整数型
| 有符号整数型 | 存储单位数 |
|---|---|
| int | 4 |
| short | 2 |
| long | 4 |
| long long | 8 |
有无符号的整型的存储单位数是一致的
| 无符号整型 | 取值范围 |
|---|---|
| unsigned int | 0~2^32-1 |
| unsigend short | 0~2^16-1 |
| unsigend long | 0~2^32-1 |
| unsigned long long | 0~2^64-1 |
浮点型
| 浮点类型 | 存储范围 |
|---|---|
| float | 4 |
| double | 8 |
| long double | 10 |
常数:
#用宏定义常量dad为jack #define dad jack
常量(查询无法更改这个量,增加安全性能,用关键字:const)
#用关键字const定义的p,无法被查询更改; const float p = 3.1212;
输入输出IO:
printf()函数:
1.可以自定义输出宽度:如果指定宽度小了,输出也不会截取,如果大了,会导致输入向右靠齐;
#includeint main(){ float a = 12.34,b=5.67568; printf("%2.4fn",a); printf("%1.3fn",b); return 0; }
2.对实时的宽度控制:
//m.n,m是控制整数的宽度,n是控制小数的宽度; printf("%m.nf",%d);
#includeint main(){ int a = 1234,b=567568; printf("%2dn",a); printf("%25dn",b); return 0; }
| 格式符 | 使用说明 |
|---|---|
| d,i | 输出带符号的十进制数 |
| o | 输出无符号的八进制数 |
| x | 输出无符号的十六进制数 |
| u | 无符号的整数 |
| c | 单个字符 |
| s | 一连串字符 |
| f | 输出实数(6位小数) |
其他输出方式:
putchar();
#includeint main(){ char ch = 'n'; putchar('C'); putchar('C'+37); putchar('151'); putchar(ch); putchar(ch-13); return 0; }
puts();
#includeint main(int argc,char* argv[]){ char ch[] = "C program language!!"; puts(ch); return 0; }
scanf()函数
1.scanf()输入时,字符用空格隔开,代表他们不是一个字符;
2.scanf()还可以指定输入的长度:
3.当用户输入的数据大于输入项的时候,多余的输入数据不会作废,会等待下一次输入操作;
4.在scanf()中不要插入字符串,他是不会显示出来的而且还会造成用户的使用困难:
例如
c scanf("请输入:%d",&a); //输入的必须是一下格式:"请输入:1"
5.scanf()有返回值,返回的是输入项的个数:
| 格式符 | 使用说明 |
|---|---|
| d,i | 输入带符号的十进制数 |
| o | 输入无符号的八进制数 |
| x | 输入无符号的十六进制数 |
| u | 输入无符号的整数 |
| c | 输入单个字符 |
| s | 输入一连串字符 |
| f | 输入实数(6位小数) |
#includeint main(){ int a,b,c; scanf("%d%d%d",&a,&b,&c); printf("第一个a:%dn第二个:%dn第三个:%dn",a,b,c); return 0; }
其他输入方式:
getchar()获得单个字符;输入的字符不需要间隔,因为间隔也是字符;
#includeint main(){ int a,b,c,d; a = getchar(); b = getchar(); printf("%c,%c",a,b); return 0; }
gets()获得一个字符串;以回车作为字符串输入结束的标志;
#includeint main(){ char a[20],b[90]; gets(a); gets(b); printf("%sn",a); printf("%sn",b); return 0; }
语句:
赋值语句:
空语句;
复合语句;{}后面不要加“;”号;
变量作用域
局部变量:
#includeint main(){ int i = 1; { int i = 2; { int i = 3; printf("%dn",i); } printf("%dn",i); } printf("%dn",i); return 0; }
全局变量:
#includeint i = 0; int main(){ { int i = 2; { int i = 3; printf("%dn",i); } printf("%dn",i); } printf("%dn",i); return 0; }
语句执行顺序:
#includeint i = 0; void a(){ char i = 'a'; printf("%c",i); } int main(){ { int i = 2; { int i = 3; printf("%dn",i); } printf("%dn",i); } printf("%dn",i); a(); return 0; }
选择结构:
逻辑运算优先级:“!”>“&&”>“||”;
| 运算符 | 结合方向 |
|---|---|
| ! | 从右向左 |
| && | 从左向右 |
| || | 从左向右 |
if结构
if(表达式)语句;
判断一个数是不是正偶数(if-else):
#includeint main(){ int i; printf("请输入一个数,判断它是否是一个正偶数。n"); scanf("%d",&i); if(i>0&&!(i%2)) { printf("%d这个数是正偶数",i); } else { printf("%d这个数不是正偶数",i); } return 0; }
if嵌套结构;
判断它是否是一个正偶数且被8整除
#includeint main(){ int i; printf("请输入一个数,判断它是否是一个正偶数且被8整除。n"); scanf("%d",&i); if(i>0&&!(i%2)) { printf("%d这个数是正偶数",i); if(!(i%8)) { printf("且这个数可以被8整除"); } else { printf("但这个数不可以被8整除"); } } else { printf("%d这个数不是正偶数",i); } return 0; }
if - else:比上面直接if嵌套代码简单;
#includeint main(){ int i; printf("请输入一个数,判断它是否是一个正偶数且被8整除。n"); scanf("%d",&i); if(i<=0||i%2) { printf("%d这个数不是正偶数",i); } else if(!(i%8)) { printf("%d这个数是正偶数且可以被8整除",i); } else { printf("%d这个数是正偶数但不可以被8整除",i); } return 0; }
switch路径:
1.switch表达式的值必须是整数,即整型与字符型,表达式两边的括号不能省略;
2.case 和 后面的常量表达式之间有空格,且常量表达式不能有变量,常量表达式必须是整型或字符型,且“:”不能省略。
#includeint main(){ int i; printf("请输入1~7之间的数,来显示星期几。n"); scanf("%d",&i); switch (i) { case 1: printf("星期一n"); break; case 2: printf("星期二n"); break; case 3: printf("星期三n"); break; case 4: printf("星期四n"); break; case 5: printf("星期五n"); break; case 6: printf("星期六n"); break; case 7: printf("星期日n"); break; default: printf("请按照要求输入"); } return 0; }
if与switch作比较来说,if可以实现switch的所有功能,但switch不能实现switch的所有功能,switch的可读性比if好;它们可以一起使用,取长补短,各取所需;
循环结构:
for语句
for(表达式1;表达式2;表达式3)
循环体;
表达式1:循环前的初始化
表达式2:中止条件
表达式3:步进条件,循环体执行完之后才运行;
计算1-200之间可以被3整除的数量的数:
#includeint main(){ int a = 0,b = 0; for (a = 0; a < 201; ++a) { if(!(a%3)) { b++; } } printf("%d",b); return 0; }
while()循环
while(表达式) 循环体;
do-while()循环
do 循环体 while(表达式)
循环大同小异:三点标配:
1.起点
2.终点
3.有重复执行的语句
跳出循环的语句:
continue语句
只是让当前执行的循环结束,接着循环下一次循环:
#includeint main(){ for (int i = 0; i < 10; ++i) { if(i == 5||i==8){ continue; } printf("%dn",i); } return 0; }
break语句
则是直接跳出当前的循环,不会再接着循环了
#includeint main(){ for (int i = 0; i < 10; ++i) { if(i == 5||i==8){ break; } printf("%dn",i); } return 0; }
goto语句()
可以让系统直接调到指定目的,但不推荐用,因为它的可读性差,不利于系统稳定;
循环嵌套:
描绘出九九乘法表:
#includeint main(){ int a = 0; for (int i = 0; i < 10; ++i) { ++a; for (int j = 1; j < a; ++j) { printf("%d*%d=%dt",i,j,(i*j)); } printf("n"); } return 0; }
金字塔
#includeint main(){ int a = 0; for (int i = 0; i < 8; ++i) { for (int j = 0; j < 15; ++j) { if(j >= (7-i) && j <= (7+i)) { printf("*"); } printf("t"); } } return 0; }
函数
无参函数
函数返回值的类型 函数名()
{
函数体
}
不能再函数内部定义函数,但可以在函数内部引用函数;
#includeint a(){ int a = 100; return a; } int main(){ int b; b = a(); printf("%d",b); return 0; }
返回值的类型转换;始终将表达式的类型转换成“函数返回值的类型”;
例如:下面的假若定义为
#includeint a(){ //a类型为字符型 char a = 100; return a; } int main(){ int b; //函数a()的返回值类型是int型 b = a(); printf("%d",b); return 0; }
假如函数内有多个return,但函数不会返回多个返回值,因为函数只能返回一个值,所以有时“return”的作用与break的作用相似,只不过一个会导致函数中止,一个是让循环中止;
函数的使用遵循“先定义,后使用”,那如果先“先使用,在定义”可以吗?
答案是:可以的,但需要声名:(不要忘记在声明 的后面加上“;”)
#includeint a(); int main(){ int b; b = a(); printf("%d",b); return 0; } int a(){ int a = 100; return a; }
定义在函数外的变量,会不断累加,除非函数有初始化,要注意!!
定义在函数内的变脸,会因为函数的消失,消失,但有例外!!!
静态变量(关键字 static)
#includeint a(); int main(){ int b,c; b = a(); c = a(); printf("%d",b); printf("%d",c); return 0; } int a(){ static int a = 100; a += 100; return a; }
有参函数:
函数返回值类型 函数名(类型1 形参1,类型2 形参2,类型3 形参3)
{
函数体
}
#include//声明函数的时候,括号内的类型必须有,形参可以没有; int add(int,int); int main(){ int b,c; b = add(2,4); printf("%d",b); return 0; } int add(int add_1,int add_2){ int add_3; add_3 = add_1 + add_2; return add_3; }
递归函数:(听说蛮好用的,目前没有涉及到)
#includeint add(int add_1); int main(){ int b,c; b = add(100); printf("%d",b); return 0; } int add(int add_1){ if( add_1 == 1) return 3; add(add_1-1); }
递归分为
- 直接递归
- 间接递归
递归可以解决的问题满足三点:
- 要解决的问题可以转化成新的问题,而且新问题与旧问题没有本质的区别;
- 问题逐渐转化,原来的问题可以解决;
- 函数中有结束递归的条件;
利用求n!:
#includeint add(int n); int main(){ int b,c; b = add(5); printf("%d",b); return 0; } int add(int n){ if(n == 1) return 1; return n* add(n-1); }
逆序输出:
1使用循环:
#includeint main(){ int a,b =0; printf("请输入一串数字。"); scanf("%d",&a); while(1) { if(a>10) { printf("%d",a%10); a = a/10; } else { printf("%d",a); break; } } return 0; }
递归函数的方法:
#includeint in(int); int main(){ int a,b =0; printf("请输入一串数字。"); scanf("%d",&a); in(a); return 0; } int in(int n){ if(n<10){ printf("%d",n); } else{ printf("%d",n%10); in(n/10); } }
练习:
#includeint in(int); int main(){ int a,b =0; printf("请输入一串数字。"); scanf("%d",&a); b=in(a); printf("%d",b); return 0; } int in(int n){ if(n == 1) { return 1; } return (n*n*n + in(n-1)); }
数组
数据类型 数组名[整型常量表达式] = {数据1,数据2,数据3,...}
数组的赋值:
#includeint main(){ int list[5]; for (int i = 0; i < 5; ++i) { list[i] = i+1; } for (int i = 0; i < 5; ++i) { printf("%dn",list[i]); } return 0; }
使用数组与随机生成函数:
#include#include #include int list[20]; int main(){ srand((unsigned int) time(0)); for (int i = 0; i < 20; ++i) { list[i] = rand()%1001; } for (int i = 0; i < 20; ++i) { printf("%dn",list[i]); } return 0; }
冒泡排列:
#include#include #include int list_a[20]; int b; int main(){ srand((unsigned int) time(0)); for (int i = 0; i < 20; ++i) { list_a[i] = rand()%1001; } for (int i = 0; i < 19; ++i) { for (int i = 0; i < 19; ++i) { if (list_a[i] > list_a[i + 1]) { b = list_a[i]; list_a[i] = list_a[i + 1]; list_a[i + 1] = b; } else { ; } } } for (int i = 0; i < 20; ++i) { printf("%dn", list_a[i]); } return 0; }
选择排序:
#include#include #include int list_a[20]; int temp; int main(){ srand((unsigned int) time(0)); for (int i = 0; i < 20; ++i) { list_a[i] = rand()%1001; } for (int i = 0; i < 19; ++i) { int pos = 0; for (int j = 1; j < 20-i; ++j) { if(list_a[pos] < list_a[j]) { pos = j; } //检测是否需要更换位置 if(pos != 19-i) { temp = list_a[pos]; list_a[pos] = list_a[19-i]; list_a[19-i] = temp; } } } for (int i = 0; i < 20; ++i) { printf("%dn", list_a[i]); } return 0; }
二维数组:
数据类型 数组名[整数常量表达式] [整数常量表达式],...
二维数组赋值
int seat[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
int seat[3][3] = {1,2,3,4,5,6,7,8,9};
二维数组可以省略第一个下标;
此外还有多维数组;
指针
数据类型* 变量名; 数据变量 *变量名;
&变量名 可以获得变量的地址
#includeint main(){ int a = 21; int *p = &a; printf("%d",*p); return 0; }
这里说明一下:
int *p = &a;
中的“*”星号仅仅起到标记作用,a的地址还是赋给P的;
类似:
int *p; p = &a; //不可以 *p = &a;
而printf(“%d”,*p);中的星号是起作用的,类似箭头指向P中所存地址中的内容;
scanf与指针的作用:因为p是用于存储地址的所以可以直接将scanf的形参可以直接用它;
#includeint main(){ int a = 21; int *p = &a; scanf("%d",p); printf("%d",*p); return 0; }
指针的可以进行四则运算不用小括号括起来,在自增自减的时候要用小括号括起来:
(*P)++; (*p)--;
熟悉指针的练习-指针与数组的关系;
同一数组中的变量的地址
#includeint main(){ int list_a[10]; int *p; for (int i = 0; i < 10; ++i) { p = &list_a[i]; printf("%dn",p); } return 0; }
#includeint main(){ int list_a[10]={1,2,3,4,5,6,7,8,9,0}; int *p; //下面两种赋值都是可以的; //p = &list_a[0]; p = list_a; for (int i = 0; i < 10; ++i) { printf("%dn",*(p+i)); } return 0; }
用指针实现数组的逆序输出,更简单;
#includeint main(){ int list_a[10] = {1,2,3,4,5,6,7,8,9,0}; int *p_1; p_1 = list_a; for (int i = 0; i < 10; ++i) { printf("%d",*(p_1+9-i)); } return 0; }
指向二维数组的指针:
例如
num[2][2] int *p = num[][0]; num[2][1]的指针是p+2*1+1;
保存指针的数组;
#includeint main(){ int list_a[4][4] = {{1,2,3,4},{5,6,7,8},{11,12,13,14},{15,16,17,18}}; int *list_p[4]; for (int i = 0; i < 4; ++i) { list_p[i] = list_a[i]; } for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { printf("%dn",*(list_p[i]+j)); } } return 0; }
指针与函数的结合
可以通过让函数传入指针获得更改数据的力量:
#includeint add(int *p); int main(){ int a =10; add(&a); printf("%d",a); return 0; } int add(int *p) { *p = *p + 5; return 0; }
指针还可以用来指代函数;
二级指针:
int **p;
结构:
关键词:struct
struct 结构类型名
{
数据类型1 成员变量名1;
数据类型2 成员变量名2;
数据类型3 成员变量名3;
数据类型4 成员变量名4;
数据类型5 成员变量名5;
}变量名;
#includeint main(){ struct student { int id_name; char sex; short height; short weight; short age; }student1= {110,2,175,70,21}; printf("%d",student1.id_name); return 0; }
typedef的作用:赋予特定的符号和类型关键字一样的效果
typedef struct student ST; typedef int integer;
#includeint main(){ struct student { int id_name; char sex; short height; short weight; short age; }student1= {110,2,175,70,21}; typedef struct student ST; ST student2 = {120,3,180,76,24}; printf("%dn",student1.id_name); int *p = &student2.id_name; printf("%d",*p); return 0; }
链表:
结构体中有指针,指针指向同类型的结构体;
#includestruct student { int id; char sex; struct student *p; }; int main(){ typedef struct student st; st student1 = {1,2}; st student2 = {3,4}; st student3 = {5,6}; student1.p = &student1; student2.p = &student3; student3.p = &student2; printf("%dn",student1.id); printf("%dn",student1.p -> id); printf("%dn",student2.p -> id); return 0; }
链表与数组的配合
数组是可以存放大量一样类型的数据;长度固定;
链表可以存储大量任意类型的数据;长度可变;
链表最小单元----结点;
结点可以分为“数据域”,“指针域”;
struct student
{
//数据域
int id;
char sex;
//指针域
struct student *p;
};
链表的构成为:
- 头结点
- 数据结点
- 尾结点
建立动态链表:
malloc()动态申请空间;
#include#include struct student { int id; char sex; struct student *p; }; int main(){ typedef struct student st; st *next; next = (st *) malloc(sizeof(st)); if(next!=NULL) { next -> id = 10; next -> sex = 1; printf("%d %d",next -> id,next -> sex); } return 0; }
建立动态链表的源码:
#include#include struct student { int id; char sex; struct student *p; }; int main(){ typedef struct student st; st student1 = {1,'a'}; st student2 = {2,'b'}; st student3 = {3,'c'}; student1.p = &student2; student2.p = &student3; st *next; next = (st *) malloc(sizeof(st)); if(next != NULL) { next -> id = 4; next -> sex = 'd'; student3.p = next; } st *start; start = &student1; for (int i = 0; i < 4; ++i) { printf("id:%dtsex:%cn",start->id,start->sex); start = start -> p; } return 0; }
对链表的操作:
- 插入结点
- 删除结点
在链表开头插入新的结点:
#include#include struct student { int id; char sex; struct student *p; }; int main(){ typedef struct student st; st student1 = {1,'a'}; st student2 = {2,'b'}; st student3 = {3,'c'}; student1.p = &student2; student2.p = &student3; st *next; next = (st *) malloc(sizeof(st)); if(next != NULL) { next -> id = 4; next -> sex = 'd'; student3.p = next; } // st *start; // start = &student1; // for (int i = 0; i < 4; ++i) { // printf("id:%dtsex:%cn",start->id,start->sex); // start = start -> p; // } st *p_new; p_new = (st *) malloc(sizeof(st)); if(p_new!=NULL) { p_new -> id = 0; p_new -> sex = 'e'; p_new -> p = &student1; } st *start; start = p_new; for (int i = 0; i < 10; ++i) { printf("id:%dtsex:%cn",start -> id,start -> sex); start = start -> p; } return 0; }
在链表结尾插入结点:
#include#include struct student { int id; char sex; struct student *p; }; int main(){ typedef struct student st; st student1 = {1,'a'}; st student2 = {2,'b'}; st student3 = {3,'c'}; student1.p = &student2; student2.p = &student3; st *next; next = (st *) malloc(sizeof(st)); if(next != NULL) { next -> id = 4; next -> sex = 'd'; student3.p = next; } // st *start; // start = &student1; // for (int i = 0; i < 4; ++i) { // printf("id:%dtsex:%cn",start->id,start->sex); // start = start -> p; // } //开头插入链表结点 st *p_new; p_new = (st *) malloc(sizeof(st)); if(p_new!=NULL) { p_new -> id = 0; p_new -> sex = 'e'; p_new -> p = &student1; } //结尾插入链表结点 st *bottom; bottom = (st *)malloc(sizeof(st)); if(bottom!=NULL) { bottom -> id = 5; bottom -> sex = 'f'; bottom -> p = NULL; next -> p = bottom; } st *start; start = p_new; for (int i = 0; i < 10; ++i) { printf("id:%dtsex:%cn",start -> id,start -> sex); start = start -> p; } return 0; }
在链表中间出插入结点;
#include#include struct student { int id; char sex; struct student *p; }; int main(){ typedef struct student st; st student1 = {1,'a'}; st student2 = {2,'b'}; st student3 = {3,'c'}; student1.p = &student2; student2.p = &student3; st *next; next = (st *) malloc(sizeof(st)); if(next != NULL) { next -> id = 4; next -> sex = 'd'; student3.p = next; } // st *start; // start = &student1; // for (int i = 0; i < 4; ++i) { // printf("id:%dtsex:%cn",start->id,start->sex); // start = start -> p; // } //开头插入链表结点 st *p_new; p_new = (st *) malloc(sizeof(st)); if(p_new!=NULL) { p_new -> id = 0; p_new -> sex = 'e'; p_new -> p = &student1; } //结尾插入链表结点 st *bottom; bottom = (st *)malloc(sizeof(st)); if(bottom!=NULL) { bottom -> id = 5; bottom -> sex = 'f'; bottom -> p = NULL; next -> p = bottom; } st *temp; temp = (st *) malloc(sizeof(st)); if(temp!=NULL) { temp -> id = 11; temp -> sex = 'y'; temp -> p = next; student3.p = temp; } st *start; start = p_new; for (int i = 0; i < 10; ++i) { printf("id:%dtsex:%cn",start -> id,start -> sex); start = start -> p; } return 0; }
删除链表中的结点:
用到的函数free()释放内存;
学生系统检测:



