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语言 ,