C语言-数组:数组(定义、初始化、元素的访问、遍历)内存和内存地址、数组的查找算法和排序算法;
本章概述思维导图:
C语言数组
在C语言中,数组是一种固定大小的、相同类型元素的有序集合,通过索引(下标)访问。
数组
数组:是一种容器,可以用来存储同种数据类型的多个值;
数组特点:
1.连续的空间;
2.一旦定义了,长度不可变换;
代码示例:
#include <stdio.h>
int main()
{int arr1[3];//定义了数组:arr1;用来存储3个int类型的数据;char arr2[3];//定义了数组:arr2;用来存储3个char类型的数据;float arr3[3];//定义了数组:arr3;用来存储3个float类型的数据;return 0;
}
数组的初始化
数组的初始化:定义数组的时候,第一次给数组赋值;
数组初始化细节:
长度省略:数组值的个数就是数组的长度;
长度未省略:数组的个数<=长度;
代码示例:
#include <stdio.h>
int main()
{//长度未省略:数组的个数<=长度int arr1[3]={1,22,333};//定义了数组:arr1;用来存储int类型的数据;char arr2[3]={'i','j','k'};//定义了数组:arr2;用来存储char类型的数据;float arr3[3]={1.25,6.68,0.888};//定义了数组:arr3;用来存储float类型的数据;//长度省略:数据值的个数就是数组的长度int arr4[]={8,9,100};//定义了数组:arr4;用来存储int类型的数据;char arr5[]={'a','b','c'};//定义了数组:arr5;用来存储char类型的数据;float arr6[]={154.25,9.68,3.888};//定义了数组:arr6;用来存储float类型的数据;return 0;
}
数组中元素的访问--获取和修改
索引:索引就是数组的一个编号,也叫做:角标、下标、编号;
特点:从0开始的,连续+1,不间断;
数组的获取:
数组的修改:
索引细节:
1. 索引的范围:最小索引0;最大索引:数组长度-1;
2. 越界访问:C语言不检查数组边界,越界访问会导致未定义行为(如崩溃或数据损坏)
代码示例:
#include <stdio.h>
int main()
{//数组的初始化int arr1[3]={1,22,333};//定义了数组:arr1;用来存储3个int类型的数据;char arr2[3]={'i','j','k'};//定义了数组:arr2;用来存储3个char类型的数据;float arr3[3]={1.25,6.68,0.888};//定义了数组:arr3;用来存储3个float类型的数据;//数组元素的获取和修改arr1[0]=4;//将数组arr1中第一个元素:1 修改为:4;arr2[1]='a';//将数组arr2中第二个元素:j 修改为:a;arr3[2]=3.1415;//将数组arr3中第三个元素:0.888 修改为:3.1415return 0;
}
数组遍历
在C语言中,数组遍历是指依次访问数组中的每一个元素,通常使用循环结构(如 for
、while
)实现。
代码示例:
#include <stdio.h>
int main()
{//数组的初始化int arr1[3]={1,22,333};//定义了数组:arr1;用来存储3个int类型的数据;char arr2[3]={'i','j','k'};//定义了数组:arr2;用来存储3个char类型的数据;float arr3[3]={1.25,6.68,0.88};//定义了数组:arr3;用来存储3个float类型的数据;//遍历数组arr1for(int i=0;i<3;i++)printf("arr1[%d]=%d\t",i,arr1[i]);putchar('\n');//遍历数组arr2for(int i=0;i<3;i++)printf("arr2[%d]=%c\t",i,arr2[i]);putchar('\n');//遍历数组arr1for(int i=0;i<3;i++)printf("arr1[%d]=%.2f\t",i,arr3[i]);putchar('\n');return 0;
}//代码运行结果:
arr1[0]=1 arr1[1]=22 arr1[2]=333
arr2[0]=i arr2[1]=j arr2[2]=k
arr1[0]=1.25 arr1[1]=6.68 arr1[2]=0.88
内存和内存地址
内存和内存地址
内存:软件程序在运行时,用来临时存储数据的,操作系统会把内存按照字节划分为N多个小格子
内存地址:内存中每一个小格子的编号(一格小格子1字节(8位));
内存地址作用:快速的管理内存空间;
通常用十六进制表示
C语言中的内存地址:
示例:
int 类型--->4个字节 首地址-->找到第一个小格子;根据4个字节
char类型-->1个字节 首地址-->找到第一个小格子;根据1个字节
取地址占位符:%p;
代码示例:
#include <stdio.h>
int main()
{ int num1=0;printf("num1的地址为:%p\n",&num1);int arr1[3]={1,22,333};printf("arr1的地址为:%p\n",arr1);return 0;
}//代码运行结果:
num1的地址为:0x7ffeaba095d8
arr1的地址为:0x7ffeaba095dc
内存地址的规则:每个内存单元有唯一地址:无论是代码、数据还是栈/堆空间,每个字节都有一个独立的地址。
数组在内存中的深入刨析
数组名是首地址,索引在输出数组的地址时不需要取地址符:&;
代码示例:
#include <stdio.h>
int main()
{ int arr1[3]={1,22,333};printf("arr1的地址为:%p\n",arr1);return 0;
}//代码运行结果:
arr1的地址为:0x7ffeaba095dc
数组的地址是连续的:数组元素的地址按类型大小连续排列;
数组名【索引】:地址偏移n个单位;
单位:根际数据类型相关;int4个字节、char1个字节……
代码示例:
#include <stdio.h>
int main()
{int arr1[3]={1,22,333};printf("arr1[0]:%p\tarr1[1]:%p\tarr1[2]:%p\t\n",&arr1[0],&arr1[1],&arr1[2]);return 0;
}//代码运行结果:
arr1[0]:0x7ffc1d13880c arr1[1]:0x7ffc1d138810 arr1[2]:0x7ffc1d138814
数组的常见问题
数组作为函数的形参,要注意什么?
数组作为函数的形参实现上传递的是数组的首地址,如果是要做函数中对数组进行遍历的话,记得一定要把数组的长度一起传递过去;
在主函数定义处中:arr表示的是完整的数组;
在函数中:arr只是一个变量,用来记录数组的首地址;
数组的索引越界:数组的最小索引为:0 ;数组的最大索引为:长度-1;
代码示例:
#include <stdio.h>
void arr_put(int arr[],int len);//函数声明
int main()
{int arr1[]={1,2,3,4};int len1=sizeof(arr1)/sizeof(int);arr_put(arr1,len1);return 0;
}
void arr_put(int arr[],int len)//函数封装:遍历数组
{for(int i=0;i<len;i++){printf("arr[%d]=%d\t",i,arr[i]);}putchar('\n');
}//代码运行结果:
arr[0]=1 arr[1]=2 arr[2]=3 arr[3]=4
数组的查找算法
基本查找(顺序查找):就是从数组的0索引开始,依次往后查找。找到了返回数据对应索引,如果没有找到,就会返回-1;
代码示例:
#include <stdio.h>
void arr_put(int arr[],int len);//函数声明
int chazhao_arr(int arr[],int len,int num);//函数声明:查找算法
int main()
{int arr1[]={1,2,3,4};int len1=sizeof(arr1)/sizeof(int);arr_put(arr1,len1);int num1=0;printf("输入要查找的数据:\n");scanf("%d",&num1);int a=chazhao_arr(arr1,len1,num1);if(a != -1){printf("查找的数据对应索引为:%d\n",a);}else printf("未查找到数据\n");return 0;
}
void arr_put(int arr[],int len)//函数封装:遍历数组
{for(int i=0;i<len;i++){printf("arr[%d]=%d\t",i,arr[i]);}putchar('\n');
}
int chazhao_arr(int arr[],int len,int num)//函数封装:查找算法
{for(int i=0;i<len;i++){if(arr[i] == num){return i;}}return -1;
}//代码第一次运行结果:
arr[0]=1 arr[1]=2 arr[2]=3 arr[3]=4
输入要查找的数据:
2
查找的数据对应索引为:1//代码第二次运行结果:
arr[0]=1 arr[1]=2 arr[2]=3 arr[3]=4
输入要查找的数据:
6
未查找到数据
数组的排序算法
冒泡排序算法:相邻的数据两两比较,小的放前面,大的放后面
1.相邻的元素两两比较,大的放右边,小的放左边
2.第一轮结束,最大值已经找到,在数组的最右边
3.第二轮结束只要在剩余的元素找最大值就可以
4.第三轮结束只要在剩余的元素找最大值就可以
5. ……
6. 全部排序完
细节:如果数组中有N个数据,总共我们z只用执行N-1轮的比较代码就可以
第一轮比较完毕后,最大值就已经确定,第二轮可以少循环一次,后面以此类推
代码示例:
#include <stdio.h>
void arr_put(int arr[],int len);//函数声明
void arr_min_max(int arr[],int len);//函数声明:排序算法从小到大排序
int main()
{int arr1[5]={88,66,775,958,12};//定义数组int len1=sizeof(arr1)/sizeof(int);arr_put(arr1,len1);//数组遍历arr_min_max(arr1,len1);//数组排序arr_put(arr1,len1);//数组遍历
}
void arr_put(int arr[],int len)//函数封装:遍历数组
{for(int i=0;i<len;i++){printf("arr[%d]=%d\t",i,arr[i]);}putchar('\n');
}
void arr_min_max(int arr[],int len)//函数封装:排序算法从小到大排序
{for(int i=0;i<len-1;i++)//比较的轮数,减一是因为最后一次不需要比较{int temp=0;for(int j=0;j<len-1-i;j++)//相邻比较,减i减1是因为每轮比较都以排除一个数据,提升效率{if(arr[j]>arr[j+1]){temp=arr[j];arr[j]=arr[j+1];arr[j+1]=temp;}}}
}//代码运行结果:
arr[0]=88 arr[1]=66 arr[2]=775 arr[3]=958 arr[4]=12
arr[0]=12 arr[1]=66 arr[2]=88 arr[3]=775 arr[4]=958
选择排序算法:从0索引开始,拿着每一个索引上的元素跟后面的元素依次比较,大的放前面,小的放后面,以此类推;
代码示例:
#include <stdio.h>
void arr_put(int arr[],int len);//函数声明
void arr_max_min(int arr[],int len);//函数封装:选择排序从大到小排序
int main()
{int arr1[5]={88,66,775,958,12};int len1=sizeof(arr1)/sizeof(int);arr_put(arr1,len1);arr_max_min(arr1,len1);arr_put(arr1,len1);
}
void arr_put(int arr[],int len)//函数封装:遍历数组
{for(int i=0;i<len;i++){printf("arr[%d]=%d\t",i,arr[i]);}putchar('\n');
}void arr_max_min(int arr[],int len)//函数封装:选择排序从大到小排序
{for(int i=0;i<len-1;i++){int temp=0;for(int j=i+1;j<len;j++){if(arr[i]<arr[j]){temp=arr[i];arr[i]=arr[j];arr[j]=temp;}}}
}//代码运行结果:
arr[0]=88 arr[1]=66 arr[2]=775 arr[3]=958 arr[4]=12
arr[0]=958 arr[1]=775 arr[2]=88 arr[3]=66 arr[4]=12
数组练习题
通过本章的学习,接下来就是进入实战环节,小伙伴们开始攻略C语言数组(冒泡/选择排序和查找算法)练习题啦!小伙伴们先尝试自己敲代码敲完后在来查看代码示例呦!
数组(求最值)
题目:已知数组元素为:{33,5,22,44,55},请找出数组中最大值并打印在控制台上
#include <stdio.h>
int max_out(int arr[],int len);
int main()
{int arr[5]={33,5,22,44,55};int len=sizeof(arr)/sizeof(int);int max=max_out(arr,len);printf("max=%d\n",max);return 0;
}
int max_out(int arr[],int len)//函数封装:找最值
{int max=0;for(int i=0;i<len;i++){if(max<arr[i]){max=arr[i];}}return max;
}
数组(求和)
题目:生成10个1~100之间的随机数存入数组
1.求出所有数据的平均数
2.统计有多少个数据比平均值小
代码示例:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int sum_out(int arr[]);
int main()
{srand(time(NULL));//生成种子int arr[10];for(int i=0;i<10;i++){arr[i]=rand()%100+1;printf("arr[%d]=%d\n",i,arr[i]);}int sum=sum_out(arr);printf("和为:%d\n",sum);int count=sum/10;printf("平均值为:%d\n",count);int count1=0;//统计比平均值小的变量;for(int i=0;i<10;i++){if(arr[i]<count){printf("%d比平均值小\n",arr[i]);count1++;}}printf("一共有%d个数字比平均值小\n",count1);return 0;
}
int sum_out(int arr[])//求数组的和
{int sum=0;for(int i=0;i<10;i++){sum+=arr[i];}return sum;
}
数组(反转数组)
题目:键盘录入五个数据并存入数组,完成以下需求
1.遍历数组
2.反转数组
3.再次遍历
代码示例:
#include <stdio.h>
void bianli_arr(int arr[],int len);
int main()
{printf("输入五个数据\n");int arr[5];for(int i=0;i<5;i++){scanf("%d",&arr[i]);}bianli_arr(arr,5);int temp=0;for(int i=0;i<5/2;i++){temp=arr[i];arr[i]=arr[4-i];arr[4-i]=temp;}bianli_arr(arr,5);return 0;
}
void bianli_arr(int arr[],int len)
{for(int i=0;i<len;i++){printf("arr[%d]=%d ",i,arr[i]);}printf("\n");
}
数组(替换)
题目:定义一个5个成员整型数组data[]={10,22,88,66,88},将所有的88替换成666
代码示例:
#include<stdio.h>
int main()
{int arr[]={10,22,88,66,88};int len=sizeof(arr)/sizeof(int);for(int i=0;i<len;i++){if(arr[i] == 88){arr[i]=666;}}for(int i=0;i<len;i++){printf("%d ",arr[i]);}return 0;
}
数组(统计)
题目:定义一个5个成员整型数组data[]={10,22,88,66,88},统计88的个数
代码示例:
#include<stdio.h>
int main()
{int arr[]={10,22,88,66,88};int len=sizeof(arr)/sizeof(int);int count=0;for(int i=0;i<len;i++){if(arr[i] == 88){count++;}}printf("88出现的个数有%d个\n",count);return 0;
}
数组(正向/逆向排序)
题目:定义一个5个成员整型数组,从键盘上获取5个整数,输出数组所有成员(正向和逆向);输出最大值,最小值和平均值;
代码示例:
#include<stdio.h>
void arr_bianli(int arr[],int len);
int main()
{int arr[5];printf("输入五个数:\n");for(int i=0;i<5;i++){scanf("%d",&arr[i]);}/*从大到小排序*/for(int i=0;i<4;i++){for(int j=0;j<4-i;j++){if(arr[j]<arr[j+1]){arr[j]=arr[j+1]^arr[j];arr[j+1]=arr[j]^arr[j+1];arr[j]=arr[j]^arr[j+1];}}}arr_bianli(arr,5);/*从小到大排序*/for(int i=0;i<4;i++){for(int j=0;j<4-i;j++){if(arr[j]>arr[j+1]){arr[j]=arr[j+1]^arr[j];arr[j+1]=arr[j]^arr[j+1];arr[j]=arr[j]^arr[j+1];}}}arr_bianli(arr,5);printf("最小值为:%d\t最大值为:%d\n",arr[0],arr[4]);int sum=0;for(int i=0;i<5;i++){sum+=arr[i];}printf("平均值为:%d\n",sum/5);return 0;
}
void arr_bianli(int arr[],int len)//函数封装:循环打印遍历数组
{for(int i=0;i<len;i++){printf("%d ",arr[i]);}printf("\n");
}
制作不易!喜欢的小伙伴给个小赞赞!喜欢我的小伙伴点个关注!有不懂的地方和需要的资源随时问我哟!