本文章简介:C/C++语言的指针对于初学者来说一直以来都是一个头痛的问题,非常难于理解,本文通过举例子,打比喻的方式,将指针用通俗易懂的语言进行描述,请抽点时间认真阅读,你会发现其实指针也没有那么难。
在C/ C++ 中,指针是一个非常重要的概念,它存储了另一个变量的内存地址。通过指针,我们可以直接访问和修改某个内存变量所在的内存地址中的数据,这为程序提供了更高的灵活性和效率。
一、指针相关的基本概念
1、 指针(Pointer)
指针本质上就是内存地址,是内存单元的唯一标识,是一个具体的数值(如:0x7FF6),代表内存中的某个位置。
任何变量、数组、结构体、函数等等在内存中都有对应的地址,这个地址其实就是指针。可以这么理解:C/C++对变量、数组的引用,对函数的调用等等,其实都是通过地址访问进行的。
例如
int a = 10;
当定义变量a时,变量a在内存中占据一块空间,这块空间的地址就是a的指针。
接下来我们做一个比喻来进行说明:内存的地址在计算机中是连续存储的,目前我们有一个1M的内存,内存的地址范围是:0x00000~0xFFFFF,每一个内存地址可以存放一个数据,我们可以把每一个地址(指针)看作是每一个房间号,每个房间住着的人就相当于内存中存储的数据,也就是说每个房间号就是这个房间的“指针”,每个房间住的不同的人就是内存中存储的不同的数据,我们要想找到不同的人(内存中的数据),只要找到这个人的房间号(指针)就可以找到这个人。
2、 指针变量(Pointer Variable)
指针变量用于存储内存地址的变量,主要功能是存储另一个变量的内存地址,而不是直接存储数据值。
详细说明:
指针变量是专门用来存储指针(内存地址)的变量,它本身也占据一定的内存空间。
指针变量的类型必须与它所存储的地址对应的变量类型一致(或兼容)。
通过指针变量,可以间接操作它所存储的地址对应的变量。
指针变量必须明确指向某种数据类型(如 int、char 等)的变量地址
举例说明:
int a = 10; // 普通变量a,存储值10
int *p; // 声明一个int类型的指针变量p
p = &a; // 将a的地址赋值给p,p现在指向a
printf(“%d”, *p); // 通过指针p访问a的值,输出10
*p = 20; // 通过指针p修改a的值
printf(“%d”, a); // 此时a的值已变为20,输出20
在上面的代码中:
&a 表示取变量 a 的内存地址
*p 表示访问 p 所指向的变量(称为 “解引用”)
p 本身存储的是 a 的地址
指针与指针变量的区别:
指针是内存地址的统称(是 “值”),可以将指针理解为 “指向变量的路标”。
指针变量是存储这种地址的变量(是 “容器”),普通变量存储的是实际数据(如整数、字符等),指针变量存储的是某块内存的地址,通过这个地址可以找到对应的变量。
指针变量就是 “存放指针的变量”,通过指针变量可以方便地操作它所指向的内存中的数据,间接操作它所指向的变量的值。
3、取地址:获取变量的内存地址,通过取地址运算符“&”获取内存地址。
作用:获取变量在内存中的地址(指针)。
操作对象:必须是一个已定义的变量(不能对常量或表达式使用)。
返回结果:该变量的内存地址(指针值)。
举例说明:
int a = 10;
int *p;
p = &a;
将变量a的地址赋值给指针变量p,此时p中存储的是a的地址,可理解为"p指向a"
这里&a的结果是变量a的内存地址(比如0x7ffd),这个地址被存储到指针变量p中。
4、取指针存储的数值:通过解引用运算符“*”获取指针存储的数值。
作用:通过指针变量所存储的地址,访问该地址对应的变量,即 “找到指针指向的目标”的值。
操作对象:必须是一个指针变量(存储了有效地址的变量)。
返回结果:指针所指向的变量的具体的内容(数值),可以对其进行读写操作。
举例说明:
int a = 10;
int *p = &a;
printf(“%d”, p); // 输出10,通过p的地址找到a并读取其值
p = 20; // 通过p的地址找到a并修改其值为20
printf(“%d”, a); // 输出20,a的值已被修改
这里p表示“p 所指向的变量”(即a),通过可以间接操作a的值。
形象比喻
“&变量”就像“给物品贴标签”,标签上写着物品的位置(地址)。
“指针”就像“按标签找物品”,根据标签上的位置找到并操作物品本身(例如修改变量的值)。
通过&和的配合,就能完成“获取地址→存储地址→通过地址操作变量” 的完整指针使用流程。
感兴趣的可以在计算机中实际运行下面的程序,体会一下指针、指针变量和地址之间的关系。
#include
using namespace std;
int main() {
int num = 100; // 声明一个整数变量
int *ptr; // 声明一个指向int类型的指针
ptr = # // 将num的地址赋值给指针ptr
cout << "变量num的值: " << num << endl;
cout << "变量num的地址: " << &num << endl;
cout << "指针ptr存储的地址: " << ptr << endl;
cout << "指针ptr指向的值: " << *ptr << endl; // 解引用操作
// 通过指针修改变量的值
*ptr = 200;
cout << "修改后num的值: " << num << endl;
return 0;
}
二、指针的常见操作
动态内存分配
int *p = new int; // 分配一个int
*p = 100;
int *arr = new int[10]; // 分配数组
delete p; // 释放单个对象
delete[] arr; // 释放数组
void指针
void *vp;
int a = 10;
vp = &a; // 可以指向任何类型
空指针:不指向任何有效内存地址的指针
int *ptr = nullptr; // C++11引入的空指针常量,推荐使用
int *ptr = NULL; //老式写法
指针算术运算:指针可以进行加减运算,移动的字节数取决于指针类型
int arr[] = {10, 20, 30, 40, 50};
int *p = arr; // 指向数组第一个元素
cout << *p << endl; // 输出10,指针此时指向数组的第一个元素
cout << *(p + 1) << endl; // 输出20,指针此时指向数组的第二个元素
cout << *(p + 2) << endl; // 输出30,指针此时指向数组的第三个元素
p++; // 指针向后移动一个int大小的位置
cout << *p << endl; // 输出20
指针使用注意事项
未初始化的指针(野指针)非常危险,可能导致程序崩溃
指针使用完毕后,应及时设置为nullptr,避免悬空指针
不要访问已释放的内存
指针运算时要确保不超出有效内存范围
不同类型的指针不能直接赋值(需要显式类型转换)
总结:指针到底是什么?
答曰:指针就是地址,C/C++中的任何“东四”(变量、函数名、数组名等等)都有地址,想进行什么操作,只要知道当前指针存储的是什么东西的地址,也就可以对相关的内容进行操作了。
1024





