数组作为函数传参
在写代码时候,会把数组作为参数传参,例如下面是一个冒泡排序函数,进行传参:
首先冒泡排序是如下代码,可以实现升序输出:
#include <stdio.h>
int main()
{
int arr[10] = { 0,1,2,5,3,4,6,7,8,9 };
int sz = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < sz-1; i++)
{
for (int j = 0; j < sz - 1 - i; j++)
{
int temp = 0;
if (arr[j] > arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
如果把冒泡排序的过程放到函数中,下面是错误演示:
void bubble_sort(int arr)
{
int sz = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < sz - 1; i++)
{
for (int j = 0; j < sz - 1 - i; j++)
{
int temp = 0;
if (arr[j] > arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
int main()
{
int arr[10] = { 0,1,2,5,3,4,6,7,8,9 };
bubble_sort(arr);
for (int i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)
{
printf("%d ", arr[i]);
}
return 0;
}
虽然看似正确的代码,实际运行时却是错误的,问题就出在传参的过程。
调试代码会发现,问题在于函数内部的sz出了问题,那么sz为什么会出现问题?
先说结论,原因后面分析:
arr作为数组传参,传递的是地址,所以在函数进行传参的时候,传递的其实是首元素的地址。
于是冒泡排序的正确函数体实现方式:
void bubble_sort(int arr[], int sz)
{
for (int i = 0; i < sz - 1; i++)
{
for (int j = 0; j < sz - 1 - i; j++)
{
int temp = 0;
if (arr[j] > arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
int main()
{
int arr[10] = { 0,1,2,5,3,4,6,7,8,9 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr,sz);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
数组名究竟代表什么意义?
先说结论:
通常情况下,数组名代表的是首元素的地址,也有两个特例:
1.sizeof(数组名)
数组名单独放在sizeof中,计算的是整个数组的大小。
2.&数组名
表示整个数组的地址,但也是从头开始的。
除这两种之外,其他都表示首元素的地址。
于是,实际上,这两个输出其实是一样的:
#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5 };
printf("%p\n", arr);
printf("%p\n", &arr[0]);
return 0;
}