数组-1:点此转入
目录
4.数组作为函数参数
往往我们在写代码的时候,会将数组作为参数传给函数,比如:我们要实现一个冒泡排序函数将一个整形数组排序。那我们会这样使用该函数:
4.1 冒泡排序函数的错误设计
//方法1
#include <stdio.h>
void bubble_sort(int arr[])
{
int sz = sizeof(arr) / sizeof(arr[0]);
int right = sz - 1;
int i = 0, j = 0;
for (i = 0; i < sz; i++)
for(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] = { 2,3,5,7,9,8,4,6,1,0 };
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; i++)
printf("%d ", arr[i]);
printf("\n");
bubble_sort(arr);
for (i = 0; i < sz; i++)
printf("%d ", arr[i]);
return 0;
}
运行结果如图:
我们可以看到,数组并没有被有序排列,所以方法1是存在问题的
那我们来找一下问题,调试之后可以看到bubble_sort函数内部的sz的值为2,难道数组作为函数参数的时候,不是把整个数组传递过去的吗?
4.2 数组名是什么?
#include <stdio.h>
int main()
{
int arr[10] = {1,2,3,4,5};
printf("%p\n", arr);
printf("%p\n",&arr[0]);
printf("%d\n",*arr);
//输出结果
return 0;
}
运行结果如图:
我们可以看到,前两个打印出的结果是一样的,而第三个经过解引用的arr,打印出的则是arr[1]的值,所以我们可以得出结论:
数组名是数组首元素的地址
但是如果数组名是首元素地址,那么:
int arr[10] = {0};
printf("%d\n",sizeof(arr));
为什么输出的结果是:40?
补充:
- sizeof(数组名),计算整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数组。
- &数组名,取出的是整个数组的地址。&数组名,数组名表示整个数组。
以上两种情况数组名均是整个数组,除以上两种情况之外,所有的数组名都表示元素首元素的地址。
4.3 冒泡排序的正确设计
当数组传参的时候,实际上只是把数组的首元素的地址传递过去了。
所以即使在函数参数部分写成数组的形式:int arr[]表示的依然是一个指针:int *arr。
那么,函数内部sizeof(arr)结果是8或4或2(由编译器与机器决定).
如果方法1错了,该怎么设计?
#include <stdio.h>
void bubble_sort(int arr[], int sz)
{
int i = 0, j = 0;
for (i = 0; i < sz; i++)
for(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] = { 2,3,5,7,9,8,4,6,1,0 };
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; i++)
printf("%d ", arr[i]);
printf("\n");
bubble_sort(arr, sz);
for (i = 0; i < sz; i++)
printf("%d ", arr[i]);
return 0;
}
5.数组实例
5.1 数组的应用实例1:三子棋(井字棋)
语言实现三子棋(井字棋):点此转入
5.2 数组的应用实例2:扫雷游戏
C语言实现扫雷小游戏:点此转入