C语言(指针)4

news2024/11/19 8:49:39

                 Hi~!这里是奋斗的小羊,很荣幸各位能阅读我的文章,诚请评论指点,关注+收藏,欢迎欢迎~~     

                                💥个人主页:小羊在奋斗

                                💥所属专栏:C语言   

        本系列文章为个人学习笔记,在这里撰写成文一为巩固知识,二为同样是初学者的学友展示一些我的学习过程及心得。文笔、排版拙劣,望见谅。 

一、指针与数组

        1.数组名

        通过前面的学习我们知道,数组名就是数组首元素的地址,但是看到下面的代码你会不会怀疑这句话呢?

        按道理说数组名是数组首元素的地址,那 sizeof(arr)求出来应该是4个字节的大小,这里为什么是40个字节的大小呢?

        其实,我们说数组名就是数组首元素的地址在大多数情况下并没有错,只是有两个例外。

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

        (2)&数组名:这里的数组名表示的也是整个数组,取出的是整个数组的地址。 

            除此之外,数组名表示的都是数组首元素的地址。 

        看到上面 “取出的是整个数组的地址” 这句话,有些小伙伴可能又有疑惑了,因为他们记得我在之前的文章中说过,不管内存地址多大, “&” 操作符取出的只是内存单元地址最小的那个,那么不管是数组首元素的地址,还是整个数组的地址不是都一样吗?那为什么还要区分呢?

        如果你并没有这个疑惑,可能是你学的非常扎实,我们一起继续努力;也可能是你学的还不太扎实,或者没有好好看我之前的文章,罚你去看 —> C语言(指针)1 。

        我们在之前的文章中说过,指针的类型决定了指针的差异、决定了在对指针进行解引用时的权限、指针 +- 整数的结果取决于指针的类型等。我们还说过,地址就是指针,指针就是地址,当我们对数组首元素的地址和整个数组的地址进行一些操作时,你还觉得它们没什么区别吗?

        ( 我们每次打印得到的地址都不一样,不必在意 )。 

        可以看到,对数组首元素的地址+1增大了4个字节,对整个数组的地址+1增大了40个字节(其中地址是16进制表示),这一点相信看过我之前文章的小伙伴都已经非常清楚了,就不再赘述了。所以说,虽然数组首元素的地址和整个数组的地址取出来是一样的,但还是有很大的差别的。

        2.使用指针访问数组

        其实在之前的文章中我们已经多次的使用了指针来访问数组,这里只做一些补充。

        上面的几种输入方式都是可行的,但是你不能写成下面这种:

        上面代码的问题是,当输入操作结束后指针变量p已经指向数组内最后一个元素,如果你还想要通过指针自加的方式打印数组,就需要重新让指针变量p指针数组首元素。这种写法不推荐,还是写成之前的那几种形式更好一些。

        3. 一维数组传参的本质

        之前已经说过,数组传参的时候实参直接写数组名,传递的是数组首元素的地址,形参可以写数组的形式,也可以写指针的形式。来看下面的代码:

        上面sz1和sz2的值打印出来是一样的吗?如果不一样sz1和sz2分别等于多少?

        打印出来sz1 = 10,sz2 = 1。 

        对于sz1, sizeof(arr)中的 “arr” 表示的是整个数组的地址,所以sizeof(arr)求的是整个数组的大小,单位是字节,sizeof(arr[0])求的是数组首元素的大小,所以相除的结果应该就是数组内元素的个数;对于sz2,因为前面说过数组传参的时候传递的是数组首元素的地址,所以自定义函数fun()形参接收的时候自然只能得到数组首元素的地址,那么sizeof(arr)中的 “arr” 表示的只是数组首元素的地址,求出的就只是数组首元素的大小,sizeof(arr[0])求出的也是数组首元素的大小,所以相除的结果就为1。

        有没有对上面代码形参的部分写的 int arr [ ] 有疑惑呢,并不是我们之前写过的 int *arr,按道理来说数组传参传过来的是地址,应该用指针来接收,但是依旧能正常运行。所以我想说的是,arr[ ]本质上也是指针,arr[i] == *(arr + i)。其中括号内写不写数组的长度都是无所谓的,因为它只能接收首元素的地址。

        那我们想在自定义函数中使用数组内元素的个数这个值怎么办呢?很简单,将这个值作为函数参数传过去就行。

        总结:(1)不能看到sizeof(arr)就认定了arr表示的是整个数组的地址,还要看它是不是函数的形参;

                   (2)在用上面的方法求数组内元素个数的时候,最好紧跟在数组的定义后面写;

                   (3) 形参即使写成数组的形式,本质上也是一个指针变量;

                   (4)在自定义函数中使用数组内元素个数这个值需要在函数调用的时候作为函数参数传过去。

        4.冒泡排序

        学了上面的内容,我们就可以用数组和指针的知识来实现一下冒泡排序。我们这里写升序。

        首先,我们先简单地介绍一下冒泡排序是怎么一回事,详细的解释这里就不赘述了,不了解的同学还请查看别的资料。冒泡排序就是重复地遍历要排序的一组数,比较相邻的元素,并交换它们的位置,直到整个列表都是按照从小到大(或从大到小)的顺序排列,如果有N个元素重复的次数就是N - 1次。

        具体实现如下:

#include <stdio.h>

void bubble_sort(int arr[], int n)
{
	int i = 0; 
	int j = 0;
	int num = 0;
	printf("正序:");
	for (i = 0; i < n - 1; i++)//共n - 1趟
	{
		for (j = 0; j < n - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				num = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = num;
			}
		}
	}
}

int main()
{
	//定义一个数组存放待排序的n个数
	int arr[100] = { 0 };
	int i = 0;
	int n = 0;

	while (scanf("%d", &arr[n++]), arr[n - 1] != -1);//以-1为输入结束标志
	n--;
	//冒泡排序函数
	bubble_sort(arr, n);
	for (i = 0; i < n; i++)
	{
		printf("%d ", *(arr + i));
	}
	return 0;
}

        实验结果也没问题: 

        

        但上面的代码效率还不够高,还能再优化一下。请你思考一个问题,如果当某一趟前后两个数两两相互比较过后,并没有发生交换,这时候整个数组中的元素是不是已经有序了?答案是的。那按照上面的代码即使已经有序了还要把每一趟都判断一遍才能结束,做了很过无用功。

        某一趟没有发生交换,就说明这一趟并没有满足 if 判断表达式的情况,那我们就可以在 if 分支的外面和里面设定一个标志,当不满足某一条件是,说明并没有进入到 if 分支内,这时候就可以确定这组数已经有序,然后跳出循环结束任务。

#include <stdio.h>

void bubble_sort(int arr[], int n)
{
	int i = 0; 
	int j = 0;
	int num = 0;
	printf("正序:");
	for (i = 0; i < n - 1; i++)//共n - 1趟
	{
		int flag = 1;//假设这组数本来就是有序的
		for (j = 0; j < n - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				flag = 0;//还没有有序的时候改变标志
				num = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = num;
			}
		}
		if (1 == flag)//如果确实有序就跳出循环
		{
			break;
		}
	}
}

int main()
{
	//定义一个数组存放待排序的n个数
	int arr[100] = { 0 };
	int i = 0;
	int n = 0;

	while (scanf("%d", &arr[n++]), arr[n - 1] != -1);//以-1为输入结束标志
	n--;
	//冒泡排序函数
	bubble_sort(arr, n);
	for (i = 0; i < n; i++)
	{
		printf("%d ", *(arr + i));
	}
	return 0;
}

        如果一组待排序的数是最乱的情况,那上面的代码与之前的一样;如果一组待排序的数已经基本有序,那上面的代码效率更高。

        5.二级指针

        前面不止一次说过,指针变量也是变量,既然是变量就会有地址,普通变量的地址存放在指针变量中,那指针变量的地址存放到哪里呢?接下来就介绍二级指针。

        

        相信通过之前一级指针变量的学习,二级指针对我们来说简直易如反掌,这里就不再过多赘述了。另外三级指针也是这样的用法,但更高级的指针基本用不到。

         二级指针的用法也是类似一级指针的用法:

        ( **ppa == *pa == a )这就像我们玩的套娃,你想拿到最小的那个就一层一层的去找。

        按照前面的内容,一级指针和一维数组有着密切的联系,那二级指针和二维数组有没有联系呢?没有。 

        6.指针数组

        看到这个名字你有没有疑惑,指针数组到底是指针还是数组?我们知道,整型数组是存放整型元素的数组,字符数组是存放字符元素的数组,那同样的指针数组就是存放指针的数组了,其中元素的类型是指针类型。 

        为什么要有指针数组呢?原因和整型数组及其他数组一样,当我们想创建多个相同类型的变量的时候一个一个去创建很繁琐,于是就出现了相应类型的数组,那指针数组的出现也是一样。

        但我们需要创建多个指针变量的时候,指针数组就为我们提供了比较简洁的方法,当然和其他数组一样指针数组也可以遍历打印出来:

         需要注意的是此时数组里存的是地址,需要用解引用操作符 “ * ”。

        7.指针数组来模拟二维数组
         

        上面虽然我们没有定义二维数组,但我们用指针数组的方法模拟实现了二维数组。

        上面代码的执行细节是,我们首先对指针数组arr解引用找到对应下标的元素,其中元素也是地址,那我们再对这个地址解引用就能得到对应下标的元素,此时的元素就是arr1、arr2、arr3三个数组中存的整型元素。 

        如果觉得我的文章还不错,请点赞、收藏 + 关注支持一下,我会持续更新更好的文章。

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

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

相关文章

我必须要吹一波MATLAB 2024a,太牛逼了!|福利:附安装教程及下载地址

最近逛MATLAB官网&#xff0c;发现MATLAB 2024a版本已经Pre-release了&#xff0c;翻了下release note&#xff0c;不得不感叹&#xff0c;实在是太强了&#xff01; 这次重点更新了四个工具箱&#xff1a; Computer Vision Toolbox Deep Learning Toolbox Instrument Contro…

1.基于python的单细胞数据预处理-降维可视化

目录 降维的背景PCAt-sneUMAP检查质量控制中的指标 参考&#xff1a; [1] https://github.com/Starlitnightly/single_cell_tutorial [2] https://github.com/theislab/single-cell-best-practices 降维的背景 虽然特征选择已经减少了维数&#xff0c;但为了可视化&#xff0…

InputStream,OutputStream的用法以及相应的案例

1. 文件系统的操作&#xff1a;File类。 2. 文件内容的操作&#xff1a;Stream流。 字符流&#xff1a;IntputStream &#xff0c; OutputStream。 字节流&#xff1a;read &#xff0c; write。 InputStream&#xff0c;OutputStream InputStream和OutputStream都不能被实例…

Web数字孪生引擎

Web数字孪生引擎是指用于在Web上创建和运行数字孪生的软件平台。它们通常提供一组API和工具&#xff0c;用于连接到实时数据源、可视化数据并创建交互式体验。Web数字孪生引擎被广泛应用于各种应用&#xff0c;例如工业物联网、智能建筑、城市管理和公共安全等。北京木奇移动技…

Linux 安裝 rpm包

下载 地址&#xff1a;https://developer.aliyun.com/packageSearch 安装 rpm -ivh lsof-4.87-6.el7.x86_64.rpmlsof -Ki|awk {print $2}|sort|uniq -c|sort -nr|head lsof | wc -l

上位机图像处理和嵌入式模块部署(树莓派4b和电源供给)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面&#xff0c;我们说过pc电脑和嵌入式设备&#xff0c;两者都可以实现相同的软件功能。但是和pc相比较&#xff0c;嵌入式设备不仅价格更便宜&a…

RabbitMQ (windows) 安装

大家好我是苏麟 , 今天安装一下 RabbitMQ . 官网 : RabbitMQ: One broker to queue them all | RabbitMQ 1.点击 Getting Started 2. 点击 Docs 3.点击 Install And Upgrade 4.点击 installation via Chocolatory 5. 直接下载安装包 RabbitMQ 下好了先放在一遍 RabbitMQ 需要 E…

前端框架-echarts

Echarts 项目中要使用到echarts框架&#xff0c;从零开始在csdn上记笔记。 这是一个基础的代码&#xff0c;小白入门看一下 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" co…

新手做抖音小店必须了解的回款周期问题!这样做,一步快速结算

哈喽~我是电商月月 我们做抖音小店&#xff0c;在商品上架出单后&#xff0c;商家需要到商品的上家拍单&#xff0c;由上家发货给顾客&#xff0c;顾客收到货后&#xff0c;周期一到才能赚取到商品的差价&#xff0c;这个时间大概在7~15天之内&#xff0c;想准时发货不超时违规…

八款免费好用的3D建模AI工具,让你的设计更简单!

随着人工智能和大语言模型的不断发展&#xff0c;AI工具正逐渐渗透到3D建模领域中。传统上&#xff0c;3D建模师需使用如3ds Max、Maya等这类复杂的3D建模软件&#xff0c;投入大量的时间与精力来创作精细的模型。然而&#xff0c;有了AI工具的辅助&#xff0c;设计过程不仅对专…

激光测径仪在胶管生产中扮演着什么角色?

关键词&#xff1a;激光测径仪,胶管,胶管测径仪,在线测径仪 胶管生产的基本工序为混炼胶加工、帘布及帆布加工、胶管成型、硫化等。不同结构及不同骨架的胶管&#xff0c;其骨架层的加工方法及胶管成型设备各异。 全胶胶管因不含骨架层&#xff0c;只需使用压出机压出胶管即可&…

AWS云优化:实现性能和成本的最佳平衡

随着企业数字化转型的加速&#xff0c;对云计算平台的需求也不断增长。AWS作为云计算行业的领导者之一&#xff0c;提供了广泛的云服务和解决方案&#xff0c;帮助企业实现业务的创新和发展。在AWS云上部署应用程序和服务后&#xff0c;对其进行优化是至关重要的&#xff0c;以…

【官方下载】Android 开发环境之 java 11 下载地址和下载操作步骤

作者介绍&#xff1a; 百度资深Android工程师T6&#xff0c;在百度任职7年半。 目前&#xff1a;成立赵小灰代码工作室&#xff0c;欢迎大家找我交流Android、微信小程序、鸿蒙项目。文章底部&#xff0c;csdn有为我插入微信的联络方式&#xff0c;欢迎大家联络我。 一&#x…

TikTok机房ip好还是住宅ip好?

住宅ip比较好&#xff0c;机房数据中心IP高效、低价&#xff0c;所以使用的人多且用处复杂&#xff0c;这类ip极大可能存在滥用的黑历史&#xff0c;通过此类ip访问tiktok&#xff0c;被禁止的可能性更高&#xff0c;更容易被拉入黑名单。所以我们推荐tiktok独享原生ip搭建节点…

计算机组成结构—指令和指令格式

目录 一、指令的基本格式 二、指令字长 1. 定长指令字结构 2.变长指令字结构 三、地址码 1.四地址指令 2.三地址指令 3.二地址指令 4.一地址指令 5. 零地址指令 四、操作码 1. 定长操作码指令格式 2. 扩展操作码指令格式 五、指令的操作数类型和操作类型 1. 操作…

openai 开源模型Whisper语音转文本模型下载使用

Whisper Whisper 是一种通用语音识别模型。它是在大量不同音频数据集上进行训练的,也是一个多任务模型,可以执行多语言语音识别、语音翻译和语言识别。官方地址 https://github.com/openai/whisper 方法 一个Transformer序列到序列模型被训练在多种语音处理任务上,包括多语…

mac 讨厌百度网盘怎么办

一、别拦我 首先请允许我泄个愤&#xff0c;tmd百度网盘下个1g的文件下载速度竟然超不过200k&#xff0c;只要不放在所有已打开软件的最前面&#xff0c;它就给你降到10k以内&#xff0c;关键是你慢就慢了&#xff0c;我也不是很着急&#xff0c;关键是你日常下载失败并且总是…

2024年滴滴前端一二三面(汽车资产管理)

面试前&#xff0c;先找面经哥&#xff0c;点击此处查看更多面经 一面 1、聊项目 2、实现 TypeScript 的 Await 3、手写 compose 4、用 Vue 或者 React 实现一个组件&#xff0c;组件通过 checkbox 控制列表传入数据每一列的全选反选 二面 1、项目问题以及实现细节 2、小程序…

跟TED演讲学英文:Why US politics is broken — and how to fix it by Andrew Yang

Why US politics is broken — and how to fix it Link: https://www.ted.com/talks/andrew_yang_why_us_politics_is_broken_and_how_to_fix_it? Speaker: Andrew Yang Date: April 2024 文章目录 Why US politics is broken — and how to fix itIntroductionVocabularyTr…

找不到msvcp120dll,无法继续执行代码的多种解决方法分享

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“msvcp120.dll丢失”。这个错误通常会导致某些应用程序无法正常运行。为了解决这个问题&#xff0c;我们需要采取一些措施来修复丢失的msvcp120.dll文件。本文将介绍6种常见的解决方法&…