官方的定义我就不抄过来了,它的作用是“给已知数据类型重命名”。
重命名的好处是能区分不同场合使用不同数据类型,这就好比同样是可乐,有些人就喜欢可口可乐,有些人喜欢百事可乐,typedef作用就像是一个标签一样,本来同一叫做可乐或者绿茶就可以了,但是实际使用场合中,会有需求希望做出区分,有了typedef,绿茶就可以重命名为统一绿茶和统一薄荷绿茶或者康师傅绿茶、雀巢绿茶了。
今天看源码的时候,突然明白为啥要给数据类型取别名?就是为了让在不同使用环境下让数据类型变得有“具体含义”,就像统一绿茶,统一二字表明了它是统一公司的。
例如int可以重名名为size,long,length等。
例如一个struct结构,你定义后,命名为cola。假设你定义了两个类使用它,这两个类分别是Mcdonal(麦当劳)和KFC(肯德基)。你发现这个概念太笼统,于是,在Mcdonal这个类里面,你用typedef定义为coco-cola;在KFC这个类里面,你typedef重定义为pesi-cola。
typedef struct cola
{
intiNum;
} coco-cola,pesi-cola;
linux内核中,很多很复杂的“结构”,例如内存结构描述符,进程结构描述符,但它们也会有类似上面那种情况,需要用在不同的背景下;因此,经常使用typedef重命名。
例如上面的cola结构体,我们把它重名明为coco-cola,那么下次就直接这样声明:
coco-cola a;
pesi-cola b;
或者用原本的数据类型,需要加“strcut”声明
struct cola c;
linux内核经常看到这样的“数据类型”声明:
size n;
gfp_t gfp_data;
pg_data_t data_new;
看似很简单,其实他们的本体可能是很复杂的,例如pg_data_t,看似和size一样简单,但它实际定义如下,它是pglist_data这个struct的别名。
typedef struct pglist_data {
struct zone node_zones[MAX_NR_ZONES];
struct zonelist node_zonelists[MAX_ZONELISTS];
int nr_zones;
#ifdef CONFIG_FLAT_NODE_MEM_MAP /* means !SPARSEMEM */
struct page *node_mem_map;
#ifdef CONFIG_CGROUP_MEM_RES_CTLR
struct page_cgroup *node_page_cgroup;
#endif
#endif
#ifndef CONFIG_NO_BOOTMEM
struct bootmem_data *bdata;
#endif
#ifdef CONFIG_MEMORY_HOTPLUG
/*
* Must be held any time you expect node_start_pfn, node_present_pages
* or node_spanned_pages stay constant. Holding this will also
* guarantee that any pfn_valid() stays that way.
*
* Nests above zone->lock and zone->size_seqlock.
*/
spinlock_t node_size_lock;
#endif
unsigned long node_start_pfn;
unsigned long node_present_pages; /* total number of physical pages */
unsigned long node_spanned_pages; /* total size of physical page
range, including holes */
int node_id;
wait_queue_head_t kswapd_wait;
struct task_struct *kswapd;
int kswapd_max_order;
} pg_data_t;
当我们声明一个结构体时,如下声明
pg_data_t data;
或者
strcut pglist_data data;