带你学C带你飞(2)

小甲鱼C语言系列课程笔记,共61个视频,每6个视频总结一次笔记,预计10篇。

https://www.bilibili.com/video/BV17s411N78s

取值范围

CPU能读懂的最小单位:比特位,bitb
内存最小寻址单位:字节,ByteB
1B = 8b

符号位

signed类型的存储单元中,第一位是符号位。0为正,1为负。

示例

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
#include <math.h>

int main()
{
// pow函数计算幂,需要导入<math.h>
// unsigned int result = pow(2, 32) - 1;
int result = pow(2, 31) - 1; // 去掉符号位
// printf("result = %u\n", result);
printf("result = %d\n", result);
return 0;
}

字符和字符串

1
2
3
4
5
6
7
8
9
// test1.c
#include <stdio.h>

int main()
{
char a = 'C';
printf("%c = %d\n", a, a); // ASCII
return 0;
}
1
2
3
4
5
6
7
8
9
// test2.c
#include <stdio.h>

int main()
{
char a = 70, b = 105, c = 115, d = 104, e = 67; // FishC
printf("%c%c%c%c%c\n", a, b, c, d, e);
return 0;
}

字符串

1
char 变量名[数量]

示例

1
2
3
4
5
6
7
8
#include <stdio.h>

int main()
{
char a[5] = {'F', 'i', 's', 'h', 'C'};
printf("%s\n", a);
return 0;
}

算术运算符

运算符 名称 例子 结果
+ 5 + 3 8
- 5 - 3 2
* 5 * 3 15
/ 5 / 3 1
5.0 / 3.0 1.666667
% 取余 5 % 3 2
5.0 % 3.0 出错
+ 正号 +5 5
- 负号 -5 -5

运算符的优先级

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <math.h>

int main()
{
int i, j, k;
i = 1 + 2;
j = 1 + 2 * 3;
k = i + j + -1 + pow(2, 3);
printf("i = %d\n", i);
printf("j = %d\n", j);
printf("k = %d\n", k);
return 0;
}

类型转换

1
2
3
4
5
6
7
8
9
#include <stdio.h>
#include <math.h>

int main()
{
printf("整型输出:%d\n", 1 + 2.0);
printf("浮点型输出:%f\n", 1 + 2.0);
return 0;
}

运行结果
运行结果

强制类型转换

1
2
3
4
5
6
7
8
9
#include <stdio.h>
#include <math.h>

int main()
{
printf("整型输出:%d\n", 1 + (int)2.0); // 将2.0强制转换为int
printf("浮点型输出:%f\n", 1 + 2.0);
return 0;
}

运行结果

运行结果

浮点数强转为整型,无四舍五入,直接舍去小数部分。

关系运算符、逻辑运算符

关系运算符

1
< <= > >= == !=

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>

int main()
{
int a = 5, b = 3;

printf("%d\n", 1 < 2);
printf("%d\n", a > b);
printf("%d\n", a <= b + 1);
printf("%d\n", 'a' + 'b' <= 'c');
printf("%d\n", (a = 3) > (b = 5));

return 0;
}

运行结果:1为真,0为假

运行结果

逻辑运算符

运算符 含义 优先级 举例 说明
! !a 如果a为真,则!a为假;如果a为假,则!a为真
&& a && b ab同真,真;任一为假,假
|| a || b ab同假,假;任一为真,真

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>

int main()
{
int a = 5, b = 3;
printf("%d\n", a > 1 && 1 < b);
printf("%d\n", a + 1 || 2 == 0);
printf("%d\n", !(a + b));
printf("%d\n", !0 + 1 < 1 || !(3 + 4));
printf("%d\n", 'a' - 'b' && 'c');

return 0;
}

运行结果:编写代码时,任何非0都表示真,只有0表示假

运行结果

短路求值

又称最小化求值,是一种逻辑运算符的求值策略。
只有当第一个运算数的值无法确定逻辑运算的结果时,才对第二个运算数进行求值。

C语言对 与 或 采用短路求值。

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>

int main()
{
int a = 3, b = 3;
(a = 0) && (b = 5);
printf("a = %d, b = %d\n", a, b);
(a = 1) || (b = 5);
printf("a = %d, b = %d\n", a, b);
return 0;
}

短路求值,运行结果:
a = 0赋值已经成立,&&就不再执行b = 5
a = 1赋值已经成立,||就不再执行b = 5

运行结果

if语句

单分支

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>

int main()
{
int i;
printf("您老贵庚啊:");
scanf("%d", &i); // 获取输入
if (i >= 18)
{
printf("进门左拐!\n");
}
return 0;
}

运行结果

双分支

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>

int main()
{
int i;
printf("您老贵庚啊:");
scanf("%d", &i);
if (i >= 18)
{
printf("进门左拐!\n");
}
else
{
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
#include <stdio.h>

int main()
{
int i;
printf("请输入分数:");
scanf("%d", &i);
if (i >= 90)
{
printf("分数等级为:A\n");
}
else if (i >= 80 && i < 90)
{
printf("分数等级为:B\n");
}
else if (i >= 70 && i < 80)
{
printf("分数等级为:C\n");
}
else if (i >= 60 && i < 70)
{
printf("分数等级为:D\n");
}
else
{
printf("分数等级为:E\n");
}
return 0;
}

运行结果

switch语句和分支嵌套

switch语句结构

1
2
3
4
5
6
7
8
9
switch (表达式)
{
case 常量表达式1: 语句1; break;
case 常量表达式2: 语句2; break;
case 常量表达式3: 语句3; break;
……
case 常量表达式n: 语句n; break;
default: 语句n+1; break;
}

示例:评级反推成绩

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
#include <stdio.h>

//通过评级反推分数范围,使用switch
int main()
{
char c;
printf("请输入评级:");
scanf("%c", &c);
switch (c)
{
case 'A':
printf("90+\n");
break;
case 'B':
printf("80-90\n");
break;
case 'C':
printf("70-80\n");
break;
case 'D':
printf("60-70\n");
break;
case 'E':
printf("60-\n");
break;
default:
printf("输入错误\n");
break;
}
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
#include <stdio.h>

//根据流程图写代码
int main()
{
int a, b;
printf("请输入a和b的值:");
scanf("%d %d", &a, &b);
if (a != b)
{
if (a > b)
{
printf("%d > %d\n", a, b);
}
else
{
printf("%d < %d\n", a, b);
}
}
else
{
printf("%d = %d\n", a, b);
}
return 0;
}

bug:悬挂else

else始终与最近的if匹配,不考虑缩进问题。

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
//错误代码
#include <stdio.h>

int main()
{
char isRain, isFree;

printf("是否有空?(Y/N)");
scanf("%c", &isFree);

getchar(); //过滤回车

printf("是否下雨?(Y/N)");
scanf("%c", &isRain);

if (isFree == 'Y')

if (isRain == 'Y')
printf("记得带伞哦!\n");

else //悬挂else
{
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
#include <stdio.h>

int main()
{
char isRain, isFree;

printf("是否有空?(Y/N)");
scanf("%c", &isFree);

getchar(); //过滤回车

printf("是否下雨?(Y/N)");
scanf("%c", &isRain);

if (isFree == 'Y')
{
if (isRain == 'Y')
{
printf("记得带伞哦!\n");
}
}
else //悬挂else
{
printf("女神没空!\n");
}
return 0;
}

bug:等号问题

赋值用=,判断是否相等用==

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 正确代码
#include <stdio.h>

int main()
{
char hasBF;

printf("小花是否有男朋友?(Y/N)");
scanf("%c", &hasBF);
if (hasBF == 'Y') // 逻辑用==,赋值用=
{
printf("那……祝福你们咯!\n");
}
else
{
printf("那我们在一起吧!\n");
}
return 0;
}