目录
ASCII 码 | 字符 | ASCII 码 | 字符 | ASCII 码 | 字符 | ASCII 码 | 字符 | |||||||
十进位 | 十六进位 | 十进位 | 十六进位 | 十进位 | 十六进位 | 十进位 | 十六进位 | |||||||
32 | 20 | 56 | 38 | 8 | 80 | 50 | P | 104 | 68 | h | ||||
33 | 21 | ! | 57 | 39 | 9 | 81 | 51 | Q | 105 | 69 | i | |||
34 | 22 | " | 58 | 3A | : | 82 | 52 | R | 106 | 6A | j | |||
35 | 23 | # | 59 | 3B | ; | 83 | 53 | S | 107 | 6B | k | |||
36 | 24 | $ | 60 | 3C | < | 84 | 54 | T | 108 | 6C | l | |||
37 | 25 | % | 61 | 3D | = | 85 | 55 | U | 109 | 6D | m | |||
38 | 26 | & | 62 | 3E | > | 86 | 56 | V | 110 | 6E | n | |||
39 | 27 | ' | 63 | 3F | ? | 87 | 57 | W | 111 | 6F | o | |||
40 | 28 | ( | 64 | 40 | @ | 88 | 58 | X | 112 | 70 | p | |||
41 | 29 | ) | 65 | 41 | A | 89 | 59 | Y | 113 | 71 | q | |||
42 | 2A | * | 66 | 42 | B | 90 | 5A | Z | 114 | 72 | r | |||
43 | 2B | + | 67 | 43 | C | 91 | 5B | [ | 115 | 73 | s | |||
44 | 2C | , | 68 | 44 | D | 92 | 5C | \ | 116 | 74 | t | |||
45 | 2D | - | 69 | 45 | E | 93 | 5D | ] | 117 | 75 | u | |||
46 | 2E | . | 70 | 46 | F | 94 | 5E | ^ | 118 | 76 | v | |||
47 | 2F | / | 71 | 47 | G | 95 | 5F | _ | 119 | 77 | w | |||
48 | 30 | 0 | 72 | 48 | H | 96 | 60 | ` | 120 | 78 | x | |||
49 | 31 | 1 | 73 | 49 | I | 97 | 61 | a | 121 | 79 | y | |||
50 | 32 | 2 | 74 | 4A | J | 98 | 62 | b | 122 | 7A | z | |||
51 | 33 | 3 | 75 | 4B | K | 99 | 63 | c | 123 | 7B | { | |||
52 | 34 | 4 | 76 | 4C | L | 100 | 64 | d | 124 | 7C | | | |||
53 | 35 | 5 | 77 | 4D | M | 101 | 65 | e | 125 | 7D | } | |||
54 | 36 | 6 | 78 | 4E | N | 102 | 66 | f | 126 | 7E | ~ | |||
55 | 37 | 7 | 79 | 4F | O | 103 | 67 | g | 127 | 7F | DEL |
源文件:XXX.c 表示C语言源文件
标准定义了多种类型的”单词”:
关键词(keywords): return、for、void、…
标识符(identifiers):x、y、z、…
字面值(literal): 3、4、 “Hello World!” 、…
注释(comment): /*This is a comment.*/、…
操作符(operator): +、-、 * 、/、… 分隔符(separator):{、}、…
左值: 指的是引用对象的一种 特殊表达式,该表达式 可以访问或改变对象( 至少可以改变一次)。
右值: 非左值表达式。
- #include<stdio.h> // 预处理 包含头文件 为了认识printf
- int main(){ // 主函数入口。有且只有一个
- printf("HelloWorld");// 打印文字 printf输出
- return 0; // 返回给系统
- }
程序: 为了解决特定问题而使用计算机语言编写的有序指令序列集合
程序执行的过程:编写(cpp)->编译(obj)->链接(exe)->运行(exe)
注释: // 行注释 /* */ 块注释
换行:\n
良好的编程风格:1 注释 2 缩进 3 换行 4 空格 5 一行只有一条语句
计算机作用:解决现实中的问题。
数据类型:整数 小数 字符
int float char
%d:表示准备输出一个整数的值。 %d跟变量的值是一一对应的关系。
%f:表示准备输出一个小数的值。
%c:表示准备输出一个字符的值。
1T=1000G=1000*1000M=1000*1000*1000K=1000*1000*1000*1000byte
位是最小单位 一个字节是8位
sizeof可以获得类型所占得字节数 单位是字节
- #include
- int main(){
- int a = 100;
- int b = sizeof(a);
- printf("int 做占得字节数是:%d个", b);
- return 0;
- }
int 所占得内存是4个字节
float 所占内存为 4个字节
char 所占内存为1个字节
int float char
%d %f %c
int a = 0;
printf(“%d”,a);
一个字节是 8位。
int 4个字节
float 4个字节
char 一个字节
unsigned char 表示的最大的值是255 最小的值是 0
(signed) char 表示的最大值是127 最小值 - 128
溢出:当数值大于这个类型能表达的最大位数时,最高位被抛弃
#include int main(){ unsigned char a = 255; a = a + 1; printf("%d", a); return 0; } |
数值的编码表示:数值在内存中都是以补码的形式存在的。
原码:数值的正常的表示
反码:除了符号位 其他各位 取反
补码:反码+1
对于正数来说:原码 反码 补码 相同
对于负数来说:不同
-1 + 1 = 0 溢出
标识符:为了解决内存地址不方便记忆的问题,
我们用标识符给内存取名,方便记忆。
标识符===变量
标识符的命名规则:1、由数字、字母、下划线组成。
2、不能由数字开头
3、不能是关键字。(特殊字符 蓝色)
4、尽量使用有意义的标识符
& 地址符。
输入完成按回车表示结束。
内存申请后一般讲内存初始化为0;
输入:scanf 将键盘上输入的数存到内存中。
1 要申请一块内存,用来接收输入的数值。 int a;
2 通过scanf 方法将键盘的输入写入内存。scanf(“%d”,&a);
#include int main(){ int a = 0; scanf("%d", &a); printf("%d", a); return 0; } |
输入两个整数a和b,输出他们的和
#include int main(){
int a = 0; scanf("%d", &a); int b = 0; scanf("%d", &b); int c = a + b; printf("%d", c); return 0; } |
算法的三种结构:
1 顺序结构:程序的运行顺序与编码顺序相同。
#include int main(){ // 输入一个半径 int r scanf // 求圆的面积 3.14 * r * r // 输出 圆的面积 printf int r = 0; printf("请输入圆的半径:"); scanf("%d", &r); float s = 3.14 * r * r;
printf("圆的面积是:%f", s); return 0; } |
2 选择结构:根据条件不同执行不同的代码;
语法: if (条件){ 语句; } |
语法2: if (条件){ 语句1; } else{ 语句2; } |
#include int main(){ // 1 输入可乐的价格 float price // 2 输入你的口袋里的金额 float money // 3 如果钱够 就输出 购买成功 // 4 否则 输出 金额不足。
float price = 0; printf("请输入可乐的价格:"); scanf("%f", &price); float money = 0; printf("请输入你口袋的金额:"); scanf("%f", &money); if (money >= price){ printf("购买成功"); } else{ printf("金额不足"); } return 0; } |
语法 3 if (条件1){ 语句1; } else if (条件2){ 语句2; } else{ 语句3; } |
#include int main(){ // 请输入C语言成绩 int a // 成绩 >= 90 优 // 成绩 >= 80 良 // 成绩 >= 60 及格 // 成绩 < 60 不及格
int a = 0; printf("请输入C语言成绩:"); scanf("%d", &a); if (a >= 90) { printf("优"); } else if (a >= 80){ printf("良"); } else if (a >= 60){ printf("及格"); } else { printf("不及格"); }
return 0; } |
注意: 1 大括号成对出现 2 if这行的条件后面不能加 分号(;) 3 只要有条件 就要有if,只要有if 就要有条件;else 可以单独一行 |
算法的三种结构:
1 顺序结构:程序的执行顺序与编码顺序相同。
2 选择结构
If-else
switch-case
switch (要判断的变量){ case 可能的值1: 语句1; break; case 可能的值2: 语句2; break; .... case 可能的值n: 语句n; break; default: 语句n + 1; break; } |
switch 可能 case 情况 break 跳出语法 default 默认的 |
#include int main(){ //S small 160 -- 165 //M middle 165 -- 170 //L large 170 -- 175 // 请输入衣服的规格;输出对应的身高。 // S M L 之外的 输出 输入错误; char a = 0; printf("请输入衣服的规格:"); scanf("%c", &a); switch (a){ case 'S': printf("160 -- 165"); break; case 'M': printf("165--170"); break; case 'L': printf("170--175"); break; default: printf("输入错误"); break; } return 0; } |
#include int main(){ // 请输入你的名次: int // 1 获得 IPNONE 7 一台 // 2 获得三星note7 一台 // 3 华为荣耀7 一台 // 其他 谢谢参与 int a = 0; printf("请输入你的名次:"); scanf("%d", &a); switch (a){ case 1: printf("获得 IPNONE 7 一台"); break; case 2: printf("获得三星note7 一台"); break; case 3: printf("获得华为荣耀7一台"); break; default: printf("谢谢参与"); break; } return 0; } |
注意事项: 1 switch 只能判断特定的值,不能判断范围 2 switch 只能对整型和字符型变量进行判断,不能对浮点型进行判断。 3 switch 中break 不能少; 4 switch 的case中判断的值不能重复 |
循环结构:
语法: while (条件){ 语句; } |
其中最复杂的是第二步 |
算法的三种结构:
1 顺序结构:
2 选择结构:
1 if-else
2 switch-case
3 循环结构:
1 while
1 初始化:为循环做准备 2 条件判断:判断是否继续执行。 3 语句执行:需要解决的问题。 4 条件变化:为了可以退出循环。 |
2 for
for (初始化; 条件判断; 条件改变){ 语句执行; } |
for (int a = 0; a < 10; a++){ printf("hello\n"); } |
int s = 0; int a = 0; while (a < 10){ s = s + a; a++; } 或者: int s = 0; for (int i = 0; i < 10; i++){ s = s + i; } |
当循环的次数定了的时候,一般用for 当循环的次数不确定的时候,一般用while |
break:破坏循环结构,跳出整个循环。
for (int i = 0; i < 10; i++){ if (i == 5){ break; } printf("%d\n", i); } |
continue:跳过当前循环的剩余代码,进入下一次循环
for (int i = 0; i < 10; i++){ if (i == 5){ continue; } printf("%d\n", i); } |
// 循环输入一个数,如果是0就终止; break int a = 0; while (1){ printf("请输入一个整数:"); scanf("%d", &a); if (a == 0){ break; } } 或者: int a = 0; printf("请输入一个数"); scanf("%d", &a); while (a != 0){ printf("请输入一个数"); scanf("%d", &a); } 或者: int a = 1; while (a != 0){ printf("请输入一个数"); scanf("%d", &a); } |
do-while:当要先做再判断时使用。
do{ 语句; } while (条件); |
//先输入在判断。 int a = 0; do{ printf("请输入一个数"); scanf("%d", &a); } while (a != 0); |
#include int main(){ //输入一个数。倒叙输出各个位上的数。 //123456 6 5 4 3 2 1 // 1输出个位上的数 %10 // 2将这个数去掉个位上的数。 / 10 // 3当这个数最后变成0时结束 int a = 0; printf("请输入一个正整数:"); scanf("%d", &a); while(a != 0){ int b = a % 10; printf("%d\n", b); a = a / 10; } return 0; } |
#include int main(){ //输入两个数。求他们的最大公约数。 //公约数:8 a 12 b 1 2 4 i a%i== 0 && b%i==0 // 1 输入两个数。 // 2 求出两个数中最小的那个c。 // 3 从1到c // 4 将得到的所有的公约数依次赋值给d d的最终值就是最大的 //找到的最后的那个就是最大公约数 int a = 0; int b = 0; printf("请输入两个数a和b:"); scanf("%d %d", &a, &b); int c = a > b ? b : a; int d = 0;
for (int i = 1; i <= c; i++){ if (a % i == 0 && b % i == 0){ d = i; } } printf("%d和%d的最大公约数是:%d", a, b, d); return 0; } |
#include int main(){ //输入一个数。判断这个数是否是质数。 //只能被1 和本身整除的数。 //只要能被2---本身- 1 中任意一个数整除 就不是质数 // 1 输入一个数a // 2 从 2 -- a-1 i; // 3 判断 a%i== 0 如果能 就不是。 // 4 当说有的数都被判断过才能确定它是质数 int a = 0; printf("请输入一个数:"); scanf("%d", &a); int c = 0; for (int i = 2; i <= a - 1; i++){ if (a % i == 0){ printf("不是质数\n"); break; } if (i == a - 1){ printf("是质数\n"); } } return 0; } |
If-else
1 多重if
If(){ }else if(){ }else if(){ } ... else{ } 适用的例子就是我们的考试成绩例子 |
2 嵌套if
#include int main(){ //超市买东西,结账: // 0 200以内不打折 200 9.5 // 1 100 以内 95折 100--200 - 9折 200以上 85折 //先输入是否会员 0 代表不是 1代表是 int //再输入购买金额 float int m = 0; printf("请输入是否会员:"); scanf("%d", &m); float buy = 0; printf("请输入购买金额:"); scanf("%f", &buy); float pay = 0; if (m == 0){ //不是会员 if (buy < 200){ pay = buy; } else{ pay = buy * 0.95; } } else{ //是会员 if (buy < 100){ pay = buy * 0.95; } else if (buy < 200){ pay = buy * 0.9; } else { pay = buy * 0.85; } } printf("请支付%f元", pay); return 0; } |
总结:当要判断的对象是单一的情况下,用多重if
如果判断的对象是多个的情况下,用嵌套
#include int main(){ //输入一个数。倒叙输出各个位上的数。 //123456 6 5 4 3 2 1 // 1输出个位上的数 %10 // 2将这个数去掉个位上的数。 / 10 // 3当这个数最后变成0时结束 int a = 0; printf("请输入一个正整数:"); scanf("%d", &a); while(a != 0){ int b = a % 10; printf("%d\n", b); a = a / 10; } return 0; } |
#include int main(){ //输入两个数。求他们的最大公约数。 //公约数:8 a 12 b 1 2 4 i a%i== 0 && b%i==0 // 1 输入两个数。 // 2 求出两个数中最小的那个c。 // 3 从1到c // 4 将得到的所有的公约数依次赋值给d d的最终值就是最大的 //找到的最后的那个就是最大公约数 int a = 0; int b = 0; printf("请输入两个数a和b:"); scanf("%d %d", &a, &b); int c = a > b ? b : a; int d = 0;
for (int i = 1; i <= c; i++){ if (a % i == 0 && b % i == 0){ d = i; } } printf("%d和%d的最大公约数是:%d", a, b, d); return 0; } |
#include int main(){ //输入一个数。判断这个数是否是质数。 //只能被1 和本身整除的数。 //只要能被2---本身- 1 中任意一个数整除 就不是质数 // 1 输入一个数a // 2 从 2 -- a-1 i; // 3 判断 a%i== 0 如果能 就不是。 // 4 当说有的数都被判断过才能确定它是质数 int a = 0; printf("请输入一个数:"); scanf("%d", &a); int c = 0; for (int i = 2; i <= a - 1; i++){ if (a % i == 0){ printf("不是质数\n"); break; } if (i == a - 1){ printf("是质数\n"); } } return 0; } |
If-else
1 多重if
If(){ }else if(){ }else if(){ } ... else{ } 适用的例子就是我们的考试成绩例子 |
2 嵌套if
#include int main(){ //超市买东西,结账: // 0 200以内不打折 200 9.5 // 1 100 以内 95折 100--200 - 9折 200以上 85折 //先输入是否会员 0 代表不是 1代表是 int //再输入购买金额 float int m = 0; printf("请输入是否会员:"); scanf("%d", &m); float buy = 0; printf("请输入购买金额:"); scanf("%f", &buy); float pay = 0; if (m == 0){ //不是会员 if (buy < 200){ pay = buy; } else{ pay = buy * 0.95; } } else{ //是会员 if (buy < 100){ pay = buy * 0.95; } else if (buy < 200){ pay = buy * 0.9; } else { pay = buy * 0.85; } } printf("请支付%f元", pay); return 0; } |
总结:当要判断的对象是单一的情况下,用多重if
如果判断的对象是多个的情况下,用嵌套
双重循环:循环里面嵌套循环
1 外层循环 用i 控制 ;内层循环 用j控制
2 i是用来控制行数 j是用来控制列数。
#include int main(){ //**** //**** //**** //**** for (int i = 0; i < 4; i++){ for (int j = 0; j < 4; j++){ printf("*"); } printf("\n"); } return 0; } |
当我们阅读双重循环的代码时:
我们可以将外层循环的i的值先固定,然后将注意力放在内层循环上。
可以将双重循环简化成单重循环。
1*1 1*2 1*3 1*4 1*5 1*6 1*7 1*8 1* 9
2*1 2*2 2*3 2*4 2*5 2*6 2*7 2*8 2* 9
3*1 3*2 3*3 3*4 3*5 3*6 3*7 3*8 3* 9
4*1 4*2 4*3 4*4 4*5 4*6 4*7 4*8 4* 9
5*1 5*2 5*3 5*4 5*5 5*6 5*7 5*8 5* 9
6*1 6*2 6*3 6*4 6*5 6*6 6*7 6*8 6* 9
7*1 7*2 7*3 7*4 7*5 7*6 7*7 7*8 7* 9
8*1 8*2 8*3 8*4 8*5 8*6 8*7 8*8 8* 9
9*1 9*2 9*3 9*4 9*5 9*6 9*7 9*8 9* 9=81
#include int main(){ for (int i = 1; i <= 9; i++){ for (int j = 1; j <= 9; j++){ printf("%d*%d=%d\t", i, j, i*j); } printf("\n"); } return 0; } |
1*1
2*1 2*2
3*1 3*2 3*3
4*1 4*2 4*3 4*4
5*1 5*2 5*3 5*4 5*5
6*1 6*2 6*3 6*4 6*5 6*6
7*1 7*2 7*3 7*4 7*5 7*6 7*7
8*1 8*2 8*3 8*4 8*5 8*6 8*7 8*8
9*1 9*2 9*3 9*4 9*5 9*6 9*7 9*8 9* 9
for (int i = 1; i <= 9; i++){ for (int j = 1; j <= i; j++){ printf("%d*%d=%d\t", i, j, i*j); } printf("\n"); } |
#include int main(){ *难度 for (int i = 0; i < 4; i++){ for (int j = 0; j < 4; j++){ printf("*"); } printf("\n"); } **难度 for (int i = 0; i < 4; i++){ for (int j = 0; j < 4; j++){ printf("%d",i); } printf("\n"); } ***难度 for (int i = 0; i < 4; i++){ for (int j = 0; j < 4; j++){ printf("%d",10 * i+j); } printf("\n"); } ****难度 for (int i = 1; i <= 9; i++){ for (int j = 1; j <= i; j++){ printf("%d*%d=%d\t", i, j, i*j); } printf("\n"); } return 0; } |
c语言调试:
F5 一直运行,直到碰到第一个断点
F9 下断点,取消断点
F10 单步运行,检查每一步的运行结果
F11 ...
双重循环:循环里面嵌套循环。
1 外层循环用i,内层用j
2 i控制行数,j控制列数
#include int main(){ /*11 22 33 44 55 66 77 88 99*/ for (int i = 0; i < 3; i++){ for (int j = 0; j < 3; j++){ printf("%d ", (i * 3 + j + 1) * 11); } printf("\n"); } return 0; } |
#include int main(){ //编写一个程序,求 //s = 1 + (1 + 2) + (1 + 2 + 3) + .... + //(1 + 2 + 3 + .... + 100)的和 //分析:1 对于每一项我们都会 // 2 把每一项的求和 ,重复 int s = 0; for (int i = 1; i <= 100; i++){ for (int j = 1; j <= i; j++) { s = s + j; } } printf("%d", s);
return 0; } |
#include int main(){ //输出3 -- 1000以内所有的质数 for (int i = 3; i <= 1000; i++){ for (int j = 2; j <= i - 1; j++){ if (i % j == 0){ break; } if (j == i - 1){ printf("%d是质数\n", i); } } } return 0; } |
%x 代表使用十六进制查看数据。
指针:实际上就是内存的地址;
要得到一个变量的地址,只要在这个变量前面加上&;
1 每一次运行同一个变量得到的地址都不相同:因为操作系统每次给程序
分配的内存不同。
int a = 0; int b = &a; printf("%x", b); Error:无法从int * 转化为 int |
指针(地址)也是可以存在变量中的,指针的数据类型是数据的数据类型加‘*’,
即:int 的地址的 指针变量类型为 int*
char 的地址的 指针变量类型为 char*
所有的地址类型所占的内存都是一样的,4个字节 32位
#include int main(){ //有一个字符 'x';请输出这个字符在内存中的地址。
char a = 'x'; int b = 4; float c = 4.0f; double d = 8.0; char * e = &a; int * f = &b; float * g = &c; double * h = &d; printf("char 占得字节数为%d\n", sizeof(a)); printf("int 占得字节数为%d\n", sizeof(b)); printf("float 占得字节数为%d\n", sizeof(c)); printf("double 占得字节数为%d\n", sizeof(d)); printf("char* 占得字节数为%d\n", sizeof(e)); printf("int* 占得字节数为%d\n", sizeof(f)); printf("float* 占得字节数为%d\n", sizeof(g)); printf("double* 占得字节数为%d\n", sizeof(h)); return 0; } |
可以通过地址查看内存中的值 只要在地址前加 *
#include int main(){ //有一个字符 'x';请输出这个字符在内存中的地址。 char a = 'x'; char* b = &a; printf("%x\n", b); printf("char* 占%d个字节\n",sizeof(b)); printf("%c\n", a); printf("%c\n", *b); return 0; } |
#include int main(){ int a = 3; int* c = &a; *c = 5; printf("%d", a); return 0; } |
指针不但可以读取内存的数据,还可以改变内存的数据。
int main(){ //有一个变量a=3 一个变量b = 4 //交换a和b的值 int a = 3; int b = 4; int c = 0; printf("交换前%d %d\n", a, b); c = a; a = b; b = c; printf("交换后%d %d\n", a, b); return 0; } |
#include int main(){ //有一个变量a=3 一个变量b = 4 //通过指针交换a和b的值 int a = 3; int b = 4; int c = 0; int* p = &a; int* p1 = &b; printf("交换前%d %d\n", a, b); c = *p; *p = *p1; *p1 = c; printf("交换后%d %d\n", a, b); return 0; } |
#include int main(){ int a = 3; printf("%d\n",*(&a)); return 0; } |
* 与 & 一起用,相互抵消。
指针:内存的地址。
%x 表示以十六进制查看数据 %d 表示以十进制查看数据。
1 可以通过 &+变量名 的方式查看内存地址
#include int main(){ int a = 3; printf("%d", &a); return 0; } |
2 指针变量是有自己的数据类型的 (如:int*)
所有的数据类型 有自己对应的指针变量类型:
Int -> int* float->float* char->char* double->double *
#include int main(){ int a = 3; printf("%x ", &a); int* b = &a; printf("%x", b); float c = 0.3f; float* d = &c; return 0 ; } |
3 所有的指针变量所占的字节数相同。都是4个字节。
#include int main(){ int a = 3; printf("int 占得字节数为%d\n ", sizeof(a)); int* b = &a; printf("int* 占得字节数为%d\n ", sizeof(b)); float c = 0.3f; printf("float 占得字节数为%d\n ", sizeof(c)); float* d = &c; printf("float* 占得字节数为%d\n ", sizeof(d)); char e = 'x'; printf("char 占得字节数为%d\n ", sizeof(e)); char* f = &e; printf("char* 占得字节数为%d\n ", sizeof(f)); double g = 0.8; printf("double 占得字节数为%d\n ", sizeof(g)); double* h = &g; printf("double* 占得字节数为%d\n ", sizeof(h)); return 0 ; } |
4 可以通过 *+指针 查看内存的值。
#include int main(){ int a = 3; int* p = &a; printf("%d ", a); printf("%d ", *p); return 0 ; } |
5 可以通过*+ 指针 改变内存的内容
#include int main(){ int a = 3; int* p = &a; *p = 5; printf("%d", a); return 0 ; } |
交换的基本套路。
#include int main(){ // 输入两个数a和b 交换ab的值。输出a和b; int a = 0, b = 0; printf("请输入两个数:"); scanf("%d %d", &a, &b); //交换 int c = 0; c = a; a = b; b = c; printf("%d %d", a, b); return 0 ; } |
#include int main(){ // 输入两个数a和b 使用指针交换ab的值。输出a和b; int a = 0, b = 0; printf("请输入两个数:"); scanf("%d %d", &a, &b); int* p1 = &a; int* p2 = &b; //交换 int c = 0; c = *p1; *p1 = *p2; *p2 = c; printf("%d %d", a, b); return 0 ; } |
int main(){ int a = 3; printf("%d", *&a); return 0 ; } |
1.指针就是地址,指针绑定了一块内存
2.指针的类型:是一种人为想象出来的数据类型,不是你看到的类型
根据变量的数据类型来确定,在变量的数据类型后面加*
3.指针的加减运算:
加了指针绑定的字节数
4.扩展变量的作用域!
- //交换两个数
- void swap(int* p, int* q)//形参
- {
- int t = *p;
- *p = *q;
- *q = t;
- }
-
- int main(void)
- {
- int a = 10;
- int b = 20;
- swap(&a,&b);//交换了上面的a b,并没有交换主函数中a b
- printf("%d %d\n", a, b);//20 10
- return 0;
- }
1.函数的定义
返回值类型 函数名(形式参数)
{
函数体
}
注意:
1>有且仅有一个主函数,可以有0---多个子函数
2.函数的调用
调用时写出的参数叫“实际参数”,形参和实参的个数要一致,且类型也最好一致
注意:
1>先定义再调用
2>主函数不能被调用,子函数之间可以相互调用
3>一个函数A调用了另一个函数B,我们把这种调用叫“嵌套调用”
自己调用自己叫做“递归调用”
3.函数的声明:
扩展函数的作用域
- void Play(void);
- void Eat(void);
- void Drink(void);//函数的声明
-
- int main(void)
- {
- Eat();
- return 0;
- }
1.函数的定义:
- 返回值类型 函数名(形式参数){
- }函数体
- .返回值类型要和return后表达式的值保持一致!
- int m(void){ return 3.4;}//会将3.4转换成3
- void m(void){
- return;//return语句后可以不写数值.
- printf("好累啊.\想睡觉,就睡吧。\n");
- }
.return [表达式]; 返回表达式的值并且结束函数的执行
2.函数的分类
。主函数:有且仅能有一个,程序从主函数开始执行,主函数执行完程序也就结束了
。子函数:可以有多个子函数
。主调函数
。被调函数
3.函数的调用;
。函数名(实际参数);
实际参数和形参的个数及类型要一致.
调用流程:step1.参数传递 step2.执行函数体 step3.返回
4.函数的声明。
函数和变量要先定义再使用.
5.作用域的概念
1>程序的构成.
文件--->函数--->语句(有可能含有语句块)
2>作用域的分类
文件作用域
函数作用域
语句块作用域
3>在不同的作用域中可以含有相同名字的对象
- 局部有先
- void ww(void){
- int a = 20;{
- printf("%d", a);//20
- int a = 30;
- printf("%d", a);//30
- }
- printf("%d", a);//20
- }
- int main(void){
- int a = 10;
- ww();
- printf("%d", a);//10
- return 0;
- }
4> 函数只能定义在文件作用域
变量和数组想定义在哪个作用域都可以!
5>作用域的扩展
- 。全局变量----extern
- 。全局函数----extern
- 。局部变量----指针
- extern void foo(void);
- extern int wl;
- int main(void){
- int asb = 10;//?
- wl = 100;
- foo(&asb);
- return 0;
- }
- int wl = 0;//全局变量,extern
- void foo(int* p){//全局函数,extern
- printf("%d", *p);
- }
-
- void f(int* p){
- *p = 100;
- }
-
- int main(void){
- int a = 10;//通过指针扩展
- f(&a);
- printf("%d", a);
- return 0;
- }
6>函数的设计规范
.保证一个函数只有一个功能
.有多少个功能就写多少个函数
- #include
- int add(int a, int b){
- return a + b;
- }
- int sub(int a, int b){
- return a - b;
- }
- int mul(int a, int b){
- return a * b;
- }
- int divide(int a, int b){
- return a / b;
- }
- void menu(void){
- system("cls");
- printf("=======菜单========\n");
- printf("1.加法.\n");
- printf("2.减法.\n");
- printf("3.乘法.\n");
- printf("4.除法.\n");
- printf("0.退出.\n");
- printf("=================\n");
- printf("请选择[0--4]:");
- }
- int select(void)
- {
- int sel = 0;
- scanf("%d", &sel);//a
- return sel;
- }
- void set(int* p, int* q){
- printf("请输入第一个数:");
- scanf("%d", p);
- printf("请输入第二个数:");
- scanf("%d", q);
- }
- void compute(void)
- {
- int a = 0, b = 0;
- while (1)
- {
- menu();
- switch (select())
- {
- case 1:set(&a, &b); printf("结果是:%d", add(a, b)); break;
- case 2:set(&a, &b); printf("结果是:%d", sub(a, b)); break;
- case 3:set(&a, &b); printf("结果是:%d", mul(a, b)); break;
- case 4:set(&a, &b); printf("结果是:%d", divide(a, b)); break;
- case 0:exit(0);//exit(0)用于结束程序
- default:printf("错误,请输入0--4的值.\n"); break;
- }
- system("PAUSE");
- }
- }
- int main(void){
- compute();
- return 0;
- }
- //作业:
- //1.数组逆置!
- void reverse(int* p, int len)
- {
-
- }
- //2.写函数DTB, n存放待转换的十进制数, p指向存储二进制数的数组!
- void DTB(int n, int* p)
- {
-
- }
- int main(void){
-
- DTB(a, sizeof(a)/sizeof(int));
- return 0;
- }
函数:将程序模块化。
1 返回值类型 (int char void )
2 函数名
3 参数 (桥梁) (int char float double int *
4 函数体
5 返回值。(桥梁)
#include int sum(int num1,int num2){ int c = num1 + num2; return c; } int main(){ int a = 10; int b = 5; int res = sum(a, b); printf("%d", res); return 0; } |
参数分为 形参 和 实参 。
形参 是实参的一个拷贝
#include // 交换两个数 a 和b的值 void change(int num1, int num2){ int c = num1; num1 = num2; num2 = c; } int main(){ int a = 10; int b = 5; change(a, b); printf("%d,%d", a, b); return 0; } |
#include // 交换两个数 a 和b的值 void change(int* p1, int* p2){ int c = *p1; *p1 = *p2; *p2 = c;
} int main(){ int a = 10; int b = 5; int* p = &a; int*pp = &b; change(p, pp); printf("%d,%d", a, b); return 0; } |
函数的返回值实际是存到 eax寄存器中作为结果
使用数组作为参数传递
//int max(int aa[5]) //传递的是指针 //int max(int aa[]) //传递的是指针 int max(int* aa,int num){ //传递的是指针 //printf("%d ", sizeof(aa)); int maxNum = aa[0]; for (int i = 1; i < num; i++){ if (maxNum < aa[i]){ maxNum = aa[i]; } } return maxNum; } int main(){ int a[] = { 1, 2, 5, 30, 4,90,70,60 ,89,900,765,45678}; int num = sizeof(a) / sizeof(a[0]); int ret = max(a,num); printf("%d", ret); return 0; } |
编译的过程是从上往下依次编译
函数的声明 和 定义。
声明:没有函数体的
定义:函数的实现,有函数体的。
C语言中的内存分布:
当多个函数需要共享变量时,使用全局静态区域。
当你需要申请较大的空间时,从堆中申请
否则从栈中申请。
1 栈 系统为每个函数调用分配的空间 叫栈
函数调用结束,这次调用的函数产生的栈空间,会被释放。(临时内存块)
局部变量和形参的空间都在栈中分配
栈的内存多大?1M 左右。
2 堆(Malloc) 物理内存的绝大部分。如何申请堆内存?
Malloc 堆内存申请函数,单位字节。
3 静态(全局)区域
在函数外申请的空间。
全局变量系统会将它初始化为0
Static 静态的。
#include void f1(); int main(){ f1(); f1(); return 0; } void f1(){ static int b = 0; //静态变量 不会被释放 b++; printf("%d ", b); } |
#include void f1(); int main(){ f1(); f1(); return 0; } void f1(){ int b = 0; //局部变量 会被释放 b++; printf("%d ", b); } |
函数的调用:
1 嵌套调用
#include void f1(); void f2(); void f3(); int main(){ f1(); return 0; } void f1(){ printf("f1\n"); f2(); } void f2(){ printf("f2\n"); f3(); } void f3(){ printf("f3\n"); } |
#include #include int b[10]; int main(){ int a[10] = { 0 }; // 在堆中申请空间。 //int p[10]; //在栈中申请空间 int i = 0; while (1){ int* p1 = (int*)malloc(100000000); if (p1 == 0){ printf("error\n"); break; } else{ i++; printf("1 "); free(p1); } } printf("%d ",i); return 0; } |
内存的分布:
1 栈:调用函数时,系统给函数分配的空间。
局部变量 形参
2 堆:系统的大部分物理内存。
malloc ---> int* p = (int*)malloc(20 * sizeof(int));
Free 释放
内存泄漏
记得 谁申请 谁释放。
3 静态(全局)区域:
自动初始化为0
文件共享。
变量的作用域:
全局变量的范围是整个文件。
局部变量(形参)的范围是变量所在函数。
当有多个相同的变量在不同的作用域中时,访问的是最近的这个变量(就近原则)
int a = 1; int main(){ { int a = 10; } { int a = 100; } printf("%d ", a); return 0; } |
函数的嵌套调用:
void f2(); void f1(){ f2(); } void f2(){ } int main(){ f1(); return 0; } |
函数的递归调用:
1 自己调用自己;
2 必定有退出条件。
int fn(int n){ if (n == 0) return 1; return n * fn(n - 1); } int main(){ int num = 10; int ret = fn(num); printf("%d", ret); return 0; } |
int f(int n){ if (n == 0) return 0; if (n == 1) return 1; return f(n - 1) + f(n - 2); } int fn(int n){ if (n == 0) return 1; return n * f(n - 1); } |
二维数组:int a[行数][列数]
对于双重循环 i 控制行 j 控制列
#include #include //输入12个数,将他们存到 三行四列的数组中,求出这个数组中的最大值。 int main(){ int b[3][4]; for (int i = 0; i < 3; i++){ for (int j = 0; j < 4; j++){ printf("请输入一个数:"); scanf("%d", &b[i][j]); } }
for (int i = 0; i < 3; i++){ for (int j = 0; j < 4; j++){ printf("%d ",b[i][j]); } printf("\n"); } //假设一个值是最大值,把这个值跟其他所有的值比较,赋值 int maxNum = b[0][0]; for (int i = 0; i < 3; i++){ for (int j = 0; j < 4; j++){ if (maxNum < b[i][j]){ maxNum = b[i][j]; } } } printf("最大的值是%d ", maxNum); return 0; } |
字符串:多个字符。字符数组。
char b[10] = { 'r', 'o', 's', 'e' }; printf("%s", b); |
对于字符串来说:它需要的空间比你需要存储的字符的个数要多一个。
这个是结束符,值是0 ‘\0’
一个字节对应一个英文字符
两个字节对应一个汉字
字符串的表示
char b[5] = “rose”; |
char * b = "rose"; |
1 这个字符串占了多少字节 +1
2 这个字符串的长度。 == 字符的个数
#include #include //int slen(char * b){ // int len = 0; // // while (*b != 0){ // len++; // b++; // } // // // return len; //} int main(){ char * b = "abcdabcdabcdabcdabcdabcd"; int ret = strlen(b); printf("%d", ret); return 0; } |
如何输入输出一个字符串。
int main(){ char a[100]; printf("请输入一个字符串"); scanf("%s", a); printf("输入的字符串为%s", a); return 0; } |
int main(){ char a[100]; printf("请输入一个字符串"); gets(a); puts(a);
return 0; } |
//输入一个字符串。判断这个字符串是不是回文 #include #include int main(){ char a[100]; int isTrue = 0; printf("请输入一个字符串:\n"); gets(a); int len = strlen(a); for (int i = 0; i < len / 2;i++) { if (a[i] == a[len - 1 - i]){ isTrue++; } else{ break; } } if (isTrue == len / 2){ printf("是回文"); } else{ printf("不是回文"); } return 0; } |