数组——初识数据结构

代码星辉·七月创作之星挑战赛 10w+人浏览 266人参与

一维数组

数组的创建

数组是一种相同类型元素的集合

数组的创建方式

C99 中引入了变长数组的概念,变长数组支持数组的大小使用变量来指定

明显这里的vs2019不支持变长数组

数组初始化和不完全初始化

第二个数组就是典型的不完全初始化,开辟了10个空间,只有第一个是1,剩下的就用0填充

这里的ch1和ch2看起来似乎一样,但ch1只有 a b c, 后面的0是编译器主动加上的;ch2是abc\0,\0的ASCII码值也是0,所以后面也是6个0,但ch2本身就自带了一个

这样的代码也是有问题的,这里只用了一个空字符串初始化,所以数组的长度是一个元素

一维数组的使用

一个数组初始化好后每个元素都有其下标,下标是从0开始的

一维数组在内存中的存储

这里我们打印一下数组的每个元素的地址看看,%p是打印地址

我们发现每个相邻的地址最后的数字就相差4,因为这是整形数组,而一个整型是4个字节

数组在内存重视连续存放的!

随着数组下标的增长,地址也是由低到高变化的

数组开辟的空间也不宜太大

数组中的数据放在栈区

0和\0

二维数组

二维数组的创建

初始化

第一个参数是行数,第二个是列数

这个数组是怎么存放的呢?

其实是1234先把第一行放满,5放在第二行,其余的位置都是0

还有另一种初始化方式

就是指定初始化位置

以及,对于二维数组,初始化时,可以省略行,不能省略列

二维数组的使用

我们尝试一下一列一列打印

二维数组在内存中的存储

试着打印一下地址看看

能发现他们似乎也是连续存放的

也能将它们理解为一个12元素的整型数组

数组越界

当我们访问的空间超过数组申请的空间时,就造成了越界访问

还有这样

可能有人比较疑惑,为啥5会打印两次呢?

第一次打印了5个,第二次还是从行的下标0位置处开始,5这个位置是数组第二行的第一个元素,所以还会被打印一次。

数组应用

冒泡排序

冒泡排序(Bubble Sort)是一种简单直观的排序算法

冒泡排序的核心思想是:

通过相邻元素两两比较,把较大的元素“冒泡”到序列的一端,像水中的气泡一样逐步上升。

具体过程如下:

  • 从头到尾依次比较相邻两个元素,如果前一个比后一个大,就交换它们;

  • 每完成一轮,最大的元素就被“冒泡”到了当前未排序部分的末尾;

  • 然后对剩下的部分重复这一过程,直到整个序列有序。

比如排序 [5, 2, 4, 3, 1],第一轮结束后变成 [2, 4, 3, 1, 5],最大值 5 被放到了最后。之后对 [2, 4, 3, 1] 再次进行“冒泡”,直到全部排好序。

设有一个长度为 n 的数组,共需进行最多 n-1 轮“冒泡”:

  • 第 1 轮:比较 n-1 次,把最大值移到末尾;

  • 第 2 轮:比较 n-2 次,把次大值移到倒数第二位;

  • n-1 轮:只需比较 1 次。

基本理念就是数组中的元素两两相比较,随后判断是否交换位置,最终的目的是排成一个升序或降序数组

或者函数的形式

#include<stdio.h>
void bubble_sort(int arr[10])
{
	//求数组的元素个数
	int sz = sizeof(arr) / sizeof(arr[10]);
	//冒泡排序的趟数
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		//一趟冒泡排序
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}

int main()
{
	int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);

	//0 1 2 3 4 5 6 7 8 9
	//要对数组升序排序
	//冒泡排序
	bubble_sort(arr);
	//打印
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

但结果好像不对诶~

原来上面数组名传参的时候传递的只是数组首元素的地址,形参就是指针变量来接收,并没有把整个数组传上去。(这叫做数组名的降级)

上面sz就是1了,所以数组才会没变化

这时我们只需要在main函数里先把sz计算好,然后传给排序函数就行

#include<stdio.h>
void bubble_sort(int arr[10],int sz)
{
	//冒泡排序的趟数
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		//一趟冒泡排序
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}

int main()
{
	int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);

	//0 1 2 3 4 5 6 7 8 9
	//要对数组升序排序
	//冒泡排序
	bubble_sort(arr,sizeof(arr)/sizeof(arr[0]));
	//打印
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

看一下这段代码

运行结果是两边都相等!

这里刚好也得出了

当p指向数组的第一个元素时,p+i就指向数组第i个元素

p里存放着数组首元素的地址,所以p和arr可以相互替换,下面这些效果也相等

还有加法交换律能得出的结论

前面讲了数组名是数组首元素地址,但存在两个例外

sizeof(数组名),数组名表示整个数组,计算的是整个数组的大小,单位是字节

&数组名,数组名表示整个数组,取出的是整个数组的地址

看看这个,前面两个+1后跳过了一个整型元素,地址都是+4,而第三个+1后跳过了整个数组,地址变化了40个字节

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值