目录
第一题:用数组作为参数实现冒泡排序
不用函数的冒泡排序
冒泡排序原理:
一共经过n-1次排序:相邻之间两两作比较。交换位置
cpp
//数组作为参数实现冒泡排序
int main()
{
int arr[] = { 10,9,8,7,6,5,4,3,2,1 };
int sz = sizeof(arr) / sizeof(arr[0]);
for(int i=0;i<sz-1;i++)
{
for(int 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;
}
}
}
for(int i=0;i<sz;i++)
{
printf("%d ", arr[i]);
}
return 0;
}
错误的数值传参冒泡排序
我们将冒泡的实现封装成一个函数,这时我们发现出来,问题,打印的结果并没实现冒泡排序
cpp
//错误的数组作为参数实现冒泡排序
void bubble_sort(int arr[])
{
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < sz - 1; i++)
{
for (int 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 };
bubble_sort(arr);
int i = 0;
for(i=0;i<10;i++)
{
printf("%d ", arr[i]);
}
return 0;
}
错误的原因
这是因为,有一个知识点需要补充。
就是什么是数组名
什么是数组名arr
- 数组名其实是地址,而且是首元素的地址
- 但是有两个特例不是首元素的地址
- sizeof(arr)这里不是首元素的地址,这里是整个数组的大小
- &arr,对数组取地址,这里不是对首元素取地址,这里是对数组取地址
- 除了这两个特例以外,其他的情况都是首元素的地址
- 数组是数组同样其实也是指针,因此可以用数组接收,也可以用指针接收
下面我们用的数组名arr传参,这里arr是首元素的地址。
cpp
bubble_sort(arr);
参数传给
cpp
void bubble_sort(int arr[])
//也可以用
void bubble_sort(int* arr)
被下面的调用,但是由于arr是首元素的地址,所以sizeof(arr)求出的是首元素的大学4字节,
sizeof(arr【0】)也是首元素的地址4字节。所以这是式子的结果为1;并非实际大小10.
cpp
int sz = sizeof(arr) / sizeof(arr[0]);
正确的数组传参的冒泡排序
cpp
//正确的数组作为参数实现冒泡排序
void bubble_sort(int arr[],int sz)
{
int i = 0;
for (int i = 0; i < sz - 1; i++)
{
for (int 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 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr,sz);
int i = 0;
for(i=0;i<10;i++)
{
printf("%d ", arr[i]);
}
return 0;
}
数组的地址和数组首元素的地址的区别
虽然数组名在一些情况相当于数组首元的地址,但是这并不能代表数组的地址等于数组首元素的地址。
下面我们可以看出,数组名和数组首元素还有数组的地址的地址是一样的。
而当我们对数组的地址和数组首元素的地址+1之后,就会发现他们并不一样。
我们发现数组名+1,和数组首元素+1,相当于地址加了4,这是应为他们加一相当于跳过了一位元素,四个字节。
而数组的地址加一,相当于整个数组10个元素都+1,那么就加了40个字节的地址。