一:背景
在 CLR 源碼中,我們會看到很多關于 typedef
的定義,比如下面這樣:
//?Callback?function?type?used?by?DacStreamManager?to?coordinate
//?amount?of?available?memory?between?multiple?streamable?data
//?structures?(e.g.?DacEENamesStreamable)
typedef?bool?(*Reserve_Fnptr)(DWORD?size,?void?*?writeState);typedef?BOOL?(*NTQUERYSYSTEMINFORMATION)(SYSTEM_INFORMATION_CLASS?SystemInformationClass,PVOID?SystemInformation,ULONG?SystemInformationLength,PULONG?ReturnLength);typedef?struct?_HashInstanceKey?{TADDR?addr;DAC_INSTANCE*?instance;
}?HashInstanceKey;typedef?TokenHashMap<EEClass>?EEClassToTypeRefMap;
typedef?TokenHashMap<MethodTable>?MTToTypeRefMap;
如果你不了解 C 的話又是一陣頭暈,那 typedef
到底能給我們帶來什么好處呢?直白的說,它可以給某一些類型定義別名,比如結構體
,變量
,函數指針
等等,類型越復雜好處越大,接下來我們舉兩個例子說明一下。
二:typedef 的簡單用法
使用 typedef 定義函數指針
在不用 typedef
的前提下,我們看看原生方式的 函數指針
有多么復雜,參考代碼如下:
#include?<iostream>//函數指針
int?(*ptrAddFunc)(int?a,?int?b);int?Add(int?a,?int?b)?{?return?a?+?b;?}int?main()
{int?(*ptrAddFunc1)(int?a,?int?b)?=?Add;int?(*ptrAddFunc2)(int?a,?int?b)?=?Add;int?sum1?=?ptrAddFunc1(10,?20);int?sum2?=?ptrAddFunc1(100,?200);printf("sum1=%d,?sum2=%d",?sum1,?sum2);
}
如果用 typedef
來統一替換別名會怎么樣呢?試一試就知道了哈,參考代碼如下:
#include?<iostream>//函數指針
typedef?int?(*ptrAddFunc)(int?a,?int?b);int?Add(int?a,?int?b)?{?return?a?+?b;?}int?main()
{ptrAddFunc?func1?=?Add;ptrAddFunc?func2?=?Add;int?sum1?=?func1(10,?20);int?sum2?=?func2(100,?200);printf("sum1=%d,?sum2=%d",?sum1,?sum2);
}
是不是找到了寫 C# 的感覺了哈,太方便了。
建立一套自己的類型系統
熟悉 C# 的朋友應該了解其有一套基元類型如:Int32, Int64,Float, Double,那如何將它帶到 C 的環境下呢?這就需要用 typedef 啦,參考如下代碼:
#include?<iostream>typedef?long?long?Int64;
typedef?int?Int32;
typedef?float?Float;
typedef?double?Double;int?Add(int?a,?int?b)?{?return?a?+?b;?}int?main()
{Int32?i32?=?10;Int64?i64?=?11;size_t?s1?=?sizeof(Int32);size_t?s2?=?sizeof(Int64);printf("output:sizeof_int=%zu,sizeof_long=%zu,i32=%d,i64=%d",?s1,?s2,?i32,?i64);
}output:sizeof_int=4,sizeof_long=8,i32=10,i64=11
三:typedef 和 define 的區別
仔細想想,其實它們基因是不同的,一個是占位符
,一個是取別名
,兩個不同用途的東西自然就會在多個場景下有著不一樣的展示, 比如在指針
上就有區別。
#include?<iostream>#define?ptr1?char*
typedef?char*?ptr2;int?main()
{ptr1?p1,?p2;ptr2?p10,?p20;printf("output:?p1=%zu,?p2=%zu,p10=%zu,?p20=%zu",?sizeof(p1),sizeof(p2),sizeof(p10),sizeof(p20));
}output:?p1=4,?p2=1,p10=4,?p20=4
從size大小可判斷,4 表示一個32bit的指針單元,那 1
是什么東西呢?我們截圖看一下:

可以看出它是一個 char
類型,這就是它們倆不一樣,當然這是編譯器層面做出的選擇,大體上就聊這么多吧,希望對你有幫助。