C++ 指针
C++ 中指针的概念和和 C 语言一样,指针就是内存的地址,指针变量则是保存了内存地址的变量。
内存地址
计算机中所有的数据都必须放在内存中,不同类型的数据占用的字节数不一 样。为了正确地访问这些数据,必须为每个字节都编上号码,就像门牌号、身份证号一样,每个字节的编号是唯一的,根据编号可以准确地找到某个字节。
我们将内存中字节的编号称为地址(Address)或指针(Pointer)。CPU 只能通过地址来取得内存中的代码和数据,程序在执行过程中会告知 CPU 要执行的代码以及要读写的数据的地址。而程序中的变量名和函数名只是地址的一种助记符,当源文件被编译和链接成可执行程序后,它们都会被替换成地址。CPU 最终访问内存时需要的是地址,而不是变量名和函数名。下面这张图可以帮助理解这些概念。
变量地址
上面说过,每一个变量都有一个内存位置,每一个内存位置都定义了可访问的地址。在 C++ 中,可以通过 &
取址符获得变量地址,通过 *
解地址符获取指针保存的值。
取地址符(&
)
C++ 提供了取址符(&
)可以获得一个变量的内存地址。示例:
#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++ 提供了解地址符(*
)获取一个内存地址保存的值。示例:
#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; /* 一个字符型的指针 */
实际上,不管是整型、浮点型、字符型,还是其它的数据类型,所有指针的数据类型都一样,都是一个与内存地址长度相同的整数,通常用十六进制表示(例如 0xffee0725
)。
不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同。
C++ 中使用指针
C++ 指针只有五种操作:
1、定义 一个指针变量
int *ptr_a;
2、把变量地址赋值给指针,使用取址符(&
)
int pi = 3.1415926;
int *ptr_pi = π
3、访问指针变量中可用地址的值,使用解地址符(*
)
int pi = 3.1415926;
int *ptr_pi = π
std::cout << *ptr_pi;