c语言中再议运算符:箭头运算符“->“、结构体成员访问运算符“.“、数组元素访问运算符“[]“ 最近我在看linux内核源码程序里面有大量代码使用了箭头运算符-、结构体成员访问运算符.、数组元素访问运算符[]以及这些运算符结合使用的代码有了一些心得可能不是很准确现在先记录下来。1箭头运算符-箭头运算符-前后的变量在物理内存上是不相连的也就是内存地址是不相连的这个比较容易理解因为箭头运算符是为了实现一个通过一个结构体指针变量来读写访问执行这个结构体变量的内部成员。我们来分析一下这句话首先存在一个结构体指针的四字节变量里面存储了一个结构体变量的地址这个地址为结构体首元素的首地址这个结构体指针变量所在位置地址是在不与真正结构体变量相邻的地方例如最常见的就是使用malloc()类似函数实现堆内存变量定义并将定义的内存变量的地址赋值给了一个例如在栈上的临时指针变量。一个在堆上一个在栈上从物理角度看两个地址是不相邻的。2结构体成员访问运算符.、数组元素访问运算符“[]”之所以将上面2个运算符一起讲解是因为两者存在相同之处也就是都是实现一个大变量内部内部一个元素的访问。结构体的概念和数组的概念存在很多一致性。结构体是内部成员类型不同的数组数组是内部成员类型相同的结构体。我们分析“内部成员”这个概念的含义从物理内存上看无论是结构体的内部成员还是数组的内部元素都是在内存上紧密相邻的不是一个在这个地方另外一个在另外一个地方内部成员都是挨个相邻的。结构体成员访问运算符可以这样分析首先它是一个双目运算符运算符前面的变量是代表这个结构体整体运算符后面代表结构体整体肚子内部一个小的成员。结构体成员访问运算符的目的是实现对这个成员变量的读写访问使用成员的内存空间或者使用成员内存空间中的数值。相邻的访问方式是最简单最高效的。数组元素访问运算符可以这样分析首先它也是一个双目运算符虽然[]是由两部分组成的但是一直是作为一个整体使用的可以看做一体。运算符前面的表示数组这个整体是一个比较大的概念运算符[]内部代表数组这个整体内部的某一个元素为什么使用索引值这个数字呢因为数组中每一个元素类型相同占用内存空间相同因此具有相同属性只是在内存中存储位置不同因此可以使用数字表示这个元素。现实中常见的就是部队士兵报数这个道理是一样对的。数组元素访问运算符[]的目的是实现对数组内部元素的访问要么使用内部元素的内存空间也么使用内部元素内存空间中的数值。数值是一种更加间接、高效的特殊结构体。3c语言中的搜索的接续性结构体成员访问运算符、数组元素访问运算符写出的代码本事就有很好的接续性比较容易理解。我的意思是从相对地址这个概念思考内部成员的访问。首先结构体变量名代表一个绝对地址成员变量代表一个相对地址绝对地址相对地址就是内部成员的绝对地址有了地址就能实现对成员变量的访问。数组也是类似的概念数组名表示一个绝对地址运算符内部的索引值表示一个相对地址数组绝对地址索引相对地址就找到了数组元素的绝对地址就可以实现对数组元素的访问。我不知道大家使用箭头运算符-的时候会不会有这样的疑问感觉少了一个结构体整体这样的一个中间元素这样的感觉。结构体指针变量存储的是结构体这个整体的地址通过它找到的应该是对应的结构体变量名然后在通过内部成员对应相对地址找到成员变量的绝对地址然后实现访问。正确的连续的访问流程应该是这样但是箭头运算符-后面根本没有结构体整体这个变量而是直接跟着结构体内部成员变量名。c语言在设计箭头运算符-的时候为什么没有体现真正的结构体变量名而是选择忽略呢我的答案是有时候根本不知道真正结构体变量名或者没有直接给出结构体变量名还是刚才的例子使用malloc()函数分配堆内存分配的这个堆内存结构体变量是没有真正名字的如果按照那种写法是没法继续写的因此c语言在设计箭头运算符的时候选择直接忽略最终结果也是接续的没问题的。我们从绝对地址相对地址的角度出发箭头运算符忽略结构体变量名是没问题的因为绝对地址和相对地址都知道了就是能事项对内部成员的访问。