C语言基础 — 结构体中的.和->的区别与联系
1. 基本功能
这两种方式其实都是结构体成员运算符,两者都具有从左到右的结合性。不同的是:
'.'
是结构体引用成员变量的方式。'->'
是结构体指针引用成员变量的方式。
2. 联系
那么既然有了’.‘这个符号,为什么还要再弄个’->‘符号呢?这不是很麻烦吗?然而,事实并非如此,’->'恰巧是为了我们更好的使用结构体这一有利的工具。请看下面这个小例子。
#include <stdio.h>
struct ptr {
int x;
int y;
};
int main(void)
{
struct ptr s = {3,4}; /*定义结构体s并对其进行初始化*/
struct ptr *sp = &s; /* 定义结构体指针sp,并对其进行初始化,sp指向结构体s */
/* 对成员进行引用*/
printf("s.x = %d\t s.y = %d\n",s.x,s.y);
printf("(*sp).x = %d\t (*sp).y = %d\n",(*sp).x,(*sp).x);
/* 引入'->'符号后,我们使用指针引用结构体成员变量 */
printf("sp->x = %d\t sp->y = %d\n",sp->x,sp->y);
return 0;
}
注意例子中(*sp).x , (*sp).y
必须要这么用,因为结构体成员运算符’.'的优先级比‘*’要高,如果不使用括号,则上面的就变成了*(sp.x),这个编译时会报错的,因为x并不是指针,不能被解引用。
从上面的例子中我们可以很容易的发现,结构体成员运算符’.‘不仅能被结构体使用,也能被结构体指针使用。而结构体运算符’->'只能被结构体指针所使用。
因为(*sp)
和s
是等价的,所以二者都可以使用结构体成员运算符'.'
。那么既然这样为什么C语言中还要在弄出一个’->
'来对结构体成员变量进行引用的呢?
看了上面的例子,我们可以看到当一个结构体指针想要引用结构体成员变量,是非常麻烦的,既要对结构图体指针使用’*
‘符号进行解引用,还要再加一个括号来保证运算符号的优先级。而我们这里只是展示了一级结构体指针,那如果是多级结构体指针呢?我们是不是要加多个这样的符号,还要考虑其结合的顺序。这岂不是非常麻烦,给编程人员造成了很大的困扰。并且结构体指针在C语言中用的非常广泛,于是呢,C语言就提出了一种简写的方式,即提供结构体成员运算符’->
'来方便我们使用。
3. 总结
通过上面的分析,我们可以发现其实结构体成员运算符’->‘只是结构体成员运算符’.'的简化。是为了方便我们在使用结构体指针时对结构体成员变量进行引用。
只是结构体成员运算符’.
‘可以对结构体成员运算符’->
‘进行等价替换。而结构体成员运算符’->
'只能用于结构体指针对结构体成员的引用。
扩展一下,关于使用结构体成员运算符’->'后,运算符优先级的问题,我们可以看下下面几个例子:
*p->str
: 读取的值指针str所指向的对象的值*p->str++
: 先读取指针str指向对象的值,然后再将str加1(与*s++相同)(*p->str)++
: 将指针str指向的对象值加1*p++->str
: 先读取指针str指向的对象的值,然后再将p加1
说明:在所有预算符中,以下四个预算符优先级最高:结构体成员运算符’->
’,结构体成员运算符’.
’,用于函数调用的’()
’,用于下标的’[]
’。