【017】C++ 指针变量详解,理解指针变量

C++ 指针变量详解

  • 引言
  • 一、内存概述
  • 二、指针变量
    • 2.1、地址和指针变量的关系
    • 2.2、定义指针变量
    • 2.3、指针变量的初始化
    • 2.4、指针类型
    • 2.5、案例
    • 2.6、注意事项
  • 三、数组元素的指针
    • 3.1、概述
    • 3.2、在使用中 [ ] 就是 *()的缩写
    • 3.3、指向同一数组的元素的两个指针变量间的关系
  • 四、字符串与指针
    • 4.1、字符数组
    • 4.2、字符串指针变量
  • 总结

引言


💡 作者简介:专注于C/C++高性能程序设计和开发,理论与代码实践结合,让世界没有难学的技术。包括C/C++、Linux、MySQL、Redis、TCP/IP、协程、网络编程等。
👉
🎖️ CSDN实力新星,社区专家博主
👉
🔔 专栏介绍:从零到c++精通的学习之路。内容包括C++基础编程、中级编程、高级编程;掌握各个知识点。
👉
🔔 专栏地址:C++从零开始到精通
👉
🔔 博客主页:https://blog.csdn.net/Long_xu


🔔 上一篇:【016】C++预处理详解(内存分区、变量的存储、头文件、宏等)

一、内存概述

对于32位平台的进程,其内存空间大小限制为4GB(2的32次方),其中1GB是操作系统保留的虚拟地址空间。因此,32位进程最多只能使用3GB的内存空间。

而对于64位平台的进程,其内存空间大小限制高达16EB(2的64次方),实际上远远超过了目前可用的物理内存容量。这意味着64位进程可以利用更多的内存资源来提高应用程序性能和响应速度。

在这里插入图片描述
系统为内存的每一个字节分配32 bit / 64 bit 的地址编码(虚拟地址),这个编号称为地址。

无论任何类型的地址,都是存储单元的编号,在32位平台上永远占4字节,在64位平台上永远占8字节。

在这里插入图片描述
取地址得到的是首地址。

二、指针变量

2.1、地址和指针变量的关系

地址就是内存的地址编号。
指针变量本质上是变量,只是该变量保存的是内存的地址编号,而不是普通数值。
在这里插入图片描述

2.2、定义指针变量

格式:

<类型名> *<变量名>;

示例:

int *data;
short *data;
long data;
double data;
char *data;
float *data;

无论任何类型的指针变量,在32位平台上永远占4字节,在64位平台上永远占8字节。

指针变量和普通变量间建立关系:

int num;
int *p;
p=&num;//取地址,p指向num
*p=10;//取内容、内容赋值

2.3、指针变量的初始化

指针变量在操作前必须指向合法的地址空间。
(1)指针变量如果不初始化,立即操作会出现段错误。
(2)指针变量如果没有指向合法的空间,建议初始化为nullptr 或 NULL。不要操作指向nullptr 或 NULL的指针变量。
(3)将指针变量初始化为合法的地址:变量地址、动态申请的地址、函数入口地址等。

int num;
int *p=NULL;
p=&num;

2.4、指针类型

(1)指针变量自身的类型:把变量名去掉,剩下的就是指针类型。

int num;
int *p;//指针类型为int *
// p是指针变量
p=&num;
// 使用时,&和*相遇,从右往左依次匹配。
*&p==p;

(2)指针变量指向的类型。

int *p;//p指向的类型是int

(3)指针变量的指向类型决定取值宽度。
在这里插入图片描述
(4)指针变量的指向类型决定了 +1 跨度。
在这里插入图片描述
(5)*p等价于num

int num=0;
int* p=&num;
// *p == num

2.5、案例

在这里插入图片描述

int num=0x01020304;

案例一,取出0x0102的值:

short *p=(short *)&num;
short get=*(p+1);

案例二,取出0x02的值:

char *p=(char *)&num;
char get=*(p+2);

案例三,取出0x0203的值:

char *p=(char *)&num;
short get=*(short *)(p+1);

2.6、注意事项

(1)void不能定义普通变量。因为系统无法计算void的大小,无法开辟空间。
(2)void* 可以定义指针变量,因为系统知道指针变量永远是4字节或8字节。此时的指针变量就是万能的一级指针变量,能保存任意一级指针的地址编码。万能指针一般用于函数的形参,达到算法操作多种数据类型的目的。

int num=0;
void *p=&num;

short num2=10;
p=&num2;

注意,不要直接对void * 的指针变量取 *,如果一定要对void * 的指针变量取值 *,就不行强转才行。

int num=0;
void *p=&num;

cout<<(int *)p<<endl;

(3)指针变量未初始化不能取 *。
(4)指针变量初始化为NULL或nulptr,也不能取 *。
(5)指针变量不要越界访问。

char ch=0;
int *p=&ch;//越界

char *p2=&ch;
p2++;//越界

在这里插入图片描述

三、数组元素的指针

3.1、概述

数组元素的指针是指向数组中单个元素的内存地址。在C和C++语言中,数组名可以被解释为指向数组第一个元素的指针,也就是说,它包含了该数组的内存地址。

要访问数组中的特定元素,可以使用下标运算符[]来访问它们。例如,如果a是一个整型数组,则a[0]表示第一个元素,a[1]表示第二个元素,以此类推。

可以通过将其加上偏移量来获取任何给定元素的地址。例如,&a[2]表示第三个元素(假设数组从零开始编号),因为它是从第一个元素开始的两个整数位置。

通过使用指向特定元素的指针变量来引用该元素,可以对其进行操作。例如,在C语言中,以下代码将把第三个元素设置为10:

int a[5];
int *p = &a[2];
*p = 10;

此时,p指向a[2](即第三个)并将其值更改为10。

数组元素的指针变量和数组名等价:
在这里插入图片描述

3.2、在使用中 [ ] 就是 *()的缩写

int arr[]={1,2,3,4,5};
cout<<"arr[1]="<<arr[1]<<endl;		// 输出2
cout<<"*(arr+1)="<<*(arr+1)<<endl;	// 输出2

cout<<"*(1+arr)="<<*(1+arr)<<endl;	// 输出2
cout<<"1[arr]="<<1[arr]<<endl;		// 输出2
// 

[ ]是*()的缩写,[ ]左边的值放在+的左边,[ ]里面的值放在+右边,整体取 *。

分析为什么arr == &arr[0]:

&arr[0]==&*(arr+0)==arr+0==arr。

示例:

int arr[]={1,2,3,4,5};
int *p=arr+3;


p[-1]=arr+3-1=arr+2=3。
p[1]=arr+3+1=arr+4=5。

3.3、指向同一数组的元素的两个指针变量间的关系

  1. 两个指针变量相减,等于它们的元素个数。
  2. 两指针变量赋值,则它们指向同一处。
  3. 两指针变量判断相等,用于判断它们是否指向同一处。
  4. 两指针变量判断大小(>、<、>=、<=、!=),用于判断它们的位置关系。
  5. 两指针变量不能相加,相加是无意义的。

四、字符串与指针

4.1、字符数组

char *str1[128]="hello world";

str1是字符数组,开辟128字节存放字符串"hello world"。sizeof(str1)是128。
在这里插入图片描述

4.2、字符串指针变量

char *str2="hello world";

这个代码的含义是将字符串的首地址赋给str2。sizeof(str2)是4或8。注意与字符数组的区别。
在这里插入图片描述
注意:不能给字符串指针变量赋值,会报错误,因为文字常量区不能赋值。

str2[3]='F';//错误的,引发异常

总结

C++ 中的指针变量是一个特殊类型的变量,它存储了另一个变量的地址。在使用指针变量时,需要注意以下几点:

  1. 指针的声明:声明一个指针需要使用星号 (*) 运算符,并在其前面加上数据类型。例如:int *ptr;

  2. 取地址运算符 &:取地址运算符 & 可以用于获取一个变量的内存地址。例如:int num = 5; int *ptr = #

  3. 解引用运算符 *:解引用运算符 * 用于访问指针所指向的实际值。例如:int num = 5; int *ptr = # cout << "Value of num is: " << *ptr;

  4. 动态内存分配:动态内存分配允许程序在运行时请求操作系统分配内存。使用 new 关键字来分配内存,并使用 delete 关键字释放已经分配的内存。

  5. 空指针检查:空指针是未初始化或者被设置为 null 的指针。在使用空指针时需要进行检查,以避免程序崩溃或者出现其他问题。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

UOS桌面系统使用RLinux恢复数据

UOS桌面系统使用RLinux恢复数据 一、工具介绍二、注意事项三、准备四、制作live系统启动盘五、拷贝文件六、进入live系统一、工具介绍 R-Linux 是一款用于 Linux 和某些 Unixes 操作系统 Ext2/Ext3/Ext4 FS 文件系统的免费文件恢复实用工具。R-Linux 与 R-Studio 使用相同的 I…

病毒分析丨plubx

作者丨黑蛋 一、基本信息 文件名称 00fbfaf36114d3ff9e2c43885341f1c02fade82b49d1cf451bc756d992c84b06 文件格式 RAR 文件类型(Magic) RAR archive data, v5 文件大小 157.74KB SHA256 00fbfaf36114d3ff9e2c43885341f1c02fade82b49d1cf451bc756d992c84b06 SHA1 1c251974b2e…

Nova 和 SuperNova:无需通用电路的通用机器执行证明系统

1. 引言 前序博客有&#xff1a; Nova: Recursive Zero-Knowledge Arguments from Folding Schemes学习笔记SuperNova&#xff1a;为多指令虚拟机执行提供递归证明基于Nova/SuperNova的zkVMSangria&#xff1a;PLONK Folding2023年 ZK Hack以及ZK Summit 亮点记Sangria&…

ptp4l测试-LinuxPTP\ptp4l配置与问题排查

目录 一、前言 1.1 什么是ptp4l 1.2 描述 1.3 官网连接 1.4 目的 1.5 平台 二、 平台必要软件 2.1 linux物理机 2.2 imx6ull开发板 三、检查硬件是否支持 3.1 ifconfig查看当前网卡的名称 3.2 ethtool检查驱动和网卡是否支持 四、开启ptp4l服务 4.1 方法一&#x…

leetcode--环形链表.找到入环节点(java)

环形链表II 环形链表.找到入环节点题目描述解题思路 环形链表.找到入环节点 LeetCode 142&#xff1a;环形链表II 可以在这里测试 题目描述 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节…

电压放大器的主要指标有哪些方面

电压放大器是电子电路中常用的器件&#xff0c;在选择和评估电压放大器时&#xff0c;需要考虑以下几个主要指标&#xff1a; 输入电阻&#xff08;Input Resistor&#xff09;&#xff1a;输入电阻是指放大器输入端的电阻值&#xff0c;它反映了放大器将输入信号转换成输出信号…

Linux驱动入门(二)——嵌入式处理器介绍和构建驱动程序开发环境

文章目录 嵌入式处理器和开发板介绍处理器简述处理器种类Intel的PXA系列处理器StrongARM系列处理器MIPS处理器摩托罗拉龙珠(DragonBall)系列处理器日立SH3处理器德州仪器OMAP系列处理器 ARM处理器ARM处理器简介ARM处理器的特点ARM处理器系列ARM处理器的应用ARM处理器选型 STM32…

Jupyter Notebook如何导入导出文件

目录 0.系统&#xff1a;windows 1.打开 Jupyter Notebook 2.Jupyter Notebook导入文件 3.Jupyter Notebook导出文件 0.系统&#xff1a;windows 1.打开 Jupyter Notebook 1&#xff09;下载【Anaconda】后&#xff0c;直接点击【Jupyter Notebook】即可在网页打开 Jupyte…

初阶数据结构之栈的实现(五)

文章目录 &#x1f60f;专栏导读&#x1f916;文章导读&#x1f640;什么是栈&#xff1f;&#x1f640;画图描述 &#x1f633;栈的代码实现及其各类讲解&#x1f633;栈的初始化代码实现及其讲解&#x1f633;栈的初始化 &#x1f633;栈的销毁代码实现及其讲解&#x1f633;…

PLX31-EIP-SIE 以太网/IP到西门子工业以太网

ProSoft Technology的EtherNet/IP to Siemens工业以太网通信网关允许支持EtherNet/IP的控制器或设备与西门子S7 PACs(包括S7-200s、S7-300s、S7-400s、S7-1200和S7-1500 PACs)之间进行高速双向数据传输。 此外&#xff0c;该网关还包括几个功能&#xff0c;包括数据优先级&…

横向移动-传递攻击SMB服务利用psexecsmbexec

win2012以上版本&#xff0c;关闭了wdigest 或者安装了 KB287199补丁。无法获取明文密码 总的来说就是win2012后无法获取明文密码 解决办法就是&#xff1a; 1.可以利用哈希hash传递&#xff08;pth&#xff0c;ptk等进行移动&#xff09; 2.利用其他服务协议&#xff08;S…

UGUI进阶知识[二十九]循环GridView

节省内存的常用滑动列表还有一种形式&#xff0c;上下滑动的GridView。这种格式的滑动列表可用于移动设备的背包&#xff0c;仓库&#xff0c;商店UI等数据可能海量从而导致产生特别多但又看不见的UI的情况。 于是基于 UGUI进阶知识[八]循环利用滑动列表的循环ListView工程做了…

Tomcat服务器、Servlet生命周期、上传下载文件、使用XHR请求数据、注解使用

文章目录 Servlet认识Tomcat服务器使用Maven创建Web项目创建Servlet探究Servlet的生命周期解读和使用HttpServletWebServlet注解详解使用POST请求完成登陆上传和下载文件下载文件上传文件 使用XHR请求数据重定向与请求转发重定向请求转发 ServletContext对象初始化参数 Servlet…

Office project 2010安装教程

哈喽&#xff0c;大家好。今天一起学习的是project 2010的安装&#xff0c;Microsoft Office project项目管理工具软件&#xff0c;凝集了许多成熟的项目管理现代理论和方法&#xff0c;可以帮助项目管理者实现时间、资源、成本计划、控制。有兴趣的小伙伴也可以来一起试试手。…

在职阿里6年,一个29岁女软件测试工程师的心声

简单的先说一下&#xff0c;坐标杭州&#xff0c;14届本科毕业&#xff0c;算上年前在阿里巴巴的面试&#xff0c;一共有面试了有6家公司&#xff08;因为不想请假&#xff0c;因此只是每个晚上去其他公司面试&#xff0c;所以面试的公司比较少&#xff09; 其中成功的有4家&am…

CSAPP Lab5- MallocLab

实验目标 本实验需要用c语言实现一个动态的存储分配器&#xff0c;也就是你自己版本的malloc&#xff0c;free&#xff0c;realloc函数。 实验步骤 tar xvf malloclab-handout.tar解压文件 我们需要修改的唯一文件是mm.c&#xff0c;包含如下几个需要实现的函数 int mm_ini…

c++调用dll出现LNK2001 无法解析的外部符号

先说说下正常的dll。 动态库显试调用一般3个文件.h .lib .dll &#xff0c;隐式调用 只需要2个文件:.h&#xff08;函数定义&#xff09; .dll 静态库2个文件&#xff1a;.h .lib 先说C正常dll显式调用 #include "BYD_MES/MES2Interface.h" //#include 是以当前…

Android 12.0下拉状态栏通知栏的通知设置默认展开

1.概述 在12.0的产品定制化中,对于SystemUI的定制也是常用的功能,而在下拉状态栏中的通知栏部分也是极其重要的部分,每条通知实时更新在通知栏部分,由于通知栏高度的限制,每条通知是默认收缩的,功能开发需要要求通知默认展开,所以就要从通知的加载流程分析 如图: 2.…

【Java基础篇】运算符

作者简介&#xff1a; 辭七七&#xff0c;目前大一&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a;Java.SE&#xff0c;本专栏主要讲解运算符&#xff0c;程序逻辑控制&#xff0c;方法的使用&…

多态的原理、单继承和多继承的虚函数表、以及虚函数表的打印。

一、多态原理 1、下面这个结果是多少&#xff1f; class A { public:virtual void func(){cout << "func()" << endl;}private:int _a 1; };int main() {printf("%d\n", sizeof(A));return 0; } 是 4&#xff1f;8&#xff1f;还是多少&am…