[C语言]进一步的来了解指针(多多多图详解)

news2024/11/30 18:47:20

        本文章进一步的来讲解指针,如果是第一次接触指针的可以先看一下对于指针的初步理解

         :

        [C语言]初步的来了解一下指针(多图详解)_HY_PIGIE的博客-CSDN博客

目录

        1.字符指针

        2.指针数组

                2.1指针数组:char*类型举例说明

                2.2指针数组:int*类型举例说明 

        3.数组指针            

                3.1数组指针的定义 

                3.2数组指针与指针数组的比较

                 3.3“&”数组名与数组名

                3.4数组指针的运用

                3.5数组指针代码解析         

        4.数组传参,指针传参

                4.1一级指针接收参数

                4.2二级指针接收参数

        5.函数指针

                5.1函数指针的定义

                5.2函数指针代码解析

        6.函数指针数组

                6.1函数指针数组的定义

                6.2函数指针数组的运用

        7.指向函数指针数组的指针


         1.字符指针

                        字符指针:char*类型

                        对于char*类型的指针,之前所提到的是存放char类型变量地址的指针,或是本身为(1字节数)加上整数‘1’后跳过1个字节,解引用时同样的只有解锁1个字节的权限。

                        但char*类型还有另一个用法:用来存放字符串

                         对于这个常量字符串的打印:

printf("%s",a);//即可打印字符串“abcdef”

                         Q:可是指针为什么不用解引用呢?不应该是*a吗??

                          A:在char*类型指针中存放字符串,我们存放的是其首元素的地址,如果我们要打印字符串则是根据首元素的地址相应的打印整串字符。

                                既然a存放的是首元素‘a’的地址,那么相应的解引用*a则是根据a的地址找到对于的内容‘a’,打印的也只有a一个字符

                                第二个printf用%s打印会报错,更进一步证实了解引用*a得到的是‘a’单字符,而不是“abcdef”字符串

 

                        C/C++会把常量字符串存储到单独的一个内存区域,当几个指针。指向同一个字符串的时候,他们实际会指向同一块内存。但是用相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块

        2.指针数组

                                对于数组,我们之前认识的有:

                                int arr[]:整型数组,存放整型的数组

                                char arr[]:字符数组,存放字符的数组

                        而对于指针数组顾名思义,即是存放指针的数组:指针类型 arr[]

                2.1指针数组:char*类型举例说明

                        对于指针数组的打印,像其他数组同样的打印方式:

for(int i = 0;i < 4;i++)
{
    printf("%s\n",arr[i]);
}

                2.2指针数组:int*类型举例说明 

                 对于其的打印有两种方式:

方式一:
for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < 6; j++)
		{
			printf("%d", *(arr[i]+j));//指针数组寸的是每个数组首元素的地址
		}                            //我们得到首元素地址后不断+1就可以得到后面的元素
		printf("\n");
	}
方式二:
for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < 6; j++)
		{
			printf("%d", arr[i][j]);
		}
		printf("\n");
	}

                打印结果均为:

        3.数组指针            

                3.1数组指针的定义 

        指针数组为存放指针的数组,那相应的数组指针:是一个指向数组的指针

        注意:‘[ ]’中的个数不能被省略

                 注意:“数组”的地址和“数组首元素”的地址,在数值上是相同的,但意义却是不同的。在数组首元素的地址上+1,会跳过一个元素的字节,得到第二个元素的地址。在数组的地址上+1,直接跳过整个数组的字节。            

                3.2数组指针与指针数组的比较

                 3.3“&”数组名与数组名

                对于一个数组,我们知道arr是数组名,其还表示为一个数组首元素的地址。那&arr到底是什么呢??既然他有&取地址符号,是不是他也是一个地址呢??

int arr[4];

                 通过打印比较我们可以发现,他们所打印出的地址是一样的,都为数组首元素的地址,既然地址一样,就证明了他们是一样的吗??

                答案是,不是的。arr与&arr只是在数值上相同,而代表的意义却大不相同

                下面会通过举例证明:

                 通过对比我们可以发现,arr与arr+1相差了4个字节。

                                                 而&arr与&arr+1相差了16个字节

                 &arr,为取数组的指针,那么其类型就为数组指针:int(*)[4],数组指针类型+1跳过的是整个数组(即:4*4=16字节数)。所以arr与arr+1、&arr与&arr+1分别的差值就会不相同。

                3.4数组指针的运用

                数组指针在一维数组上的运用较少,主要服务于二维数组,下面将通过举例说明其运用

                二维数组函数传参,可以用使用指针接收,既然是接收数组的指针,自然是使用数组指针。

                二维数组数组名是首元素地址,第一行的地址,相应的arr+1跳过16个字节,跳过第一整行,到达第二行第一个元素的地址

                二维数组运用数组指针打印:

                二维数组的数组名表示为首元素的地址,即第一行的地址。在数组指针接收的时候,得到的也只是第一行的地址,arr[3][5]中一行有5个元素,所以数组指针为int(*p)[5],表明的是一个指针指向数组的数组有5个元素。               

   //二维数组的打印//
void Printf(int(*arr)[4],int r,int c)
{
	for (int i = 0; i < r; i++)
	{
		for (int j = 0; j < c; j++)
		{
			printf("%d ", (*(arr + i))[j]);//也可以写成arr[i][j]
		}                                  //(*(arr+i))等价于arr[i]
		printf("\n");
	}
}
int main()
{
	int arr[3][4] = { {1,2,3,4},{0,0,0,0},{2,3,3,3} };
	Printf(arr, 3, 4);
	return 0;
}

                3.5数组指针代码解析         

int(*parr[10])[5];

                此代码表示的是,

                parr[10]是一个数组,含有10个元素。

                每一个元素的类型是:int (*) [5]

                即为,一个parr[10]数组含有10个元素,每一个元素的类型是:int(*)[5],每一个元素都包含5个int类型         

        4.数组传参,指针传参

                4.1一级指针接收参数

                当函数的参数部分为一级指针的时候,函数能接收的参数有:

                一维数组,一级指针的变量,与函数参数中一级指针指向的类型相同的地址。

void test(int* p)
{
    return 0;
}
int main()
{
    int a = 0;
    int arr[4];
    int *P = &a;
    test(&a);//与函数参数部分指针指向的类型相同的地址
    test(arr);//一维数组
    test(p);//一级指针
}

                4.2二级指针接收参数

                当函数的参数部分为二级指针的时候,函数能接收的参数有:

                一级指针的变量的地址,二级指针的变量,指针数组。

void test(int** p)
{
    return 0;
}
int main()
{
    int *pa;
    int **ppa
    int* a[10];
    test(&pa);//一级指针的地址
    test(ppa);//二级指针的变量
    test(a);//指针数组
}

        5.函数指针

                5.1函数指针的定义

                与前面介绍的数组指针格式类似,数组指针是指向数组的指针,则函数指针是指向函数的指针

int add(int x,int y)
{
    return x + y;
}

int main()
{
    int (*pa)(int,int) =&add;//函数指针
    int ret = (*pa)(3,2);
    printf("%d",ret);
}

                函数名为函数区域块的首地址,所以我们在定义函数指针将函数地址赋给指针的时候可以不用取地址符号,相应的在使用函数指针的时候也可以直接使用,并不需要解引用。

                下面举例证明:

int add(int x, int y)
{
    return x + y;
}

int main()
{
    int (*pa)(int, int) = &add;
    int ret = (*pa)(3, 2);

    int (*pa2)(int, int) = add;
    int ret2 = pa(3, 2);

    printf("ret = %d\n", ret);
    printf("ret2 = %d\n", ret2);
}

                打印结果:

                5.2函数指针代码解析

                代码1:

(*(void (*)())0)();

                注意:void(*)()是一种类型 

                所以,此代码其实上是一个调用函数传参的。 

                代码2:

void (*signal(int , void(*)(int)))(int);

                本代码为,signal函数的声明,函数参数分别为(整型,函数指针类型),函数返回类型为函数指针类型

                函数指针类型:(指向函数的返回类型(*)(指向函数的参数类型);

                可以看成:(但绝对不可以写成这种形式,这是错误的形式!!!!!!!!!

void(*)(int) signal(int,void(*)(int));
    类型            函数

        6.函数指针数组

                看这个名字后缀,这东西肯定是一个数组,而且还是用来存放函地址的数组。

                6.1函数指针数组的定义

                函数指针数组,是一个函数指针类型的数组

                函数指针类型:(指向函数的返回类型)(*)(指向函数的参数类型)

                数组:数组名[存放元素个数]

                结合起来就是:

                (指向函数的返回类型)(*数组名[存放元素个数])(指向函数的参数类型)

                6.2函数指针数组的运用

                函数指针数组的用途:转移表

                因为篇幅的原因,关于函数指针数组的运用将链接在下方

                链接:[C语言]运用函数指针数组构建一个简单计算器_HY_PIGIE的博客-CSDN博客

        7.指向函数指针数组的指针

                即指向函数指针数组的指针。函数指针数组,既然是数组就可以取其地址来用另一个指针变量存放

                其声明为: 

                定义其存放一个函数指针数组的指针:

int(*(*pp)[5])(int,int) = &p;

                 本文章完。

                如果文章内有不对的地方欢迎留言指正,觉得本文章对您有帮助的话还请收藏留言点赞!感谢您的支持!

                 

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

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

相关文章

Thawte旗下通配符SSL证书都有什么区别

Thawte由南非Mark Shuttleworth创立&#xff0c;Thawte SSL证书产品占据了全球SSL数字证书市场的40&#xff05;&#xff0c;是全球第三大数字证书颁发机构&#xff08;CA&#xff09;。随后VeriSign于2000年2月1日以5.75亿美元对Thawte换股完成收购&#xff0c;互相合作&#…

GDI对象泄漏导致程序UI界面绘制异常的问题排查

目录 1、问题说明 2、初步分析 3、查看任务管理器&#xff0c;并使用GDIView工具分析 5、采用历史版本比对法&#xff0c;确定初次出现问题的时间点&#xff0c;并查看前一天的代码修改记录 6、将修改的代码与测试现象结合起来&#xff0c;最终定位问题 7、事后的思考 8…

Simulating Content Consistent Vehicle Datasets with Attribute Descent(略读)

提出了一个大型的3D合成数据集VehicleX。其中各个3D模型都有现实世界的车型对应。整个数据集有1362个id&#xff0c;其中包括11种主流车型。 论文&#xff1a;https://arxiv.org/pdf/1912.08855.pdf 摘要 本文使用图形引擎来模拟带有免费注释的大量训练数据。 在合成数据和真…

回归预测 | MATLAB实现RF随机森林多输入单输出回归预测(含回归树,误差柱状图,多指标)

回归预测 | MATLAB实现RF随机森林多输入单输出回归预测(含回归树,误差柱状图,多指标) 目录 回归预测 | MATLAB实现RF随机森林多输入单输出回归预测(含回归树,误差柱状图,多指标)效果分析基本介绍输出结果程序设计学习总结参考资料效果分析

Mars3D Studio平台发布

近日我们基于提供丰富及智能化功能&#xff0c;助力团队做出精美的交互场景的理念&#xff0c;研发了Mars3D Studio平台&#xff0c;于2023年1月10日正式发布上线&#xff01;欢迎大家访问http://studio.mars3d.cn/ 网站进行体验。一、资源广场团队公开的丰富资源数据&#xff…

LeetCode题目笔记——1658. 将 x 减到 0 的最小操作数

文章目录题目描述题目难度——中等方法一&#xff1a;反向思考&#xff0c;双指针求最长子数组代码/Python代码/C方法二&#xff1a;滑动窗口代码总结我把这篇也归到面试题那一栏&#xff0c;因为觉得这题的思路和思考方式还挺好的&#xff0c;或许能用到其他题上 题目描述 给…

基于Node.js Vue清新严选助农电商平台/电商平台/购物平台

摘 要网络技术的快速发展给各行各业带来了很大的突破&#xff0c;也给各行各业提供了一种新的管理模块&#xff0c;对于清新严选助农电商将是又一个传统管理到智能化信息管理的改革&#xff0c;设计清新严选助农电商平台的目的就是借助计算机让复杂的购买商品操作变简单&#x…

gcc和gdb的使用——Linux

Linux学习全部合集点击即可订阅 “人生得意须尽欢” 这里是目录标题gcc的基本操作gcc处理代码的步骤预处理编译汇编链接头文件和库静态库动态库gdb调试makefile什么是makefile&#xff1f;进度条的实现缓冲区回车和换行git的使用.gitigonregcc的基本操作 编写代码的最基本操作…

【工具Share】用VBA获取批量文件中的同一个单元格内容

最近鼓捣了个工具&#xff0c;可以批量从固定文件夹的excel中获取同一个单元格中的具体内容&#xff08;当然&#xff0c;你也可以根据自己的需要&#xff0c;进行多个单元格内容的取得&#xff09; 可能这么说比较抽象&#xff0c;举例来说比如你在多个相同模板的excel中定义了…

java循环结构的概述

在之前的文章中&#xff0c;已经给大家详细地介绍过变量相关的内容&#xff0c;比如变量的概念、命名规范、变量的定义及底层原理等内容。但其实变量还有作用范围的概念&#xff0c;并且根据作用范围的不同&#xff0c;变量还可以分为成员变量、局部变量等内容。在我们今天开始…

Nacos config 配置中心详解

Nacos 提供用于存储配置和其他元数据的 key/value 存储&#xff0c;为分布式系统中的外部化配置提供服务器端和客户端支持。使用 Spring Cloud Alibaba Nacos Config&#xff0c;您可以在 Nacos Server 集中管理你 Spring Cloud 应用的外部属性配置。Spring Cloud Alibaba Naco…

【算法基础(1)】认识时间复杂度和常用排序算法

1 认识时间复杂度 1.1 什么是时间复杂度&#xff1f; 时间复杂度是一个函数&#xff0c;它定性描述该算法的运行时间&#xff0c;在软件开发中&#xff0c;时间复杂度就是用来方便开发者估算出程序运行时间&#xff0c;通常用算法的操作单元数量来代表程序消耗的时间&#xf…

pageoffice在线编辑word文件并禁止选中

一、整篇文档禁止选中 wordDoc.setDisableWindowSelection(true); //禁止word的选择文字功能 二、根据条件判断是否禁止选中 比如&#xff1a;选中内容超过一定字数&#xff0c;取消选中 解决方案&#xff1a;使用后端提供的OnWordSelectionChange事件。 PageOfficeCtrl po…

sgRNAs基因编辑

CRISPR-Cas9知识学习笔记 https://www.163.com/dy/article/FGCP58KC0532AN5N.html https://crispr.dbcls.jp CRISPR&#xff08;clustered regularly interspaced short palindromic repeats&#xff0c;成簇的规律间隔短回文重复序列&#xff09;和CRISPR-associated protein …

Spring Cloud Gateway服务网关的部署与使用(结合nacos)

一、微服务网关1.什么是微服务网关在传统的单体架构中&#xff0c;我们只需要开放一个服务给客户端调用即可。但是微服务架构中是将一个系统拆分成多个微服务&#xff0c;不同的微服务一般会有不同的网络地址&#xff0c;客户端在访问这些微服务时必须记住几十甚至百个地址&…

springboot多项目结构

微服务的目录结构一般分为如下几个模块&#xff1a; 当我们做的项目稍微大一点之后&#xff0c;就会经常遇到需要把不同的模块分离出来的时候&#xff0c;比如微信的朋友圈、微信支付、聊天服务等模块&#xff0c;像这种微服务项目一般都会把base、common、前端抽离出来。 com…

DP8403国产3W双通道无滤波器D类立体声音频放大器兼容替代CS8403

目标DP8403简介功能框图&#xff1a;DP8403主要特性DP8403简介 DP8403是3W双通道无滤波器D类立体声音频功率放大器芯片&#xff0c;能够以D类放大器的效率提供AB类功率放大器的性能。采用D类结构&#xff0c;DP8403 能够在 4Ω负载和 5V 电源条件下&#xff0c;提供高达 3W 输…

MySQL (五)------数据库三范式、外键约束、多表间关系、多表关联查询、子查询

数据库三范式 好的数据库设计对数据的存储性能和后期的程序开发&#xff0c;都会产生重要的影响。建立科学的&#xff0c;规范的数据库就需要满足一些规则来优化数据的设计和存储&#xff0c;这些规则就称为范式。 1.1 第一范式: 确保每列保持原子性 第一范式是最基本的范式…

深入理解java反射原理

系列文章目录 文章目录系列文章目录前言一、 如何获取反射中的Class对象&#xff1f;二、反射的步骤三、详细解答1. 获取对象类的实例2、newInstance() 的实现方式3、获取Method对象4. 调用invoke()方法。总结前言 反射是在运行状态中&#xff0c;对于任意一个类&#xff0c;都…

C 程序设计教程(10)—— 数据输入函数(scanf)用法详解

C 程序设计教程&#xff08;10&#xff09;—— 数据输入函数&#xff08;scanf&#xff09;用法详解 该专栏主要介绍 C 语言的基本语法&#xff0c;作为《程序设计语言》课程的课件与参考资料&#xff0c;用于《程序设计语言》课程的教学&#xff0c;供入门级用户阅读。 目录…