指针的概念
指针是一种特殊的数据类型,用于存储变量的内存地址而非直接存储值。通过指针可以间接访问或操作内存中的数据,常用于动态内存分配、数组操作和函数参数传递等场景。
1 2
| int var = 10; int *ptr = &var;
|
动态内存管理:通过指针可以在程序运行时动态分配或释放内存(如malloc
和free
)。
1 2
| int *arr = (int*)malloc(5 * sizeof(int)); free(arr);
|
高效数据传递:函数参数传递指针可避免数据复制,提升性能。如下面代码所示
1 2 3 4 5
| void modify(int *x) { *x = 20; } int main() { int a = 10; modify(&a); }
|
Tips:
未初始化的指针可能指向非法内存,导致崩溃。指针的字节固定为4字节或者8字节(根据操作系统确定)。如int是4字节,char 是1字节,double是8字节;但是对于指针来说char *,和int *,double *都是4字节。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #include <iostream> using namespace std;
class A { int ma_; int mb_; int mc_; }; int main() { cout << "sizeof(char) :" << sizeof(char) << endl; cout << "sizeof(int) :" << sizeof(int) << endl; cout << "sizeof(double) :" << sizeof(double) << endl; cout << "sizeof(class A):" << sizeof(A) << endl;
cout << "sizeof(char *) :" << sizeof(char *) << endl; cout << "sizeof(int *) :" << sizeof(int *) << endl; cout << "sizeof(double*):" << sizeof(double*) << endl; cout << "sizeof(class A *) :" << sizeof(A *) << endl; return 0; }
|
打印的结果为:
![image]()
其实也很好理解,指针本质是内存的地址,对于32位系统来说,指针的长度为4字节;对于64位系统来说,指针的长度为8字节。
const关键字
const
是C/C++语言中的一个重要关键字,用于定义常量,表示该变量的值在程序运行期间不能被修改。const
关键字可以应用于变量、函数参数、函数返回值以及成员函数。
const特点:
- 不可变性:
const
变量的值一旦初始化后就不能再被修改(定义时初始化)
- 编译期检查:编译器会在编译时检查对
const
变量的修改操作,并报错
- 类型安全:
const
提供了额外的类型安全保证
以下是const使用过程中可能出现的错误:
1.const常量不能再作为左值,(不然会直接修改常量的值),如:
2.不能把常量的地址泄露给一个普通的指针或者引用变量(不然会间接的修改常量的值),只能传给const类型的指针或变量
1 2 3 4 5 6 7
| const int a=10; int *p=&a;
*p=20;
const int *p=&a;
|
判断const修改的类型
C++中const修饰符的规则如下
:const修饰的是与其最近的表达式(需先去除类型说明符如int、int*)并且遵循最少原则:在int*和int之间优先选择int。去除类型说明符后的表达式即表示该部分不可修改。
const和一级指针
常量指针
见代码:
1 2 3 4 5 6 7 8
| int a=10; int b=100; const int *p=&a; int const *p=&a;
*p=20; p=&b;
|
该指针可以指向不同的int类型的内存地址,但不能通过指针间接修改所指向内存的值。
指针常量
代码如下
1 2 3 4 5 6 7 8
| int a=10; int b=100;
int * const p=&a;
p=&b; *p=20;
|
const修饰失效
注意
:当const 右边没有指针符号*时,const不参与类型定义。
1 2 3 4
| int * q1=nullptr; int *const q2=nullptr; int const *q3=nullptr;
|
const和二级指针的组合
指向常量的二级指针
1 2 3 4 5
| int x = 10; const int* p = &x; const int** pp = &p;
|
- 表示指向一个指向常量的指针的指针
- 可以通过二级指针修改一级指针的指向,可以修改二级指针
- 但不能修改最终指向的值
![image]()
指向指针常量的二级指针
1 2 3 4 5
| int x = 10; int* const p = &x; int* const* pp = &p;
|
- 表示指向一个指针常量的指针
- 不能通过二级指针修改一级指针的指向
- 但可以修改一级指针指向的值,可以修改二级指针
![image]()
二级指针常量
1 2 3 4 5 6
| int x = 10; int* p = &x; int** const pp = &p;
|
- 表示二级指针本身是常量
- 不能修改二级指针的指向
- 但可以修改一级指针的指向及其指向的值
![image]()
完全常量二级指针
- 表示指向一个指向常量的指针常量的指针
- 既不能修改一级指针的指向,也不能修改最终指向的值
![image]()
总结 const 和 指针的类型转换公式
在C++中,指针和const的组合使用需要注意类型转换的规则。以下是总结的一些转换方式:
一级指针转换
1 2 3 4 5 6 7 8 9
| int * <<<=== const int * ;
const int * <<<=== int *;
int a = 10; int *pa = &a; const int *cpa = pa;
|
二级指针转换
1 2 3 4 5 6 7 8 9 10 11
| int ** <<<=== const int **; const int **<<<=== int **;
int ** <<<===int * const *;
int * <<<===int const *;
int *const *<<<=== int **;
int const *<<<=== int *;
|
以下是一些转换的错误样例
错误样例
1 2 3
| int a=10; const int *p=&a; int *q=p;
|
1 2 3
| int a=10; int *p=&a; const int **q=&p;
|
1 2 3 4
| int a=10; int *const p=&a; int **q=&p;
|
1 2 3
| int a=10; const int *p=&a; int *const*q =&p;
|
指针与数组结合
数组指针
1 2 3 4 5 6 7 8 9 10 11
|
int a=10; int *pa=&pa;
int arr={1,2,3}; int (*pa) []=&arr;
|
指针数组
1 2 3
| int a=10,b=20,c=30; int *arr[]={&a,&b,&c};
|
指针与函数结合
函数指针
指针函数