指针问题汇总:指针与const、指向“数组/函数“”的指针、指针数组、函数返回“指针/指向数组的指针”、指针与“地址/引用”。

1 常量指针与指针常量

const char *p1 = "hello";
char *const p2 = "world";

p1是指向常量的指针,叫做常量指针,不能修改常量,只能p1++移动指向不同字母。
1. 对于变量,如int a,可以用指向变量的指针int* ptr,或指向常量的指针const int* ptr。
2. 对于常量,如const int a,只能用指向常量的指针const int* ptr。

p2本身是指针常量,可以指向非常量的字符。但是"hello"这样声明的字符串是存储在只读存储区的,不可修改。

二级指针

1const char p    限定变量p为只读。这样如p=2这样的赋值操作就是错误的。
(2const char *p   p为一个指向char类型的指针,const只限定p指向的对象为只读。这样,p=&a或  p++等操作都是合法的,但如*p=4这样的操作就错了,因为企图改写这个已经被限定为只读属性的对象。
(3char *const p  限定此指针为只读,这样p=&a或  p++等操作都是不合法的。而*p=3这样的操作合法,因为并没有限定其最终对象为只读。
(4const char *const p 两者皆限定为只读,不能改写。
有了以上的对比,再来看二级指针问题:
(1const char **p  p为一个指向指针的指针,const限定其最终对象为只读,显然这最终对象也是为char类型的变量。故像**p=3这样的赋值是错误的,而像*p=? p++这样的操作合法。
(2const char * const *p 限定最终对象和 p指向的指针为只读。这样 *p=?的操作也是错的。
(3const char * const * const p 全部限定为只读,都不可以改写。

2 指向数组的指针

指向元素的指针

int a[5] = {1,2,3,4,5};
int *p1 = a; /a、p1都是指向元素的指针, p1 == a完全等效

char a[6] = "happy";  /字符数组要多声明一个。
string str = "happy";
char* p4 = str; /不能用char类型指针指向string

指向一维数组的指针
也可以说是
①指向指针的指针:因为一维数组名是指向元素的指针,指向一维数组的指针 是 指向“指向int元素的指针”的指针。
②指向二维数组元素的指针:因为二维数组的元素时一维数组。

int (*p2)[5] = &a;  / p2是指向数组的指针,*(*p2 +  3) == 4, p2移动不了。

int vec[3][5] = {{}{}{}};
int (*p3)[5] = vec;  /p4是指向“五个int元素数组”的指针,p3+1则指向第二个数组,p3和vec等价,p3[][]

int (*p4)[5] = new int [3][5];/new也返回一个指针

3 指针数组

指针数组:成员均为指针的数组
int* x[3] 相当于定义了3个int型指针x[0] ,x[1] ,x[2]

int a[5] = { 1,2,3 };
int b[5] = {4,5,6 };
int c[5] = { 7,8,9 };
int* x[3] = { a,b,c }; /x是指针数组

如果是int arr[3][5] = { {}, {}, {} }这样定义的二维数组,元素在内存中是连续的。
在这里插入图片描述
4 指向函数的指针

int abc(int a, int b) {
	.............
}

int (*ptr1)(int, int) = &abc;
//指向函数的指针,其原型函数为形参为两个int型,返回值为int型的函数
int (*ptr1)(int a, int b); /带形参也可以
int (*ptr1)(int, int) = abc; /不加&也可以

指向函数的指针 == 函数名 == 函数的首地址
可以调用 ptr1(5, 3);

5 指针类型的函数(返回值为指针/地址)

注意返回的指针/地址,除非是static类型,不能是fun定义的局部变量,因为局部变量生存期只在fun函数内。

int* fun(int a)

6 this指针

在这里插入图片描述

7 函数返回“指向数组的指针”怎么写

①使用类型别名

typedef int arrT[10]; /array是一个类型别名,表示的类型是含有10个整数的数组,arrT相当于int [10]
using arrT = int[10]; /arrT的等价声明,同第一条
arrT* func(int i);  /func返回一个指向含有10个整数的数组的指针

②普通表示法

int arr[10];
int (*p)[10] = &arr; /p是指向含有10个整数的数组的指针
int (*(func (int i)) [10]; /函数func的返回类型是“指向含有10个整数的数组的指针”
Primer P205

③尾置返回类型 C++11
任何函数定义都可以使用尾置类型返回,但是这种形式对于返回类型比较复杂的函数最有效,比如返回类型是数组的指针或引用。 注意要在原位置放置auto

auto func(int i) -> int (*) [10];

④使用decltype

int odd[] = {1,3,5,7,9};
decltype(odd) *func(int i); /decltype的结果是一个长度为5int数组,加一个*表示该函数返回值是“指向含有5个整数的数组的指针”

8 指针就是地址

指针就是地址,地址就是指针;指针变量是一个变量,它保存了基本类型变量的地址。

int a = 8;
int* p = &a;

变量a保存了8,我们可以说a就是8。
指针p保存了a的地址,我们可以说指针就是地址。

9 引用和指针

引用本质是指针常量解引:char * const ptr; *ptr表示引用,这也解释了引用为什么必须要初始化,且后面无法修改引用。

int a =10; int& r = a;r是a的引用,在编译器底层就已经替换成int *const ptr = &a; r = *ptr,这就解释了为什么变量和引用使用相同的地址&r == &*ptr == ptr == &a

实际上"引用"可以做的任何事情"指针"也都能够做,为什么还要"引用"这东西?
答案是"用适当的工具做恰如其分的工作"。
指针能够毫无约束地操作内存中的任何东西,尽管指针功能强大,但是非常危险。
如果的确只需要借用一下某个对象的"别名",那么就用"引用",而不要用"指针",以免发生意外。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值