簡體   English   中英

使用char和int變量在c中創建數字表達式

[英]create numeric expression in c using char and int variables

您好我想做這樣的事情:

int a=1,b=2,c=3,w=4,result;
char d='+',e='-',f='/',g='*';

a d b g w  =result;
printf("%d",result);

在這個例子中結果應該是1 + 2 * 4的地方,我有什么想法嗎?

這是對您的部分提示。

這可以做什么:a + b; a-b; a * b; a / b;

注意

a / b不會給出正確答案,因為它正在執行整數除法。

它不能做什么

正確的數學,煮咖啡以及其他一切

silly_calc.c

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>

enum operation {
    INVALID,
    CONTINUE, /* got just a number */
    QUIT,
    PLUS,
    MINUS,
    MULTIPLY,
    DIVIDE
};

enum operation parse(char *expr, int *left, int *right);
int eval(const char *expr);

char *remove_spaces(char *expr);

int main() {
    char expr[256];
    FILE *fp = stdin;
    char *rv;
    int left, right;
    enum operation oper = CONTINUE;

    while (oper != QUIT) {
        fputc(':', stdout);
        rv = fgets(expr, sizeof(expr), fp);
        if( rv == NULL ) {
            if(feof(fp)) {
                fprintf(stderr, "someone closed the input\n");
                break;
            }
            if(ferror(fp)) {
                fprintf(stderr, "something bad happened\n");
                break;
            }
        }
        oper = parse(expr, &left, & right);
        /* this switch should be moved into an eval function 
         * which would deal with precedence of operations etc.
         */
        switch(oper) {
            case CONTINUE:
                fprintf (stderr, "%d\n", left);
                continue;
            case INVALID:
                fprintf(stderr, "> Don't know what to do with %-32s...\n", expr);
                continue;
            case QUIT:
                fprintf(stderr, "> quitting\n");
                break;

            case PLUS:
                fprintf(stdout, "%d\n", left + right);
                break;
            case MINUS:
                fprintf(stdout, "%d\n", left - right);
                break;
            case MULTIPLY:
                fprintf(stdout, "%d\n", left * right);
                break;
            case DIVIDE:
                fprintf(stdout, "%d\n", left / right);
                break;
        }
    }

    return 0;
}

enum operation next_expr(char *expr, int *left, int *right) 
{
    enum operation oper;
    char *nextbit = NULL;
    *left = strtol(expr, &nextbit, 10);
    if ((*left == 0 && errno == EINVAL) || nextbit == expr ) {
        if(strcasecmp(expr, "quit") == 0)
            return QUIT;
        return INVALID;
    }
    if (*nextbit == 0 )
        return CONTINUE;

    switch(*nextbit) {
        case '+': oper = PLUS; break;
        case '-': oper = MINUS; break;
        case '*': oper = MULTIPLY; break;
        case '/': oper = DIVIDE; break;
        default: 
            return INVALID;
    }
    expr = nextbit+1; /* move over to the next number */
    *right = strtol(expr, &nextbit, 10);
    if((*right == 0 && errno == EINVAL ) || nextbit == expr) {
        return INVALID;
    }
    /* what if there are still more bits in next bit? */
    return oper;
}

enum operation parse(char *expr, int *left, int *right)
{
    enum operation suboperation;
    remove_spaces(expr);
    suboperation = next_expr(expr, left, right);
    /* TODO: take care of the rest of the bits that are in the expr */
    return suboperation;
}

char * remove_spaces(char *expr)
{
    char *p = expr, *q = expr;
    while(*q != 0) {
        *p = *q; 
        q++;
        if(!isspace(*p))
            p++;
    }
    *p = 0;
    return expr;
}

您無法以嘗試的方式在C中執行動態算術。 您可以使用預處理器來發揮有限的技巧來編譯時間常數表達式,但是對於通用解決方案,您需要一個表達式評估器。

這是一個簡化的評估程序,它通過有限的健全性檢查來支持4個基本運算符:

#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

long long eval(const char *s) {
    struct operand {
        long long val;
        int op, prec;
    } stack[16], *sp, x;

    for (sp = stack;;) {
        x.val = strtoll(s, (char **)&s, 0);
        while (isspace((unsigned char)*s))
            s++;

        switch (x.op = *s++) {
        case '*':
        case '/':
        case '%': x.prec = 2; break;
        case '+':
        case '-': x.prec = 1; break;
        default:  x.prec = 0; x.op = 0; break;
        }

        while (sp > stack && x.prec <= sp[-1].prec) {
            switch ((--sp)->op) {
            case '*': x.val = sp->val * x.val; break;
            case '/': x.val = sp->val / x.val; break;
            case '%': x.val = sp->val % x.val; break;
            case '+': x.val = sp->val + x.val; break;
            case '-': x.val = sp->val - x.val; break;
            }
        }
        if (!x.op)
            return x.val;

        if (sp == stack + sizeof(stack) / sizeof(stack[0])) {
            errno = ERANGE;     /* expression complexity error */
            return 0;
        }
        *sp++ = x;
    }
}

int main(int argc, char *argv[]) {
    if (argc > 1) {
        for (int i = 1; i < argc; i++) {
            printf("%s -> %lld\n", argv[i], eval(argv[i]));
        }
    } else {
        char buf[80];
        int a = 1, b = 2, c = 3, w = 4, result;

        for (int i = 0; i < 4*4*4; i++) {
            snprintf(buf, sizeof buf, "%d %c %d %c %d %c %d",
                     a, "+-/*"[i / 16],
                     b, "+-/*"[i / 4 % 4],
                     c, "+-/*"[i % 4],
                     w);
            result = eval(buf);
            printf("%s -> %d\n", buf, result);
        }
    }
    return 0;
}

輸出:

1 + 2 + 3 + 4 -> 10
1 + 2 + 3 - 4 -> 2
1 + 2 + 3 / 4 -> 3
1 + 2 + 3 * 4 -> 15
1 + 2 - 3 + 4 -> 4
1 + 2 - 3 - 4 -> -4
1 + 2 - 3 / 4 -> 3
1 + 2 - 3 * 4 -> -9
1 + 2 / 3 + 4 -> 5
1 + 2 / 3 - 4 -> -3
1 + 2 / 3 / 4 -> 1
1 + 2 / 3 * 4 -> 1
1 + 2 * 3 + 4 -> 11
1 + 2 * 3 - 4 -> 3
1 + 2 * 3 / 4 -> 2
1 + 2 * 3 * 4 -> 25
1 - 2 + 3 + 4 -> 6
1 - 2 + 3 - 4 -> -2
1 - 2 + 3 / 4 -> -1
1 - 2 + 3 * 4 -> 11
1 - 2 - 3 + 4 -> 0
1 - 2 - 3 - 4 -> -8
1 - 2 - 3 / 4 -> -1
1 - 2 - 3 * 4 -> -13
1 - 2 / 3 + 4 -> 5
1 - 2 / 3 - 4 -> -3
1 - 2 / 3 / 4 -> 1
1 - 2 / 3 * 4 -> 1
1 - 2 * 3 + 4 -> -1
1 - 2 * 3 - 4 -> -9
1 - 2 * 3 / 4 -> 0
1 - 2 * 3 * 4 -> -23
1 / 2 + 3 + 4 -> 7
1 / 2 + 3 - 4 -> -1
1 / 2 + 3 / 4 -> 0
1 / 2 + 3 * 4 -> 12
1 / 2 - 3 + 4 -> 1
1 / 2 - 3 - 4 -> -7
1 / 2 - 3 / 4 -> 0
1 / 2 - 3 * 4 -> -12
1 / 2 / 3 + 4 -> 4
1 / 2 / 3 - 4 -> -4
1 / 2 / 3 / 4 -> 0
1 / 2 / 3 * 4 -> 0
1 / 2 * 3 + 4 -> 4
1 / 2 * 3 - 4 -> -4
1 / 2 * 3 / 4 -> 0
1 / 2 * 3 * 4 -> 0
1 * 2 + 3 + 4 -> 9
1 * 2 + 3 - 4 -> 1
1 * 2 + 3 / 4 -> 2
1 * 2 + 3 * 4 -> 14
1 * 2 - 3 + 4 -> 3
1 * 2 - 3 - 4 -> -5
1 * 2 - 3 / 4 -> 2
1 * 2 - 3 * 4 -> -10
1 * 2 / 3 + 4 -> 4
1 * 2 / 3 - 4 -> -4
1 * 2 / 3 / 4 -> 0
1 * 2 / 3 * 4 -> 0
1 * 2 * 3 + 4 -> 10
1 * 2 * 3 - 4 -> 2
1 * 2 * 3 / 4 -> 1
1 * 2 * 3 * 4 -> 24

使用這種方法,計算所有可能的運算符組合(包括用括號分組和重新排序)會更加復雜。

如果要將結果打印為字符串,則應執行以下操作:

int a=1,b=2,c=3,w=4,result;
char d='+',e='-',f='/',g='*';

//a d b g w  =result;
printf("%d %c %d %c %d", a, d, b, g, w);

但是,如果要計算表達式的結果,則需要創建一個函數來執行此操作。 這樣的東西。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM