2010-02-06 3 views
1

Каков наиболее эффективный способ создания режима с плавающей запятой, где пользователь может ввести 'f' или 'i' для переключения между целым числом и плавающей точкой? Я бы хотел сделать это, не скопировав весь код для поплавков. Я знаю, что приведение типов - это вариант, но я не совсем уверен, насколько безопасен этот способ.Что такое самый простой способ добавить режим с плавающей запятой в этот калькулятор C?

#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; 
} 
+1

домашнее задание? –

+1

Должно быть. Вчера мы видели вопрос, отправленный кем-то (возможно, его одноклассником: P) – codaddict

ответ

2

Невозможно перегрузить функции на C, поэтому вам придется делать две копии в любом случае. Тем не менее, вы можете обобщить pushing/popping, чтобы он работал на узлах с произвольными данными. Для того, чтобы сделать это безопасно, вы можете использовать маркированный союз как:

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

Это также позволяет легко распространить на другие типы данных в будущем.

Или вы могли бы просто пойти с данными void* и бросить их без всяких проблем каждый раз, когда хотите работать на нем, высокомерно предполагая, что вы всегда найдете то, что хотите (не рекомендуется).

+0

Сколько кода это спасет меня? Поэтому вместо использования int i я мог бы использовать Node.i или Node.f? – patrick

+0

Вы должны использовать 'Node n; n.data.i = ... '. Это спасло бы вас только от общих толкающих/выскакивающих частей. –

0

вы можете сделать магию с помощью макропроцессора.

Изолировать общие операции в файл заголовка, предоставлять некоторую макроперемену, например TYPE. объединяйте TYPE с именами функций для создания разных имен, замените явные типы с помощью TYPE. в основном файле включают файл макро/заголовок дважды, один раз с TYPE, определенным для int, в следующий раз с TYPE, определенным как double. вызывать специальные функции с именами, добавленными в TYPE.

Это как плохой человек C++ шаблон

Смежные вопросы