指针的声明
int *p,q
会声明一个int*和一个int使用new int []声明内存要用delete []释放
不能使用sizeof()获取动态分配的数组包含的字节数
- 对指针使用sizeof()获取的是指针的长度
指针和数组名
指针和数组名一定程度上是等价的,但是指针的值可以改变,数组名的值是不能改变的
数组名将被解释成首元素地址,但是对数组名取地址将会得到整个数组的地址
array
和&array[0]
等价,相当于是指向n个元素的第一个&array
指向这个数组,相当于指向这n个元素,向后移动将直接移动size个元素,所以*(&array)
将和array
等价
给cout一个
char*
,cout将会打印字符串,要打印指针的值,可以将其转化成int*
一些UB:
- 有些古老的编译器会将字符串字面值视为只读常量,修改会造成RE。C++的标准中将会把所有字符串字面值视为常量
- 有些编译器会只使用字符串字面值的一个副本表示所有的字符串字面值(也就是所有的字符串字面值”abc”可能只存一或多份(数量不固定),修改这个副本可能会影响其他的字符串字面值的值)
const指针
防止传递地址造成原始数据被破坏,使用const修饰符(不能通过const指针改变其指向的地址的值)
int * const p,p指向的地址不能改变
关于const指针的一些特性
- const指针只表示不能通过该指针修改指向的地址的值
- const指针可以接收const int、int类型的数据,非const指针不能接收const int数据(否则等于直接允许通过指针修改const变量)
二位数组
a[n][m]
,a相当于一个有n个元素的数组,每个元素指向一个有m个元素的数组,则a的类型是int (*a)[m]
表示一个指向m个元素的数组的指针,如果写成int *a[m]
表示的是m个指向int的指针的数组,使用a时需要解除引用两次C++可以返回字符串的首地址,后续可以访问该地址的字符串,但是要注意指针的释放
读取一行字符串getline(cin,s)
函数指针
函数指针:函数名就是函数地址
声明函数指针:
1
2int func(int a);
int (*p)(int) = func;加括号,保证优先级正确,否则
int *p(int)
会是一个返回int *
的函数通过指针调用函数
1
2p(1); // 函数名和函数指针都指向地址,行为应当一致
(*p)(1); // *p代表指向的函数,可以使用*p调用声明函数指针数组
1
int (*p[N])(int) = {f1,f2,f3,...}
p[N]
创建N个元素的数组,其余部分指示数组中元素类型声明指向整个数组的指针
1
2auto tb = &ta;
int (*(*a)[N])(int) = &ta