我们都知道数组和结构体类型为c语言中的自定义类型,用自定义类型定义的变量其实都类似于“一个包裹”,真正有意义的就是里面的成员,c语言数据处理就是对数组和结构体变量里面的成员进行“读写”访问。
数组变量成员和结构体变量成员的访问从访问方式上看c语言都定义了专门运算符来支撑:
数组成员使用符号"[]"也就是a[i]",结构体成员变量使用符号“.”也就是struct1.member的方式进行访问。结构体成员变量还可以使用一种名为“间接访问”的方式进行访问,而且c语言专门定义了一个运算符“->”来实现。间接访问的意思就是“借助指针(地址常量)偏移量+”或者“指针变量+偏移量”的方式实现。数组成员访问相对的c语言没有定义对应运算符。
结构体成员变量访问需要用到运算符“结构体指针变量(常量)->成员变量名”的方式实现结构体成员变量访问也比较直接,而且运算符“->”避免了我们程序员自己计算偏移量的麻烦,简直是对我们程序员的造福。
除了使用运算符“[]”完成数组成员的访问之外,还可以使用“指针+解引用”的方式实现,a[i]其实是*(p+i)完成同一个数组成员访问的一种“语法糖”,在c语言编程过程中两者是等效的,并且都有使用,今天我们看的例子是以第二种指针+索引值+解引用方式实现。值得注意的是*(p+i)访问成员变量,也利用c语言指针变量偏移的本质需要移动真正变量大小的内存。因此c语言在设计的时候已经都规定好了,因此*(p+i)访问数组成员也不需要程序员自己计算真正偏移多少,十分方便。在编译阶段编译器就自动计算好了。
我们来看一个例子:
首先,我们要知道一个前提,一个变量无论是静态全局变量、动态局部变量、动态堆内存变量要想有意义最起码要有至少一次写入有效数值,并一次读操作,否则没有任何意义。
静态全局变量定义:
uint8_t tab_1024[1024] = {0};静态全局变量写读操作:首先要写入有效数据,然后再读取,否则数据是错误或者脏的,没有任何意义,还可能导致意想不到的错误。
定义了一个全局变量数组,数组成员进行读写访问没有直接使用运算符“[]”,而且在函数Ymodem_Receive()中实现,里面使用了memcpy()函数利用了第二种“*(p+i)”指针变量+索引值+解引用的方式吸入有效数据。
函数Ymodem_Receive()中借助了一个uint32_t类型的普通全局变量RamSource,通过自己计算偏移量得到地址值,然后强制类型转换成指针,最后再以解引用的方式的方式实现了数组成员变量读操作,具体过程请详看上图函数。