文章目录
- 1. 冒泡排序如何实现
- 1.1 冒泡排序函数的错误设计
- 1.2 数组名是什么?
- 1.3 冒泡排序函数的正确设计
1. 冒泡排序如何实现
-
往往我们在写代码的时候,会将数组作为参数传个函数,比如:我要实现一个冒泡排序(这里要讲算法思想)函数将一个整形数组排序。
-
冒泡排序思想:两两相邻元素进行比较,有可能的话需要交换。
比如一组整形数组arr[10]={9,8,7,6,5,4,3,2,1,0},如何利用冒泡排序的方法进行排序呢?
那我们将会这样使用该函数:
1.1 冒泡排序函数的错误设计
那我们如何利用代码进行冒泡排序呢?看代码:
#include<stdio.h>
void sort(int* arr)
{//确定个数int ret = sizeof(arr) / sizeof(arr[0]);//趟数int i = 0;for (i = 0; i < ret - 1; i++){//每一趟处理数据int j = 0;for (j = 0; j < ret - 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] = { 1,3,5,7,9,2,4,6,8,10 };sort(arr);//循环打印for (int i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;
}
但当我们执行代码却发现:
为什么我们通过sort函数进行数组排序,但结果却还是原数组呢?
我们发现在sort函数内部,计算的数组个数ret=1,数组元素ret不应该是10吗?怎么就变成1了呢?(在调用函数内部查看数组所有元素:(数组名,个数)–>(arr,10)),为了解决这个问题,我们不得不了解“数组名是什么?”
1.2 数组名是什么?
这里我们打印出数组名的地址和数组首元素的地址,我们可以发现:数组名是数组首元素的地址。
1.
看到这里估计就有人疑惑了,不是说arr是数组首元素的地址吗?那首元素的地址无非就是4\8了,但这为什么是40呢?40不是整个数组地址的大小吗?
2.
我们发现数组+1和数组的第一个元素+1结果相同,但(&)取地址arr+1却不同。(解释一下为什么是40个字节:这里地址是用十六进制表示的第一位+8,第二位+2,8x160=8,2x161=32,32+8=40)。
这是因为数组+1是跳过一个数组,数组首元素+1跳过的是一个元素。
总结:
数组名是数组首元素的地址,但存在两个特例:
1.sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节。
2.&数组名,这里的数组名表示整个数组,&数组名取出的是数组的地址。
1.3 冒泡排序函数的正确设计
在此之前,我们先解决之前错误代码的问题:
#include<stdio.h>
void sort(int* arr)
{//确定个数int ret = sizeof(arr) / sizeof(arr[0]);//趟数int i = 0;for (i = 0; i < ret - 1; i++){//每一趟处理数据int j = 0;for (j = 0; j < ret - 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] = { 1,3,5,7,9,2,4,6,8,10 };sort(arr);//循环打印for (int i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;
}
当数组传参的时候,实际上只是把数组“arr”的首元素的地址传递过去了。
所以即使在函数参数部分写成数组的形式: int arr[] 表示的依然是一个指针: int *arr 。
那么,既然传过去的是首元素的地址(4)函数内部的 sizeof(arr) 结果是4,4/4得出的ret=1.
如果 方法1 错了,该怎么设计?
#include<stdio.h>
void sort(int* arr, int ret)
{//趟数int i = 0;for (i = 0; i < ret - 1; i++){//每一趟处理数据int j = 0;for (j = 0; j < ret - 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] = { 1,3,5,7,9,2,4,6,8,10 };//确定个数int ret = sizeof(arr) / sizeof(arr[0]);sort(arr,ret);//循环打印for (int i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;
}
我们在main函数里先求出数组的个数,然后再通过sort函数把数组个数传过去就可以了,这样正确的冒泡排序就写完了。