| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> C语言 ---数组 -> 正文阅读 |
|
[C++知识库]C语言 ---数组 |
数组: ??? 数组就是变量的组合,是一种批量定义变量的方式。 ??? 定义数组:类型 数组名[长度]; ??????? int arr[5] <=> int n0,n1,n2,n3,n4; ??? 使用数组:数组名[下标]; ??????? 下标范围:[0,长度-1]; ? ??初始化:类型 数组名[长度] = {0,1,2,4,...}; ??????? 1、使用数组定义出的变量与普通变量一样,默认值是不确定的。 ??????? 2、初始化语法只有定义数组时才能使用,这也是唯一一次能对数组批量访问的机会,数组定义完成后就只能单个访问,数组的初始化过程是编译器帮助完成的。 ??????? 3、如果初始化数据过多,编译器会产生警告,并丢弃多余的数据。 int arr[5] = {1,2,3,4,5,6,7}; ??????? 4、如果初始化数据不够,编译器会自动补0。 int arr[5] = {}; ??????? 5、初始化数组时,数组的长度可以省略,编译器会统计数据的个数,设置给数组。 ??????????? int arr[] = {1,2,3,4,5}; ?????????? ?sizeof(arr)/sizeof(arr[0])? ??? 数组的遍历:需要与for循环配合,使用循环变量作为数组的下标。 ??????? int arr[] = {1,2,3,4,5}; ??????? size_t len = sizeof(arr)/sizeof(arr[0]); ??????? for(int i=0; i<len; i++) ??????? { ??????????? printf("%d ",arr[i]); ??????? } ??? 练习9、定义个数组并随机初始化,计算出数组中的最大值、最小值、平均值。 #include <stdio.h> int main(int argc,const char* argv[]) { int arr[] = {-1,1,3,5,7,6,19,8,4,2,10}; int min = arr[0] , max = arr[0] , sum = arr[0]; size_t len = sizeof(arr)/sizeof(arr[0]); for(int i=1; i<len; i++) { if(arr[i] > max) max = arr[i]; if(arr[i] < min) min = arr[i]; sum += arr[i]; } printf("%d %d %g\n",max,min,sum*1.0/len); return 0; } ??? 练习10、输入一个整数,分解显示,例如:输入12345,显示为:1 2 3 4 5。 #include <stdio.h> #include <stdlib.h> int main(int argc,const char* argv[]) { int num; printf("请输入一个整数:"); scanf("%d",&num); if(num < 0) { printf("- "); num = abs(num); } char arr[10] , cnt=0; while(num) { arr[cnt++] = num % 10; num /= 10; } for(int i=cnt-1; i>=0; i--) { printf("%d ",arr[i]); } return 0; } ??????????? 变长数组: ??? 变长数组就是使用变量作为数组的长度,这种数组在编译时长度可以不确定,在执行数组的定义语句前,长度变量可以变化,当执行数组的定义语句后,数组的长度才确定下来,但确定下来后就不能再变。 ??? 优点:可以根据实际情况设置数组的长度,达到节约内存的目的。 ??? 缺点:变长数组不能初始化,原因是数组的初始化时编译器帮助完成的,而编译时编译器无法知道数组的长度。 ??? ??? size_t len; ??? // 这个过程中可以根据实际情况给len赋值 ??? int arr[len]; 练习11:给定N个整数,计算它们的平均值,例如:7 5 -3.2 4.8 99 98 2.3 7.123 2.35。 #include <stdio.h> int main(int argc,const char* argv[]) { size_t len; scanf("%d",&len); float num,sum = 0; for(int i=0; i<len; i++) { scanf("%f",&num); sum += num; } printf("%g\n",sum/len); return 0; } 二维数组: 一维数组相当于把变量排成一排,二维数组就是把变量排成一个方阵。 定义: 类型? 数组名[行数][列数]; 注意:二维数组在初始化时,其他特点与一维数组相同,不同的是列数必须确定。 练习1:输入矩阵的阶数n,按照螺旋顺序填充数字,n>=2。 #include <stdio.h> int main(int argc,const char* argv[]) { ??? int n; ??? printf("请输入矩阵的阶数:"); ??? scanf("%d",&n); ??? int arr[n][n] , val = 1; ??? arr[n/2][n/2] = n*n; ??? // n/2计算出圈数 ??? for(int i=0; i<n/2; i++) ??? { ??????? // 行下标:圈数,列下标:[圈数,n-1-圈数) ??????? for(int j=i; j<n-i-1; j++) ??????????? arr[i][j] = val++; ??????? // 行下标:[圈数,n-1-圈数) 列下标:n-1-圈数 ??????? for(int j=i; j<n-i-1; j++) ??????????? arr[j][n-1-i] = val++; ??????? // 行下标:n-1-圈数 列下标:[n-1-圈数,圈数) ??????? for(int j=n-1-i; j>i; j--) ??????????? arr[n-1-i][j] = val++; ??????? // 行下标:[n-1-圈数,圈数 列下标:圈数 ??????? for(int j=n-1-i; j>i; j--) ??????????? arr[j][i] = val++; ??? } ??? // 遍历矩阵 ??? for(int row=0; row<n; row++) ??? { ??????? for(int col=0; col<n; col++) ??????? { ??????????? printf("%2d ",arr[row][col]); ??????? } ??????? printf("\n"); ??? } ??? return 0; } 作业: ??? 1、定义个数组并随机初始化,计算出数组中第二大的值(要求使用速度最快的方法)。 #include <stdio.h> // 1、定义个数组并随机初始化,计算出数组中第二大的值(要求使用速度最快的方法)。 int main(int argc,const char* argv[]) { ??? int arr[] = {10,3,7,5,8,9,2,4,0,6}; ??? size_t len = sizeof(arr)/sizeof(arr[0]); ??? int max = arr[0] , max2 = arr[1]; ??? for(int i=1; i<len; i++) ??? { ??????? if(arr[i] > max) ??????? { ??????????? max2 = max; ??????????? max = arr[i]; ??????? } ??????? else if(arr[i] > max2) ??????? { ??????????? max2 = arr[i];?? //?? 保证第二大的值就是第二大的值,而不单纯只是从max1退位下来的值 ??????? } ??? } ??? printf("%d\n",max2); ??? return 0; } ? ??2、定义个数组并随机初始化,求该数组进行升序排序(使用任何排序方法都行)。 #include <stdio.h> #include <stdbool.h> int main(int argc,const char* argv[]) { ??? int arr[] = {10,3,7,5,8,9,2,4,0,6}; ??? size_t len = sizeof(arr)/sizeof(arr[0]); ??? ??? // 经典排序 ??? for(int i=0; i<len-1; i++) ??? {?? ??????? for(int j=i+1; j<len; j++) ??????? { ??????????? if(arr[i] > arr[j]) ??????????? { ??????????????? int tmp = arr[i]; ??????????????? arr[i] = arr[j]; ??????????????? arr[j] = tmp; ??????????? } ??????? } ??? }?? ??? // 冒泡排序:通过前后比较数据,把较大的数交换到后面,它每一趟排序都把当前待排序的最大值放在最后面,该过程非常像气泡在水底上升的过程,因此叫冒泡排序,这种排序算法的特点:对数据的有序性敏感,在排序过程中一旦数据已经排序完成,冒泡排序会立即结束。 ??? bool flag = true; ??? for(int i=len-1; i>0 && flag; i--) ??? {?? ??????? flag = false; ??????? for(int j=0; j<i; j++) ??????? { ??????????? if(arr[j] > arr[j+1]) ??????????? { ??????????????? int tmp = arr[j]; ??????????????? arr[j] = arr[j+1]; ??????????????? arr[j+1] = tmp; ??????????????? flag = true; ??????????? } ??????? } ??? }?? ??? // 选择排序:每次从先假定当前位置的数据是最小值,然后与它后面的数据进行比较(经典排序会立即交换),记录最小值的下标,如果最小值下标不是当位置,则把最小值与当前数据交换,与经典排序相比数据比较的次数没有变,但大大降低了数据的交换次数,以此提高排序速度。 ??? for(int i=0; i<len-1; i++) ??? {?? ??????? int min = i; ??????? for(int j=i+1; j<len; j++) ??????? { ??????????? if(arr[min] > arr[j]) ??????????????? min = j; ??????? } ??????? if(min != i) ??????? { ??????????? int tmp = arr[min]; ??????????? arr[min] = arr[i]; ??????????? arr[i] = tmp; ??????? } ??? }?? ? ????????// 遍历数组 ??? for(int i=0; i<len; i++) ??? {?? ??????? printf("%d ",arr[i]); ??? }?? ??? return 0; } ??? 3、输入一个整数,计算出每位数字出现的次数(参考练习10)。 #include <stdio.h> int main(int argc,const char* argv[]) { ??? int num; ??? printf("请输入一个整数:"); ??? scanf("%d",&num); ??? ??? int cnts[10] = {}; // 记录每个数字出现的次数 ??? do{ ??????? cnts[num%10]++; ??? }while(num/=10); ??? for(int i=0; i<10; i++) ??? {?? ??????? if(cnts[i]) ??????????? printf("数字%d 出现了%d次\n",i,cnts[i]); ??? }?? ??? return 0; } ??? 4、输入一个整数,判断是否是回文数(左右对称的数字叫回文数)。 #include <stdio.h> int main(int argc,const char* argv[]) { ??? int num; ??? printf("请输入一个整数:"); ??? scanf("%d",&num); ??? // 把num倒着拆分出来组成一个新的整数 ??? int tmp = num , new = 0; ??? do{ ??????? new = new*10+tmp%10; ??? }while(tmp/=10); ??? // 如果新组成的整数等于原来的整数则是回文数 ??? if(new == num) ??????? printf("是回文数!\n"); ??? else ??????? printf("不是回文数!\n"); ??? /* ??? // 把整数的每一位数字拆分出来并记录位数 ??? char arr[10],cnt=0; ??? do{ ??????? arr[cnt++] = num % 10; ??? }while(num/=10); ??? // 把第一位与倒数第一位比较,把第二位与倒数第二位比较,... 只要有一次不相等它就不是回文数 ??? for(int i=0; i<cnt/2; i++) ??? { ??????? if(arr[i] != arr[cnt-i-1]) ??????? { ??????????? printf("不是回文数!\n"); ??????????? return 0; ??????? } ??? } ??? printf("是回文数!\n"); ??? */ ??? return 0; } ?? ?5、计算并显示出100的阶乘(用数组模拟乘法的计算过程)。 #include <stdio.h> int main(int argc,const char* argv[]) { ??? // 把数组当作一张非常长的纸,并且存储1×2×3的值 ??? char arr[200] = {6}; ??? int cnt = 1; ??? for(int i=4; i<101; i++) ??? { ??????? int carry = 0; ??????? for(int j=0; j<cnt; j++) ??????? { ??????????? // 用i与数组中的每个数字相乘并加上前一位的进位 ??????????? int num = i*arr[j]+carry; ??????????? // 计算出当前位的值 ??????????? arr[j] = num % 10; ??????????? // 计算出下一位的进位 ??????????? carry = num / 10; ??????? } ??????? while(carry) ??????? { ??????????? arr[cnt++] = carry % 10; ??????????? carry /= 10; ??????? } ??? } ??? for(int i=cnt-1; i>=0; i--) ??? { ??????? printf("%d",arr[i]); ??? } ??? return 0; } ??? 6、计算出100000的阶乘末尾有多少个零(思考阶乘末尾的0是如何产生的)。 #include <stdio.h> int main(int argc,const char* argv[]) { ? ????????// 分析:结尾的是*10产生的,2*5产生的10,因为2是无限的,所以只要计算出能拆分出多个5就能计算出末尾有多少个0。 ??? int cnt = 0; ??? for(int i=5; i<=100000; i++) ??? {?? ??????? int num = i; ??????? while(0 == num%5) ??????? { ??????????? num/=5; ??????????? cnt++; ??????? } ??? }?? ??? printf("%d\n",cnt); ??? return 0; } ? ??附加题:编程解决约瑟夫出圈问题。41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。 #include <stdio.h> // 约瑟夫出圈问题 int main(int argc,const char* argv[]) { ??? // 用数组代表每个人,值为0表示人活着,值为1表示人死了 ??? int arr[41] = {}; ??? // 记录活人的数量,当cnt等于2时结束自杀 ??? int cnt = 41; ??? // 用来遍历数组 ??? int index = 0; ??? // 用来计数 ??? int num = 0; ??? // 开始自杀 ??? while(cnt > 2) ??? { ??????? // 判断人是否活着 ??????? if(0 == arr[index]) ??????? { ??????????? // 计数加1 ??????????? num++; ??????? } ??????? // 判断是否数到3 ??????? if(num == 3) ??????? { ??????????? // 杀死数到3的人 ??????????? arr[index] = 1; ??????????? // 记数归0 ??????????? num = 0; ??????????? // 人数减1 ??????????? cnt--; ??????? } ??????? // 下一个人,当数数组的末尾时要回头 ??????? if(41 == ++index) ??????????? index = 0; ??? } ??? // 找出活着的人 ??? for(int i=0; i<41; i++) ??? { ??????? if(0 == arr[i]) ??????? { ??????????? printf("%d\n",i+1); ??????? } ??? } ??? return 0; } |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 10:06:27- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |