专业编程基础技术教程

网站首页 > 基础教程 正文

C++|有了变量为什么还需要指针?(高级语言离不开指针)

ccvgpt 2024-08-05 12:24:14 基础教程 17 ℃

程序在计算机内部运行时,程序和程序处理的数据都存储在计算机的内存中。计算机的的做法是将全部代码保存代码区,然后再由操作系统和编译器为程序处理的数据另外分配内存区域,如静态存储区存储全局变量、静态局部变量,动态存储区(栈区)存储局部动态变量、形参,动态分配区(栈区)存储用户临时根据需要申请的可以由变量确定内存单元大小的动态数据。

为了对内存进行管理,给内存中的每一个存储单元都分配了一个地址。对于一般的变量,操作系统和编译器都会维护一份变量名与内存地址的对照表,用户可以不关注内存地址而直接通过变量名就可以方便对内存中代码与数据进行访问。

C++|有了变量为什么还需要指针?(高级语言离不开指针)

因为地址的编号虽有规律性,但却没有与其存储内容的相关、地址显得没有太多含义,所以用变量名代替地址,就是为了让地址便于理解和阅读。但与此同时也让用户对内存中保存的代码和数据的直接管理,中间多了一层障碍。相邻的地址本身是极有规律性的,一般高级语言中定义的数组的数组名就是数组首元素的地址。变量名的引入,丧失了利用地址规律性的优势。因为对存储在一起的一大片数据的处理,利用地址的规律性,是极其方便的。

特别是当某一个变量或数据结构无法事先确定所需内存单元大小时,也就是需要根据当时程序代码运行的需要临时申请可以变化的内存单元进行数据处理时(变量控制内在单元大小)。将地址能显性地呈现在程序开发者面前就很有必要了。

这就是指针,这种数据类型的值就是一个内存单元地址,指针可以指向编号为该地址对应的数据。当然,在如Java的语言中用“引用”的称呼来完成指针的功能。

指针的存在,一方面可能利用地址的规律性,另外一方面即使没有事先定义变量,也可以利用指针存入并引用数据。

1 指针派生类型

指针可以通过取址运算符&取得某一个变量的地址或某一复杂数据类型(如数组或函数)的首地址,也可以通过函数mallowc()分配用户指定大小的内存单元的首地址。

1.1 简单指针变量

如定义一个整形变量:

int i;

假设地址是0x2000,该地址保存的值是“5”,用户直接通过变量名“i”就可以得到其值“5”,而用户是可管“0x2000”这个地址的,其变量名与地址的对应关系由操作系统和编译器负责。

如是定义一个整形变量和整形指针:

int i *pi;

pi = &i;

1.2 数组指针

详情见:《C++|指针强大功能:灵活引用数组》

1.3 函数指针

函数指针是指持有函数地址的指针。其声明的格式如下:

void (*foo)();

2 指针的功能和优势

正确灵活地运用指针,可以提高程序代码的质量。因为其能像汇编语言一样处理内在地址,所以指针具有以下独特的优势。

  • 可以有效地表示和引用各种数据结构,如方便地使用数组和字符串;

  • 可以令函数返回多于一个的独立结果;

  • 利用指针可进行内存的动态分配;

1.1 间接访问

利用指针变量间接访问某一单元或一片连续的存储区

详情见:《C++|指针强大功能与优势:利用指针变量访问一片连续的存储区》

1.2 作函数参数

详情见:《C|实参到形参的单向值传递、指针变量做形参,调用时多值返回》

1. 3 灵活引用数组

详情见:《C++|指针强大功能:灵活引用数组》

1.4 动态分配内存

详情见:《C++|动态内存分配:通过指针临时按需分配堆内内存》

3 高级语言中指针功能的应用

如果没有指针,就无法构造正统的数据结构,因此,比较成熟的、正统的编程语言,必定会存在指针。

Java没有指针吗?

Java只能通过指针来操作数组和对象,因此,Java比C更离不开指针。(数组名在一般高级语言中定义的是数组元素的首地址,是一个常量,其本身也主要是利用内存地址逻辑上的连续性或规律性。)

Java只是把指针换了一个说法而已,叫“引用”。Java没有指针运算,因此不存在指针运算和数组之间的那种微妙关系,此外你也不能取得指向变量的指针。

除了Java外,Lisp、smalltalk和Perl(Ver.5以后)中相当于指针的对象也被称为“引用”,但是也有人会使用“指针”这样的叫法。也就是说,这些语言并没有严格地将“引用”和“指针”分开。因为它们的本质相同。

Pascal、Modula2/3和C一样,都称之为指针。

Ada中的名称为“Access类型”,有点令人费解。

悲哀的是,C++在语法上将“指针”和“引用”区别成两个不同的概念。C++中“指针”和C、Pascal的“指针”,以及Java的“引用”同义。其次,C++中的“引用”是指本来应该被称为“别名”(alias)的对象。正因为是别名,所以一旦确定“别名是什么”,就再也不能更改了。

实际上,C++的术语“引用”也是通过指针来实现的,所以它是一处重复的功能。当然,在某些运算符重载,以及复制构造函数的场景下,可能会不得不使用“引用”。

Tags:

最近发表
标签列表