A detailed introduction to C++ pointer variable, maybe helpful!!! ?
指针变量
Guderian出品
想获得更佳阅读体验?戳https://g-ss-hacker.github.io/2019/08/05/c-%E6%8C%87%E9%92%88%E5%8F%8A%E5%85%B6%E5%BA%94%E7%94%A8/
指针变量的定义、赋值
对指针变量的类型说明,一般形式为:
类型说明符 *变量名;
其中,*表示这是一个指针变量,变量名即为定义的指针变量名,类型说明符表示该指针变量所指向的变量的数据类型。
1、普通变量定义
int a = 3;
定义了变量a
,是int
型的,值为3。内存中有一块内存空间是放a
的值,对a
的存取操作就是直接到这个内存空间存取。内存空间的位置叫地址,存放3的地址可以用取地址操作符&
对a
运算得到:&a
。
2、指针变量定义
int *p = NULL;
定义了一个指针变量p
,p
指向一个内存空间,里面存放的是一个内存地址。现在赋值为NULL
(其实就是0,表示特殊的空地址)。
3、给指针变量p赋值
p = &a;
即把a
变量的内存空间地址(比如:XXX)给了p
。显然,直接对p
存取,操作的是地址。通过这个地址间接地操作,才是整数3。P的间接操作要使用指针操作符“*”
,即*p
的值才是3。设有指向整型变量的指针变量p
,如要把整型变量a
的地址赋予p
可以有以下两种方式:
①指针变量初始化的方法
int a; int *p = &a;
②赋值语句的方法
int a; int *p; p = &a;
不允许把一个数赋予指针变量,故如下的赋值是错误的:int *p;p = 1000;
。被赋值的指针变量前不能再加“*”
说明符,故如下的赋值也是错误的:*p = &a;
。
说明 | 样例 |
---|---|
指针定义:类型说明符 *指针变量名 | int *p; |
取地址运算符:& | p = &a; |
间接运算符:* | *p = 20; |
指针变量直接存取的是内存地址 | cout<<p; 结果可能是:0x24ae9d |
间接存取的才是存储类型的值 | cout<<*p; 结果是:20 |
指针变量同普通变量一样,使用之前不仅要定义说明,而且必须被赋值具体的值,未经赋值的指针变量不能使用。如定义了int a; int *p = &a;
,则*p
表示p
指向的整型变量,而p
中存放的是变量a
占用单元的起始地址,所以*p
实际上访问了变量a
,也就是说*p
$ \Longleftrightarrow $a
。
【例1】输入两个不同的数,通过指针对两个数进行相加和相乘,并输出。
#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
int a, b, s, t, *pa, *pb;
pa = &a; pb = &b;
a = 10; b = 20;
s = *pa + *pb;
t = *pa * *pb;
printf("a = %d, b = %d\n", *pa, *pb);
printf("s = %d, t = %d\n", s, t);
return 0;
}
输出:
a = 10, b = 20
s = 30, t = 200
指针的引用与运算
一般的,指针(int *p
)与普通变量(int a
)的对应关系为:
指针变量 | 普通变量 |
---|---|
p | &a |
*p | a |
*p = 3 | a = 3 |
以下为指针的一些运算:
1、指针变量的初始化
方法 | 说明 |
---|---|
int *p = NULL; | NULL 是特殊的地址0,叫零指针 |
int a; int *p = &a; | p 初始化为a 的地址 |
int *p = new(int); | 申请一个空间给p ,*p 内容不确定 |
要强调的是,对于定义的局部指针变量,其内容(地址)是随机的,直接对它操作可能会破坏程序或系统内存的值,引发不可预测的错误。所有编程中指针变量要保证先初始化或赋值,给予正确的地址再使用,避免产生*野指针。
2、指针变量的+、-运算
指针变量的内容是内存地址,它有两个常用的运算:加、减,这两个运算一般都是配合数组操作的。
【例2】输入N个整数,使用指针变量访问输出。
#include <cstdio>
using namespace std;
int a[101], n;
int main()
{
scanf("%d",&n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
int p = &a[1]; //定义指针变量int p,初始化为数组开始元素的地址,即a[1];
for (int i = 1; i <= n; i++)
{
printf("%d ", *p);
p++; //p指向下一个数,详见说明
}
return 0;
}
输入:
4
2 1 6 0
输出:
2 1 6 0
【说明】
p++
的意思是“广义的加1”,不是p
的值(地址)加1,而是根据类型int
增加sizeof(int)
,即刚好“跳过”一个整数的空间,达到下一个整数。
类似的:
①p--
就是向前“跳过”一个整数的空间,达到前一个整数。
②(p + 3)
就是指向后面第3个整数的地址。
3、无类型指针
有时候,一个指针根据不同的情况,指向的内容是不同类型的值,我们可以先不明确定义它的类型,只是定义一个无类型的指针,以后根据需要再用强制类型转换的方法明确它的类型。
【例3】无类型指针运用举例。
#include <iostream>
using namespace std;
int a = 10;
double b = 3.5;
void *p;
int main()
{
p = &a; //p的地址赋值
cout<<*(int*)p<<endl; //必须明确p指向的空间的数据类型,详见说明
p = &b;
cout<<*(double*)p<<endl;
return 0;
}
输出:
10
3.5
【说明】
必须明确p
指向的空间的数据类型,类型不一样的不仅空间大小不相同,储存的格式也不同。如果把cout<<*(double*)p<<endl;
改成cout<<*(long long*)p<<endl;
输出的结果将是:4615063718147915776
。
4、多重指针
既然指针是指向其他类型的,指针本身也是一种类型。因此,C++允许递归地指针指向指针的指针——多重指针。
【例4】双重指针运用举例。
#include <cstdio>
using namespace std;
int a = 10;
int *p;
int **pp; //定义双重指针
int main()
{
p = &a; //将p指向a
pp = &p; //将pp指向p
printf("%d = %d = %d\n", a, *p, **pp); //**pp通过2次间接访问了a的变量的值10
return 0;
}
输出:
10 = 10 = 10
【说明】
多重指针可以多次“间接”访问数据;算法竞赛上主要的应用是*动态的多维数组,功能十分强大!!!
结束语
以上就是C++指针变量的用法说明,喜欢的话别忘了点赞、收藏?!