2011-07-14 26 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