C++ 复合数据类型:指针

文章目录

  • 指针
    • 用法
    • 无效指针
    • 空指针
    • void *ptr
    • 指向指针的指针
    • 指向常量的指针
    • 指针常量
    • 指针和数组
      • 指针数组和数组指针

指针

计算机中的数据都存在内存中,访问内存的最小单元是“字节”,所有数据,就保存在内存中具有连续编号的一串字节中。
在这里插入图片描述
指针顾名思义就是指向另一种数据类型的复合类型。指针是C/C++中保存另一个数据对象在内存中的“地址”。通过指针可以访问到指向的那个数据对象,所以这是一种间接访问对象的方法。
指针的定义语法形式:类型* 指针变量;
类型是指针指向的对象的类型。
例如:以下 int 类型占4个字节,char占1个字节,指针占8个字节,指针里存的是a的地址:
00 00 00 34 F7 EF F8 88
在这里插入图片描述

#include<iostream>using namespace std;int main()
{//定义指针int *p1;long *p2;long long *p3;cout << "p1长度:" << sizeof(p1) << endl;cout << "p2长度:" << sizeof(p2) << endl;cout << "p3长度" << sizeof(p3) << endl;//指针存放的都是地址,因此它的长度只与系统有关,而不是与类型有关//此处输出都是8}

用法

//指针的使用
int a = 10;
int b = 20;
long c = 88;p1 = &a; //p1指针指向a
p2 = &c;
cout << "p1:" << p1 << endl;
cout << "p2:" << p2 << endl;//如何通过指针获取内容
cout << "*p1:" << *p1 << endl;  //*p1:10
cout << "*p2:" << *p2 << endl;  //*p2:88
*p1 = 33;
cout << "a:" << a << "\t*p1:" << *p1 << endl;  //a:33    *p1:33

无效指针

定义一个指针后,如果不进行初始化,指针的内容就是不确定的。如果这时把它的内容当成一个地址去访问,那访问的是不存在的对象;如果访问到的是系统核心区域,修改其中的内容就有可能导致系统崩溃。这样的指针就是“无效指针”,也被叫做“野指针”。

int *p1;
//*p1 = 100   //直接解引用,危险!指针没有初始化,是无效指针

空指针

如果先定义了一个指针,但不确定它要指向哪一个对象,可以先初始化为“空指针”。空指针不指向任何对象。

//空指针
int *np = nullptr;  //空指针的字面值常量,推荐使用
np = NULL;  //预处理变量
np = 0; //只有0可以初始化,让其指向一个未被使用的内存int zero = 0;
//np = zero  //该初始化行不通

void *ptr

// void *ptr
int a = 10;
char b = 'c';
long d = 67.2;int *p1 = &a; //p1只能指向int类型//想要一个能指向任意类型的指针
void *ptr;
ptr = &a;
ptr = &b;
ptr = &c;// cout << *ptr << endl; //错误,void类型指针只能用来存储地址,但是不能解引用

指向指针的指针

也叫“二级指针”,用连续两个“*” 表示,如果是三级指针则用三个表示。
在这里插入图片描述

    // 指向指针的指针int i = 22;int *p5 = &i;int **pp5 = &p5;cout << "i:\t" << i << endl;cout << "p5:\t" << p5 << endl;cout << "pp5:\t" << pp5 << endl;cout << "*p5:\t" << *p5 << endl;cout << "*pp5:\t" << *pp5 << endl;cout << "**pp5:\t" << **pp5 << endl;/*输出
i:      22
p5:     0x61fdc8
pp5:    0x61fdc0
*p5:    22
*pp5:   0x61fdc8
**pp5:  22
*/

指向常量的指针

//指向常量的指针
const int i = 10, j = 20;
const int *p = &i;
cout << "p\t" << p << endl;
cout << "*p\t" << *p << endl;
//*p = 15 //错误,常量不可修改
p = &j;  //但是指针指向的对象可以换
cout << "*p\t" << *p << endl;

指针常量

int x = 10; 
int y = 20; 
int *const ptr = &x; // 定义一个指向整型变量的指针常量,指向 xcout << "x 的值为:" << x << endl;
cout << "通过指针访问 x 的值:" << *ptr << endl;// 尝试修改指针指向的地址
// ptr = &y; // 这行代码会导致编译错误,因为 ptr 是一个指针常量,不能再指向其他地址// 通过指针修改所指向地址的内容
*ptr = 100;
cout << "修改后,x 的值为:" << x << endl;

指针和数组

用到数组名时,编译器一般都会把它转换为指针,这个指针就指向数组第一个元素。所以也可以用数组名给指针赋值

//指针和数组的关系
int arr[5] = {1, 2, 4, 5, 6};
cout << "&arr\t" << &arr << endl;
cout << "arr\t" << arr << endl;
cout << "&arr[0]\t" << &arr[0] << endl;
cout << "arr+1\t" << arr + 1 << endl; // arr+1 相当于是arr[1]的地址
cout << "&arr[1]\t" << &arr[1] << endl;int *ptr = arr;
cout << "ptr\t" << ptr << endl;
cout << "*ptr\t" << *ptr << endl;
cout << "ptr+1\t" << ptr + 1 << endl;
cout << "*(ptr + 1)\t" << *(ptr + 1) << endl;输出:
&arr    0x61fe00
arr     0x61fe00
&arr[0] 0x61fe00
arr+1   0x61fe04
&arr[1] 0x61fe04
ptr     0x61fe00
*ptr    1
ptr+1   0x61fe04
*(ptr + 1)      2

指针数组和数组指针

int arr[5] = {1, 2, 3, 4, 6};
//指针数组,本质是数组,数组的所有的元素都是同类型的指针
int *pa[5]; 
cout << "sizeof(pa)\t" << sizeof(pa) << endl;
pa[0] = arr;
pa[1] = arr +1;
cout << "pa[0]\t" << pa[0] << endl;
cout << "*pa[0]\t" << *pa[0] << endl;输出
sizeof(pa)      40
pa[0]   0x61fe00
*pa[0]  1//数组指针,本质是指针,指向一个数组 
int (*ap)[5] = &arr;
cout << "sizeof(ap)\t" << sizeof(ap) << endl;
cout << "ap\t" << ap << endl;
cout << "*ap\t" << *ap << endl;
cout << "**ap\t" << **ap << endl;
cout << "*(*ap + 1)\t" << *(*ap + 1) << endl;输出:
sizeof(ap)      8
ap      0x61fe00
*ap     0x61fe00
**ap    1
*(*ap + 1)      2

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【JAVA面试题】基本类型的强制类型转换是否会丢失精度?引用类型的强制类型转换需要注意什么?

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a; JAVA ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 思路 1、继承关系 2、运行时类型检查 结语 我的其他博客 前言 在Java编程中&#xff0c;强制类型转换是一个常见的操作&#xf…

Python实现AR协方差结构线性回归模型(GLSAR算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 GLSAR是具有AR协方差结构的广义最小二乘法线性回归模型。 本项目通过GLSAR回归算法来构建AR协方差结构…

Nature 新研究发布,GPT 驱动的机器人化学家能够自行设计和进行实验,这对科研意味着什么?

文章目录 前言揭秘Coscientist不到四分钟&#xff0c;设计并改进了程序能力越大&#xff0c;责任越大 前言 有消息称&#xff0c;AI 大模型 “化学家” 登 Nature 能够自制阿司匹林、对乙酰氨基酚、布洛芬&#xff0c;甚至连复杂的钯催化交叉偶联反应&#xff0c;也能完成。 …

2. 行为模式 - 命令模式

亦称&#xff1a; 动作、事务、Action、Transaction、Command 意图 命令模式是一种行为设计模式&#xff0c; 它可将请求转换为一个包含与请求相关的所有信息的独立对象。 该转换让你能根据不同的请求将方法参数化、 延迟请求执行或将其放入队列中&#xff0c; 且能实现可撤销…

智能优化算法应用:基于白冠鸡算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于白冠鸡算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于白冠鸡算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.白冠鸡算法4.实验参数设定5.算法结果6.参考文…

Http---HTTP 请求报文

1. HTTP 请求报文介绍 HTTP最常见的请求报文有两种: GET 方式的请求报文POST 方式的请求报文 说明: GET: 获取web服务器数据POST: 向web服务器提交数据 2. HTTP GET 请求报文分析 HTTP GET 请求报文效果图: GET 请求报文说明: ---- 请求行 ---- GET / HTTP/1.1 # GET请…

FreeRTOS之队列集操作(实践)

多个任务在在同一队列中传递的同一种数据类型&#xff0c;而队列集能够在任务之间传递不同的数据类型。 配置流程&#xff1a;&#xff08;更详细流程参考正点原子的教程&#xff09; 1、启用队列集将configUSE_QUEUE_SETA置1&#xff09; 2、创建队列集 3、创建队列或信号…

(十七)Flask之大型项目目录结构示例【二扣蓝图】

大型项目目录结构&#xff1a; 问题引入&#xff1a; 在上篇文章讲蓝图的时候我给了一个demo项目&#xff0c;其中templates和static都各自只有一个&#xff0c;这就意味着所有app的模板和静态文件都放在了一起&#xff0c;如果项目比较大的话&#xff0c;这就非常乱&#xf…

学鸿蒙开发的过程,差点要了我的命!

我真的好想感慨一下&#xff0c;这个世界真的给计算机应届生留活路了吗&#xff1f; 看着周围的同学&#xff0c;打算搞前端、JAVA、C、C的&#xff0c;一个两个去跑去应聘。你以为是00后整治职场&#xff1f; 真相是主打一个卑微&#xff1a;现阶段以学习为主&#xff08;工资…

劈窗算法反演地表温度

目录 摘要操作步骤提取热红外单波段提取NDVI同步像元分辨率与个数劈窗算法地表温度反演制图 摘要 主要使用HJ-2&#xff08;环境减灾二号卫星&#xff09;的IRS传感器的两个热红外波段&#xff0c;以及红波段与近红波段计算得到的NDVI&#xff0c;使用劈窗算法&#xff0c;得到…

MailChecker:一款功能强大的跨语言临时电子邮件安全检测库

关于MailChecker MailChecker是一款功能强大的跨语言临时电子邮件安全检测工具&#xff0c;该工具可以帮助广大研究人员快速对目标电子邮件进行安全检测和内容验证。该工具后端由一个包含了超过55000个的虚假电子邮件提供商的数据库驱动&#xff0c;当你需要使用电子邮件与你的…

安全运营之团队人员组织建议

安全运营是一个持续的过程&#xff0c;需要不断地评估风险、监测威胁、改进措施和更新策略&#xff0c;以确保组织的安全性和可靠性。由人员、数据、平台&#xff08;工具&#xff09;、流程的共同组合构成安全运营体系。 一、安全运营团队目标 图-安全运营团队目标 安全运营团…