C++ 指针
开始之前,我们先来说说 变量 、变量所指向的数据 、内存 三者相互间的关系
先来了解几个相关的名称
概念 | 说明 |
---|---|
内存条 | 内存条是 CPU 可通过总线寻址,并进行读写操作的电脑部件 通常所说电脑内存 (RAM) 的大小,即是指内存条的总容量 |
内存 | 内存是连续的存储空间,大小等于内存条的总容量 |
内存编址 | 就是将内存条划分为不同的单元格,并编一个号,就像尺子一样 每段大小的单位是字节,就像尺子刻度间的大小是 1 毫米 |
内存分配 | 根据变量的类型分配内存单元,变量内存单元的起始地址为变量的地址 变量内存单元的大小为变量类型的大小,如 int = 4byte,占用 4 格 分配后,每个变量对应一个地址,对变量的访问就是通过地址进行的 |
变量引用 | 从变量名对应的地址开始的若干单元格取出数据 字节数由变量类型决定 |
变量赋值 | 将数据按照该变量名定义的类型存入对应的内存单元中, 内存单元的内容就是变量的值 |
我们用一张图来理解上面这些概念
变量地址
上面说过,每一个变量都有一个内存位置,每一个内存位置都定义了可访问的地址
-
取址符 (
&
)C++ 提供了 取址符(&) 可以获得一个变量的内存地址
/** * file: main.cpp * author: 简单教程(www.twle.cn) * * Copyright © 2015-2065 www.twle.cn. All rights reserved. */ #include <iostream> using namespace std; int main () { int var1; char var2[10]; std::cout << "var1 变量的地址: "; std::cout << &var1 << std::endl; std::cout << "var2 变量的地址: "; std::cout << &var2 << std::endl; return 0; }
编译和运行以上范例,输出结果如下
var1 变量的地址: 0x7ffee55a01c0 var2 变量的地址: 0x7ffee55a01ee
你的输出结果可能和我的不一样,但没关系,它都表示了一个内存位置
-
解地址符 (
*
)C++ 提供了 解地址符( * ) 获取一个内存地址保存的值
/** * file: main.cpp * author: 简单教程(www.twle.cn) * * Copyright © 2015-2065 www.twle.cn. All rights reserved. */ #include <iostream> using namespace std; int main () { int a = 100; double pi = 3.1415926; std::cout << "a 变量的地址: "; std::cout << &a << std::endl; std::cout << "pi 变量的地址: "; std::cout << &pi << std::endl; std::cout << "a 变量的地址保存的值: "; std::cout << *(&a) << std::endl; std::cout << "pi 变量的地址保存的值: "; std::cout << *(&pi) << std::endl; return 0; }
编译和运行以上范例,输出结果如下
a 变量的地址: 0x7ffee1d241b8 pi 变量的地址: 0x7ffee1d241b0 a 变量的地址保存的值: 100 pi 变量的地址保存的值: 3.14159
C++ 指针
指针 是一个变量,其值为另一个变量的地址,即,内存位置的直接地址
跟其它变量或常量一样,必须在使用指针存储其它变量地址之前,对其进行声明
指针变量声明的一般形式为
[存储类型] type_name *var_name;
- type_name 必须是一个有效的 C++ 数据类型
- var_name 是指针变量的名称
- 星号
*
用来指定一个变量是指针
以下是有效的指针声明
int *ip; /* 一个整型的指针 */ double *dp; /* 一个 double 型的指针 */ float *fp; /* 一个浮点型的指针 */ char *ch; /* 一个字符型的指针 */
所有指针的值的实际数据类型,不管是整型、浮点型、字符型,还是其它的数据类型,都是一样的,都是一个代表内存地址的长的十六进制数
不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同
C++ 中使用指针
C++ 指针只有五种操作
-
定义一个指针变量
int *ptr_a;
-
把变量地址赋值给指针,使用取址符 (
&
)int pi = 3.1415926; int *ptr_pi = π
-
访问指针变量中可用地址的值,使用解地址符 (
*
)int pi = 3.1415926; int *ptr_pi = π std::cout << *ptr_pi;
-
简单的自增自减和加法减法运算符
因为指针保存的是变量的地址,而变量的地址是十六进制整形,所以也支持四种操作,而且只支持这四种
ptr_pi++; ptr_pi--; ptr_pi = ptr_pi - 3; ptr_pi = ptr_pi + 3;
-
简单的比较两个指针的大小,可以使用三个比较运算符
==
、<
和>
这三个比较运算符用于比较指针指向的内存地址是否相等,是否大于或小于
我们写一个范例来演示前三种操作
/** * file: main.cpp * author: 简单教程(www.twle.cn) * * Copyright © 2015-2065 www.twle.cn. All rights reserved. */ #include <iostream> int main () { double pi = 3.1415926; // 实际变量的声明 double *ptr_pi; // 指针变量的声明 ptr_pi = π // 在指针变量中存储 pi 的地址 // 输出变量 pi 的地址 std::cout << "pi 变量的地址为: " << &pi << std::endl; // 在指针变量中存储的地址 std::cout << "ptr_pi 保存的值为: "<< ptr_pi << std::endl; std::cout << "pi 变量的值为: " << pi << std::endl; // 访问指针中地址的值 std::cout << "ptr_pi 中地址的值为: " << *ptr_pi << std::endl; return 0; }
编译和运行以上范例,输出结果如下
pi 变量的地址为: 0x7ffeec7e61b0 ptr_pi 保存的值为: 0x7ffeec7e61b0 pi 变量的值为: 3.14159 ptr_pi 中地址的值为: 3.14159
C++ 指针范例
虽然 C++ 中的指针只有三种操作,但是它既可以作为函数的参数,有可以作为函数的返回值,当然,还有自增自减操作
范例 | 说明 |
---|---|
C++ Null 指针 | C++ 支持空指针 NULL 指针是一个定义在标准库中的值为零的常量 |
C++ 指针的算术运算 | 可以对指针进行四种算术运算:++、--、+、- |
C++ 指针 vs 数组 | 指针和数组之间有着密切的关系 |
C++ 指针数组 | 可以定义用来存储指针的数组 |
C++ 指向指针的指针 | C++ 允许指向指针的指针 |
C++ 传递指针给函数 | 通过引用或地址传递参数,使传递的参数在调用函数中被改变 |
C++ 函数返回指针 | C++ 允许函数返回指针到局部变量、静态变量和动态内存分配 |