0%

C/C++中几个易混淆的点

数组指针&指针数组

参考:https://www.cnblogs.com/mq0036/p/3382732.html,两者内存分布写的很详细。

数组指针

定义int (*p)[n];

()优先级比[]高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。

如要将二维数组赋给一指针,应这样赋值:

1
2
3
4
int a[3][4];
int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。
p = a; //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0]
p++; //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]

所以数组指针也称指向一维数组的指针,亦称行指针。

指针数组

定义int *p[n];

[]优先级比*高,先与p结合成为一个数组,再由int说明这是一个整型指针数组,它有n个指针类型的数组元素。这里执行p+1时,则p指向下一个数组元素,这样赋值是错误的:p=a;因为p是个不可知的表示,只存在p[0]、p[1]、p[2]…p[n-1],而且它们分别是指针变量可以用来存放变量地址。但可以这样 p=a; 这里*p表示指针数组第一个元素的值,a的首地址的值。
如要将二维数组赋给一指针数组:

1
2
3
4
5
int *p[3];
int a[3][4];
p++; //该语句表示p数组指向下一个数组元素。注:此数组每一个元素都是一个指针
for(i=0;i<3;i++)
p[i] = a[i];

这里int *p[3] 表示一个一维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2],所以要分别赋值。

常量指针&指针常量

指针常量

定义int * const p = &a;

p是个常量,p的类型是int,所以p的值不能改变,但是\p的值可以改变。

常量指针

定义const int * p = NULL;

p是个常量,p的类型是int\,所以*p的值不能改变,但是p的值可以改变。利用这个特性,在函数传参时使用常量指针可以防止函数对变量值的误修改。

常量指针常量

定义const int * const p = &a;

p是个常量,p也是个常量,p的类型是int\,所以*p的值不能改变,p的值也不能改变。

引用&常量引用

引用

定义int& r = a;

C++ 引用,引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。

函数可以通过引用传参,void foo(int &a){a = 1;}修改引用形参可以改变实参。

常量引用

定义const int& r = a;

函数可以通过常量引用传参,void foo(const int &a) {;}只能读取a,不能修改a。利用这个特性,在函数传参时使用常量指针可以防止函数对变量值的误修改。

函数指针&指针函数

函数指针

定义函数指针void (*pFun)(int a, int b);

定义函数void Fun(int a, int b) {;}

将Fun函数的首地址赋给指针变量pFunpFun = Fun;也可以是pFun = &Fun;

通过指针函数调用pFun(1, 2);也可以是(*pFun)(1, 2);

函数指针定义时返回值,参数类型,个数都必须与要指向的函数相同。

指针函数

指针函数是返回类型为指针的函数。

C结构体内存对齐