C 语言中,「.」与「->」有什么区别?
问题
C 语言中的.
和->
两种操作符,除了表达形式有些不同,功能几乎是完全一样,有时候又让人分不清,怎么回事呢?
说出下面的不同
1 | // 1 |
这是会被编译器警告的
unnamed struct/union that defines no instances
这是常规的结构体定义
这是使用
typedef
为一个匿名结构体起了别名Msg
,并为这类结构体的指针
起了别名Msgptr
和 3 一样,但是结构体多了个名字
但其实编译器不会认这个结构体的名字
为什么要说这个呢,因为要区分.
和->
的关键,就在于它们跟在结构体
还是结构体的指针
的后面
举个例子
我定义了一个嵌套结构
1 | typedef struct { |
那么我该怎么用这个定义好的结构?
声明变量
以下都是有效的结构体声明,他们本质上是同一类结构体
1 | // Structures |
以下都是有效的指针,指向一段被看作是Msg
类型的内存空间
1 | // Pointers |
区分用法
首先,最直观的区分就是两者跟在不同的变量后
.
用在结构体
后面->
用在结构体的指针
后面
知乎的一个高赞回答,也是这样的说法:
- 编译器会将
p->member
变成访问p+offset_member
这个内存地址的变量 - 编译器会将
s.member
变成访问&s+offset_member
这个内存地址的变量
如下代码证明第一条是正确的:
1 | Msgptr ptr = malloc(sizeof(Msg)); |
指针加法会一次增加指向的变量的类型的单位大小
,如整形是 4 字节。这里转为void
类型则每次增加 1 字节
如下代码可以验证第二条:
1 | Msg structMsg = {1,{"bkft",21}}; |
参考
C 语言中,「.」与「->」有什么区别?