C语言中借助条件编译实现泛型的效果

本文介绍了如何在C语言中利用条件编译来模拟泛型的效果。通过定义不同的宏,可以在编译时确定数组类型,实现自定义长度和类型的数组。文章给出了一个例子,展示了如何创建和使用这种泛型数组来存储int、float和char类型的数据。
摘要由CSDN通过智能技术生成

    最近C++代码写得比较多,感觉泛形蛮实用的,而且我一直都觉得语言都是相通的,一样的需求,在不同的语言中应该都是能够得到实现的,只是表述方式有所不同。对于某种功能,有的语言可能实现起来比较复杂,有的语言由于自身特性则相对简单,但是所有的语言应该都是能够实现这样的功能的,只是有些方法还没有想到而已,所以不存在某种功能是某种语言所独有的(个人观点)。

    同理,看到泛型这么实用,而且C++,Java都存在泛形,于是我觉得C语言也应该有泛形,虽然C语言本身没有对泛形的支持(据我所知),但是肯定有方法能够实现,或许这个方法会很笨拙,但是绝对存在。

    下面是我思索过后,得出的方法(这个过程肯定是写了不只一段测试代码的,但是错误的方法就没必要列出来了,这里只给出目前所能想到的比较好的方法):

    以我给出的代码为例子,我这里实现了一个能够自定义长度的数组,数组的类型为Ary_Var , 数组长度存放在arySize中,该数据结构的定义如下:

typedef  struct  VarArray  VarArray  ;

 

struct  VarArray {

   Ary_Var  *varAry   ;  // 定义一个类型为Ary_Var的指针,

                                   // 用于创建一个动态申请空间的数组

                                   // 此处Ary_Var的类型未定(这是泛形的关键)

 

   int      arySize  ;      //存放数组长度

} ;

 

然后借助于C语言的条件编译让Ary_Var类型在编译时能够被确定,因为在C语言中,变量的类型在编译时必须是确定的,否则就会报错,所以要借助于条件编译让Ary_Var在编译时被替换为C语言的合法类型(int , float或其他类型)。具体实现:将上述实现的数据结构放在一个头文件中,并且在该头文件中,以条件编译的方式,指定在不同编译条件下Ary_Var的实际类型,具体代码如下:

 

头文件:VarArray.h

 

# ifndef VarArray_h

# define VarArray_h

 

# ifdef Ary_INT

# define Ary_Var int      //当Ary_INT被定义,则Ary_Var的实际类型为int

# endif

 

# ifdef Ary_LONG

# define Ary_Var long     //当Ary_LONG被定义,则Ary_Var的实际类型为long

# endif

 

# ifdef Ary_CHAR

# define Ary_Var char     //当Ary_CHAR被定义,则Ary_Var的实际类型为char

# endif

 

# ifdef Ary_FLOAT

# define Ary_Var float    //当Ary_FLOAT被定义,则Ary_Var的实际类型为float

# endif

 

# include <stdlib.h>

 

typedef  struct  VarArray  VarArray  ;

 

struct  VarArray {

    Ary_Var  *varAry  ;    //定义一个类型为Ary_Var的指针,

                                     //用于创建一个动态申请空间的数组

                                     //此处Ary_Var的类型未定(这是泛形的关键)

    int      arySize  ;        //存放数组长度

} ;

 

/*

* 数组的初始化方法,通过定义含有参数的宏来实现

* (注意:为数组申请空间malloc时,

* 也采用未定类型Ary_Var,而没有采用具体类型)

*/

# define  aryInit(Ary, size)  {\

Ary.arySize = size ;\

Ary.varAry  = (Ary_Var *) malloc ( size * sizeof (Ary_Var)) ;\

}

 

# endif

 

此外还需要一个头文件,用于关闭VarArray.h中通过#define所定义的宏,因为在C语言中用户通过#define所定义的的宏,从定义处开始到文件末尾都是可用的,而此处实现的可自定义长度的泛型数组可能会在同一个文件中多处用到,故需要关闭相关宏,以避免干扰。具体代码如下:

 

头文件:AryEnd.h

 

# undef  Ary_Var

# undef  VarArray

# undef  aryInit

# undef  VarArray_h

 

接下来编写测试代码,具体实现如下:

 

源文件:Test.c

 

# include <stdio.h>

 

void showInt ()

{

/*

* 运用VarArray.h中实现的可自定义长度的泛型数组来存储int型数据

 */

 

# define Ary_INT           //指定泛型数组的类型为int

# include "VarArray.h"     //导入泛型数组的定义,并将数组类型确定为int

# undef Ary_INT            //关闭宏

 

    int i ;

    enum {NUM = 2} ;       //用常量来指定数组的长度(长度为2)

 

    VarArray test ;       //实例化一个可自定义长度的泛型数组

    aryInit (test, NUM) ;  //初始化该数组对象,长度为NUM

 

    printf ("Input %d data of int:\n", NUM) ;

 

    for (i = 0; i < test.arySize; i++)

        scanf ("%d", &test.varAry[i]) ; //逐一存入数据到数组中去

 

    printf ("type int:\n") ;

 

    for (i = 0; i < test.arySize; i++) //将数组中的元素逐一输出

    {

        if (!(i % 4) && i) printf ("\n") ;

        printf ("%d\t", test.varAry[i]) ;

    }

 

    printf ("\n\n") ;

 

# include "AryEnd.h"                   //导入关闭宏的头文件

 

}

 

void showFloat ()

{

/*

* 运用VarArray.h中实现的可自定义长度的泛型数组来存储float型数据

 */

 

# define Ary_FLOAT      //指定泛型数组的类型为float

# include "VarArray.h"  //导入泛型数组的定义,并将数组类型确定为float

# undef Ary_FLOAT       //关闭宏

 

    int i ;

    enum {NUM = 2} ;       //用常量来指定数组的长度(长度为2)

 

    VarArray test ;       //实例化一个可自定义长度的泛型数组

    aryInit (test, NUM) ;  //初始化该数组对象,长度为NUM

 

    printf ("Input %d data of float:\n", NUM) ;

 

    for (i = 0; i < test.arySize; i++)

        scanf ("%f", &test.varAry[i]) ; //逐一存入数据到数组中去

 

    printf ("type float:\n") ;

 

    for (i = 0; i < test.arySize; i++) //将数组中的元素逐一输出

    {

        if (!(i % 4) && i) printf ("\n") ;

        printf ("%f\t", test.varAry[i]) ;

    }

 

    printf ("\n\n") ;

 

# include "AryEnd.h"                   //导入关闭宏的头文件

}

 

void showChar ()

{

/*

* 运用VarArray.h中实现的可自定义长度的泛型数组来存储char型数据

 */

 

# define Ary_CHAR       //指定泛型数组的类型为char

# include "VarArray.h"  //导入泛型数组的定义,并将数组类型确定为char

# undef Ary_CHAR        //关闭宏

 

    int i ;

    enum {NUM = 2} ;       //用常量来指定数组的长度(长度为2)

 

    VarArray test ;       //实例化一个可自定义长度的泛型数组

    aryInit (test, NUM) ;  //初始化该数组对象,长度为NUM

 

    printf ("Input %d data of char:\n", NUM) ;

 

    for (i = 0; i < test.arySize; i++)

        scanf ("%c", &test.varAry[i]) ; //逐一存入数据到数组中去

 

    printf ("type char:\n") ;

 

    for (i = 0; i < test.arySize; i++) //将数组中的元素逐一输出

    {

        if (!(i % 4) && i) printf ("\n") ;

        printf ("%c\t", test.varAry[i]) ;

    }

 

    printf ("\n\n") ;

 

# include "AryEnd.h"                   //导入关闭宏的头文件

}

 

int main (int argc, char **argv)

{

    showInt () ;                        // 运用可自定义长度的泛型数组来存储int型数据,并输出

    while (getchar () != '\n') ;

 

    showFloat () ;                    // 运用可自定义长度的泛型数组来存储float型数据,并输出

    while (getchar () != '\n') ;

 

    showChar () ;                    // 运用可自定义长度的泛型数组来存储char型数据,并输出

    return 0 ;

}

----@Author CLinHF 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值