下面的程序试图将几种基本数据类型合并为一种通用类型并实现简单的算术运算。
#include<stdio.h>
#include<malloc.h>
union generaltype
{
char c;
int i;
long l;
float f;
double d;
char *s;
};
struct object
{
union generaltype data;
char buffer[100];
int type;
void (*get)(struct object *);
void (*set)(struct object *);
};
void get(struct object *o)
{
switch(o->type) //根据类型进行相应的输出
{
case 1:
printf("%c",o->data.c);
break;
case 2:
printf("%d",o->data.i);
break;
case 3:
printf("%ld",o->data.l);
break;
case 4:
printf("%f",o->data.f);
break;
case 5:
printf("%lf",o->data.d);
break;
case 6:
printf("%s",o->data.s);
break;
}
}
void set(struct object *o)
{
char *p=o->buffer,c;
char MAXINT[]="32767",MININT[]="-32768";
char MAXLONG[]="2147483647",MINLONG[]="-2147483648";
int point=0;
int digitlenth=0,lenth=0;
int e=0,flag=0;
int i;
//统计数码、字符、正负号、E和e个数
for(i=0; p[i]!='\0'; i++)
{
c=p[i];
lenth++;
if(isdigit(c)) digitlenth++;
else if(c=='.')point++;
else if(c=='E'||c=='e')e++;
else if(c=='-')flag++;
}
//char
if(lenth=3 && p[0]=='\'' && p[2]=='\'') // ‘A’样式
{
o->data.c=p[1];
o->type=1;
}
//int -
else if(flag==1 && point==0 && p[0]=='-' && strcmp(p,MININT)<=0 && e==0)
{
sscanf(p,"%d",&(o->data.i));
o->type=2;
}
//int +
else if(flag==0 && point==0 && strcmp(p,MAXINT)<=0 && e==0)
{
sscanf(p,"%d",&(o->data.i));
o->type=2;
}
//long -
else if(flag==1 && point==0 && p[0]=='-' && strcmp(p,MINLONG)<=0 && e==0)
{
sscanf(p,"%ld",&(o->data.l));
o->type=3;
}
//long +
else if(flag==0 && point==0 && strcmp(p,MAXLONG)<=0 && e==0)
{
sscanf(p,"%ld",&(o->data.l));
o->type=3;
}
//float -
else if(flag==1 && point==1 && p[0]=='-' && lenth<=8 && e<=1)
{
sscanf(p,"%f",&(o->data.f));
o->type=4;
}
//float +
else if(flag==0 && point==1 && lenth<=8 && e<=1)
{
sscanf(p,"%f",&(o->data.f));
o->type=4;
}
//double -
else if(flag==1 && point==1 && p[0]=='-' && lenth>8 && e<=1)
{
sscanf(p,"%lf",&(o->data.d));
o->type=5;
}
//double +
else if(flag==0 && point==1 && lenth>8 && e<=1)
{
sscanf(p,"%lf",&(o->data.f));
o->type=5;
}
//char *
else //不能识别的都作为字符串处理
{
sscanf(p,"%s",o->data.s);
o->type=6;
}
}
//设置类型结构中的函数指针指向实际的函数,使其具有方法调用的能力
void object_init(struct object *o)
{
o->get=get;
o->set=set;
}
int main()
{
struct object *o1,*o2;
o1=(struct object *)malloc(sizeof(struct object *));
o2=(struct object *)malloc(sizeof(struct object *));
object_init(o1);object_init(o2);
printf("intput data 1:"); scanf("%s",o1->buffer); //以字符串形式输入数据
printf("intput data 2:"); scanf("%s",o2->buffer); //以字符串形式输入数据
o1->set(o1); printf("o1 type is %d\n",o1->type);
o2->set(o2); printf("o2 type is %d\n",o2->type);
if(o1->type==2 && o2->type==2) //int类型加法运算
{
printf("%d+%d=%d\n",o1->data.i,o2->data.i,o1->data.i+o2->data.i);
}
else if(o1->type==4 && o2->type==4) //float类型加法运算
{
printf("%f+%f=%f\n",o1->data.f,o2->data.f,o1->data.f+o2->data.f);
}
//可以增加不同类型的运算,这里省略
}
运行结果如下:
分析:
上面的程序演示将几种基本类型合并为一种通用类型,数据全部以字符串形式输入,通过词法分析,得到数码字符、正负号、小数点、E或e的个数,简单地判断其可能的数据类型并记录其类型值到结构成员type中,get和set函数根据类型特性进行相应的输出和输入操作。
main函数中演示了int和float类型的加法运算,感兴趣的读者可以进一步扩展运算符的适应能力,使得类型的通用性在运算中更具有可操作性,限于篇幅,这里就省略了。