练习:
1.计算n的阶乘(不考虑溢出):
//计算 n的阶乘 #include <stdio.h> //5!= 1 * 2 * 3 * 4 * 5 //先用循环生成1-n个数字,再依次相乘 int main() { int n = 0; scanf("%d", &n); int i = 0; int ret = 1; // 相乘后赋值给该函数,因为0乘任何数都为0,所以初始化为1 for ( i = 1; i <= n; i++) // 利用循环生成1-n个数字 { ret = ret * i; // 依次相乘 } printf("%d\n", ret); return 0; }
2.计算1! + 2! + 3! +...+ 10! :
(第一种方法:效率比较低,会重复计算之前的计算过的阶乘,但逻辑比较好理解)
//计算1! + 2! + 3! +...+ 10! : #include <stdio.h> //5!= 1 * 2 * 3 * 4 * 5 //内循环:循环生成1-n个数字,再依次相乘 //外循环:阶乘相加 int main() { int n = 0; int i = 0; int ret = 1; // 相乘后赋值给该变量,因为0乘任何数都为0,所以初始化为1 int sum = 0; // 外循环将阶乘相加赋给该值 //外循环:阶乘相加 for ( n = 1; i <= 10; n++) // 加到10! { ret = 1; // 内循环中相乘后赋值给该变量,每次出了循环要重新刷新该值(重点) //内循环:循环生成1-n个数字,再依次相乘 for (i = 1; i <= n; i++) // 利用循环生成1-n个数字 { ret = ret * i; // 依次相乘 } sum += ret; // 将阶乘相加赋给该值 } printf("%d\n", sum); return 0; }
(第二种方法:在原本已计算的阶乘上再乘上’下一个数‘,实现‘下一个数’的阶乘)
//第二种方法: //计算1! + 2! + 3! +...+ 10! : #include <stdio.h> //5!= 1 * 2 * 3 * 4 * 5 int main() { int n = 0; int i = 0; int ret = 1; // 相乘后赋值给该变量,因为0乘任何数都为0,所以初始化为1 int sum = 0; // 将阶乘相加赋给该值 for (n = 1; n <= 10; n++) // 执行到10! { ret = ret * n; // 直接乘n, //在原本已计算的阶乘上再乘上’下一个数‘,实现下一个数的阶乘 sum += ret; // 将阶乘相加赋给该值 } printf("%d\n", sum); return 0; }
3.在一个有序数组中查找具体的某个数字n。(讲解二分查找算法‘折半查找算法’):
(第一种方法:逻辑简单,而且在无序数组中也可以使用,但效率较低,需要一个一个查找)
//在一个有序数组中查找具体的某个数字n。 #include <stdio.h> int main() { int arr[] = { 1,2,3,4,5,6,7,8,9,10 }; // 升序(有序数组) //数组下标: 0 1 2 3 4 5 6 7 8 9 int find = 7; // 在数组中要找的值 int i = 0; // 数组下标 //利用for循环在数组中一个一个查找 for ( i = 0; i < 10; i++ ) { if (arr[i] == find) { printf("找到了,该值在数组中对应的下标是:%d\n", i); break; // 找到后跳出循环 } } if (i == 10) // 10超过数组下标了,说明数组中没有这个值 { printf("数组中没有该值。\n"); } return 0; }
(第二种方法:二分查找算法‘折半查找算法’,在有序数组查找中效率更高,一次查找就能排除一半的值,重点!!)
(思路:(重点!!))
(改错:“对比中间下标和所找值的下标”,是要对比数组中对应下标的值)
(代码实现:结合上面原理图理解)
//第二种方法 #include <stdio.h> int main() { int arr[] = { 1,2,3,4,5,6,7,8,9,10 }; // 升序(有序数组) //数组下标: 0 1 2 3 4 5 6 7 8 9 int find = 7; // 在数组中要找的值 int i = 0; // 数组下标 int sz = sizeof(arr) / sizeof(arr[0]); // 求元素个数 // sizeof(arr): 计算数组总大小(单位是字节) // sizeof(arr[0]):计算数组中单个元素大小 // 用 sizeof(arr) / sizeof(arr[0]) ,总大小 除以 单个大小 = 元素个数 // 1. 求左下标和右下标: int left = 0; // 左下标 int right = sz - 1; // 右下标 // 因为数组是从0开始得,所以用 元素个数-1 得出 最右边下标 int flag = 0; // 用来设置未找到情况下的处理 //循环查找: while ( left <= right ) // left <= right: 说明被左右下标包裹中的数组还有值,还有值就继续循环查询 { // 2.确定中间元素下标: int mid = (left + right) / 2; //进行查找: //找到: if (arr[mid] == find) { printf("找到了,该值在数组中对应的下标是:%d\n", mid); flag = 1; break; } //未找到: //中间值小于要找的值,排除mid和小于mid左边的值 else if (arr[mid] < find) { left = mid + 1; // 调整左下标 } //中间值大于要找的值,排除mid和大于mid右边的值 else { right = mid - 1; // 调整右下标 } } if (flag == 0) { printf("没找到\n"); } return 0; }
4.编写代码,演示多个字符从两端移动,向中间汇聚:
Sleep(1000):休眠1秒后再执行后面语句,Sleep需要一个windows.h的头文件
system("cls"):system函数可以执行系统命令,cls是清理屏幕
//编写代码,演示多个字符从两端移动,向中间汇聚: #include <stdio.h> #include <string.h> #include <windows.h> int main() { //利用字符数组来存储字符串,后面隐藏一个\0 char arr1[] = "welcome to school!!!!!"; char arr2[] = "######################"; //定义左右下标: int left = 0; int right = strlen(arr1) - 1; // strlen(数组名称):求数组的长度,计算字符数组中\0前有多少个字符 // 数组长度 - 1 = 最右端的小标 while (left <= right) // 如果left > right说明数组中左右下标之间已经没有值了 // 所以有值则一直循环到无值 { arr2[left] = arr1[left]; // 将arr1靠左边上的值 赋值给 arr2最左边的值 arr2[right] = arr1[right]; // 将arr1靠右边上的值 赋值给 arr2最右边的值 printf("%s\n", arr2); // 打印重新赋值后的arr2 Sleep(1000); // 休眠1秒后再执行后面语句 //Sleep需要一个windows.h的头文件 system("cls"); // system函数可以执行系统命令,cls是清理屏幕 left++; // ”倒数最左“ right--; // “倒数最右” } printf("%s\n", arr2); return 0; }
5.编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则提示登录成功,如果三次均输入错误,则退出程序):
strcmp库函数:
两个字符串比较相等不能使用==(等于),应该使用strcmp库函数,需添加<string.h>头文件
strcmp返回0表示2个字符串相等
strcmp返回>0的数字,表示第一个字符串大于第二个字符串
strcmp返回<0的数字,表示第一个字符串小于第二个字符串
字符串比较大小:比较对应位置字符的ASCII值
abcd 和 abq 比较:第一位a=a,第二位b=b,第三位c<q(c的ASCII值小于q的)
所以 abcd < abq
//5: #include <stdio.h> #include <string.h> int main() { int i = 0; //假设密码是:“123456” char password[20] = {0}; int flag = 0; for ( i = 0; i < 3; i++) // 循环3次 { printf("请输入密码:>"); scanf("%s", password); // 因为password是数组,数组名本来就是地址,所以不用加取地址符& // 判断密码是否正确: // 两个字符串比较相等不能使用==(等于), // 应该使用strcmp库函数,需添加<string.h>头文件 // strcmp返回0表示2个字符串相等 // strcmp返回>0的数字,表示第一个字符串大于第二个字符串 // strcmp返回<0的数字,表示第一个字符串小于第二个字符串 // 字符串比较大小:比较对应位置字符的ASCII值 // abcd 和 abq 比较:第一位a=a,第二位b=b,第三位c<q(c的ASCII值小于q的) // 所以 abcd < abq if (strcmp(password, "123456") == 0) { printf("登录成功\n"); flag = 1; break; // 成功则跳出循环 } else { printf("密码错误\n"); } } if (flag == 0) { printf("退出程序\n"); } return 0; }
补充内容:变量的左值和右值
//变量的左值和右值 #include <stdio.h> int main() { int a = 10; // 在内存申请名叫a的空间,把10存进去 a = 20; // 把20放在a的这块空间里,这里使用的是a的空间 int b = a; // 这里是使用了a中存放的值,把a中的20存放到b的空间(使用的是b的空间)中 //使用变量空间的变量就是 左值 , 使用变量中存放的值的变量是 右值 // 简单理解 (空间) (空间的内容) return 0; }