C 语言复习总结记录二

C 语言复习总结记录二

一 控制语句

1、语句的分类
  1. 表达式语句
  2. 函数调用语句
  3. 复合语句
  4. 控制语句
  5. 空语句

控制语句 控制程序的执行流程,实现程序的各种结构方式

C 语言支持三种结构 :顺序结构、选择结构、循环结构,由特定的语句定义符组成C语言有九种控制语句,可分成以下三类:

  1. 条件判断语句也叫分支语句:if 语句、switch 语句

  2. 循环执行语句:do while 语句、while 语句、for 语句

  3. 转向语句:break 语句、goto 语句、continue 语句、return 语句

2、分支语句

0 表示假,非 0 即为真

c++ 复制代码
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之间的奇数

c++ 复制代码
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] 的整数,输出对应的星期几;其语句常用格式如下

c++ 复制代码
switch(整型表达式)
{
    case 整型常量表达式:
        语句;
        break;
    ...
    default:
        语句;
        break;
}

break 语句的实际效果是把语句列表划分为不同的分支部分

c++ 复制代码
#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

c++ 复制代码
//该段程序即打印字符, 例如 
// 输入 111'\n', 则控制台打印 111'\n'
int ch = 0;
while ((ch = getchar()) != EOF) {
	putchar(ch);
}

break 跳出终止当前语句,在此处即为跳出 while 循环或终止 while 循环

continue 用于终止本次循环,直接跳转到 while 语句的判断部分,进行下一次循环的判断

c++ 复制代码
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 的数字

c++ 复制代码
//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循环变种

c++ 复制代码
#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 循环

特点:循环至少会执行一次

c++ 复制代码
#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 只能从最内层循环退出到上一层的循环

c++ 复制代码
for(...)
    for(...)
   {
        for(...)
       {
            if(disaster)
                goto error;
       }
   }
    ...
error:
 if(disaster)
         // 处理错误情况

关机小程序

c++ 复制代码
#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 的阶乘

c++ 复制代码
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!

c++ 复制代码
int res = 1, sum = 0;
for (int i = 1; i <= 10; ++i)
{
	res *= i;
	sum += res;
}
printf("%d\n", sum); //4037913

3、在一个有序数组中查找具体的某个数字 n(二分查找)

c++ 复制代码
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、编写代码,演示多个字符从两端移动,向中间汇聚

c++ 复制代码
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、编写代码实现,模拟用户登录情景,并且只能登录三次(只允许输入三次密码,如果密码正确则提示登录成功,如果三次均输入错误,则退出程序

c++ 复制代码
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] 范围内的随机数

c++ 复制代码
//简单的测试, 当不设置种子时默认为 1, 每次程序的执行结果都是一样的
for (int i = 0; i <= 10; ++i)
{
	int res = rand();
	printf("%d\n", res);
}
c++ 复制代码
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;
}
相关推荐
尘浮生3 分钟前
Java项目实战II基于SpringBoot的客户关系管理系统(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·后端·微信小程序·小程序
晚风_END7 分钟前
postgresql|数据库开发|python的psycopg2库按指定顺序批量执行SQL文件(可离线化部署)
服务器·开发语言·数据库·python·sql·postgresql·数据库开发
夕阳产业——JAVA,入坑=失业12 分钟前
泛型擦除是什么?
java·开发语言
阿猿先森18 分钟前
PyQt6+pyqtgraph折线图绘制显示
开发语言·python
legend_jz22 分钟前
【Linux】线程的互斥和同步
linux·运维·服务器·开发语言·笔记·学习·学习方法
l1384942745134 分钟前
Java综合练习
java·开发语言·算法
人机emmo_49037211221 小时前
第4关 Java分支结构之Switch【Java 分支结构之 Switch:灵活的选择利器】
java·开发语言·python
z0006161 小时前
C语言之函数的参数
c语言·数据结构·算法
重生之我是数学王子1 小时前
QT 实现仿制 网络调试器(未实现连接唯一性) QT5.12.3环境 C++实现
开发语言·c++·qt
St_Ludwig1 小时前
蓝桥杯疑似例题解答方案(打印任意阶杨辉三角)
c语言·c++·后端·算法·职场和发展·蓝桥杯