C++:指针和引用

指针的基础

数据在内存当中是怎么样被存储的

数据在内存中的存储方式取决于数据的类型和计算机的体系结构

基本数据类型
整数类型:整数在内存中以二进制补码的形式存储。对于有符号整数,最高位为符号位,0 表示正数,1 表示负数。例如,在一个 32 位的系统中,int类型的整数5的二进制表示为00000000 00000000 00000000 00000101,而-5的二进制补码表示为11111111 11111111 11111111 11111011。不同大小的整数类型(如char、short、int、long等)所占用的内存字节数不同,其取值范围也不同。
浮点类型:浮点数在内存中的存储遵循 IEEE 754 标准。以单精度浮点数(float)为例,它占用 32 位内存,其中包括 1 位符号位、8 位指数位和 23 位尾数位。浮点数通过科学计数法的形式表示,指数部分采用偏移码存储,尾数部分则是二进制小数的有效数字。例如,浮点数3.14在内存中的存储形式是经过一系列转换后得到的二进制编码。
字符类型:字符类型通常占用 1 个字节的内存空间,其存储的是字符对应的 ASCII 码值或 Unicode 码值。例如,字符’A’的 ASCII 码值为 65,在内存中存储的二进制形式为01000001。
数组
数组是相同类型数据的集合,其元素在内存中是连续存储的。例如,一个包含 5 个int类型元素的数组int arr[5],在内存中会依次存储这 5 个整数,每个整数占用相应的字节数(如在 32 位系统中为 4 字节)。数组名可以看作是指向数组首元素的指针,通过指针的偏移可以访问数组中的各个元素。
结构体
结构体是不同类型数据的组合,其成员在内存中的存储顺序与结构体定义中的顺序一致。结构体的大小通常是其成员大小的总和,但由于内存对齐的要求,可能会存在一些额外的填充字节,以保证结构体的每个成员都能在适当的内存地址上对齐,从而提高访问效率。例如,定义一个结构体struct Student { char name[20]; int age; float score; };,其成员name、age和score会依次存储在内存中,并且可能会根据编译器的对齐规则进行适当的填充。
指针
指针存储的是内存地址,其大小通常与计算机的字长相同。例如,在 32 位系统中,指针占用 4 字节,而在 64 位系统中,指针占用 8 字节。指针所指向的数据类型决定了通过指针访问内存时所读取或写入的数据大小和格式。
字符串
在 C 语言中,字符串是以字符数组的形式存储的,并且以’\0’作为字符串的结束标志。例如,字符串"Hello"在内存中实际上存储为’H’、‘e’、‘l’、‘l’、‘o’、'\0’这 6 个字符的 ASCII 码值,占用 6 个字节的内存空间。而在一些高级语言中,字符串可能会有更复杂的存储结构和管理方式,但本质上也是存储字符序列的一种数据类型。

访问方式

直接访问
定义:直接访问是指通过变量名或地址直接对数据进行操作,即直接使用变量名来访问和修改其对应内存地址中的数据值。
示例:在大多数编程语言中,定义一个变量后,可以直接使用该变量名来进行赋值、读取等操作。例如在 C 语言中,int num = 10; 定义了一个整型变量 num 并初始化为 10,之后可以直接通过 num 来访问和修改这个值,如 num = 20; 就直接将变量 num 的值修改为 20。
优点:简单直观,易于理解和使用,代码的可读性较高,能够直接反映出对哪个变量进行了何种操作。
缺点:对于一些复杂的数据结构或需要动态分配内存的情况,直接访问可能不够灵活,难以对数据进行有效的组织和管理。
间接访问
定义:间接访问是指通过指针或引用等方式来访问数据,即先获取数据的地址,然后通过该地址来访问和操作数据。
示例:在 C 语言中,可以定义一个指针变量来存储另一个变量的地址,然后通过指针来间接访问该变量的值。例如,int num = 10; int *ptr = # 这里定义了一个指针变量 ptr,并将它指向变量 num 的地址,通过 *ptr 就可以间接访问和修改 num 的值,如 *ptr = 30; 此时 num 的值就被修改为 30 了。
优点:更加灵活,可以动态地分配和管理内存,方便地操作复杂的数据结构,如链表、树等。通过指针或引用,可以在不同的函数或模块之间共享和传递数据,而无需将数据本身进行复制,提高了程序的效率和内存的利用率。
缺点:使用间接访问需要对指针和内存管理有更深入的理解,否则容易出现指针错误,如空指针引用、野指针等,导致程序出现错误甚至崩溃。


#include <iostream>
using namespace std;int main() {int i = 0;cout << "请输入i的值"  << endl;cin >> i;cout << "i = " << i << endl;//直接访问cout << "i在内存当中的地址是" << &i << endl;int* p = &i;cout << *p << endl;//间接访问cout << p << endl;cout << &p << endl;return 0;
}

在这里插入图片描述

指针变量作为函数参数传输


#include <iostream>
using namespace std;int swapNumbers(int * numPtr1, int* numPtr2)
{int tmp;tmp = *numPtr1;*numPtr1 = *numPtr2;*numPtr2 = tmp;return 0;
}int main() {int num1 = 90;int num2 = 88;swapNumbers(&num1,&num2);cout << "num1 = " << num1 << endl;cout << "num2 = " << num2 << endl;return 0;
}

在这里插入图片描述

指向数组的指针变量


#include <iostream>
using namespace std;int main() {int arr[] = {1,2,3,4};int* ptr = arr;int* ptr1 = &arr[0];for (int i = 0; i < sizeof(arr) / sizeof(int); i++){cout << *(ptr + i) << " ";}cout << endl;for (int i = 0; i < sizeof(arr) / sizeof(int); i++){cout << *(ptr1 + i) << " ";}return 0;
}

数组的第一个元素和数组名称指向的是同一个地址空间
在这里插入图片描述

引用


#include <iostream>
using namespace std;int add(int& a, int& b)
{cout << a + b << endl;return 0;
}int main() {int a = 99; int b = 1;add(a, b);return 0;
}

在这里插入图片描述

const关键字

常量变量定义

#include <iostream>int main() {// 定义一个常量整数,使用const关键字const int MAX_VALUE = 100;// 试图修改常量的值,会导致编译错误// MAX_VALUE = 200;std::cout << "常量MAX_VALUE的值为: " << MAX_VALUE << std::endl;return 0;
}

在这里插入图片描述

常量指针

#include <iostream>int main() {int num = 50;// 定义一个常量指针,指针指向的内容不能通过该指针修改const int* ptr = &num;// 下面这行代码会导致编译错误,因为不能通过常量指针修改所指向的值// *ptr = 100;std::cout << "通过常量指针获取的值为: " << *ptr << std::endl;return 0;
}

在这里插入图片描述

指针常量

#include <iostream>int main() {int num = 50;int num2 = 99;// 定义一个指针常量,指针本身的地址不能改变,但可以通过它修改所指向的值int* const ptr = &num;// 下面这行代码会导致编译错误,因为指针本身的地址不能改变//ptr = num2;*ptr = 100;std::cout << "修改后的值为: " << num << std::endl;return 0;
}![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/04721be84a0043bdb55e54457ad22754.png)
## 常引用```c
#include <iostream>int main() {int num = 50;// 定义一个常引用,引用所指向的内容不能通过该引用修改const int& ref = num;// 下面这行代码会导致编译错误,因为不能通过常引用修改所指向的值// ref = 100;std::cout << "通过常引用获取的值为: " << ref << std::endl;return 0;
}

在这里插入图片描述

函数参数中的 const

#include <iostream>// 函数声明,参数为常引用,保证函数内部不会修改传入的值
void printValue(const int& value) {std::cout << "传入的值为: " << value << std::endl;
}int main() {int num = 50;// 调用函数,传递变量的常引用printValue(num);return 0;
}

在这里插入图片描述

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

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

相关文章

使用esp32c3开发板通过wifi连网络web服务器

实验基本拓扑就是&#xff1a; esp32c3开发板通过Wifi模块连上局域网&#xff0c;局域网一台服务器通过FastAPI提供8000端口的web服务&#xff0c;在esp32c3开发板中烧录micropython固件&#xff0c;在python交互模式下&#xff0c;连上Wifi模块&#xff0c;并使用socket模块获…

自动化运维-检测Linux服务器CPU、内存、负载、IO读写、机房带宽和服务器类型等信息脚本

前言&#xff1a;以上脚本为今年8月1号发布的&#xff0c;当时是没有任何问题&#xff0c;但现在脚本里网络速度测试py文件获取不了了&#xff0c;测速这块功能目前无法实现&#xff0c;后面我会抽时间来研究&#xff0c;大家如果有建议也可以分享下。 脚本内容&#xff1a; #…

网络安全:我们的安全防线

在数字化时代&#xff0c;网络安全已成为国家安全、经济发展和社会稳定的重要组成部分。网络安全不仅仅是技术问题&#xff0c;更是一个涉及政治、经济、文化、社会等多个层面的综合性问题。从宏观到微观&#xff0c;网络安全的重要性不言而喻。 宏观层面&#xff1a;国家安全与…

通威传媒:移动AI数字人OLED透明屏应用案例

在科技与创新不断交融的今天&#xff0c;尼伽OLED品牌与通威传媒携手合作&#xff0c;共同推出了移动AI数字人OLED透明屏显示设备。这款设备不仅融合了尼伽OLED品牌的卓越显示技术与通威传媒的深厚积累&#xff0c;更在定点介绍、手动讲解模式、中控控制以及数字人联动等方面实…

Proteus 8.17的详细安装教程

通过百度网盘分享的文件&#xff1a;Proteus8.17(64bit&#xff09;.zip 链接&#xff1a;https://pan.baidu.com/s/1zu8ts1Idhgg9DGUHpAve7Q 提取码&#xff1a;8q8v 1.右击【Proteus8.17(64bit&#xff09;.zip】&#xff0c;选择【全部解压缩......】。 &#xff0c; 2.…

人工智能:塑造未来的工作与生活

目录 人工智能技术的应用前景与影响 人工智能的历史与现状 人工智能的应用领域 人工智能的前景与挑战 个人视角&#xff1a;人工智能的应用前景与未来 人工智能在生活中的潜力 面对人工智能带来的挑战 我的观点与建议 结语 人工智能技术的应用前景与影响 随着人工智能…

VSCode自定义插件创建教程

文章目录 一、前言二、插件维护三、调试插件四、使用 vsce 生成 vsix 插件五、问题&#xff1a;打开调试窗口后&#xff0c;输入helloworld并没有指令提示六、插件创建实战七、拓展阅读 一、前言 对于前端程序猿来讲&#xff0c;最常用的开发利器中VSCode首当其冲&#xff0c;…

vue功能基础元素使用

4.:inline"true"元素&#xff0c;能够左右元素保持在同一行 这个好处非常直观&#xff0c;但要注意和el-col同时使用时&#xff0c;就会出现el-input换行&#xff0c;即便调整好&#xff0c;放大缩小也会出现换行问题。 5.filterable 下拉框带搜索功能 6.clearable下…

uniapp 购物弹窗组件 (微信小程序)

效果图&#xff0c;暂时只适应单规格&#xff0c;居中弹出和下方弹出&#xff0c;如需求不满足&#xff0c;请自行修改代码 &#xff08;更新于24/11/15) 居中显示效果 下方弹出效果 html <template><view class"" v-if"show":class"mod…

单片机学习笔记 5. 数码管静态显示

更多单片机学习笔记&#xff1a;单片机学习笔记 1. 点亮一个LED灯单片机学习笔记 2. LED灯闪烁单片机学习笔记 3. LED灯流水灯单片机学习笔记 4. 蜂鸣器滴~滴~滴~ 目录 0、实现的功能 1、Keil工程 1-1 数码管显示原理 1-2 静态与动态显示 1-3 74HC573锁存器的工作原理 1-…

内容占位符:Kinetic Loader HTML+CSS 使用CSS制作三角形原理

内容占位符 前言 随着我们对HTML和CSS3的学习逐渐深入&#xff0c;相信大家都已经掌握了网页制作的基础知识&#xff0c;包括如何使用HTML标记构建网页结构&#xff0c;以及如何运用CSS样式美化页面。为了进一步巩固和熟练这些技能&#xff0c;今天我们一起来完成一个有趣且实…

【YOLOv8】安卓端部署-1-项目介绍

【YOLOv8】安卓端部署-1-项目介绍 1 什么是YOLOv81.1 YOLOv8 的主要特性1.2 YOLOv8分割模型1.2.1 YOLACT实例分割算法之计算掩码1.2.1.1 YOLACT 的掩码原型与最终的掩码的关系1.2.1.2 插值时的目标检测中提取的物体特征1.2.1.3 coefficients&#xff08;系数&#xff09;作用1.…

Hadoop 学习心得

一、引言 &#xff08;一&#xff09;学习 Hadoop 的背景和目的 随着信息技术的飞速发展&#xff0c;数据量呈爆炸式增长&#xff0c;传统的数据处理方式已难以满足需求。在这样的背景下&#xff0c;为了能够在大数据领域有所发展&#xff0c;我开始学习 Hadoop。Hadoop 作为处…

【全面解读】Apache SeaTunnel常见问题全攻略

使用SeaTunnel需要安装Spark或者Flink这样的引擎么&#xff1f; 不需要&#xff0c;SeaTunnel 支持 Zeta、Spark 和 Flink 作为同步引擎的选择&#xff0c;您可以选择之一就行&#xff0c;社区尤其推荐使用 Zeta 这种专为同步场景打造的新一代超高性能同步引擎。Zeta 被社区用…

STM32完全学习——系统时钟设置

一、时钟框图的解读 首先我们知道STM32在上电初始化之后使用的是内部的HSI未经过分频直接通过SW供给给系统时钟&#xff0c;由于内部HSI存在较大的误差&#xff0c;因此我们在系统完成上电初始化&#xff0c;之后需要将STM32的时钟切换到外部HSE作为系统时钟&#xff0c;那么我…

分布式系统稳定性建设-性能优化篇

分布式系统稳定性建设-性能优化篇 系统稳定性建设是系统工程的核心内容之一。以下是一些重要的方面: 架构设计: 采用模块化、松耦合的架构设计,以提高系统的可扩展性和可维护性。合理划分系统功能模块,降低单个模块的复杂度。定义清晰的接口和数据交换标准,确保各模块之间协调…

网络学习第四篇

引言&#xff1a; 我们在第三篇的时候出现了错误&#xff0c;我们要就行排错&#xff0c;那么我们要知道一下怎么配置静态路由实现ping通&#xff0c;这样子我们才知道下一跳到底是什么&#xff0c;为什么这样子做。 实验目的 理解和掌握静态路由的基本概念和配置方法。 实…

[控制理论]—位置式PID与增量式PID

位置式PID与增量式PID 1.位置式PID 按模拟PID控制算法&#xff0c;以一系列的采样时刻点kT代表连续时间t&#xff0c;以矩形法数值积分近似代替积分&#xff0c;以一阶后向差分近似代替微分&#xff0c;即&#xff1a; t ≈ k T &#xff08; k 0 , 1 , 2... &#xff09; …

【c++丨STL】list的使用

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;C、STL 目录 前言 list简介 一、list的默认成员函数 构造函数(constructor) 析构函数 赋值重载 二、list的迭代器接口 迭代器的功能分类 三、list的容量…

Unity 编辑器下 Android 平台 Addressable 加载模型粉红色,类似材质丢失

Unity 编辑器下 Android 平台 Addressable 加载模型粉红色&#xff0c;类似材质丢失 Addressable Play Mode Script加载模式 选择 Use Existiing Build 1.Unity 切换到 PC 平台&#xff0c;执行 Addressable Build 运行&#xff0c;加载 bundle 内的预制体 显示正常 2.Unit…