C语言结构体中,使用「.」和「->」的区别

C语言结构体访问成员,「.」和「->」分别什么时候用呢

相同点

首先两者的功能是一致的,都用于访问结构体或类的成员。

两种运算符优先级也相同。

不同点

通常情况下,结构体变量用「.」来访问成员,而结构体指针用「->」来访问。

两者的联系

我们先定义一个结构体Vec,再定义几个结构体变量和指针:

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;

通过这种指针等级的判断,可以很快判断出某个变量可以用什么运算符访问成员;也可以判断两个变量是否同级,来进行赋值。
当然,并不是同级的变量可以任意赋值,还要考虑其他的因素,如是否存在野指针,访问是否越界的此类的情况。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值