C语言-----数组(1)https://developer.aliyun.com/article/1544216
二维数组在内存中的存储
二维数组的位置 int main() { int arr[3][5] = { 0 }; int i = 0; for (i = 0; i < 3; i++) { int j = 0; for (j = 0; j < 5; j++) { printf("&arr[%d][%d]= %p\n",i,j ,&arr[i][j]); } } return 0; } int main() { int arr[3][5] = { 1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7 }; //1 2 3 4 5 //2 3 4 5 6 //3 4 5 6 7 int i = 0; for (i = 0; i < 5; i++) { int j = 0; for (j = 0; j < 3; j++)//将行和列置换过来 { printf("%d", arr[j][i]); } printf("\n"); } return 0; } 输出结果是: 123 234 345 456 567 变长数组: 在vs2020无法使用,但是在devc++可以使用 int main() { int n = 0; int arr[n]; int i = 0; for (i = 0; i < n; i++) { scanf("%d", &arr[i]); } for (i = 0; i < n; i++) { printf("%d", arr[i]); } return 0; } int main() { int n = 0; int arr[n]; int i = 0; scanf("%d", &n); for (i = 0; i < n; i++) { arr[i]=6; } for (i = 0; i < n; i++) { printf("%d", arr[i]); } return 0; } 变长数组不能初始化,好处就是程序员可以为数组分配一个精确的长度 变长数组的意思就是:数组的大小可以使用变量来指定的
数组训练
#include <string.h>//一定要添加的头文件,对于stelen #include <stdio.h> int main() { //char arr[] = "abc"; //a b c \0 //0 1 2 3对应的下标,最右边的结尾c所对应的下标应该-1 char arr1[] = "hello bit!!!!!!"; char arr2[] = "###############"; int left = 0; int right = strlen(arr1) - 1;//看5、6、7行理解为什么这么写 //数组的最右边应该从arr1数组的长度减一开始算 while (left<=right)//循环停止的条件 { arr2[left] = arr1[left]; // arr2的左边等于arr1的左边 arr2[right] = arr1[right]; // arr2的右边等于arr1的右边 printf("%s\n", arr2); // 再将改变后的arr2打印出来 left++; //left依次向右边走 right--; right依次向左边走 } return 0; } 若是想看到动态变化效果,改动如下: 添加睡眠时间1000毫秒,在44行 #include <stdio.h> #include <string.h> #include <wiindows.h> int main() { char arr1[] = "hello bit!!!!!!"; char arr2[] = "###############"; int left = 0; int right = strlen(arr1) - 1; while (left<=right)//循环停止的条件 { arr2[left] = arr1[left]; // arr2的左边等于arr1的左边 arr2[right] = arr1[right]; // arr2的右边等于arr1的右边 printf("%s\n", arr2); // 再将改变后的arr2打印出来 Sleep(1000);//1000的单位是毫秒,休眠1000毫秒 left++; //left依次向右边走 right--; //right依次向左边走 } return 0; } 引用Sleep()需要引用头文件#include <windows.h> 在47行后面添加这么一串代码去//执行系统命令清理屏幕,使出现的代码只出现在第一行,清理控制台平屏幕的信息 system("cls"); 改动如下: #include <stdlib.h> #include <stdio.h> #include <string.h> #include <wiindows.h> int main() { char arr1[] = "hello bit!!!!!!"; char arr2[] = "###############"; int left = 0; int right = strlen(arr1) - 1; while (left<=right)//循环停止的条件 { arr2[left] = arr1[left]; // arr2的左边等于arr1的左边 arr2[right] = arr1[right]; // arr2的右边等于arr1的右边 printf("%s\n", arr2); // 再将改变后的arr2打印出来 Sleep(1000);//1000的单位是毫秒,休眠1000毫秒 system("cls");//执行系统命令清理屏幕 left++; //left依次向右边走 right--; //right依次向左边走 } return 0; } 注意###//system()使用的话需要引用头文件: #include <stdlib.h> 但是最后一次代码也被清除了 所以我们仍需做出改动: int main() { char arr1[] = "hello bit!!!!!!"; char arr2[] = "###############"; int left = 0; int right = strlen(arr1) - 1; while (left<=right)//循环停止的条件 { arr2[left] = arr1[left]; // arr2的左边等于arr1的左边 arr2[right] = arr1[right]; // arr2的右边等于arr1的右边 printf("%s\n", arr2); // 再将改变后的arr2打印出来 Sleep(1000);//1000的单位是毫秒,休眠1000毫秒 system("cls");//执行系统命令清理屏幕 left++; //left依次向右边走 right--; //right依次向左边走 } printf("%s\n", arr2); return 0; } 在循环的结束末尾再次打印就好了 system("cls");这个代码仅仅只是清理屏幕,但是数组内的内容还在 因为数组里面的内容还在,再将内容打印一遍就出现最后的结果了
折半查找也叫二分查找 查找的前提条件是数据是有序的 通过下标选择中间元素 一次二分查找如下 int main() { int arr[] = { 1,2,3,4,5,6,7,8,9,10 };//输入一个数组 int k = 0; //定义一个变量 scanf_s("%d", &k);//输入要查找的值,假设是7 int sz = sizeof(arr) / sizeof(arr[0]); //得到数组的长度 int left = 0; // 左端下标 int right = sz-1;//左右下标确定,因为是从0开始的,所以右端下标要-1 while (left<=right)//当left<=right时,应该就同时指向同一个数//此处为循环的的条件 { int mid = (left + right) / 2; //下标的中间值 if (arr[mid] < k)//如果中间值对应的数小于想要查找的值,就从下标mid+1的后面开始寻找 { left = mid + 1; } else if (arr[mid] > k) { right = mid - 1;//如果下标是中间值所对应的数字大于要寻找的数字,那么下标右边的数字可以不用看了,直接从中间值左边的那一个下标所对应的数字看起,左边的那个数字为新的right } else { printf("找到了,下标是%d\n", mid); break; //找到了就break跳出循环 } } if (left > right) { printf("找不到\n"); } return 0; } 如果left<=right一直满足,程序就会一直循环,直到找到你输入的值 思考:此处的while()里面的括号内能放1吗? 因为找不到就死循环了,找不到不会break 第二种写法:定义flag//定义flag为0,就是没找到,但是 如果找到了就定义flag成1,没找到依然为0 int main() { int flag = 0;//假设找不到为0 int arr[] = { 1,2,3,4,5,6,7,8,9,10 };//输入一个数组 int k = 0; //定义一个变量 scanf_s("%d", &k);//输入要查找的值,假设是7 int sz = sizeof(arr) / sizeof(arr[0]); //得到数组的长度 int left = 0; // 左端下标 int right = sz-1;//左右下标确定,因为是从0开始的,所以右端下标要-1 while (left<=right)//当left<=right时,应该就同时指向同一个数//此处为循环的的条件 { int mid = (left + right) / 2; //下标的中间值 if (arr[mid] < k)//如果中间值对应的数小于想要查找的值,就从下标mid+1的后面开始寻找 { left = mid + 1; } else if (arr[mid] > k) { right = mid - 1;//如果下标是中间值所对应的数字大于要寻找的数字,那么下标右边的数字可以不用看了,直接从中间值左边的那一个下标所对应的数字看起,左边的那个数字为新的right } else { printf("找到了,下标是%d\n", mid); flag = 1; //找到就为1 break; //找到了就break跳出循环 } } if (flag == 0)//如果变为0,就是没找到 { printf("找不到"); } return 0; } 为什么这里写的是sizeof,而不是strlen,因为strlen是求字符串长度的,而这里的arr被int定义为整型,strlen只能针对字符串或者字符数组 用(left + right) / 2去求平均值存在问题,那么如何求两个较大的数的平均值呢? 假设现在有两个数a和b,现在a>b,去求平均值,将a>b的那部分减下来,然后除以二,给b一部分,给a一部分,现在a=b现在a和b的值就是他们原先值的平均值,以后求平均值可以这么写 int num = a+(b-a)/2