重温C++编程-强大的指针功能与C++的引用
zhezhongyun 2025-10-23 14:14 3 浏览
程序中的数据(变量,数组等)对象总是存放在内存中,在生命期内这些对象占据一定的内存空间,有确定的存储位置,实际上,每个内存单元都有一个地址,即以字节为单位连续编码。编译器将程序中的对象名转换成机器指令识别的地址,通过地址来存储对象值。
C、C++语言中把这种存放对象地址的变量叫做指针变量:
int i = 1;
int *p = &i;指针变量的类型是它所指向的对象的类型,这样就实现了对数据的间接引用。这种操控是高效的。
C语言给人留下最深印象的是面向过程的编程(函数: functioon),以及强大的指针操作能力。
指针作为一种对计算机中存储数据区的间接引用操作,无疑是直接和高效的。这是一把几乎没有受控的手术刀。可能是软件开发早期阶段,程序员行列还是是少数人群体,基本都是能力非常强的人,同时解决的问题场景也相对不复杂的原因,同期以C语言为代表的编程语言,给予程序员以最大可能的操控能力,为的是能解决面临的貌似比编程语言等计算机工具要难的现实问题。
那时候担心的是程序员手头工具能力的不足。因此,此种情况下,计算机系统方面对程序员是给予最高操作权限的。
指针某种程度上就是这个有近乎最高操作权限的手术刀。高效,高能,当然也是高危的。
C语言的众多问题,最核心的就是指针的不合理使用导致的难以浮现的崩溃,和难以防范有心人的不良行为带来的安全隐患。
同时,后来程序员行列人员的扩张以及代码规模的倍增,导致很难用早些年能力高超的人员素质去要求所有的程序员,特别是刚从事写代码的程序员。因此,提供简单易写,安全的编程语言就逐渐成为编程语言的主流。
这些编程语言基本都对指针做了不同程度的限制,当然在安全易用的同时,也就给指针搭上了枷锁。所以,从实际代码的执行性能的角度上,后来的这些编程语言无疑均是无法超越C语言的,因为代码从执行角度,对存储数据的操作最终都需要归到寻址上。C语言是直接公开指针操作,而后来的编程语言都给指针操作带上了壳和各种限制校验,后者这些都是代价。所以性能上都必然有所损失。
C++语言在这众多的语言中,从代码执行性能的角度无疑是仅次于C语言的。因为它一方面基本保留了C语言的指针操作的支持,另一方面也针对C语言的缺陷做了一定的细节的调整使用,以减少问题的出现。
我们先看一下C++中支持的与C语言基本一致的指针操作。
int i = 1;
int *p = &i;
*p += 1; // 对p指向的内容进行操作
cout << "p:" << p << ", *p = " << *p << endl; // 输出:p:0x8d58dff804, *p = 1&操作符用于获取一个变量的地址, int* 定义了一个int类型的指针变量, *p用于获取指针指向的数据内容。
指针的运算通常用于数组对象:
int list[5] = {1, 2, 3, 4, 5};
int *p = list;
cout << "list[1]: " << *(p + 1) << endl;指针p指向的是数组的首,通过指针的移动,可以寻找到连续存储的数组对应位置的元素。
这种寻址方式体现出数组对象存储的连续性和直接寻址的高效性。
指针对象也经常用于函数参数的传递:
int print_list(const int* list, int size) {
for (int i = 0; i < size; i++) {
cout << "list[" << i << "]: " << *(list + i) << endl;
}
}
int main() {
int list[5] = {1, 2, 3, 4, 5};
print_list(p, 5);
return 0;
}C++中使用const修饰符,申明函数参数中指针参数的不可改变。
可以申明指针变量为const,一个非const指针可以赋值给const指针,反之不可以。
指针做函数的入参,提供了数据传递的效率,既避免了数据的复制,同时保留了对原有数据可能的修改的能力。
我们看另外的一个例子:
int* p = new int; // 在栈上分配一个整数类型的对象
*p = 1; // 初始化
delete p; // 释放栈上内存在C++中使用new关键字,可以在栈上分配一块存储区域,这块分配的存储必须要手工释放,否则会导致内存泄漏。
这类似于C语言中的malloc/free函数,C++推荐使用new/delete代替。
上面我们介绍了指针在C++语言中三种常见的使用方式:寻址,数组对象的指针运算,函数参数的传递。其他的滥用可能会带来安全风险。
我们来看C++跟指针相对应的引用。
引用类型允许我们通过不同的名称访问同一个变量。引用在定义时必须初始化,并且一旦初始化后就不能再改变引用的对象。
int i = 1;
int &b = i;
b = 2;
cout << "i:" << i << endl; // 输出i: 2我们可以看到引用在这里起到了指针一样的寻址作用,但不支持直接对指针进行的运算。这带来了安全性。
总结一下,指针的寻址是一个高效率的行为,但指针运算在强大的同时也是危险的,早期的程序员是默认能力强大并且自律的群体,但随之程序员行列的倍数级别的扩充,新进人员的能力不足以支撑这种默认,必须给予限制。
C++在保留C语言指针的高效的同时,引入了引用这个概念,支持大多数情况下的类似指针的寻址能力,但同时提供了安全性。
C/C++甚至是后来的其他的编程语言,从对数据的操控上来讲,几乎所有的性能优化都来自于对指针的有效使用,所以关注代码的性能,必然需要关注指针或者类似指针的东西。
就像强大的手术刀一样,作为程序员,我们在使用编程语言提供的工具时,必须要对自己的行为保持一定的约束,需要清楚知晓每一个工具能实现的功能,也需要注意这种工具的另一面:可能的负面影响,然后规避这些不好的方面。
今天先聊到此,明天继续探索C++世界。
相关推荐
- Python入门学习记录之一:变量_python怎么用变量
-
写这个,主要是对自己学习python知识的一个总结,也是加深自己的印象。变量(英文:variable),也叫标识符。在python中,变量的命名规则有以下三点:>变量名只能包含字母、数字和下划线...
- python变量命名规则——来自小白的总结
-
python是一个动态编译类编程语言,所以程序在运行前不需要如C语言的先行编译动作,因此也只有在程序运行过程中才能发现程序的问题。基于此,python的变量就有一定的命名规范。python作为当前热门...
- Python入门学习教程:第 2 章 变量与数据类型
-
2.1什么是变量?在编程中,变量就像一个存放数据的容器,它可以存储各种信息,并且这些信息可以被读取和修改。想象一下,变量就如同我们生活中的盒子,你可以把东西放进去,也可以随时拿出来看看,甚至可以换成...
- 绘制学术论文中的“三线表”具体指导
-
在科研过程中,大家用到最多的可能就是“三线表”。“三线表”,一般主要由三条横线构成,当然在变量名栏里也可以拆分单元格,出现更多的线。更重要的是,“三线表”也是一种数据记录规范,以“三线表”形式记录的数...
- Python基础语法知识--变量和数据类型
-
学习Python中的变量和数据类型至关重要,因为它们构成了Python编程的基石。以下是帮助您了解Python中的变量和数据类型的分步指南:1.变量:变量在Python中用于存储数据值。它们充...
- 一文搞懂 Python 中的所有标点符号
-
反引号`无任何作用。传说Python3中它被移除是因为和单引号字符'太相似。波浪号~(按位取反符号)~被称为取反或补码运算符。它放在我们想要取反的对象前面。如果放在一个整数n...
- Python变量类型和运算符_python中变量的含义
-
别再被小名词坑哭了:Python新手常犯的那些隐蔽错误,我用同事的真实bug拆给你看我记得有一次和同事张姐一起追查一个看似随机崩溃的脚本,最后发现罪魁祸首竟然是她把变量命名成了list。说实话...
- 从零开始:深入剖析 Spring Boot3 中配置文件的加载顺序
-
在当今的互联网软件开发领域,SpringBoot无疑是最为热门和广泛应用的框架之一。它以其强大的功能、便捷的开发体验,极大地提升了开发效率,成为众多开发者构建Web应用程序的首选。而在Spr...
- Python中下划线 ‘_’ 的用法,你知道几种
-
Python中下划线()是一个有特殊含义和用途的符号,它可以用来表示以下几种情况:1在解释器中,下划线(_)表示上一个表达式的值,可以用来进行快速计算或测试。例如:>>>2+...
- 解锁Shell编程:变量_shell $变量
-
引言:开启Shell编程大门Shell作为用户与Linux内核之间的桥梁,为我们提供了强大的命令行交互方式。它不仅能执行简单的文件操作、进程管理,还能通过编写脚本实现复杂的自动化任务。无论是...
- 一文学会Python的变量命名规则!_python的变量命名有哪些要求
-
目录1.变量的命名原则3.内置函数尽量不要做变量4.删除变量和垃圾回收机制5.结语1.变量的命名原则①由英文字母、_(下划线)、或中文开头②变量名称只能由英文字母、数字、下画线或中文字所组成。③英文字...
- 更可靠的Rust-语法篇-区分语句/表达式,略览if/loop/while/for
-
src/main.rs://函数定义fnadd(a:i32,b:i32)->i32{a+b//末尾表达式}fnmain(){leta:i3...
- C++第五课:变量的命名规则_c++中变量的命名规则
-
变量的命名不是想怎么起就怎么起的,而是有一套固定的规则的。具体规则:1.名字要合法:变量名必须是由字母、数字或下划线组成。例如:a,a1,a_1。2.开头不能是数字。例如:可以a1,但不能起1a。3....
- Rust编程-核心篇-不安全编程_rust安全性
-
Unsafe的必要性Rust的所有权系统和类型系统为我们提供了强大的安全保障,但在某些情况下,我们需要突破这些限制来:与C代码交互实现底层系统编程优化性能关键代码实现某些编译器无法验证的安全操作Rus...
- 探秘 Python 内存管理:背后的神奇机制
-
在编程的世界里,内存管理就如同幕后的精密操控者,确保程序的高效运行。Python作为一种广泛使用的编程语言,其内存管理机制既巧妙又复杂,为开发者们提供了便利的同时,也展现了强大的底层控制能力。一、P...
- 一周热门
- 最近发表
- 标签列表
-
- HTML 教程 (33)
- HTML 简介 (35)
- HTML 实例/测验 (32)
- HTML 测验 (32)
- JavaScript 和 HTML DOM 参考手册 (32)
- HTML 拓展阅读 (30)
- HTML文本框样式 (31)
- HTML滚动条样式 (34)
- HTML5 浏览器支持 (33)
- HTML5 新元素 (33)
- HTML5 WebSocket (30)
- HTML5 代码规范 (32)
- HTML5 标签 (717)
- HTML5 标签 (已废弃) (75)
- HTML5电子书 (32)
- HTML5开发工具 (34)
- HTML5小游戏源码 (34)
- HTML5模板下载 (30)
- HTTP 状态消息 (33)
- HTTP 方法:GET 对比 POST (33)
- 键盘快捷键 (35)
- 标签 (226)
- opacity 属性 (32)
- transition 属性 (33)
- 1-1. 变量声明 (31)
