首先两者的功能是一致的,都用于访问结构体或类的成员。
两种运算符优先级也相同。
通常情况下,结构体变量用「.」来访问成员,而结构体指针用「->」来访问。
struct Vec {
int x;
int y;
}
struct Vec vec0 = {1, 2};
struct Vec vec1 = {3, 4};
struct Vec* pVec = &vec0;
我们可以知道:
如果要访问vec1的x,可以有:vec0.x 和 pVec->x 以及 (pVec).x三种方式。
可以看出 -> 和 ( ). (注意这里有个点)是完全等效的,且「.」完全包含了「->」的功能。
换句话说,去除「->」运算符对程序的功能完善没有任何影响,加入「->」的作用仅仅是简化我们的代码。
当多级指针和&地址运算符嵌套出现,有时候很难分清到底是用「.」还是「->」。
我们可以通过指针等级来判断。
从最开始的结构体变量,设为"0级指针",结构体指针为1级指针。
「&」运算符使用后指针等级+1;
「」运算符使用后-1;
「[]」运算符使用后也会-1,x[5] 等效于 (x+5);
「->」运算符可以看成指针等级先-1,再使用「.」运算符;
当变量的指针等级为0时,就可以使用「.」运算符,直接其访问成员。
struct Vec {
int x;
int y;
Vec* arry[2];
}
struct Vec vec0 = {1, 2};
struct Vec vec1 = {3, 4};
// 前者定义的是1级指针;后者的vec0是"0级",通过&等级+1后,两者等级相同,可以赋值
struct Vec* pVec0 = &vec0;
struct Vec* pVec1 = &vec1;
// 定义一个指针数组
struct Vec* arryVec[2];
// 前者是指针数组的一个元素,即1级指针;后者也为1级指针
arryVec[0] = pVec0;
// 前者是1级指针;后者的vec1是"0级",通过&等级+1
arryVec[1] = &vec1;
// arryVec是指针数组,属于2级指针,使用[]后降为1级,可以用->直接访问x,也可用*降级后访问
cout<< arryVec[0]->x <<endl;
cout<< (*arryVec[0]).x <<endl;
// arryVec值+1表示地址+1,从arryVec[0]的地址变成arryVec[1]的地址;
// arryVec是2级指针,2次*后变成"0级",可以用.直接访问arry成员;
// 而arry成员是个2级指针,通过[]等级-1后为1级,与pVec0正好相等,可以赋值。
(**(arryVec + 1)).arry[0] = pVec0;