C语言-数组:数组(定义、初始化、元素的访问、遍历)内存和内存地址、数组的查找算法和排序算法;

本章概述思维导图:

C语言数组

在C语言中,数组是一种固定大小的、相同类型元素的有序集合,通过索引(下标)访问。

数组

数组:是一种容器,可以用来存储同种数据类型的多个值;

数组特点:

1.连续的空间;

2.一旦定义了,长度不可变换;

代码示例:

cpp 复制代码
#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;
}

数组的初始化

数组的初始化:定义数组的时候,第一次给数组赋值;

数组初始化细节:

长度省略:数组值的个数就是数组的长度;

长度未省略:数组的个数<=长度;

代码示例:

cpp 复制代码
#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语言不检查数组边界,越界访问会导致未定义行为(如崩溃或数据损坏)

代码示例:

cpp 复制代码
#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.1415
	return 0;
}

数组遍历

在C语言中,数组遍历是指依次访问数组中的每一个元素,通常使用循环结构(如 forwhile)实现。

代码示例:

cpp 复制代码
#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类型的数据;
	
	//遍历数组arr1
	for(int i=0;i<3;i++)
		printf("arr1[%d]=%d\t",i,arr1[i]);
	putchar('\n');
	//遍历数组arr2
	for(int i=0;i<3;i++)
		printf("arr2[%d]=%c\t",i,arr2[i]);
	putchar('\n');
	//遍历数组arr1
	for(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;

代码示例:

cpp 复制代码
#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

内存地址的规则:每个内存单元有唯一地址:无论是代码、数据还是栈/堆空间,每个字节都有一个独立的地址。

数组在内存中的深入刨析

数组名是首地址,索引在输出数组的地址时不需要取地址符:&;

代码示例:

cpp 复制代码
#include <stdio.h>
int main()
{	
	int arr1[3]={1,22,333};
	printf("arr1的地址为:%p\n",arr1);
	return 0;
}

//代码运行结果:
arr1的地址为:0x7ffeaba095dc

数组的地址是连续的:数组元素的地址按类型大小连续排列;

数组名【索引】:地址偏移n个单位;

单位:根际数据类型相关;int4个字节、char1个字节......

代码示例:

cpp 复制代码
#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;

代码示例:

cpp 复制代码
#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;

代码示例:

cpp 复制代码
#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.第三轮结束只要在剩余的元素找最大值就可以

  1. ......

  2. 全部排序完

细节:如果数组中有N个数据,总共我们z只用执行N-1轮的比较代码就可以

第一轮比较完毕后,最大值就已经确定,第二轮可以少循环一次,后面以此类推

代码示例:

cpp 复制代码
#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索引开始,拿着每一个索引上的元素跟后面的元素依次比较,大的放前面,小的放后面,以此类推;

代码示例:

cpp 复制代码
#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},请找出数组中最大值并打印在控制台上

cpp 复制代码
#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.统计有多少个数据比平均值小

代码示例:

cpp 复制代码
#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.再次遍历

代码示例:

cpp 复制代码
#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

代码示例:

cpp 复制代码
#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的个数

代码示例:

cpp 复制代码
#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个整数,输出数组所有成员(正向和逆向);输出最大值,最小值和平均值;

代码示例:

cpp 复制代码
#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");
}

制作不易!喜欢的小伙伴给个小赞赞!喜欢我的小伙伴点个关注!有不懂的地方和需要的资源随时问我哟!

相关推荐
拳里剑气几秒前
C语言:顺序表(上)
c语言·开发语言·数据结构·学习方法
Vegetable_Dragon8 分钟前
数论1.01
算法
Star在努力13 分钟前
15-C语言:第15天笔记
c语言·笔记·算法
我有一计33340 分钟前
【算法笔记】5.LeetCode-Hot100-矩阵专项
人工智能·算法·程序员
行然梦实1 小时前
KnEA(Knee-point-driven Evolutionary Algorithm)简介
人工智能·算法·机器学习
qq_513970441 小时前
力扣 hot100 Day58
算法·leetcode
螺丝钉的扭矩一瞬间产生高能蛋白2 小时前
MCU+RTOS调试
c语言·stm32·单片机·嵌入式硬件·嵌入式
liulilittle2 小时前
DDD领域驱动中瘦模型与富态模型的核心区别
开发语言·c++·算法·ddd·领域驱动·思想
Das12 小时前
【初识数据结构】CS61B 中的归并排序和选择排序
数据结构·算法·排序算法
l1t3 小时前
开源嵌入式数组引擎TileDB的简单使用
c语言·数据库·c++