循环语句与数组
文章目录
1. for 循环
1.1 语法
for (表达式1;表达式2;表达式3)
{
循环体。
}
- 循环从 表达式1开始 ——> 表达式2 (判别表达式) ——> 真 ——> 执行循环体 ——> 表达式3 ——> 判断表达式2
- 真: 继续 ——> 循环体 ——> 表达式3 ——> 表达式2 。。。
- 假:跳出循环。( 正常情况下,for循环的出口是 表达式2 )
1.2 练习:
- 使用 for 循环 求 1~100 的 和。
// 1~100 求和 1+2+3+4+5+。。。+100
int main(void)
{
// 定义循环因子。
int i = 0; // 定义i,给初值。
// 定义变量 记录累加值
int sum = 0; // 初值为 0
for (i = 1; i <= 100; i++)
{
sum = sum + i;
}
// 循环结束,打印 累加结果
printf("sum = %d\n", sum);
return EXIT_SUCCESS;
}
1.3 for 循环的变换形式
-
循环因子 i:
-
在 for 循环之前定义。 在 for 循环,结束后依然能使用。
-
定义 在for 循环之内。 for 循环结束后,不能使用!
for (int i = 1; i <= 100; i++) // 将 i 的定义放到 for 内 表达式1上。 { sum = sum + i; } // 循环结束,打印 累加结果 printf("sum = %d, i = %d\n", sum, i); // 编译器保存,“未定义标识符”
-
-
for 循环 3 个表达式,在使用时,均可省略。 但,2 个 “ ; ” 不允许省略。
-
省略 表达式1
int i = 1; // 定义 循环因子 int sum = 0; for (; i <= 100; i++) // 不写表达式1 { sum = sum + i; }
-
省略 表达式3
int i = 1; // 定义 循环因子 int sum = 0; for ( ; i <= 100; ) // 不写表达式1, 不写表达式3 { sum = sum + i; i++; // 将原来的表达式3写到循环体中。 }
-
省略 表达式2
int i = 1; // 定义 循环因子 for ( ; ; ) // 不写表达式2, 相当于 for ( ; 1 ; )表达式2为 真(1)。 这是一个死循环。 { printf("i = %d\n", i); i++; } // for ( ; ; ) 死循环 相当于 while(1) {};
-
-
for 每个表达式中, 可以含有多个算式。
int i = 0; // 定义 循环因子 int a = 0; for (i=1, a=3; a<20, i<10; i++, a+=3) // i<10, a <20 也可以写成 i<10 && a<20 { printf("i = %d\n", i); printf("a = %d\n", a); }
-
死循环
// 方法1: for(;;) // 方法2: while(1)
1.4 练习:
-
猜数字游戏:
- 产生一个随机数。用户键盘键入一个数据,程序提示用户,输入的数据 > < == 随机数。用户根据提示不断变换输入,最终猜中!
-
生成随机数:
-
添加一个随机数种子。作用:保证随机是真正的随机。
srand(time(NULL)); // 固定写法。 // time(NULL): 获取系统当前时间。unsigned long long 类型。 // srand() 函数来生成随机数。使用 系统时间为 算法的系数。
-
添加头文件
// srand() --- <stdlib.h> // time() --- <time.h>
-
生成随机数。
int n = rand() % 100; // 随机数范围: 0 ~ 99 int n = rand() % 100 + 13; // 随机数范围: 13 ~ 112 int n = rand() % 63 + 17; // 随机数范围: 0+17 ~ 62+17
-
-
思路分析
// 伪代码 int main(void) { 1. 生成随机数。(3步骤) 2. 创建死循环, 供用户猜测 while(1) int num ; while (1) { 接收用户输入: scanf("%d", &num); if 判断用户输入的数据,与实际随机 大小。 num > 随机数 提示用户。继续循环。 num < 随机数 提示用户。继续循环。 num == 随机数 提示用户 猜中!结束循环。 break; 跳出循环。 } return 0; }
-
编码实现
int main(void) { // 播种随机数种子 srand(time(NULL)); // 生成随机数 n int n = rand() % 100; // 范围 0-99 // 定义 num 变量,存储用户输入的数据。 int num; // 创建 死循环,给用户猜数字。 for (;;) // while(1) 等价 { printf("请输入猜测的数字:"); // 获取用户输入数据 scanf("%d", &num); // 提示用户,测试方向 if (num > n) { printf("猜大了!\n"); } // 如果 if分支、for、while 满足后,执行语句只有一条时,{} 可以省略。 else if (num < n) printf("猜小了!\n"); // 语法允许,不写 {} else { printf("猜中了!!!\n"); break; // 不必再循环。 } } printf("本尊数:%d\n", n); return EXIT_SUCCESS; }
1.5 嵌套 for 循环
int i = 0; // 外层循环的循环因子
int j = 0; // 内层循环的循环因子
for (i = 0; i < 10; i++)
{
for (j = 2; j < 10; j++)
{
// 循环体
}
}
- 结论: 外层循环执行一次, 内层循环执行 一周。
1.6 练习:
-
模拟电子表打印
-
分析:
// 最外层 for (i = 0; i < 24; i++) { for (j = 0; j < 60; j++) { for (k = 0; k < 60; k++) { 打印时间。 } } } 11:30:54 11:30:56 ... 11:31:00 ... 12:00:00 12:00:01
-
实现:
int main(void) { int i, j, k; for (i = 0; i < 24; i++) // 小时 { for (j = 0; j < 60; j++) // 分钟 { for (k = 0; k < 60; k++) // 秒 { printf("%02d:%02d:%02d\n", i, j, k); Sleep(980); system("cls"); // 清屏 } } } return EXIT_SUCCESS; }
1.7 练习:
-
打印正序 9x9 乘法表
1x1= 1 // 第1行, 打印1列 1x2= 2 2x2= 4 // 第2行,打印2列 1x3= 3 2x3= 6 3x3= 9 // 第3行,打印3列 1x4= 4 2x4= 8 3x4=12 4x4=16 // 第4行,打印4列 ... 1x9= 9 2x9=18 3x9=27 4x9=36 5x9=45 6x9=54 7x9=63 8x9=72 9x9=81 // 第9行,9列 jxi = 第 i 行,打印 i 列。
-
分析+实现
for (i = 1; i <= 9; i++) // 外层,描述行。 { for (j = 1; j <= i; j++) // 内层,描述每一列。 { printf("%dx%d=%d\t", j, i, i*j); } printf("\n"); }
-
打印倒序 9x9 乘法表
1x9= 9 2x9=18 3x9=27 4x9=36 5x9=45 6x9=54 7x9=63 8x9=72 9x9=81 // 行
1x8= 8 2x8=16 3x8=24 4x8=32 5x8=40 6x8=48 7x8=56 8x8=64
1x7= 7 2x7=14 3x7=21 4x7=28 5x7=35 6x7=42 7x7=49
1x6= 6 2x6=12 3x6=18 4x6=24 5x6=30 6x6=36
1x5= 5 2x5=10 3x5=15 4x5=20 5x5=25
1x4= 4 2x4= 8 3x4=12 4x4=16
1x3= 3 2x3= 6 3x3= 9
1x2= 2 2x2= 4
1x1= 1
jxi = 值
for (i = 9; i >= 1; i--) // i 控制 行
{
for (j = 1; j<=i; j++)
printf("%dx%d=%d\t", j, i, i*j);
putchar('\n');
}
// 上述省略{}写法无误, 不推荐。--- 推荐下面的写法。
int main(void)
{
int i, j;
for (i = 9; i >= 1; i--)
{
for (j = 1; j <= i; j++)
{
printf("%dx%d=%d\t", j, i, j * i);
}
putchar('\n'); // printf("\n");
}
return EXIT_SUCCESS;
}
2. 跳转语句
2.1 break
-
作用1:
- 一次break,可以跳出一重循环。( for、while、do while )
-
作用2:
- 防止 case 穿透。 结束 switch();
2.2 continue
-
作用:结束 本次 循环。continue关键字之后的代码,在这次循环中,不执行。
-
示例1:
-
示例2:
int main(void) { for (int i = 0; i < 10; i++) { for (int j = 0; j < 5; j++) { if (j == 2) { continue; // 只跳出(后续代码代码不执行)本次 j == 3 时的循环, } printf("i = %d, j= %d\n", i, j); } printf("\n"); } return EXIT_SUCCESS; }
2.3 goto
-
语法:
- 设定一个标签。标签名自定义,一般大写。如:ABC、 LABLE、AAA
- 使用 “goto 标签名” 跳转到标签的位置。(只函数内生效)
-
示例:
int main(void) { printf("==========1=========\n"); printf("==========2=========\n"); printf("==========3=========\n"); goto LABLE; printf("==========4=========\n"); printf("==========5=========\n"); printf("==========6=========\n"); printf("==========7=========\n"); LABLE: printf("==========8=========\n"); printf("==========9=========\n"); return EXIT_SUCCESS; }
-
示例:
-
goto 语法过于灵活,会打乱程序的执行逻辑,降低代码的 可读性。 后续编程中,尽量少用。
- C 程序中,简单的逻辑,依然可以使用 goto 。
3. 数组
-
什么是数组:
- 数组是,相同数据类型有序的、连续的存储集合。
-
%p:
- 用来打印变量内存地址的专用 格式匹配符 (占位符)
3.1 基本特性
-
各个元素,连续存储。
-
数组名为地址,是数组首个元素的地址。arr == &arr[0]
-
求数组的总大小:
printf("数组的大小:%u\n", sizeof(arr));
-
求数组每一个元素的大小:
printf("数组元素的大小:%u\n", sizeof(arr[0]));
-
求数组元素的个数:
printf("数组元素的个数:%d\n", sizeof(arr)/sizeof(arr[0]));
-
数组第一个元素的下标: 0
-
数组最后一个元素的下标:
sizeof(arr)/sizeof(arr[0]) - 1
3.2 数组初始化
// 初始化方法1
int arr[5] = {3, 7, 2, 1, 9};
// 初始化方法2【多用】
int arr[5] = {3, 7}; // 剩余未初始化的元素,默认值 0
// 初始化方法3【多用】
int arr[5] = {0}; // 初始化一个 全部元素为 0 的数据。 ---清0 常用。
// 初始化方法4【多用】
int arr[] = {3, 7, 2, 1, 6, 9, 13}; // 编译器会自动求取数组元素个数。
// 初始化方法5
int arr[] = {0}; // 定义了只有一个元素的数组,值为 0,是只有一个
// 初始化方法6【多用】
int arr[10]; // 声明了一个有10个元素数组。
arr[0] = 5;
arr[1] = 6;
arr[2] = 7; // 剩余未初始化的元素,默认值 —— 随机数。
3.3 练习
- 数组元素逆序
// 数组元素逆序
int main(void)
{
int arr[] = {1, 6, 8, 0, 4, 3, 9, 2}; // 变为:{2, 9, 3, 4, 0, 8, 6, 1}
// 获取数组的元素个数
int n = sizeof(arr) / sizeof(arr[0]);
int i = 0; // 从前向后
int j = n-1; // 从后向前
int tmp = 0; // 定义临时变量。
// 交换数组元素之前,打印数组的所有元素。
for (int i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
putchar('\n');
// 循环交换数组元素。
while (i < j)
{
tmp = arr[i]; // 三杯水变量交换法
arr[i] = arr[j];
arr[j] = tmp;
i++; // 不断后移
j--; // 不断前移
}
// 交换数组元素之后,打印数组的所有元素。
for (int i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
putchar('\n');
return 0;
}
4. 冒泡排序
int main(void)
{
int i, j, tmp;
int xjp[] = {12, 2, 32, 14, 62, 54, 27, 89, 9, 10, 3};
// 求取数组元素个数。
int n = sizeof(xjp) / sizeof(xjp[0]);
// 开始排序。
for (i = 0; i < n - 1; i++) // 外层控制行
{
for (j = 0; j < n - 1 - i; j++) // 内层控制列。
{
// 相邻两两比较,三杯水交换
if (xjp[j] > xjp[j + 1])
{
tmp = xjp[j];
xjp[j] = xjp[j + 1];
xjp[j + 1] = tmp;
}
}
}
// 打印排序结果。
for (i = 0; i < n; i++)
{
printf("%d ", xjp[i]);
}
printf("\n");
return EXIT_SUCCESS;
}
5. 配置 VS2019 快捷导入代码
- 准备 快捷导入代码的脚本文件,保存在系统目录中(位置自定义)
-
在 VS2019 中配置,使用上述目录中的 脚本文件。
- 工具 —— 代码片段管理器 —— 修改 Basic 为 Visual C++ —— 选择 上述自定义的目录位置(不需要选择到具体脚本文件)。
-
在程序中使用 快捷导入代码。
- #1 ---- tab 键。
诚挚感谢传智播客王飞老师的详细讲解和提供的材料素材。