向此 C 计算器添加浮点模式的最简单方法是什么?

发布于 2024-08-20 06:52:57 字数 2924 浏览 7 评论 0原文

创建浮点模式(用户可以输入 'f''i' 在整数和浮点之间切换)的最有效方法是什么?我想这样做,而不必复制浮点数的整个代码。我知道类型转换是一种选择,但我不完全确定这是否是最安全的方法。

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

What is the most efficient way to create a floating point mode where the user can enter 'f' or 'i' to switch between integer and floating point? I'd like to do this without having to copy the entire code for floats. I know typecasting is an option but I'm not completely sure if it's the safest way.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

始终不够爱げ你 2024-08-27 06:52:57

C 中无法重载函数,因此无论如何您都必须执行两个副本。但是,您可以概括推入/弹出,以便它在具有任意数据的节点上运行。为了安全地做到这一点,您可以使用标记联合,例如:

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

这还允许您将来轻松扩展到其他数据类型。

或者,您可以使用 void* 数据,并在每次要对其进行操作时不安全地强制转换它,傲慢地假设您总能找到您想要的内容(不推荐)。

There's no way to overload functions in C, so you'll have to do two copies in any case. However, you can generalize the pushing/popping so that it operates on nodes with arbitrary data. To do it safely, you can use a tagged union like:

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

This also allows you to easily extend to other data types in the future.

Or you could just go with a void* data and cast it unsafely each time you want to operate on it, arrogantly assuming that you'll always find what you want (not recommended).

浅紫色的梦幻 2024-08-27 06:52:57

你可以用宏预处理器做一些魔术。

将常用操作隔离到头文件中,提供一些宏变量,例如TYPE。
将 TYPE 连接到函数名称以创建不同的名称,用 TYPE 替换显式类型。
在主文件中包含宏/头文件两次,一次将 TYPE 定义为 int,下一次将 TYPE 定义为 double。调用名称附加 TYPE 的特殊函数。

这就像穷人 C++ 模板

you could do some magic with macro preprocessor.

Isolate common operations into header file, provide some macro variable, for example TYPE.
concatenate TYPE to function names to create distinct names, replace explicit types with TYPE.
in main file include macro/header file twice, one time with TYPE defined to int, next time with TYPE defined as double. call special functions with their names appended with TYPE.

This is like poor man C++ template

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文