当前位置:编程学习 > C/C++ >>

C与泛型

【问题描述】泛型是一种特殊的类型,它把指定类型的工作推迟到客户端代码声明并实例化类或方法的时候进行。泛型旨在解决函数名字冲突的问题。一般认为泛型是高级语言的能力,泛型的实现一般借助高级语言的模板概念。C语言是否能实现泛型呢?答案是能,不过比高级语言困难得多。下面总结两种泛型的实现方法。

【解析】

编译环境:

Fedora 10, gcc版本gcc4.3.2

1 利用函数指针实现泛型

【代码清单】

printtest.c

[html]
#include <stdio.h> 
#include <stdlib.h> 
 
#define DEBUG 0 
 
#define PRINTSTAT( FORMAT, STAT) \ 
    printf("**************** " FORMAT " Test ****************\n"\ 
    ,STAT); 
 
#define DEBUG_PRINT(FORMAT, VALUE) printf("File %s line %d: "\ 
            #VALUE " = " FORMAT "\n"\ 
            ,__FILE__, __LINE__,VALUE\ 
            ); 
 
enum { 
    RET_OK, 
    RET_FAIL 
}; 
 
typedef int (*FXPrintFun)(void *data); 
 
int print(FXPrintFun _print, void *data) 

    return _print(data); 

 
static int print_int(void *data) 

    printf("%d", (int)data); 
 
    return RET_OK; 

 
static int print_int2(void *data) 

    printf("%d", *(int*)data); 
 
    return RET_OK; 

 
static int print_float(void *data) 

    printf("%f", *(float*)data); 
 
    return RET_OK; 

 
static int print_str(void *data) 

    printf("%s", (char*)data); 
 
    return RET_OK; 

 
int main(void) 

    int i = 0; 
    float f = 2.6; 
    char *test = "Generics test!"; 
 
    int *pi = &i; 
    float *pf = &f; 
 
#if DEBUG 
    DEBUG_PRINT("%f", f) 
#endif 
 
    PRINTSTAT( "%s", "Integer") 
    for(; i<10; i++) 
        print(print_int, (void *)i); 
    printf("\n"); 
 
    PRINTSTAT( "%s", "Integer") 
    for(i = 0; i<10; i++) 
        print(print_int2, (void *)pi); 
    printf("\n"); 
 
    PRINTSTAT( "%s", "Float") 
    print(print_float, (void *)pf); 
    printf("\n"); 
 
    PRINTSTAT( "%s", "String") 
    print(print_str, (void *)test); 
    printf("\n"); 
 
    return RET_OK; 

#include <stdio.h>
#include <stdlib.h>

#define DEBUG 0

#define PRINTSTAT( FORMAT, STAT) \
 printf("**************** " FORMAT " Test ****************\n"\
 ,STAT);

#define DEBUG_PRINT(FORMAT, VALUE) printf("File %s line %d: "\
   #VALUE " = " FORMAT "\n"\
   ,__FILE__, __LINE__,VALUE\
   );

enum {
 RET_OK,
 RET_FAIL
};

typedef int (*FXPrintFun)(void *data);

int print(FXPrintFun _print, void *data)
{
 return _print(data);
}

static int print_int(void *data)
{
 printf("%d", (int)data);

 return RET_OK;
}

static int print_int2(void *data)
{
 printf("%d", *(int*)data);

 return RET_OK;
}

static int print_float(void *data)
{
 printf("%f", *(float*)data);

 return RET_OK;
}

static int print_str(void *data)
{
 printf("%s", (char*)data);

 return RET_OK;
}

int main(void)
{
 int i = 0;
 float f = 2.6;
 char *test = "Generics test!";

 int *pi = &i;
 float *pf = &f;

#if DEBUG
 DEBUG_PRINT("%f", f)
#endif

 PRINTSTAT( "%s", "Integer")
 for(; i<10; i++)
  print(print_int, (void *)i);
 printf("\n");

 PRINTSTAT( "%s", "Integer")
 for(i = 0; i<10; i++)
  print(print_int2, (void *)pi);
 printf("\n");

 PRINTSTAT( "%s", "Float")
 print(print_float, (void *)pf);
 printf("\n");

 PRINTSTAT( "%s", "String")
 print(print_str, (void *)test);
 printf("\n");

 return RET_OK;
}
Makefile

[html]
OBJS = printtest.o 
TARGET = printtest 
SRC = printtest.c 
 
all:$(OBJS) 
    gcc -g $(OBJS) -o $(TARGET) 
$(OBJS):printtest.s 
    gcc -g -c printtest.s -o $(OBJS) 
printtest.s:printtest.i 
    gcc -g -S printtest.i -o printtest.s 
printtest.i:$(SRC) 
    gcc -g -E $(SRC) -o printtest.i 
clean: 
    rm *~ *.o *.s *.i $(TARGET) 

OBJS = printtest.o
TARGET = printtest
SRC = printtest.c

all:$(OBJS)
 gcc -g $(OBJS) -o $(TARGET)
$(OBJS):printtest.s
 gcc -g -c printtest.s -o $(OBJS)
printtest.s:printtest.i
 gcc -g -S printtest.i -o printtest.s
printtest.i:$(SRC)
 gcc -g -E $(SRC) -o printtest.i
clean:
 rm *~ *.o *.s *.i $(TARGET)
*此处为了观察代码的编译、汇编、链接过程,Makefile稍显复杂,可直接用下述指令编译

[html] view plaincopyprint?gcc printtest.c -o printtest 

gcc printtest.c -o printtest
 

【运行结果】

[html] 
**************** Integer Test **************** 
0123456789 
**************** Integer Test **************** 
0123456789 
**************** Float Test **************** 
2.600000 
**************** String Test **************** 
Generics test! 

**************** Integer Test ****************
0123456789
**************** Integer Test ****************
0123456789
**************** Float Test ****************
2.600000
**************** String Test ****************
Generics test!
 


上述代码,有一处值得注意,在定义时,提供了两种print_int函数:

[html]
static int p

补充:软件开发 , C语言 ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,