我们对数组进行冒泡排序,借助冒泡排序,来加深对“arr”、&arr[0]、*arr的理解。
首先来看一下这段代码:
#define _CRT_SECURE_NO_WARNINGS
//对数组进行冒泡排序
#include<stdio.h>
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;
}
运行结果:
不难看出,我们的排序并没有成功,这是为什么呢?冒泡排序是可以实现正确的排序的,所以我们应该不是出错在排序算法上,让我们调试一下,找找原因。
我们发现,冒泡排序中一个重要的变量出现了错误,sz的值为1,并不是我们想要的数组的长度,这是为什么呢?sz是这样子计算的: int sz = sizeof(arr) / sizeof(arr[0]);sizeof(arr[0])这部分不会出错,那就是sizeof(arr)出问题了,在函数参数传递过程中出现了错误。那是什么错误呢?难道数组作为函数参数传递的时候,不是把整个数组传递过去?我们来研究一下数组名到底是啥,在参数传递过程中到底传递的是什么?
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
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得到的是数组首元素的值。
但是,我们再看下面这个代码:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
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;
}
运行结果:
为什么sizeof(arr)等于20,不等于4呢?所以我们不能单纯的把数组名和首元素地址划等号,可以这样来理解,数组名代表的就是一个数组,代表的是一块内存空间,只不过数组名的值是数组首元素的地址,在将数组作为参数传递的过程中,传递的数组名其实是一个值,并且这个值就是数组首元素的地址值。
为什么要这么规定呢?有一个原因就是为了节约空间、提高效率。如果在传参过程中将整个数组传过去,在数组较大时,耗费的时间和空间都是比较大的,如果我们只传一个首地址,并且知道数组的大小,那么计算机就可以根据首地址找到属于该数组的整块内存空间了,就减少了时间复杂度和空间复杂度。
所以,大家应该就知道这个冒泡排序怎么改进了,我们将数组作为函数参数时,应该传递数组名和数组大小,这样子函数就能正常工作了。下面是改进后的代码。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
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;
}
运行结果:
这样子就得到正确的结果了,如果从大到小排序只需要改变判断条件即可:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
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;
}
运行结果: