对数组进行冒泡排序,并理解“arr”、&arr[0]、*arr

我们对数组进行冒泡排序,借助冒泡排序,来加深对“arr”、&arr[0]、*arr的理解。

首先来看一下这段代码:

#define _CRT_SECURE_NO_WARNINGS
//对数组进行冒泡排序
#include
void SortArray(int arr[])
{
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (int i = 0; i < sz - 1; ++i)
	{
		for (int j = 0; j < sz - i - 1; ++j)
		{
			if (arr[j] > arr[j + 1])
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}
int main()
{
	int arr[5] = { 12,4,35,65,7 };
	SortArray(arr);
	for (int i = 0; i < 5; ++i)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

运行结果:

对数组进行冒泡排序,并理解“arr”、&arr[0]、*arr_第1张图片

不难看出,我们的排序并没有成功,这是为什么呢?冒泡排序是可以实现正确的排序的,所以我们应该不是出错在排序算法上,让我们调试一下,找找原因。

对数组进行冒泡排序,并理解“arr”、&arr[0]、*arr_第2张图片

我们发现,冒泡排序中一个重要的变量出现了错误,sz的值为1,并不是我们想要的数组的长度,这是为什么呢?sz是这样子计算的: int sz = sizeof(arr) / sizeof(arr[0]);sizeof(arr[0])这部分不会出错,那就是sizeof(arr)出问题了,在函数参数传递过程中出现了错误。那是什么错误呢?难道数组作为函数参数传递的时候,不是把整个数组传递过去?我们来研究一下数组名到底是啥,在参数传递过程中到底传递的是什么?

#define _CRT_SECURE_NO_WARNINGS
#include
int main()
{
	int arr[5] = { 12,4,35,65,7 };
	printf("%p\n", arr);
	printf("%p\n", &arr[0]);
	printf("%d\n", *arr);
	return 0;
}

运行结果:

对数组进行冒泡排序,并理解“arr”、&arr[0]、*arr_第3张图片

我们发现,数组名是数组首元素的地址,且*arr得到的是数组首元素的值。

但是,我们再看下面这个代码:

#define _CRT_SECURE_NO_WARNINGS
#include
int main()
{
	int arr[5] = { 12,4,35,65,7 };
	printf("%p\n", arr);
	printf("%p\n", &arr[0]);
	printf("%d\n", *arr);
	printf("%d\n", sizeof(arr));
	return 0;
}

 运行结果:

对数组进行冒泡排序,并理解“arr”、&arr[0]、*arr_第4张图片

 为什么sizeof(arr)等于20,不等于4呢?所以我们不能单纯的把数组名和首元素地址划等号,可以这样来理解,数组名代表的就是一个数组,代表的是一块内存空间,只不过数组名的值是数组首元素的地址,在将数组作为参数传递的过程中,传递的数组名其实是一个值,并且这个值就是数组首元素的地址值。

为什么要这么规定呢?有一个原因就是为了节约空间、提高效率。如果在传参过程中将整个数组传过去,在数组较大时,耗费的时间和空间都是比较大的,如果我们只传一个首地址,并且知道数组的大小,那么计算机就可以根据首地址找到属于该数组的整块内存空间了,就减少了时间复杂度和空间复杂度。

所以,大家应该就知道这个冒泡排序怎么改进了,我们将数组作为函数参数时,应该传递数组名和数组大小,这样子函数就能正常工作了。下面是改进后的代码。

#define _CRT_SECURE_NO_WARNINGS
#include
void SortArray(int arr[],int sz)
{
	for (int i = 0; i < sz - 1; ++i)
	{
		for (int j = 0; j < sz - i - 1; ++j)
		{
			if (arr[j] > arr[j + 1])
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}
int main()
{
	int arr[5] = { 12,4,35,65,7 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	SortArray(arr, sz);
	for (int i = 0; i < 5; ++i)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

运行结果:

对数组进行冒泡排序,并理解“arr”、&arr[0]、*arr_第5张图片

这样子就得到正确的结果了,如果从大到小排序只需要改变判断条件即可:

#define _CRT_SECURE_NO_WARNINGS
#include
void SortArray(int arr[],int sz)
{
	for (int i = 0; i < sz - 1; ++i)
	{
		for (int j = 0; j < sz - i - 1; ++j)
		{
			if (arr[j] < arr[j + 1])
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}
int main()
{
	int arr[5] = { 12,4,35,65,7 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	SortArray(arr, sz);
	for (int i = 0; i < 5; ++i)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

 运行结果:

对数组进行冒泡排序,并理解“arr”、&arr[0]、*arr_第6张图片

 

你可能感兴趣的:(排序算法,算法,c语言,开发语言,后端)