今天去面试 面试官问我 a->b 跟 a.b有啥区别,我说第一个是通过指针去访问成员,第二个是点语法去访问 ,一般用在结构体变量去访问其内部成员b 是通过指针偏移去查找的
typedef struct Student {
int age;
char *name;
}
Student *st1;
Student *st2;
变量名只是结构体首元素的地址
st1->age 是指针从0位置 取出4个字节 就是 age 的内存地址(int类型 4个字节)
st1->name 是指针跳过前4个字节 取出 name 所在的4个字节的内存
st1.age 是指针从0位置 取出4个字节 就是 age 的内存地址(int类型 4个字节)
st1.name 是指针跳过前4个字节 取出 name 所在的4个字节的内存
当时回答的是通过a->b ,a.b是两种不同的访问方式 属于编译器语法,访问结构体内部成员本质就是通过首地址偏移去访问内部成员.
下边通过汇编代码来解释a->b 和 a.b 的区别
mov dword ptr [ebp-8] , eax 从 eax( *st 所指向内存) 寄存器里取出4个字节 存放到 ebp-8里边
mov dword ptr [ebp-0Ch] , eax 从eax寄存器重取出4个字节数据 放到 ebp-0Ch里边
从汇编代码可要看出来 a->b ,a.b 没有本质区别 都是从内存里取出4个字节的数据 ,找到 b 所在内存
如果要通过st->name 汇编代码又是怎么样子呢?
mov dword ptr [ebp-10h],eax ==> st1->age
mov dword ptr [ebp-0Ch],eax ==> st1->name
[ebp-10h] st1->age的地址值 十进制16对应的是十六进制 10 所以这里是ebp-10h
[ebp-0Ch] st1->name的地址值 十进制12对应对应十六进制C 所以这里是ebp-0Ch
可以看出来 从st1->name 到st1->age 是相差4个字节的,所以结构体访问其成员变量就是通过指针地址偏移完成的
从汇编上看a->b 和 a.b 本质是一样的 都是通过eax取出4个字节 放到一个内存地址里 这个内存地址 根据在结构体里成员属性的位置而不同