C++中的指针pointer2

Made by Mike_Zhang


所有相关文章:
C++中的指针pointer - 指针的声明, 取地址运算符号, 指针的赋值, 指针运算符
C++中的指针pointer2 - 指针运算, 指向空的指针与空类型指针, 指向常量的指针与指针常量

之前的文章中我已经介绍了C++中指针的基本内容, 包括声明, 取地址运算符号, 赋值和运算符. 接下来我会介绍指针运算, 指向空的指针与空类型指针, 指向常量的指针与指针常量.

指针运算

指针运算就是对指针地址进行运算. 指针经过运算后, 其内存指向(地址)可能会发生变化, 其指向内存的内容(原值)也可能会发生变化. 以下举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
using namespace std;
int main(){
int a = 10;
int * p = &a; //定义指针并赋值
printf("%d, %d\n", p, *p);
p++; //指针自加运算
printf("%d, %d\n", p, *p);
p++; //指针自加运算
printf("%d, %d\n", p, *p);
p--; //指针自减运算
printf("%d, %d\n", p, *p);
}

输出结果:
1
2
3
4
-446765300, 10
-446765296, -446765280
-446765292, 32766
-446765296, -446765280

由此发现, 指针运算后会使指针地址变化, 相对应的指向内存的内容也会发生变化, 但是内存内容的变化规律是和地址变化规律没有直接联系的. 另外, 指针进行加1运算后, 其地址的值并不是简单的加一, 而是而是加上一个变量对应类型的字节宽度, int对应的宽度就是sizeof(int), 也就是4. long类型宽度就是sizeof(long), 也就是8. 举例:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
using namespace std;
int main(){
long a = 10;
long * p = &a;
printf("%d, %d\n", p, *p);
p++;
printf("%d, %d\n", p, *p);
p++;
printf("%d, %d\n", p, *p);
p--;
printf("%d, %d\n", p, *p);
}

输出结果:
1
2
3
4
-369174776, 10
-369174768, -369174752
-369174760, 540288561
-369174768, -369174752


指向空的指针与空类型指针

指向空的指针

指向空的指针表示为:

1
void* p;

指向空的指针是有指向的, 即指向空类型void, 但是在后期使用时可以给其赋值不同类型的数据. 举例:
1
2
3
4
5
6
7
8
9
#include <iostream>
using namespace std;
int main(){
int a = 10;
int * p = &a;
void* p1 = NULL; //定义指向空的指针
p1 = p; //给指向空的指针重新赋值指向
cout << p1 << endl;
}

空类型指针

空类型的指针是指未初始化的指针, 不能直接使用, 需要赋值后才能使用, 在编写代码时需要注意. 举例:

1
2
3
4
5
6
7
8
#include <iostream>
using namespace std;
int main(){
int* p2 = NULL; //定义空类型指针, 未初始化, 不能直接使用
int b = 20;
p2 = &b; //初始化p2
cout << p2 << endl;
}


指向常量的指针与指针常量

指向常量的指针

指向常量的指针(pointer-to-const)说明指针内存指向的内容是一个常量, 使用const关键字表示, 如下:

1
2
int a = 10;
int const *p = &a;

其中指针内存指向的内容(p)是一个常量, 其无法修改内存数据, 也就是a, 做到了“只读”.
但是我们可以修改p, 也就是内存指向(地址). 举例如下:
1
2
3
4
5
int a = 10;
int b = 20;
int const *p = &a;
p = &b; //允许
*p = 20; //报错

总的来说, 使用指向常量的指针(pointer-to-const)可以防止我们改变指针指向的内容(
p), 做到“只读”, 但是不能防止我们改变指针的内存指向(地址p). 指向常量的指针也称常量指针.

指针常量

指针常量(const pointer)说明这个指针本身是一个常量, 使用const关键字表示, 如下:

1
2
int a = 10;
int* const p = &a;

其中指针p是常量, 其无法修改, 也就是说我们无法修改它的内存指向, 也就是地址.
但是我们可以修改p, 也就是说我们可以修改指针指向内存的内容. 举例如下:
1
2
3
4
5
int a = 10;
int b = 20;
int* const p = &a;
p = &b; //报错
*p = 20; //允许

总的来说, 使用指针常量(const pointer)可以防止我们改变指针的内存指向(地址p), 但不可以防止我们改变指向内存的内容(
p).

两者可以用一张图总结:
Pointers-to-const and const pointers
图源: Prata S - C++ Primer Plus 6th Edition - 2011

指向常量的指针常量

指向常量的指针常量, 它的指针指向(地址p)以及它内存指向的内容(*p)都是常量, 都不能改变, 如下:

1
2
int a = 10;
int const * const p = &a;


引用:
Prata S - C++ Primer Plus 6th Edition - 2011


写在最后

本文介绍了指针运算, 指向空的指针与空类型指针, 指向常量的指针与指针常量, 之后会继续更新.
最后,希望大家一起交流,分享,指出问题,谢谢!


原创文章,转载请标明出处
Made by Mike_Zhang




感谢你的支持

C++中的指针pointer2
https://ultrafish.io/post/cpp-pointer2/
Author
Mike_Zhang
Posted on
December 6, 2020
Licensed under