C语言 二分查找(折半查找) 函数 VS2022

#include<stdio.h>

int binsearch(int arr[], int x, int sz)
{
	int mid = 0;
	int left = 0;
	int right = sz - 1;

	while (left <= right)
	{
		mid = ((right - left) / 2 + left);
		if (x < arr[mid])
		{
			right = mid - 1;
		}
		else if (x > arr[mid])
		{
			left = mid + 1;
		}
		else
		{
			return mid;
		}
	}
	return 0;
}

int main()
{
	int i = 1;
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	scanf("%d", &i);
	int sz = sizeof(arr1) / sizeof(arr1[0]);
	int red = binsearch(arr1, i, sz);
	if (red)
	{
		printf("找到了!下标为%d\n", red);
	}
	else
	{
		printf("未找到\n");
	}
	return 0;
}

        在编写这段代码的时候,我遇到了一个非常容易被忽略的问题(就是这个问题折磨了我二十分钟!!!),那就是使用sizeof()去测量数组的长度(数组中元素个数)。下面附上sizeof()函数的使用手册。

"sizeof" - C++ Search results (cplusplus.com)

        想必大家都知道sizeof()可以计算操作数的大小,那么数组的长度就是整个数组的大小除以数组中单个元素的大小。举个栗子,在上述代码中,给定数组arr1[] = { 1,2,3,4,5,6,7,8,9,10 },因为1个整型的大小为4Byte,则由10个整型构成的数组的大小为40Byte。故sizeof(arr1) = 40,sizeof(arr1[0]) = 4(求下标为0的元素的大小)。这样,我们就可以算出数组中所包含的元素个数啦。

        其实,我还没有提到问题的关键。问题的关键在于,当我们将二分查找用函数实现时,实参和形参的关系!!!下面这段代码为错误示范(当时我至少白了三根头发!):

int binsearch(int arr[], int x)
{
	int mid = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	int left = 0;
	int right = sz - 1;
	while (left <= right)
	{
		mid = ((right - left) / 2 + left);
		if (x < arr[mid])
		{
			right = mid - 1;
		}
		else if (x > arr[mid])
		{
			left = mid + 1;
		}
		else
		{
			return mid;
		}
	}
	return 0;
}

int main()
{
	int i = 1;
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	scanf("%d", &i);
	int red = binsearch(arr1, i);
	if (red)
	{
		printf("找到了!下标为%d\n",red);
	}
	else
	{
		printf("未找到\n");
	}
	return 0;
}

        大家有看出什么问题吗?没错!我是将数组传给函数后,测量的数组的长度。此时我们所得到的sizeof(arr)和sizeof(arr[0])的值分别变为8、4。

         这是因为我们在传参过程中,数组将下标为0的元素的地址以指针的形式传递给了函数,避免了形参拷贝实参而造成的空间浪费,而我采用了x64,这才得到了数组指针的大小 sizeof(arr) = 8;而指针数组中每个元素都是指针,整型指针的大小为4,即sizeof(arr[0]) = 4。自然而然,函数的返回值也就错了。

        最后,希望你们,也希望自己越来越优秀......

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晓铭同学381125

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值