C 语言复习总结记录二
一 控制语句
1、语句的分类
- 表达式语句
- 函数调用语句
- 复合语句
- 控制语句
- 空语句
控制语句 控制程序的执行流程,实现程序的各种结构方式
C 语言支持三种结构 :顺序结构、选择结构、循环结构,由特定的语句定义符组成C语言有九种控制语句,可分成以下三类:
-
条件判断语句也叫分支语句:if 语句、switch 语句
-
循环执行语句:do while 语句、while 语句、for 语句
-
转向语句:break 语句、goto 语句、continue 语句、return 语句
2、分支语句
0 表示假,非 0 即为真
int score = 0;
scanf("%d", &score);
if (score >= 90)
{
printf("恭喜你,及格了");
}
else
{
printf("继续加油吧");
}
//else 是和它离的最近的 if 匹配的
int a = 0, b = 2;
if (a == 1)
if (b == 2)
printf("b == 2 !");
else
printf("a != 1 !");
判断一个数是否为奇数;输出1-100之间的奇数
int main() {
//奇数 : 不能被二整除的数
int input = 0;
scanf("%d", &input);
if (input % 2) //这里用/也行, 但整除其实就是看余数, 用%更简洁
printf("The input is an odd number");
else
printf("The input is not an odd number");
for(int i = 1; i <= 100; ++i) {
if (i % 2)
printf("%d\n", i);
}
return 0;
}
switch 语句
常用于多分支的情况
例如,输入 [1, 7] 的整数,输出对应的星期几;其语句常用格式如下
switch(整型表达式)
{
case 整型常量表达式:
语句;
break;
...
default:
语句;
break;
}
break 语句的实际效果是把语句列表划分为不同的分支部分
#include <stdio.h>
int main()
{
int n = 1;
int m = 2;
switch (n)
{
case 1:
m++; //n = 1, m++ 后 m = 3, 没有 break 继续执行
case 2:
n++; //n = 2, m = 3
case 3:
switch (n)
{//switch允许嵌套使用
case 1:
n++;
case 2: //n = 2 跳转到该位置
m++;
n++;
break; //n = 3, m = 4 跳出该 switch 作用域
} //没有 break 继续向下执行
case 4:
m++;
break; //n = 3, m = 5 跳出 switch 作用域
default:
break;
}
printf("m = %d, n = %d\n", m, n);
return 0;
}
在使用 switch 语句时要在分支语句的最后加上 break; 如果不加的话后面的语句会被继续执行
无条件跳转到 .L8,如果没有 break,后面的段就会继续执行
对于 switch - case 语句的理解:
它具有 跳转 的作用,当和某一个数字或者字符匹配上的时候,就会跳转到对应的入口地址处
break 也具有 跳转 的作用,当匹配对应的时候,执行跳转到对应的入口地址,后面就会顺着这个地址一直执行下去
3 循环语句
while 循环
编写程序,要求只打印输入的数字字符,跳过其它字符,当数字字符为 6 时,终止程序
了解一些关于 getchar 和 putchar 的基础知识,EOF 在 C 语言中是一个宏定义,通常等于 -1。它用于指示输入的结束,无论是从文件读取还是从标准输入读取数据时,当没有更多数据可读时,就会遇到 EOF。(在标准输入中,通过输入特定的字符或组合来表示 EOF,Windows Ctrl+Z 回车产生EOF,Unix/Linux 则是 Ctrl+D)
scanf 和 printf 可处理各类型的数据,比如整型、字符、浮点型等,但 getchar 和putchar 只针对字符
getchar:函数原型 int getchar(void),从标准输入 stdin 获取一个字符(一个无符号字符),返回值是用户输入的字符的 ASCII 码
putchar:原型 int putchar(int c) 整数参数 c,代表需要输出的字符。主要功能是将字符 c 写入标准输出设备(通常指的是控制台窗口),并返回所写入的字符,发生错误,则返回 EOF
//该段程序即打印字符, 例如
// 输入 111'\n', 则控制台打印 111'\n'
int ch = 0;
while ((ch = getchar()) != EOF) {
putchar(ch);
}
break 跳出终止当前语句,在此处即为跳出 while 循环或终止 while 循环
continue 用于终止本次循环,直接跳转到 while 语句的判断部分,进行下一次循环的判断
char ch = '\0';
while ((ch = getchar()) != EOF) {
if (ch == '5')
break;
if (ch < '0' || ch > '9' ) //注意因为没有 ch == '\n' 时打印是重叠的
continue;
else
putchar(ch);
}
for 循环
for 循环的一般格式
for(初始化循环变量; 判断循环条件; 调整循环变量)
循环语句;
打印 1 - 10 的数字
//while 循环
int i = 1; //初始化循环变量
while (i <= 10) //判断循环条件
{
printf("%d\n", i); //循环语句
++i; //调整循环变量
}
//for 循环
for (int i = 1; i <= 10; ++i)
{
printf("%d\n", i);
}
当存在固定的循环结束条件和循环变量时,明显 for 循环的在格式上比 while 循环更简洁
建议:一般不在 for 循环体内修改循环变量,防止循环条件失去控制;一般建议循环条件的取值范围采用 前闭后开 的写法(代码便于理解)
一些 for循环变种
#include <stdio.h>
int main()
{
//1、死循环
for(;;)
{
printf("死循环");
}
//2、双层 for
int i = 0;
int j = 0;
for(i = 0; i < 2; ++i)
{
for (j = 0; j < 2; ++j)
printf("Time \n");
} //总打印 4
for(; i < 2; ++i)
{
for (; j < 2; ++j)
printf("Time \n");
} //总打印 2
//3、多变量控制循环条件
int x= 0, y = 0;
for(; x < 2 && y < 5; ++x,++y)
printf("Time \n");
//小练习, 循环执行了几次 ?
int i = 0, k = 0;
for(i =0,k=0; k = 0; i++,k++)
k++; // 0 次, 因为 k = 0 表达式的结果返回的是 k赋值后的结果为 0, 因此循环不会执行
return 0;
}
do while 循环
特点:循环至少会执行一次
#include <stdio.h>
int main(){
int i = 1, j = 1;
do {
++i;
if (i == 7) break;
if (i == 4) continue;
++j;
} while (i < 10);
printf("%d\n", j); //5
return 0;
}
4 goto 语句
C 语言中提供了可以跳转的 goto 语句和标记跳转的符号,最常见的用法是终止程序深度嵌套结构的处理过程。例如:一次跳出两层或多层循环
break 只能从最内层循环退出到上一层的循环
for(...)
for(...)
{
for(...)
{
if(disaster)
goto error;
}
}
…
error:
if(disaster)
// 处理错误情况
关机小程序
#include<stdio.h>
int main()
{
char input[10];
system("shutdown -s -t 60");
again:
printf("电脑将在1分钟内关机如果输入: 我是超人, 就取消关机 ! \n 请输入:>");
scanf("%s", &input);
if(strcmp(input, "我是超人") == 0)
system("shutdown -a");
else
goto again;
return 0;
}
//使用 while 循环替代
int main()
{
char input[10];
system("shutdown -s -t 60");
while(1){
printf("电脑将在1分钟内关机如果输入: 我是超人, 就取消关机 ! \n 请输入:>");
scanf("%s", &input);
if(strcmp(input, "我是超人") == 0)
{
system("shutdown -a");
break;
}
}
return 0;
}
练习
1、计算 n 的阶乘
int n = 0, res = 1;
scanf("%d", &n);
for (int i = 1; i <= n; ++i)
{
res *= i;
}
printf("%d\n", res);
2、计算 1! + 2! + 3! + …… + 10!
int res = 1, sum = 0;
for (int i = 1; i <= 10; ++i)
{
res *= i;
sum += res;
}
printf("%d\n", sum); //4037913
3、在一个有序数组中查找具体的某个数字 n(二分查找)
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int n = 0, left = 0, right = (sizeof(arr) / sizeof(int)) - 1;
scanf("%d", &n);
while (left <= right)
{
int index = (left + right) / 2; //数组中间元素下标
if (n > arr[index]) //比中间元素还大,说明在右侧
{
left = index + 1;
}
else if (n < arr[index])
{
right = index - 1;
}
else
{
printf("该数字在数组中对应的下标为 %d\n", index);
break;
}
}
4、编写代码,演示多个字符从两端移动,向中间汇聚
char arr[] = "Hello World!";
int left = 0, right = strlen(arr) - 1;
while (left <= right) {
printf("%s\n", arr);
arr[left] = ' ';
arr[right] = ' ';
++left;
--right;
}
5、编写代码实现,模拟用户登录情景,并且只能登录三次(只允许输入三次密码,如果密码正确则提示登录成功,如果三次均输入错误,则退出程序
int i = 1;
char password[] = "123456";
char input[10];
for (i = 1; i <= 3; ++i)
{
printf("please input:");
scanf("%s", input);
if (strcmp(input, password) == 0)
break;
}
if (i == 4)
printf("exit \n");
else
printf("login \n");
6、猜数字游戏
原型:void srand(unsigned seed);
rand 函数用来发生随机数, 当然是 伪随机数
原型:int rand(void)
seed 的作用:srand 函数的作用是根据参数 seed,设置一个随机起始点,而 rand 函数根据这个起始点,发生随机数序列。默认的随机种子为 1。如果随机种子一样,rand 函数所发生的随机序列也一样。
因此,为使每次程序运行都能发生不同的随机序列,每次都应发生一个不同的种子参数
说明 :因为 rand 的内部实现是用线性同余法做的,它不是真的随机数,只不过是因为其周期特别长,所以一定范围内可看成是随机的,rand() 会返回一随机数值,范围在0 至 RAND_MAX 间。
在调用此函数发生随机数前,必须先利用 srand() 设好随机数种子,如果未设随机数种子,rand() 在调用时会主动设随机数种子为 1。rand() 发生的是假随机数字,每次执行时是雷同的。
若要不同, 以不同的值来初始化它. 初始化的函数就是 srand()
rand() % (n + 1); 生成 [0 , n] 的整数(n < RAND_MAX),为什么 n + 1,前面是取模运算 %
rand() % (n - m + 1) + m; 生成 [m , n] 范围内的随机数
//简单的测试, 当不设置种子时默认为 1, 每次程序的执行结果都是一样的
for (int i = 0; i <= 10; ++i)
{
int res = rand();
printf("%d\n", res);
}
void menu() {
printf("*********************************\n");
printf("************ 1.play *************\n");
printf("************ 0.exit *************\n");
printf("*********************************\n");
}
void game() {
int input = -1;
int res = rand() % (9 + 1);
while (1) {
printf("请输入一个 0 - 9 的数字 \n");
scanf("%d", &input);
if (input > res)
{
printf("猜大了\n");
}
else if (input < res)
{
printf("猜小了\n");
}
else
{
printf("猜中了\n");
break;
}
}
}
int main() {
int input = -1;
srand((unsigned)time(NULL)); //NULL 参数使用当前的系统时间
do {
menu();
printf("请输入以上数字选择功能: \n");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
break;
default:
printf("选择错误, 请重新输入! \n");
break;
}
} while (input);
return 0;
}
ut > res)
{
printf("猜大了\n");
}
else if (input < res)
{
printf("猜小了\n");
}
else
{
printf("猜中了\n");
break;
}
}
}
int main() {
int input = -1;
srand((unsigned)time(NULL)); //NULL 参数使用当前的系统时间
do {
menu();
printf("请输入以上数字选择功能: \n");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
break;
default:
printf("选择错误, 请重新输入! \n");
break;
}
} while (input);
return 0;
}