因为百度空间没有了,所及将以前写的一篇关于C语言粘贴符的使用的随笔迁移至此。
最近在百度知道看到有关C语言泛型的问题因为举例比较长,在这里作为回答,并作为C语言知识的记录,如果有不同意见,欢迎大家互相探讨,其实我的模拟泛型的思路就是使用粘贴符##以及宏定义完成。下面举例双向链表的实现,代码如下:
#include "stdafx.h" #include <string.h>// 这里是对双向链表的定义,相当于泛型模板 #define DECLARE(node_type) struct node_type##_node{struct node_type##_node* priv; struct node_type##_node* next; node_type value;} // 这里是初始化一个给定节点的宏定义,node是一个结构体,如果是指针,会出现错误。 #define INIT_LINK_NODE(node) do{node.priv=NULL, node.next=NULL;}while(0) // 这个宏定义初始化一个给定指针的node,node必须是指针,否则会出现错误。 #define INIT_LINK_NODE_P(pnode) do{node->priv=NULL, node->next=NULL;}while(0) // 这个宏定义用来定义一个value为type类型的变量 #define NEW(type, var_name) struct type##_node var_name // 这个宏定义用来定义一个value为type类型的node数组 #define ARRAY(type, var_name, len) struct type##_node var_name[len] // 这个宏用来引用value值类型为type的node类型,例如可用在 sizeof(TYPE(int)) // 这样就计算出了value值类型为int的node节点的字节长度。 #define TYPE(type) struct type##_nodetypedef struct people_{char name[50];long birthday;char hobby[100]; }people;// 以下是对具体类型链表的声明。 DECLARE(int); // 声明一个value类型是int类型的链表node DECLARE(double); // 声明一个value类型是double类型的链表node DECLARE(people); // 声明一个value类型是struct_node类型的nodeint _tmain(int argc, _TCHAR* argv[]) {// 接下来就是测试是否能够正常使用链表的时候NEW(int, int_node);NEW(double, double_node);NEW(people, people_node);ARRAY(int, int_node_array, 10);ARRAY(double, double_node_array, 10);ARRAY(people, people_node_array, 10);// 接下来分别测试value值类型分别为int,double, people// 的node类型。int_node.next = NULL;int_node.priv = NULL;int_node.value = 300;printf("int_node{priv:%d, next:%d, value:%d}\n", (int)int_node.priv, (int)int_node.next, int_node.value);double_node.next = NULL;double_node.priv = NULL;double_node.value = 3.5268;printf("double_node{priv:%d, next:%d, value:%f}\n", (int)double_node.priv, (int)double_node.next, double_node.value);people_node.next = NULL;people_node.priv = NULL;strcpy(people_node.value.name, "Tom");people_node.value.birthday = 19000425;strcpy(people_node.value.hobby, "basketball");printf("people_node{priv:%d, next:%d, ""value{name:%s, birthday: %d, hobby:%s}}\n",(int)people_node.priv, (int)people_node.next, &people_node.value.name,people_node.value.birthday, &people_node.value.hobby);//ARRAY(int, int_node_array, 10);//ARRAY(double, double_node_array, 10);//ARRAY(people, people_node_array, 10);// 接下来分别测试数组。// --------------------------整形数组int_node_array[0].priv = NULL;int_node_array[0].next = &(int_node_array[1]);int_node_array[0].value = 0;for(int i = 1; i < 9; i++){int_node_array[i].priv = &(int_node_array[i-1]);int_node_array[i].next = &(int_node_array[i+1]);int_node_array[i].value = i;}int_node_array[9].priv = &(int_node_array[8]);int_node_array[9].next = NULL;int_node_array[9].value = 9;TYPE(int)* p_int_node = &(int_node_array[0]);while(NULL != p_int_node){printf("int_node{priv:%d, next:%d, value:%d}\n", (int)p_int_node->priv, (int)p_int_node->next, p_int_node->value);p_int_node = p_int_node->next;}// ------------------------------double类型数组double_node_array[0].priv = NULL;double_node_array[0].next = &double_node_array[1];double_node_array[0].value = 5.2;for(int i = 1; i < 9; i++){double_node_array[i].priv = &double_node_array[i-1];double_node_array[i].next = &double_node_array[i+1];double_node_array[i].value = i + 0.56657;}double_node_array[9].priv = &double_node_array[8];double_node_array[9].next = NULL;double_node_array[9].value = 9.5;TYPE(double)* p_double_node = &double_node_array[0];while(NULL != p_double_node){printf("double_node_array{priv:%d, next:%d, value:%f}\n", (int)p_double_node->priv, (int)p_double_node->next, p_double_node->value);p_double_node = p_double_node->next;}// ------------------------------people类型数组people_node_array[0].next = &people_node_array[1];people_node_array[0].priv = NULL;strcpy(people_node_array[0].value.name, "Tom_a");people_node_array[0].value.birthday = 19000425;strcpy(people_node_array[0].value.hobby, "basketball_a");for(int i = 1; i < 9; i++){people_node_array[i].priv = &people_node_array[i-1];people_node_array[i].next = &people_node_array[i+1];strcpy(people_node_array[i].value.name, people_node_array[i-1].value.name);strcpy(people_node_array[i].value.hobby, people_node_array[i-1].value.hobby);people_node_array[i].value.birthday = people_node_array[i-1].value.birthday+1;people_node_array[i].value.name[4]++;people_node_array[i].value.hobby[11]++;}people_node_array[9].priv = &people_node_array[8];people_node_array[9].next = NULL;strcpy(people_node_array[9].value.name, people_node_array[8].value.name);strcpy(people_node_array[9].value.hobby, people_node_array[8].value.hobby);people_node_array[9].value.birthday = people_node_array[8].value.birthday+1;people_node_array[9].value.name[4]++;people_node_array[9].value.hobby[11]++;TYPE(people)* p_people_node = &people_node_array[0];while(NULL != p_people_node){printf("people_node{priv:%d, next:%d, ""value{name:%s, birthday: %d, hobby:%s}}\n",(int)p_people_node->priv, (int)p_people_node->next, p_people_node->value.name,p_people_node->value.birthday, p_people_node->value.hobby);p_people_node = p_people_node->next;}return 0; }
本例在VS2010下运行结果如下:
如果使用visual studio 2015 运行代码,需要将strcpy改成strcpy_s,否则会提示错误。