1

ユーザーが入力できる浮動小数点モードを作成する、'f'または'i'整数と浮動小数点を切り替える最も効率的な方法は何ですか? float のコード全体をコピーする必要なく、これを行いたいと思います。型キャストがオプションであることは知っていますが、それが最も安全な方法であるかどうかは完全にはわかりません。

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

#define MAX 100

int *p;
int *tos;
int *bos;

void push(int i);
int pop(void);

int main (void)
{
    int a, b;
    char s[80];

    p = (int *) malloc(MAX*sizeof(int));    /* get stack memory */
    if (!p) {
        printf("Allocation Failure\n");
        exit(1);
    }

    tos = p;
    bos = p + MAX-1;

    printf("\nRPN Calculator\n");
    printf("Enter 'i' for integer mode\n");
    printf("Enter 'f' for floating point mode\n");
    printf("Enter 'q' to quit\n\n");
    char *endptr;

    do {        
        printf("> ");
        scanf("%s", s);
        int val = strtol(s, &endptr, 10);

        if (*endptr == '\0') {
            //printf("Got only the integer: %d\n", val);
        }
        else {  
            printf("operator: %s\n", endptr); 
            printf("integer: %d\n", val);
                if (val != 0){      /* don't push val on stack if 0 */
                push(val);
            }
        }

        switch(*endptr) {
            case 'i':
                printf("(Integer Mode)\n");
                break;
            case 'f':
                printf("(Floating Point Mode)\n");
                break;
            case '+':
                a = pop();
                b = pop();
            //  printf("%d\n",a);
            //  printf("%d\n",b);
            //  printf("%d\n",val);
                printf("%d\n", a+b);
                push(a+b);
                break;
            case '-':
                a = pop(); 
                b = pop(); 
                printf("%d\n", b-a); 
                push(b-a);
                break;  
            case '*':
                a = pop(); 
                b = pop(); 
                printf("%d\n", a*b); 
                push(a*b);
                break;
            case '/':
                a = pop(); 
                b = pop();
                if(a == 0){
                    printf("Cannot divide by zero\n");
                    break;
                }
                printf("%d\n", b/a);
                push(b/a);
                break;
            case '.':
                a = pop(); push(a);
                printf("Current value on top of stack: %d\n", a);

                break;  
            default:
            //  push(atoi(s));
                push(val);
        }
    } while (*s != 'q');    /* Do until 'q' is entered */

    return 0;
    }       

void push (int i)   /* Put an element on the stack */
{
    if (p > bos){
        printf("Stack Full\n");
        return;
    }
    *p = i;
    p++;
}

int pop (void)  /* Get the element from the top of the stack */
{
    p--;
    if(p < 0) {
        printf("Stack Underflow\n");
        return 0;
    }
    return *p;
}
4

2 に答える 2

2

C では関数をオーバーロードする方法がないため、いずれにしても 2 つのコピーを作成する必要があります。ただし、プッシュ/ポッピングを一般化して、任意のデータを持つノードで動作するようにすることができます。安全に行うには、次のようなタグ付きユニオンを使用できます。

typedef struct {
  enum {INT, FLOAT} type;
  union {
    int i;
    float f;
  } data;
} Node;

これにより、将来、他のデータ型に簡単に拡張することもできます。

または、void*データを操作するたびに安全でないデータをキャストして、必要なものが常に見つかると傲慢に仮定することもできます (推奨されません)。

于 2010-02-06T06:49:41.663 に答える
0

マクロ プリプロセッサを使用して魔法をかけることができます。

一般的な操作をヘッダー ファイルに分離し、TYPE などのマクロ変数を提供します。TYPE を関数名に連結して個別の名前を作成し、明示的な型を TYPE に置き換えます。メイン ファイルにマクロ/ヘッダー ファイルを 2 回インクルードします。1 回目は TYPE を int に定義し、2 回目は TYPE を double として定義します。名前に TYPE を追加して、特別な関数を呼び出します。

これは貧乏人の C++ テンプレートのようなものです

于 2010-02-06T06:59:22.287 に答える