数组作为函数传参
在写代码时候,会把数组作为参数传参,例如下面是一个冒泡排序函数,进行传参:
首先冒泡排序是如下代码,可以实现升序输出:
#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; }