【理解指针(四)】
文章目录
- 一、指针数组
- 二、指针数组来模拟二维数组
- 三、字符指针变量
- 注意:
- 字符串的例子(曾经的一道笔试题)
- 四、数组指针变量
- 1、什么是数组指针变量
- 2、数组指针怎么初始化
- 五、二维数组传参的本质
- 六、函数指针
- 1、什么是函数指针变量
- 2、函数的地址
- 3、使用
- 4、 `typedef`关键字
- 结束语
一、指针数组
我们可以先来回顾一下整形数组和字符数组。
- 整形数组:
是存放整形的数组
- 字符数组:
是指存放字符的数组
类比上面两个例子之后,我们可以知道指针数组就是存放指针的数组,指针数组的每一个元素都是用来存放地址(指针)的。
二、指针数组来模拟二维数组
首先我们需要知道数组名是指数组首元素的地址
#include<stdio.h>
int main()
{int str[] = { 1,2,3,4,5 };int str1[] = { 3,4,5,6,7 };int str2[] = { 5,6,7,8,9 };int* pa[3] = { str,str1,str2 };for (int i = 0; i < 3; i++){for (int j = 0; j < 5; j++){printf("%d ", *(*(pa + i)) + j);}printf("\n");}return 0;
}
我们可以得到如下的结果:
第一次的for循环是循环的行,第二次的dor循环也就是列,数组名就是数组的首元素,我们这里的pa[i]找到数组元素指向的是整形一维数组,pa[i][j]就是指向整形一维数组的元素。
模拟出⼆维数组的效果,实际上并非完全是⼆维数组,因为每⼀行并非是连续的
画个图方便大家理解:
三、字符指针变量
我们知道字符指针是char*
常如下使用:
#include<stdio.h>
int main()
{char p = 'e';char* s = &p;printf("%c\n", *s);*s = 't';printf("%c\n", *s);return 0;
}
结果会分别打印出:e 和 t 。
当然还有其他适用方式:
#include<stdio.h>
int main()
{char str[] = "hello world!!!";char* pa = str;printf("%s\n", pa);return 0;
}
注意:
这里的hello world!!!
并没有放在指针变量pa
中,而是把这个字符串的首字符的地址放在了pa
中。
pa
也就是调用字符串中首字符的地址,而字符串的地址也是首字符元素的地址。
字符串的例子(曾经的一道笔试题)
#include <stdio.h>
int main()
{char str1[] = "hello bit.";char str2[] = "hello bit.";const char* str3 = "hello bit.";const char* str4 = "hello bit.";if (str1 == str2)printf("str1 and str2 are same\n");elseprintf("str1 and str2 are not same\n");if (str3 == str4)printf("str3 and str4 are same\n");elseprintf("str3 and str4 are not same\n");return 0;
}
这题的答案是str1 and str2 are not same
和str3 and str4 are same
我们大致来分析一下:
str1
和str2
都是存的相同的字符串内容,在内存中str1
和str2
是开辟了不同的空间存放相同的内容的,实质上完全没有必要存相同的内容开辟两个空间,两个空间的地址完全不一样,所以会打印出str1 and str2 are not same
;而str3
和str4
指向的是⼀个同⼀个常量字符串,C/C++会把常量字符串存储到单独的⼀个内存区域,指针指向同⼀个字符串的时候,他们实际会指向同⼀块内存,所以这里会打印出str3 and str4 are same
。
四、数组指针变量
1、什么是数组指针变量
首先我们可以来回顾一下:整形指针变量和浮点型指针变量
-
整形指针变量:
存放的是整型变量的指针,能够指向整形数据的指针。
形如:int* pa
-
浮点型指针变量:
存放的是浮点型变量的指针,能够指向浮点型数据的指针。
形如:float* pa
那么数组指针变量就是存放的是数组的地址,指向数组数据的指针。
形如:int(*p)[10]
这里的p是自己命名,10 也是根据自己写的代码来写。
p
先和*结合,所以p
是一个指针变量,指向的是一个大小为10个整形的数组。
综上:p是一个指针,指向一个数组,这就是数组指针。
2、数组指针怎么初始化
数组指针变量是⽤来存放数组地址的
int arr[5]={0};
&arr得到的就是数组的地址
int (*p)[5]=&arr//这个数组的地址存放在数组指针变量中
五、二维数组传参的本质
(二维数组我们可以看成许多一维数组的组成)
首先我们知道数组名是数组首元素的地址,那么⼆维数组的数组名表示的就是第⼀行的地址,也就是一维数组的地址,⼆维数组传参本质上也是传递了地址,传递的是第一行这个⼀维数组的地址
我们形参用指针写的形式如下:
#include<stdio.h>
void Shuzu(int(* pa)[5], int a, int b)
{for (int i = 0; i < a; i++){for (int j = 0; j < b; j++){printf("%d ", *(*(pa + i) + j));}printf("\n");}
}
int main()
{int arr[3][5] = { {1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15} };Shuzu(arr, 3, 5);return 0;
}
当然形参我们也可以数组的形式写:
#include<stdio.h>
void Shuzu(int p[][5], int s, int c)
{for (int i = 0; i < s; i++){for (int j = 0; j < c; j++){printf("%d ", p[i][j]);}printf("\n");}
}
int main()
{int arr[3][5] = { {1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15} };Shuzu(arr, 3, 5);return 0;
}
六、函数指针
1、什么是函数指针变量
通过上面的种种类比我们知道了什么是数组指针,整形指针,那么我们可以知道函数指针变量就是用来存放函数地址的。
2、函数的地址
首先我们可以简单的写一个代码,看看函数是否有地址:
#include<stdio.h>
void Ad()
{printf("abder\n");
}
int main()
{Ad();printf("&Ad=%p\n", &Ad);printf("Ad=%p\n", Ad);return 0;
}
由结果我们可以知道函数有地址,函数名就是我们的地址
如果我们要将函数的地址存放起来,就得创建函数指针变量:
#include<stdio.h>
int Add(int x, int y)
{return x + y;
}int(*pa)(int , int ) = Add;//&Add
其中==int(*)(int,int)==就是pa函数指针变量的类型。
3、使用
#include<stdio.h>
int Add(int x, int y)
{return x + y;
}
int main()
{int (*pa1)(int ,int) = Add;printf("%d\n", (*pa1)(2,4));printf("%d\n", pa1(5,6));return 0;
}
可以得出答案是6和11。
为什么第二个打印pa1可以不解引用?
因为pa1这个指针变量存放的是Add的地址,&符号与*相互直接抵消了,所以可以不使用解引用符号。
4、 typedef
关键字
typedef是用来类型重命名的
比如:
singed int 可能你觉得每次书写比较麻烦,你就可以直接有时候typedef来重命名
也就是:typedef singed int ty_t,这个时候,想要再使用singed int 就可以直接用ty_t替换,
本质上是一样的
1.但是函数指针的重命名有些许区别:
比如,我们想要把int(*pa)(int )
重命名为pa_t
:
typedef int(*pa_t)(int); //新类型的名字必须在*号的右边
2.数组指针重命名也是如此:
比如:我们需要把int(*pc)[10]
重命名为py_y
typedef int(*py_y)[10]; //新类型的名字也需要在*号的右边
结束语
这次的内容可能有些多,但是比较好理解,希望大家可以拿到自己想要的offer,最后,如果文章有什么打错字的地方,希望大家不要介意,也希望大家可以给我提出来。
最后,祝大家每天都开开心心,我们下次再见
相关文章:
【理解指针(四)】
文章目录 一、指针数组二、指针数组来模拟二维数组三、字符指针变量注意: 字符串的例子(曾经的一道笔试题) 四、数组指针变量1、什么是数组指针变量2、数组指针怎么初始化 五、二维数组传参的本质六、函数指针1、什么是函数指针变量2、函数的…...
Ribbon简介
目录 一 、概念介绍 1、Ribbon是什么 2、认识负载均衡 2.1 服务器端的负载均衡 2.2 客户端的负载均衡 3、Ribbon工作原理 4、Ribbon的主要组件 IClientConfig ServerList ServerListFilter IRule Iping ILoadBalancer ServerListUpdater 5、Ribbon支持…...
【感悟《剑指offer》典型编程题的极练之路】02字符串篇!
个人主页:秋风起,再归来~ 文章所属专栏:《剑指offer》典型编程题的极练之路 个人格言:悟已往之不谏,知来者犹可追 克心守己,…...
通过 Docker 实现国产数据库 OpenGauss 开发环境搭建
通过 Docker 实现国产数据库 OpenGauss 开发环境搭建 一 前置准备 2.1 下载镜像 docker pull enmotech/opengauss:5.0.1构建镜像的 Dockerfile,方便后期实现个性化定制: FROM ubuntu:22.04 as builderARG TARGETARCHWORKDIR /warehouseRUN set -eux;…...
【Java】LinkedList模拟实现
目录 整体框架IMyLinkedList接口IndexNotLegalException异常类MyLinkedList类成员变量(节点信息)addFirst(头插)addLast(尾插)在指定位置插入数据判断是否存在移除第一个相等的节点移除所有相等的节点链表的长度打印链表释放回收链表 整体框架 IMyLinkedList接口 这个接口用来…...
ubuntu下mysql常用命令
1. 登录数据库 mysql -u root -p 2.创建数据库 create database 数据库名字 mysql> create database yourdb; Query OK, 1 row affected (0.03 sec)3.显示数据库 show databases; 实操结果如下 mysql> show databases; -------------------- | Database | ---…...
燃气官网安全运行监测系统-阀井燃气监测仪-旭华智能
近年来,燃气爆炸事故频发,造成了重大人员伤亡和财产损失。这也再次为我们敲响警钟,燃气是我们日常生活中不可或缺的能源,但其潜在的危险性也是不容小觑。因此在重要节点加装燃气阀井气体监测仪,并将数据上传到系统平台…...
vue 文件预览(docx、.xlsx、pdf)
1.ifream <iframe src"" ></iframe> 注: src里面是文件地址 2.vue-office 支持vue2和vue3提供docx、.xlsx、pdf多种文档的在线预览方案 2.1安装 #docx文档预览组件 npm install vue-office/docx vue-demi#excel文档预览组件 npm install vue-office…...
云架构(二) 大使模式
Ambassador pattern (https://learn.microsoft.com/en-us/azure/architecture/patterns/ambassador) 简单描述 创建一个助手服务,这个服务代表消费服务或者应用程序发送网络请求。大使服务可以看做是与客户机同一个位置的进程外代理。 这种…...
.NET Path类库的特殊方法
在.NET中Path类库是非常常用的一个类库,包含很多我们常用的方法,常用的方法这里就不详细说明了,这里记录下几个非常规的方法。 获取随机文件名: //将返回随机的文件名Console.WriteLine(Path.GetRandomFileName()); 获取禁止在路…...
【JVM】JVM常用性能调优参数详细介绍
JVM常用性能调优参数详细介绍 一、何时进行JVM调优二、性能调优三、JVM调优的基本原则四、JVM调优目标五、JVM调优的步骤六、JVM参数七、JVM参数解析及调优八、JVM参数使用手册8.1 内存相关8.2 GC策略相关8.3 GC日志相关8.4 异常相关8.5 问题定位及优化相关九、参考文档一、何时…...
React中的受控组件与非受控组件
受控组件与非受控组件 受控组件 组件(input, select)的状态与state的值绑定,组件的状态全程响应外部数据 class TestComponent extends React.Component {constructor (props) {super(props);this.state { username: lindaidai };}render () {return <input …...
uniapp实现u-datetime-picker时间选择器的默认日期定位,解决default-value不生效问题
uniapp实现u-datetime-picker,设置默认定位日期,解决default-value不生效问题 想实现的效果是点开时间选择器默认显示当前日期,而不是该选择器最早的日期 给选择器添加ref属性,如下: <u-datetime-picker :show&q…...
react native 使用ScrollView实现下拉更新,上拉加载更多
在React Native中,要实现下拉更新和上拉加载更多的功能,你需要自定义ScrollView组件,监听滚动事件并根据滚动的位置来判断何时触发更新和加载更多的操作。以下是一个基本的实现思路: 监听滚动事件:使用ScrollView的on…...
vue2完结
笔记 关于不同版本的Vue: 1.vue.js与vue.runtime.xxx.js的区别:(1)vue.js是完整版的Vue,包含:核心功能模板解析器(2)vue.runtime.xxx.js是运行版本的Vue,只包含核心功能,没有模板解析器 2.因为…...
前端网页之间传递参数
在多页面应用中,我们可能面临着前端页面之间传递参数的情况,在一个页面获取到一些参数信息后,到另一个页面去进行后续处理,需要将前一个页面得到的一些参数带到第二个页面。当参数较少时,可以在跳转第二个页面时通过se…...
【常见面试题】Golang中,协程数最多可以开多少个?
参考: Goroutine 究竟可以开多少? 一、先说结论: 能开多少个协程,取决于单个协程处理方法所占用的CPU和内存资源(也就是看你计算机运行的应用程序的具体代码逻辑)。 二、具体来说: 如果是C…...
RabbitMQ基础笔记
视频链接:【黑马程序员RabbitMQ入门到实战教程】 文章目录 1.初识MQ1.1.同步调用1.2.异步调用1.3.技术选型 2.RabbitMQ2.1.安装2.1.1 Docker2.1.1 Linux2.1.1 Windows 2.2.收发消息2.2.1.交换机2.2.2.队列2.2.3.绑定关系2.2.4.发送消息 2.3.数据隔离2.3.1.用户管理2…...
大型项目管理神器:掌握yarn monorepo的安装和使用
I. 引言 在当今的前端开发中,由于项目规模的不断增长和多团队协同,Monorepo成为了越来越流行的开发模式。Monorepo指的是将多个相关项目或者模块打包在一起的软件开发模式,它可以让开发人员更好地组织管理代码,减少重复的代码&am…...
算法打卡day28|贪心算法篇02|Leetcode 122.买卖股票的最佳时机 II、55. 跳跃游戏、45.跳跃游戏 II
算法题 Leetcode 122.买卖股票的最佳时机 II 题目链接:122.买卖股票的最佳时机 II 大佬视频讲解:买卖股票的最佳时机 II视频讲解 个人思路 因为只有一只股票,且两天作一个交易单元,那每次只收集正利润就可以最终最多可以获取的利润…...
2013年认证杯SPSSPRO杯数学建模A题(第一阶段)护岸框架全过程文档及程序
2013年认证杯SPSSPRO杯数学建模 A题 护岸框架 原题再现: 在江河中,堤岸、江心洲的迎水区域被水流长期冲刷侵蚀。在河道整治工程中,需要在受侵蚀严重的部位设置一些人工设施,以减弱水流的冲刷,促进该处泥沙的淤积&…...
【3】3道链表力扣题:删除链表中的节点、反转链表、判断一个链表是否有环
3道链表力扣题 一、删除链表中的节点🌏 题目链接📕 示例🍀 分析💻 代码 二、反转链表🌏 题目链接📕 示例🍀 分析① 递归② 迭代 三、判断一个链表是否有环🌏 题目链接📕 …...
mongodb sharding分片模式的集群数据库,日志治理缺失导致写入数据库报错MongoWriteConcernException的问题总结(上)
一、背景 常见的mongodb集群模式有以下三种: 主从复制(Master-Slave)模式副本集(Replica Set)模式分片(Sharding)模式 公司测试环境搭建的集群采用分片模式,有同事反馈说…...
苹果Mac OS系统上安装brew
1.命令行安装brew Homebrew是 mac的包管理器,仅需执行相应的命令,就能下载安装需要的软件包,可以省掉自己去下载、解压、拖拽(安装)等繁琐的步骤。 a. 打开HomeBrew官网:https://brew.sh/index.html b. 点击页面上的复制按钮,打…...
应用侧渲染流程
应用侧渲染流程 《Android应用程序UI硬件加速渲染环境初始化过程分析》 https://blog.csdn.net/Luoshengyang/article/details/45769759 《Android HWUI绘制流程》 https://wizzie.top/android/android_HWUI_Draw/#1-gpu%E6%B8%B2%E6%9F%93%E7%A1%AC%E4%BB%B6%E5%8A%A0%E9%…...
学生党开放式运动耳机怎么选?五款超高销量高性价比品牌推荐
开放式运动耳机成为了许多人的运动首选装备,想要在众多的开放式耳机中找到一款价格亲民,且性能在线高性价比的开放式运动耳机可并非那么简单,所以今天我就来为大家推荐五款超高销量、高性价比的运动耳机品牌。 在推荐之前,整理了…...
服务器中有g++,但是查询不到,Command ‘g++‘ not found
有gcc但是查询不到g,gcc版本为9.5.0 (base) zyICML:~$ g -V Command g not found, but can be installed with: apt install g Please ask your administrator. 突然就出现这个问题,导致detectron装不上,现在有时间了专门研究下怎么解决 这…...
count(“0“),split() ,sys.stdin.readline() ,matrix.append, input().strip()
目录 count() 方法主要用于计算一个序列(例如列表、元组或字符串)中某个元素出现的次数...
Flink on Kubernetes (flink-operator) 部署Flink
flink on k8s 官网 https://nightlies.apache.org/flink/flink-kubernetes-operator-docs-release-1.1/docs/try-flink-kubernetes-operator/quick-start/ 我的部署脚本和官网不一样,有些地方官网不够详细 部署k8s集群 注意,按照默认配置至少有两台wo…...
代码随想录算法训练营第三十二天|122.买卖股票的最佳时机II、55. 跳跃游戏、45.跳跃游戏II
122.买卖股票的最佳时机II - 🔗 讲解 - 🔗 方法一: 💡这道题自己想到的办法没有解析那么清晰,大致思路就是第一步先找到第一个可以买进的时间(也就是第一个prices[i] < prices[i 1]的i)&…...
如何建设网站推广平台/搜索软件排行榜前十名
分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击http://www.captainbed.net 是值传递。Java语言的方法调用只支持参数的值传递。当一个对象实例作为一个参数被传递到方法中时&am…...
wordpress语言翻译/怎样在百度上发帖子
最近接手一个服务器,不过是Windows系统的,运行程序时候总是出一些问题。有点怀疑是系统的问题?于是决定从windows迁移到Linux系统里面去。不过遇到了一个大坑!!!!安装过程非常简单,就…...
旅游网站开发毕业论文前言/搜索引擎收录提交入口
用户在使用经典虚拟机时,经常会有如下疑问:门户主板页面中的 SSH/RDP 证书指纹这项信息是怎么来的?用途是什么?为什么有的时候为空?有没有对虚拟机使用有什么影响?以下我们进行一些基本的介绍: …...
做宠物网站导航应该写什么字/网站排名费用
vue-解决弹出蒙层滑动穿透问题参考文章: (1)vue-解决弹出蒙层滑动穿透问题 (2)https://www.cnblogs.com/buerjj/p/7876057.html 备忘一下。...
进行优化/深度优化
目录 题目描述 解决方案 代码 代码走读 传送门 题目描述 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。 输入/输出示例: 输入输出解释abcabcbb3因为无重复字符的最长子串是“abc”,所以其长度为3解决方案 这个问…...
资阳网站建设/百度热词指数
VR行业近年来的发展可谓是如火如荼,而与之相关的360度VR全景视频拍摄也跟着大火,无论是刚刚入行的初学者还是资深全景摄影师来说,掌握一些360度VR全景视频拍摄技巧能让你拍出更高质量的作品,这是非常有必要的,今天为大…...