【C语言】冒泡排序和数组传参

系列文章目录

【C语言】数组1.0


前言

今天主要讲初阶数组的最后一个知识点和一种算法思想:冒泡排序。

数组作为函数参数

例子写一个函数对数组进行升序

int main()
{
  int arr[] = {10,9,8,7,6,5,4,3,2,1};
  sort(arr);
  print(arr);
  return  0;
}

冒泡排序的思想
两个相邻元素进行比较,然后符合要求就进行交换
思路
我们首先对数字10进行排序在这里插入图片描述

10要和除本身之外的所有数进行比较,然后交换。一共比较9次。

接着从9开始在这里插入图片描述

9除本身和10之外,进行8次比较

以此类推
8进行了7次比较,7进行了6次比较,……,1进行了0次比较。
总结
我们可以做个总结:我们把一个数字的全部比较叫做一趟比较,那我们这个例子有10个数字,我们就有了10-1次比较(因为最后一个数字不进行比较)。一趟比较都会让这个数字来到最终应该出现的位置,本例中的10就是进行10-1-0次比较,9进行10-1-1次比较,8进行10-1-2次比较。如果还不到没关系,我们直接看代码。

代码实现
在这里插入图片描述

我们利用两个for循环来实现。第一个for循环代表多少趟冒泡排序,第二个for循环代表这趟冒泡排序中这个数字比较的次数。
里面非常巧妙地用到sz-1-i,因为i的变化,每趟冒泡排序中数字比较的次数都不同但都符合要求。

问题
事实上,当我们实现这个代码时,编译器只打印了一个10。在这里插入图片描述

这是为什么?这涉及到今天我们要讲到的数组作为函数参数的本质。

分析问题
先调试看看问题出在哪。监视所有与排序有关的变量。在这里插入图片描述

我们可以发现两个问题。一是为什么sz的值是1,而不是10?二是为什么数组传过来的只有一个数字?

本质
我们以前就说过数组名就是数组首元素的地址,既然是地址,既然函数接收数组时写成数组的形式(int arr[]),它本质上还是一个地址(指针)(in *arr)。
这就是在函数中sizeof(arr)中,arr是地址,指针的大小就是4个或8个字节,再除以sizeof(arr[0])(首元素的大小),最终等于1的原因。
而只有一个数字,是因为它本质上是首元素的地址,显示的是这个数字。
新的疑惑以及拓展
那既然这样的话,那为什么在一些情况下,sizeof(arr)的大小就是数组的大小?在这里插入图片描述
这涉及到数组名的两个特例。
一个是sizeof(数组名)内单独放数组名时,这里的数组名表示整个数组,计算的是整个数组的大小。
这可以千万不能弄混。我的理解就在主函数中我们定义的数组,我们使用它时是数组名,计算的是整个数组的大小。在把数组传给函数时,函数是用指针来接受,我们计算的是指针的大小。
二是&arr,这里的数组名表示整个数组,&arr取出的是整个数组的地址。在其余情况下,数组名都表示首元素的地址。
那arr和&arr的区别是什么?在这里插入图片描述

arr表示首元素的地址,&arr表示整个数组的地址,整个数组的地址自然就是从首元素开始,所以他们两的地址相同。

验证两者的不同。在这里插入图片描述

我们可以发现两个加1后的结果不同。arr+1逃过一个整形,&arr+1跳过一个整形数组。

解决问题
既然我们在函数中算数组元素个数时,接受到的数组只是一个指针,我们该怎么解决?很简单,在主函数中计算数组大小然后传过去。在这里插入图片描述

在这里插入图片描述

小知识为什么arr是首元素地址?
当arr是传址调用时,且数组元素个数,要创建数组和拷贝数组元素,浪费时间和空间,所以就设置arr为首元素地址。


C语言初阶的数组就已经讲完了。如果发现错误的地方,请麻烦指正,我会积极改进!感谢!

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值