C++指针变量

指针变量

Guderian出品

指针变量的定义、赋值

对指针变量的类型说明,一般形式为:

类型说明符 *变量名;

其中,表示这是一个指针变量,变量名即为定义的指针变量名,类型说明符表示*该指针变量所指向的变量的数据类型

1、普通变量定义

int a = 3;

定义了变量a,是int型的,值为3。内存中有一块内存空间是放a的值,对a的存取操作就是直接到这个内存空间存取。内存空间的位置叫地址,存放3的地址可以用取地址操作符&a运算得到:&a

2、指针变量定义

int *p = NULL;

定义了一个指针变量pp指向一个内存空间,里面存放的是一个内存地址。现在赋值为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】输入两个不同的数,通过指针对两个数进行相加和相乘,并输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#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;
}

输出:

1
2
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个整数,使用指针变量访问输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#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;
}

输入:

1
2
4
2 1 6 0

输出:

1
2 1 6 0

【说明】

p++的意思是“广义的加1”,不是p的值(地址)加1,而是根据类型int增加sizeof(int),即刚好“跳过”一个整数的空间,达到下一个整数。

类似的:

p--就是向前“跳过”一个整数的空间,达到前一个整数。

(p + 3)就是指向后面第3个整数的地址。

3、无类型指针

有时候,一个指针根据不同的情况,指向的内容是不同类型的值,我们可以先不明确定义它的类型,只是定义一个无类型的指针,以后根据需要再用强制类型转换的方法明确它的类型。

【例3】无类型指针运用举例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#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;
}

输出:

1
2
10
3.5

【说明】

必须明确p指向的空间的数据类型,类型不一样的不仅空间大小不相同,储存的格式也不同。如果把cout<<*(double*)p<<endl;改成cout<<*(long long*)p<<endl;输出的结果将是:4615063718147915776

4、多重指针

既然指针是指向其他类型的,指针本身也是一种类型。因此,C++允许递归地指针指向指针的指针——多重指针。

【例4】双重指针运用举例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#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;
}

输出:

1
10 = 10 = 10

【说明】

多重指针可以多次“间接”访问数据;竞赛上主要的应用是*动态的多维数组,功能十分强大!!!

本文标题:C++指针变量

文章作者:G-SS-Hacker

发布时间:2019年08月05日 - 21:15:09

最后更新:2020年02月20日 - 12:21:13

原始链接:https://G-SS-Hacker.github.io/c-指针及其应用/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。