41-数组 _ 数组作为函数参数

news2025/1/12 12:08:59

41-1 冒泡排序函数的设计

数组传参的时候,形参有2种写法:

1、数组

2、指针

往往我们在写代码的时候,会将数组作为参数传个函数

如:实现一个冒泡排序,将数组的数据排成升序

冒泡排序的核心思想:

1、两个相邻的元素进行比较

2、一趟冒泡排序让一个数据来到它最终应该出现的位置上

动画演示:

总体思路:

1、n个元素需要n-1趟的冒泡排序(前n-1个元素的位置的确定了,最后一个元素的位置自然也确定了)

2、每一趟需要两两之间进行比较,确定一个元素的最终位置:n个元素,第一个元素需要比n-1次,第二个元素需要比n-2次……

那我们尝试写一下代码吧:

//bubble_sort
//形参采用数组的形式
void bubble_sort(int arr[])
{
	//趟数
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		//一趟冒泡排序
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = 0;
				tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
int main()
{
	//冒泡排序:把数组排成升序
	int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };
	//理想结果:     0 1 2 3 4 5 6 7 8 9
	int sz = sizeof(arr) / sizeof(arr[0]);

	//冒泡排序的算法,对数组进行排序
	bubble_sort(arr);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

错误!结果竟然没变!(X86)

X86结果:

X64结果: 

错误原因:在数组传参时,传的数组名本质上是数组首元素的地址,地址应该使用指针来接收,所以arr这里看似是数组,实质是指针。那么,这里sizeof(arr)是指针的大小,而不是整个数组的大小。以X86环境为例,一个指针(arr)的大小是4,一个元素(arr[0])的大小也是4,相除之后结果为1,1-1=0,无法进行循环,结果不会改变

所以我们直接传sz,不在函数中进行sz的计算

修改后的代码

//bubble_sort
//形参采用数组的形式
void bubble_sort(int arr[],int sz)
{
	//趟数
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		//一趟冒泡排序
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = 0;
				tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
int main()
{
	//冒泡排序:把数组排成升序
	int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };
	//理想结果:     0 1 2 3 4 5 6 7 8 9
	int sz = sizeof(arr) / sizeof(arr[0]);

	//冒泡排序的算法,对数组进行排序
	bubble_sort(arr,sz);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

成功啦~~~

41-2 数组名是什么

41-2-1 一维数组的数组名

让我们来验证一下数组名究竟是不是首元素地址吧:

int main()
{
	int arr[10];
	printf("%p\n", arr);
	printf("%p\n", &arr[0]);
	return 0;
}

arr的地址果然与首元素地址一样: 

啊?那我们之前为什么说sizeof(arr)指的是整个数组的大小?

int main()
{
	int arr[10];
	int n = sizeof(arr);
	printf("%d\n", n);
	return 0;
}

结果是40而不是4:

数组名能确实表示首元素的地址

但是有两个例外:

1、sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节

2、&数组名,这里的数组名表示整个数组,取出的是整个数组的地址

代码测试:

int main()
{
	int arr[10];
	printf("%p\n", arr);
	printf("%p\n", &arr[0]);
	printf("%p\n", &arr);
	return 0;
}

输出结果: 

数组的地址是从首元素开始的,所以数组的地址跟首元素的地址一样

我们再加个1试一下:

int main()
{
	int arr[10] = {0};
	printf("%p\n", arr);  //arr就是首元素的地址
	printf("%p\n", arr+1);
	printf("-----------\n");
	printf("%p\n", &arr[0]);  //首元素的地址
	printf("%p\n", &arr[0]+1);
	printf("-----------\n");
	printf("%p\n", &arr);  //数组的地址
	printf("%p\n", &arr+1);
	printf("-----------\n");
	return 0;
}

结果如下:

前两个都是相差4,隔了一个元素的大小;而最后一个相差0x28,转换为十进制即为40,隔了整个数组的大小 

综上,前面的代码也可以这样写:(形参采用指针形式)

//bubble_sort
//形参采用指针的形式
void bubble_sort(int* arr,int sz)
{
	//趟数
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		//一趟冒泡排序
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = 0;
				tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
int main()
{
	//冒泡排序:把数组排成升序
	int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };
	//理想结果:     0 1 2 3 4 5 6 7 8 9
	int sz = sizeof(arr) / sizeof(arr[0]);

	//冒泡排序的算法,对数组进行排序
	bubble_sort(arr,sz);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

结果依然正确:

41-2-2 二维数组的数组名

sizeof(arr)仍然指的是整个数组的大小:

int main()
{
	int arr[3][4] = { 0 };
	printf("%d\n", sizeof(arr));
	return 0;
}

一共12个元素,每个元素4个字节:

二维数组的数组名也表示数组首元素的地址

那么二维数组的首元素是谁?是arr[0][0]吗?

不是!是arr[0],指的是第一行的地址,而不是第一行第一个的地址

我们用代码验证一下:

int main()
{
	int arr[3][4] = { 0 };
	printf("%p\n", arr);
	printf("%p\n", arr+1);
	return 0;
}

结果如下:

相差0x10,即十进制的16,正好隔了一行 

41-2-3 计算一个二维数组的行数和列数

计算行数:整个数组的大小除以第一行的大小

int main()
{
	int arr[3][4] = { 0 };
	printf("行数为%d\n", sizeof(arr) / sizeof(arr[0]));
	return 0;
}

 结果:

计算列数:一行的大小除以第一行第一个元素的大小

int main()
{
	int arr[3][4] = { 0 };
	printf("列数为%d\n", sizeof(arr[0]) / sizeof(arr[0][0]));
	return 0;
}

 结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1623814.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

新能源汽车小米su7

小米su7汽车 function init() {const container document.querySelector( #container );camera new THREE.PerspectiveCamera( 20, window.innerWidth / window.innerHeight, 1, 50000 );camera.position.set( 0, 700, 7000 );scene new THREE.Scene();scene.background ne…

kubebuilder(4)部署测试

将crd部署到k8s make install 日志&#xff1a; kustomize build config/crd | kubectl apply -f - customresourcedefinition.apiextensions.k8s.io/demoes.tutorial.demo.com created 查看下[rootpaas-m-k8s-master-1 demo-operator]# kubectl api-resources | grep demo de…

yolov8 区域声光报警+计数

yolov8 区域报警计数 1. 基础2. 报警功能2. 1声音报警代码2. 2画面显示报警代码 3. 完整代码4. 源码 1. 基础 本项目是在 yolov8 区域多类别计数 的基础上实现的&#xff0c;具体区域计数原理可见上边文章 2. 报警功能 设置一个区域region_points&#xff0c;当行人这一类别…

【AIGC调研系列】Phi-3 VS Llama3

2024-04-24日发布的Phi-3系列模型在多个方面展现出了对Llama-3的性能优势。首先&#xff0c;Phi-3-small&#xff08;7B参数&#xff09;在MMLU上的得分高于Llama-3-8B-Instruct模型&#xff0c;分别为75.3%和66%[1]。此外&#xff0c;具有3.8B参数的Phi-3 Mini在性能上优于Lla…

解密Java多线程同步:掌握线程间同步与互斥技巧

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一个人虽可以走的更快&#xff0c;但一群人可以走的更远。 我是一名后…

JavaScript:js实现在线五子棋人机(人人)对弈

在线五子棋人机对弈 全部使用前端技术,使用HTML,CSS以及JS进行实现. 棋盘在后端就是一个15*15的二维数组 页面设计 页面设计的比较粗糙 主要使用js自带的canvas画布进行绘画 HTML代码如下: <div class"outer"><canvas id"canvas" height&qu…

linux权限维持(四)

6.inetd服务后门 inetd 是一个监听外部网络请求 ( 就是一个 socket) 的系统守护进程&#xff0c;默认情况下为 13 端口。当 inetd 接收到 一个外部请求后&#xff0c;它会根据这个请求到自己的配置文件中去找到实际处理它的程序&#xff0c;然后再把接收到的 这个socket 交给那…

B2B企业如何做好谷歌Google广告推广营销布局?

当今全球化的商业环境中&#xff0c;B2B企业要想在激烈的市场竞争中脱颖而出&#xff0c;拓展海外市场成为了必经之路。而谷歌Google广告&#xff0c;作为全球最大的在线广告平台&#xff0c;无疑是企业触达全球潜在客户的黄金钥匙。云衔科技通过专业服务助力企业轻松开户与高效…

CST初级教程 二

本教程将讲解CST Studio的视窗操控的基本操作. 3D视窗的快捷操作 动态放大与缩小&#xff08;Dynamic Zoom&#xff09; 将鼠标指针移动到CST Studio图形视窗中&#xff0c;向上滚动鼠标滚轮&#xff0c;可动太放大图形视窗中的显示内容&#xff0c;向下滚动鼠标滚轮即可动态缩…

非对称渐开线齿轮学习笔记分享

最近有小伙伴遇到了非对称渐开线齿轮的加工问题,花了些时间学习了解一下,下面是总结的学习笔记,有兴趣的朋友可以瞅瞅: 目录: 为什么要采用非对称? 非对称有什么优点? 非对称齿形如何加工? 非对称齿轮怎么测量? 非对称齿轮建模 为什么要采用非对称? 现在的传动要求…

Linux:进程创建 进程终止

Linux&#xff1a;进程创建 & 进程终止 进程创建fork写时拷贝 进程终止退出码strerrorerrno 异常信号exit 进程创建 fork fork函数可以用于在程序内部创建子进程&#xff0c;其包含在头文件<unistd.h>中&#xff0c;直接调用fork()就可以创建子进程了。 示例代码&…

【C语言】深入理解KMP算法及C语言实现

一、KMP算法简介 KMP算法&#xff08;Knuth-Morris-Pratt算法&#xff09;是一种高效的字符串匹配算法&#xff0c;由Donald Knuth、James H. Morris和 Vaughan Pratt共同发明。KMP算法的核心思想是当一次字符比较失败时&#xff0c;利用已经得到的部分匹配信息&#xff0c;将模…

JVM虚拟机监控及性能调优实战

目录 jvisualvm介绍 1. jvisualvm是JDK自带的可以远程监控内存&#xff0c;跟踪垃圾回收&#xff0c;执行时内存&#xff0c;CPU/线程分析&#xff0c;生成堆快照等的工具。 2. jvisualvm是从JDK1.6开始被继承到JDK中的。jvisualvm使用 jvisualvm监控远程服务器 开启远程监控…

【Java框架】SpringMVC(三)——异常处理,拦截器,文件上传,SSM整合

目录 异常处理解释局部异常处理全局异常 拦截器拦截器介绍作用:拦截器和过滤器之间的区别拦截器执行流程代码实现补充 文件上传依赖配置MultipartResolver编写文件上传表单页APIMultipartFileFile.separator必须对上传文件进行重命名代码示例 SpringMVC文件上传流程多文件上传 …

mybatis中<if>条件判断带数字的字符串失效问题

文章目录 一、项目背景二、真实错误原因说明三、解决方案3.1针对纯数字的字符串值场景3.2针对单个字符的字符串值场景 四、参考文献 一、项目背景 MySQL数据库使用Mybatis查询拼接select语句中进行<if>条件拼接的时候&#xff0c;发现带数字的或者带单个字母的字符串失效…

Coursera: An Introduction to American Law 学习笔记 Week 03: Property Law

An Introduction to American Law 本文是 https://www.coursera.org/programs/career-training-for-nevadans-k7yhc/learn/american-law 这门课的学习笔记。 文章目录 An Introduction to American LawInstructors Week 03: Property LawKey Property Law TermsSupplemental Re…

LM324的输出VOL与IOL你注意过吗?

电路图 途中LMC6084 更改为LM324 故障现象 这个电路的输入输出表达式为 R30 两端电压等于0V 当J16 的4脚与2脚相等&#xff0c;等于5V&#xff08;或者4脚略大于2脚时&#xff09;7脚输出 约 500mV&#xff1b; 实际应该为0V左右才对.见下图 故障原因 上图运放输出低电平…

AI重塑数字安全,安恒信息行胜于言

有人曾言&#xff1a;所有行业都值得基于人工智能技术重做一遍。 深以为然。如今&#xff0c;数字安全产业面临着一次重要的重塑机遇。以大模型为代表的人工智能技术正深刻影响着数字安全市场格局、产品研发、技术方案以及运营服务。产业界已形成共识&#xff0c;即谁能抓住人…

Nginx+Lua+OpenResty(详解及使用)

一、 Nginx简介 Nginx是一个高性能的Web服务器和反向代理的软件。 Web服务器&#xff1a;就是运行我们web服务的容器&#xff0c;提供web功能&#xff0c;还有tomcat也提供类似的功能。 代理是软件架构和网络设计中&#xff0c;非常重要的一个概念。 二、Nginx的反向代理&…

WEB服务的配置与使用 Apache HTTPD

服务端&#xff1a;服务器将发送由状态代码和可选的响应正文组成的 响应 。状态代码指示请求是否成功&#xff0c;如果不成功&#xff0c;则指示存在哪种错误情况。这告诉客户端应该如何处理响应。较为流星的web服务器程序有&#xff1a; Apache HTTP Server 、 Nginx 客户端&a…