2011-07-14 39 views
2

我正在研究某种脚本语言。包含结构的值是某些脚本语言的算术运算

struct myvar 
{ 
char name[NAMELEN]; 
int type; 
void* value; 
} 
type = 0 --> int* value 
type = 1 --> char* value 
type = 2 --> float* value 

我遇到了算术运算的一些问题。看来,我需要无恶不作类型转换的过每一个操作,在发展成为写一大堆代码为他们每个人,如:

case 0: // "=" 
if(factor1.name) 
{ 
    if((factor1.type == 1) && (factor2.type==1)) 
    { 
     free(factor1.value); 
     int len = (strlen((STRING)factor2.value)+1)*sizeof(char); 
     factor1.value = malloc(len); 
     memcpy(factor1.value,factor2.value,len); 
    } 
    else if((factor1.type == 2) && (factor2.type==2)) 
    *(FLOAT*)factor1.value = *(FLOAT*)factor2.value; 
    else if((factor1.type == 0) && (factor2.type==0)) 
    *(INTEGER*)factor1.value = *(INTEGER*)factor2.value; 
    else if((factor1.type == 0) && (factor2.type==2)) 
    *(INTEGER*)factor1.value = *(FLOAT*)factor2.value; 
    else if((factor1.type == 2) && (factor2.type==0)) 
    *(FLOAT*)factor1.value = *(INTEGER*)factor2.value; 
    else 
    GetNextWord("error"); 
} 
break; 

是否有某种方式来避免这种令人厌烦的过程?否则我别无选择,只能复制粘贴“=”,“〜”,“+”,“ - ”,“*”,“/”,“%”,“>”,“ <“,”> =“,”< =“,”==“,”〜=“,”AND“,”OR“

+0

不是一个答案,但你知道,你有同样的情况两次? '((factor1.type == 1)&&(factor2.type == 1))' – MByD

+0

@MByD,我认为第一对应该是0,0,因为它正在做字符串复制,并且类型0是字符串。 – AShelly

+0

哦,是的,我的错。感谢您的评分,我只是在关注主要问题的同时从头开始。 – Anonymous

回答

2

怎样编写3个toType功能:

char* toType0(myvar* from) 
{ 
    if (from->type == 0) return (char*)(from->value); 
    else if (from->type == 1) return itoa((int*)from->value); 
    else... 
} 
int toType1(myvar* from) 
{ 
    //convert to int... 
} 

然后在你的转换例程,你可以这样做:

switch (factor1.type) 
{ 
    case 0: 
    { char* other = toType0(&factor2); 
    //assign or add or whatever.... 
    }; 
    break; 
    case 1: 
    { int other = toType1(&factor2); 
    //assign or add or whatever.... 
    }; 
    break; 
    ... 
    } 
+0

如果你想禁止某些操作,比如float到string,只要修改'toType'函数返回一个错误代码,如果转换是非法的。 – AShelly

+0

谢谢,我会试试这种方式。 – Anonymous

+0

虽然这不是一个完整的解决方案,但我也认为@ blagovest的建议是使用联合而不是void *是一个好主意。它会从您的代码中删除大量丑陋的代码。 – AShelly

2

我建议如下:应用操作时,应首先强制操作数类型。例如,如果你的操作数类型是int和float,你应该把int值强制为一个float值,然后继续float操作。所有操作的强制性都是相同的(或几乎相同)。采用这种方法,您的案例要少得多。

3

使用union,而不是一个struct为值:

struct myvar { 
    enum { 
    STRING, INT, FLOAT, 
    } type; 

    union { 
    char strval[NAMELEN]; 
    int intval; 
    float fltval; 
    } val; 
}; 

然后在你的执行赋值操作符[R脚本语言,你只是做:

factor1 = factor2; 

要获取基于你会做的类型正确的价值:

switch (operand.type) { 
    case STRING: 
    printf("%s", operand.val.strval); 
    break; 

    case INT: 
    printf("%d", operand.val.intval); 
    break; 

    case FLOAT: 
    printf("%f", operand.val.fltval); 
    break; 
} 
+1

这对分配肯定有帮助,但其他操作呢? – Vlad

+0

我需要一个特定类型的变量,不是全部在一起。 – Anonymous