CSDN话题挑战赛第2期
参赛话题:学习笔记
学习之路,长路漫漫,写学习笔记的过程就是把知识讲给自己听的过程。这个过程中,我们去记录思考的过程,便于日后复习,梳理自己的思路。学习之乐,独乐乐,不如众乐乐,把知识讲给更多的人听,何乐而不为呢?
目录
一.数组作为函数参数
往往我们写函数的时候,会将数组作为参数传给函数,而在这过程中数组名是数组首元素的地址,这篇文章,我将举两个例子(冒泡排序、二分法)来让大家了解一下数组作为函数参数需要注意什么。
二.冒泡排序
冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。
算法步骤
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
图解:
代码
错误代码
#include<stdio.h>
void maopao(int arr[])//冒泡排序(升序)
{
int sz=sizeof(arr)/sizeof(arr[0]);
for(int i=0;i<sz-1;i++)//从图解我们可以得知,n个元素进行冒泡排序需要排n-1次,因为最后一个元素不需要
{
for (int j=0;j<sz-1-i;j++)//已完成i个元素排序
{
if(arr[j]>arr[j+1])//相邻元素两两对比
{
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
int main()
{
int arr[10]={9,8,7,6,5,4,3,2,1,0};
int sz=0;
sz=sizeof(arr)/sizeof(arr[0]);//sz求出数组中的元素个数
maopao(arr);//这里调用函数只需要数组名不需要'[]'
for (int i=0;i<sz;i++)//将数组输出
{
printf("%d ",arr[i]);
}
}
运行结果是:
我们看到只有第一个相邻的元素排序了,而后面的却没有,这是因为将数组作为参数传给函数时数组名是数组首元素的地址,函数中的arr[]本质上是一个指针,sizeof(arr)在64平台上大小是8,所以int sz=sizeof(arr)/sizeof(arr[0])就是8/4=2;也就是说sz-1=1,排了一次,就得到了上述结果。
正确代码
我们发现是数组中的元素个数出了问题,解决方法也很简单,我们直接吧main函数中的sz值也传进函数就行
#include<stdio.h>
void maopao(int arr[],int sz)//冒泡排序(升序)
{
//int sz=sizeof(arr)/sizeof(arr[0]);
printf("%d\n",sz);
for(int i=0;i<sz-1;i++)//从图解我们可以得知,n个元素进行冒泡排序需要排n-1次,因为最后一个元素不需要
{
for (int j=0;j<sz-1-i;j++)//已完成i个元素排序
{
if(arr[j]>arr[j+1])//相邻元素两两对比
{
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
int main()
{
int arr[10]={9,8,7,6,5,4,3,2,1,0};
int sz=0;
sz=sizeof(arr)/sizeof(arr[0]);//sz求出数组中的元素个数
maopao(arr,sz);//这里调用函数只需要数组名不需要'[]'
for (int i=0;i<sz;i++)//将数组输出
{
printf("%d ",arr[i]);
}
}
运行结果是:
三.二分法查找
二分法我在之前文章中也提到过,要是不太熟悉可以点击链接进行查看
代码
#include<stdio.h>
int binary_search(int arr[],int k,int sz)
{
int left=0;
int right=sz-1;
while(left<=right)
{
int mid=(left+right)/2;
if(arr[mid]<k)
{
left=mid+1;
}
else if(arr[mid]>k)
{
right=mid-1;
}
else
{
return mid;
}
}
if(left>right)//没找到
return -1;
}
int main()
{
int arr[]={1,2,3,4,5,6,7,8,9,10};
int k=7;//在数组arr中找7的下标
int sz=sizeof(arr)/sizeof(arr[0]);
int ret=binary_search(arr,k,sz);//这里函数传3个参数:数组arr,k,元素个数sz
if(ret==-1)
{
printf("没找到\n");
}
else
{
printf("找到了,下标是%d",ret);
}
}
四.总结
数组名就是首元素的地址
但有两个例外:
1.sizeof(数组名)——这里的数组名表示整个数组,sizeof(数组名)计算的是整个数组的大小,单位是字节
2.&数组名,数组名代表整个数组,&数组名取出的是整个数组的地址
比如: