1.动机:前段时间,一直有个疑问,就是编译器是从哪里知道数据的类型的,数据的类型是存在内存里面的么,因为自己调试编译器,发现内存中并没有多余的数据,后来在群上发问,才知道数据在编译成汇编的过程就知道数据的类型了,也就是数据的类型识别时在内存代码区里
观察代码
#include<stdio.h> #include<string.h> struct data{ short a; long b; long long c; float e; double f; double g; bool h; char i; }; int main(){ data temp; temp.a=1; temp.b=2; temp.c=3; temp.e=4; temp.f=5; temp.g=6; temp.h=7; temp.i=8; }
在汇编里
data temp; temp.a=1; 004113BE mov eax,1 004113C3 mov word ptr [temp],ax temp.b=2; 004113C7 mov dword ptr [ebp-30h],2 temp.c=3; 004113CE mov dword ptr [ebp-2Ch],3 004113D5 mov dword ptr [ebp-28h],0 temp.e=4; 004113DC fld dword ptr [__real@40800000 (41575Ch)] 004113E2 fstp dword ptr [ebp-24h] temp.f=5; 004113E5 fld qword ptr [__real@4014000000000000 (415750h)] 004113EB fstp qword ptr [ebp-1Ch] temp.g=6; 004113EE fld qword ptr [__real@4018000000000000 (415740h)] 004113F4 fstp qword ptr [ebp-14h] temp.h=7; 004113F7 mov byte ptr [ebp-0Ch],1 temp.i=8; 004113FB mov byte ptr [ebp-0Bh],8 }
可以明显观察到short是word,int 是dword,long long是dword。。。
但是,问题又来了,int 与float都是dworld,char与bool都是byte,这个咋区分?
2.sizeof
本来一直以为sizeof也是个函数,现在才知道sizeof是个关键字
在汇编中的时候,sizeof就直接赋值了
int len=sizeof(temp); 0041143F mov dword ptr [len],30h
3.sizeof的宏实现
可以利用指正ptr 与(ptr+1)的内存偏移量来求类型或是变量的内存占用量
//变量类型类型 #define _sizeof(T) (size_t)((T*)0 + 1) //变量或是数组名 #define array_sizeof(T) ( (size_t)(&T+1) - (size_t)(&T) )
到了这时,以为问题解决了吗?才不是,继续探究指针重载++符号的原理是什么?