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

2023-11-06

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

         :

        [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;

                 本文章完。

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

                 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • c和java语言中的换行符

    现在行分隔符取决于系统 但在 C 程序中我使用 n 作为行分隔符 无论我在 Windows 还是 Linux 中运行它都可以正常工作 为什么 在java中 我们必须使用 n 因为它与系统相关 那么为什么我们在c中使用 n 作为新行 而不管我
  • 在 C# 中创建具有单独列的分隔文本

    我一直在尝试在 C 中创建一个制表符限制的文本文件 以便数据正确显示在单独的列中 Firstname Lastname Age John Smith 17 James Sawyer 31 我尝试过 t 字符 但我得到的只是 Firstnam
  • std::cout 和 std::wcout 有什么区别?

    在c 中 有什么区别std cout and std wcout 它们都控制流缓冲区的输出或将内容打印到控制台 或者它们只是相似吗 它们作用于不同的字符类型 std cout uses char作为字符类型 std wcout uses w
  • 使用Physics.Raycast 和Physics2D.Raycast 检测对象上的点击

    我的场景中有一个空的游戏对象 带有 2D 组件盒碰撞器 我将脚本附加到该游戏对象 void OnMouseDown Debug Log clic 但是当我点击我的游戏对象时 没有任何效果 你有什么想法 如何检测我的盒子碰撞器上的点击 使用光
  • C++中的类查找结构体数组

    我正在尝试创建一个结构数组 它将输入字符串链接到类 如下所示 struct string command CommandPath cPath cPathLookup set an alarm AlarmCommandPath send an
  • 将 System.Windows.Input.KeyEventArgs 键转换为 char

    我需要将事件参数作为char 但是当我尝试转换 Key 枚举时 我得到的字母和符号与传入的字母和符号完全不同 如何正确地将密钥转换为字符 这是我尝试过的 ObserveKeyStroke this new ObervableKeyStrok
  • 生成(非常)大的非重复整数序列而不进行预洗牌

    背景 我编写了一个简单的媒体客户端 服务器 我想生成一个不明显的时间值 随从客户端到服务器的每个命令一起发送 时间戳中将包含相当多的数据 纳秒分辨率 即使它不是真正准确 因为现代操作系统中计时器采样的限制 等 我想做的 在 Linux 上
  • 无法在 Windows 运行时组件库的 UserControl 中创建依赖项属性

    我想在用户控件内创建数据可绑定属性 这个用户控件包含一个 Windows 运行时组件 项目 我使用下面的代码来创建属性 public MyItem CurrentItem get return MyItem GetValue Current
  • 在一个字节中存储 4 个不同的值

    我有一个任务要做 但我不知道从哪里开始 我不期待也绝对不想要代码中的答案 我想要一些关于该怎么做的指导 因为我感到有点失落 将变量打包和解包到一个字节中 您需要在一个字节中存储 4 个不同的值 这些值为 NAME RANGE BITS en
  • 如何将整数转换为 void 指针?

    在 C 中使用线程时 我面临警告 警告 从不同大小的整数转换为指针 代码如下 include
  • 如何使用 watin 中的 FileUploadDialogHandler 访问文件上传对话框

    我正在使用 IE8 和 watin 并尝试通过我的网页测试上传文件 我不能简单地使用 set 方法设置上传文件 例如 ie FileUpload Find ById someId Set C Desktop image jpg 因为上传文本
  • 批量更新 SQL Server C#

    我有一个 270k 行的数据库 带有主键mid和一个名为value 我有一个包含中值和值的文本文件 现在我想更新表格 以便将每个值分配给正确的中间值 我当前的方法是从 C 读取文本文件 并为我读取的每一行更新表中的一行 必须有更快的方法来做
  • std::async 与重载函数

    可能的重复 std bind 重载解析 https stackoverflow com questions 4159487 stdbind overload resolution 考虑以下 C 示例 class A public int f
  • .NET中的LinkedList是循环链表吗?

    我需要一个循环链表 所以我想知道是否LinkedList是循环链表吗 每当您想要移动列表中的 下一个 块时 以循环方式使用它的快速解决方案 current current Next current List First 电流在哪里Linke
  • Process.Start() 方法在什么情况下返回 false?

    From MSDN https msdn microsoft com en us library e8zac0ca v vs 110 aspx 返回值 true 表示有新的进程资源 开始了 如果由 FileName 成员指定的进程资源 St
  • 线程和 fork()。我该如何处理呢? [复制]

    这个问题在这里已经有答案了 可能的重复 多线程程序中的fork https stackoverflow com questions 1235516 fork in multi threaded program 如果我有一个使用 fork 的
  • 使用 GROUP 和 SUM 的 LINQ 查询

    请帮助我了解如何使用带有 GROUP 和 SUM 的 LINQ 进行查询 Query the database IEnumerable
  • 当另一个线程可能设置共享布尔标志(最多一次)时,是否可以读取共享布尔标志而不锁定它?

    我希望我的线程能够更优雅地关闭 因此我尝试实现一个简单的信号机制 我不认为我想要一个完全事件驱动的线程 所以我有一个工作人员有一种方法可以使用关键部分优雅地停止它Monitor 相当于C lock我相信 绘图线程 h class Drawi
  • 在客户端系统中安装后桌面应用程序无法打开

    我目前正在使用 Visual Studio 2017 和 4 6 1 net 框架 我为桌面应用程序创建了安装文件 安装程序在我的系统中完美安装并运行 问题是安装程序在其他计算机上成功安装 但应用程序无法打开 edit 在客户端系统中下载了
  • 如何正确使用 std::condition_variable?

    我很困惑conditions variables以及如何 安全 使用它们 在我的应用程序中 我有一个创建 gui 线程的类 但是当 gui 是由 gui 线程构造时 主线程需要等待 情况与下面的函数相同 主线程创建互斥体 锁和conditi

随机推荐

  • HTML+CSS实现的简单注册表单

    效果总览 具体代码实现
  • 设置Docker阿里云镜像加速源

    设置Docker阿里云镜像源 打开文件 vi etc docker daemon json 做如下编辑 registry mirrors https xxxxxxx mirror aliyuncs com 如下 获取加速器地址 做如下操作
  • 面试高频考点 -- 常见的排序算法(7种)

    目录 1 直接插入排序 2 希尔排序 3 选择排序 4 堆排序 重要 5 冒泡排序 加优化 6 快速排序 重要 7 归并排序 重要 常见排序 稳定性 两个相等的数据 如果经过排序后 排序算法能保证其相对位置不发生变化 例如 1 直接插入排序
  • 阿里云双十二好物推荐:「mPaaS 安全加固」带你看看别人家的应用

    别人家的小孩 全世界第一可爱 但是 别人家的移动应用 搭载的可能是你写的代码 金融 教育 手游 影音视听 民生政务 社交 交通出行 电子商务 mPaaS 应用安全加固 双12荣耀返场
  • linux查看文件大小信息

    df h查看系统中文件的使用情况 Size 分割区总容量 Used 已使用的大小 Avail 剩下的大小 Use 使用的百分比 Mounted on 路径地址 FreeBSD下 当硬盘容量已满时 您可能会看到已使用的百分比超过 100 因为
  • 空调开关html,酒店墙上空调开关图解—酒店墙上空调开关图案是什么意思

    我们很多人都有住酒店的经验的 有的人事为了出差住酒店 有的人是为了去旅游 当然了 也有的人事为了爱情去酒店 二随着夏天即将到来 炎热的天气将在夏季让气温越来越热 空调已成为每个人最近购买的主要电器 随着技术的发展 中央空调已成为业界的热门产
  • 转:阿里曾鸣:下一个风口是产业互联网

    未来三年 产业互联网的突破将是可见的方向 目前为止 产业互联网的连接尚处于浅连接阶段 企业对互联网思维的应用也停留在 互联网 上 事实上 运用互联网技术工具进行的再构和创新 可能是乘数效应 他判断 未来有两条路径 一是传统产业向智能商业的升
  • 【Python】使用smtplib和email库可以实现Python脚本发送电子邮件

    前言 在 Python 有很多方向可以应用 比如爬虫 预测分析 GUI 自动化 图像处理 可视化等等 可能只需要十几行代码就能实现酷炫的功能 Python 是动态脚本语言 所以代码逻辑比 Java 要简要很多 实现同样的功能少写很多代码 而
  • 一、Linux下的SVN服务器搭建

    这里自己做个总结 环境 contos7 百度云服务 下载svn服务器 必须是联网情况下 yum y install subversion 查看下载后的信息 安装位置及详细信息 rpm ql subversion 3 创建版本库目录 可以再c
  • 2023年网络安全比赛--网络安全事件响应中职组(超详细)

    一 竞赛时间 180分钟 共计3小时 二 竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 1 黑客通过网络攻入本地服务器 通过特殊手段在系统中建立了多个异常进程 找出启动异常进程的脚本 并将其绝对路径作为Flag值提交 2 黑客通过
  • 【图像处理】怎么让图片背景变透明?怎么改变图片中线条的颜色?在线PS软件

    文章目录 前言 一 打开图 二 背景透明处理 三 改变线条颜色 总结 前言 我们处理图片将会使用到PS软件 如果安装了PS那直接打开使用 如果没有安装PS 可使用在线PS软件 https www uupoop com 一 打开图 第一步 从
  • b站up主:空狐公子 --矩阵求导(分母布局)课程笔记

    一 写在前面 最近在看图像正则化相关文章的时候 常常被矩阵求导弄得一头雾水 在B站发现一个宝藏up主空狐公子 非常的硬核 矩阵求导讲解的非常好 逻辑清楚 层层递进 很有帮助 本文做一个简单的记录 方便以后查阅回顾 求大家三连支持up 传送门
  • 我玩某宝新模式2个月收λ15万,你觉得过气的行业,真的很赚钱!

    如果有人问 有什么事 比穷更难受 我的回答一定是 马上过年了 我还在喝西北风 我的朋友先暴富了 这段时间 我就被闺蜜美美狠狠扎了心 以前她和我一样是个普通上班族 去年做微商囤了大几万的货卖不出去 老公气得要和她离婚 整日垂头丧气 谁知年底了
  • Python ceil() 函数

    描述 ceil 函数返回数字的上入整数 语法 以下是 ceil 方法的语法 import math math ceil x 注意 ceil 是不能直接访问的 需要导入 math 模块 通过静态对象调用该方法 参数 x 数值表达式 返回值 函
  • 【智能无线小车系列八】在树莓派上使用USB摄像头

    材料准备 1 树莓派 2 AS 4WD小车 3 WebCam 4 小米移动电源 5 TP LINK 高增益150MUSB无线网卡 操作流程 1 将WebCam插上树莓派后 首先要确认树莓派是否支持该设备 输入 pi raspberrypi
  • 十五、Webpack打包图片-js-Vue、Label命令、resolve模块解析

    一 webpack打包图片 1 加载图片案例准备 为了演示我们项目中可以加载图片 我们需要在项目中使用图片 比较常见的使用图片的方式是两种 img元素 设置src属性 其他元素 比如div 设置background image的css属性
  • cocos3.10版本IphoneX 1分钟适配方案

    1 第一部找到 LaunchScreen storyboard 还有 LaunchScreenBackground png 拷贝到项目中 我的是放在 过场加载图片那里 cocos里面有 2 项目的 BulidPhases 找到 CopyBu
  • 电脑强制关机两次后报错自动修复你的电脑未正确启动

    强制关机两次后报错自动修复你的电脑未正确启动 因为电脑太卡就强制关机了 开机之后没有等全部加载完 又觉得卡强制关机 再次打卡后显示正在准备自动修复 之后就自动修复你的电脑未正确启动 当时很慌 自己的毕设还有毕业论文都在电脑里 虽然没有放到系
  • 队列的实现(Java)

    Java数据结构学习笔记 一 队列 数组实现 核心逻辑代码 class ArrayQueue private int maxSize 0 private int front private int rear private int arr
  • [C语言]进一步的来了解指针(多多多图详解)

    本文章进一步的来讲解指针 如果是第一次接触指针的可以先看一下对于指针的初步理解 C语言 初步的来了解一下指针 多图详解 HY PIGIE的博客 CSDN博客 目录 1 字符指针 2 指针数组 2 1指针数组 char 类型举例说明 2 2指