C语言模拟泛型粘贴符##的使用 迁移

因为百度空间没有了,所及将以前写的一篇关于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##_node
    
typedef 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类型的node
    
    
int _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,否则会提示错误。

原文地址:https://www.cnblogs.com/lee2014/p/5040802.html