1

嗨,我是 C 的新手,刚刚用该语言编写了我的第一个程序,当我尝试运行它时,不断收到分段错误错误。我确信我在整个代码中犯了多个小错误。我已经经历了它,我无法弄清楚我的错误在哪里。这是我的代码:

// $Id: crpn.c,v 1.1 2013-10-22 13:28:04-07 - - $

#include <assert.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>

int exit_status = EXIT_SUCCESS;
#define EMPTY (-1)
#define SIZE 16

typedef struct stack stack;
struct stack {
   int top;
   int capacity;
   int size;
   double numbers[SIZE];
};

void bad_operator (const char *oper) {
   fflush (NULL);
   fprintf (stderr, "oper=\"%s\"\n", oper);
   fflush (NULL);
   exit_status = EXIT_FAILURE;
   printf("%s: invaild operator\n", oper);
}

void push (stack *the_stack, double number) {
   if (the_stack->size == the_stack->capacity) {
        printf("%a:stack overflow", number);
    }
   else {
        the_stack->numbers[the_stack->size++]=number;
    }
}

void do_binop (stack *the_stack, char oper) {
  if ((the_stack->top)<1) {
        printf("oper=\"%c\":stack underflow\n", oper);
    }
   else {
        double right = the_stack->numbers[the_stack->size--];
        double left = the_stack->numbers[the_stack->size--];
        switch (oper) {
            case '+': push (the_stack, left + right); break;
            case '-': push (the_stack, left - right); break;
            case '*': push (the_stack, left * right); break;
            case '/': push (the_stack, left / right); break;
          }
        }
}

void do_print (stack *the_stack) {
   if (the_stack->top == -1) {
       printf("stack is empty\n");
    }
   else {
       int pos;
       for (pos = 0; pos <= the_stack->top; ++pos) {
          printf("%a\n",the_stack->numbers[pos]);
   }
 }
}

void do_clear (stack *the_stack) {
   the_stack->top = -1;
}

void do_operator (stack *the_stack, const char *oper) {
   switch (oper[0] ) {
         case '+': do_binop (the_stack, '+'); break;
         case '-': do_binop (the_stack, '-'); break;
         case '*': do_binop (the_stack, '*'); break;
         case '/': do_binop (the_stack, '/'); break;
         case ';': do_print (the_stack);      break;
         case '@': do_clear (the_stack);      break;
         default : bad_operator (oper);       break;
   }
}

int main (int argc, char **argv) {
   if (argc != 1) {
      fprintf (stderr, "Usage: %s\n", basename (argv[0]));
      fflush (NULL);
      exit (EXIT_FAILURE);
   }
   stack the_stack;
   the_stack.top = EMPTY;
   char buffer[1024];
   for (;;) {
      int scanrc = scanf ("%1023s", buffer);
      if (scanrc == EOF) break;
      assert (scanrc == 1);
      if (buffer[0] == '#') {
         scanrc = scanf ("%1023[^\n]", buffer);
         continue;
      }
      char *endptr;
      double number = strtod (buffer, &endptr);
      if (*endptr == '\0') {
         push (&the_stack, number);
      }else if (buffer[1] != '\0') {
         bad_operator (buffer);
      }else {
         do_operator (&the_stack, buffer);
      }
   }
   return exit_status;
}
4

3 回答 3

4

让我“教你钓鱼”:

调试器会准确地告诉您故障在哪里。如果您使用的是 IDE(Xcode、Eclipse、VS),它有一个很好的接口,您应该使用它。如果不:

-g使用开关编译您的程序: gcc -g mycode.c. 这会将调试信息添加到可执行文件(使调试器为您提供更好的信息)。

$ gdb my_executable
...
> run
...
Segmentation fault
> where

这将为您提供确切的位置(哪个功能在哪个行号上)。

于 2013-10-24T00:17:05.530 回答
0

你永远不会初始化the_stack.sizethe_stack.capacity.

stack the_stack;
the_stack.top = EMPTY;
the_stack.size = 0;
the_stack.capacity = SIZE;

也不清楚top和之间的预期区别size是什么。push函数递增, sizebutdo_binopdo_printuse top,它永远不会递增。

于 2013-10-24T00:45:19.770 回答
0

问题是,在你的push()函数中:

the_stack->numbers[the_stack->size++]=number;

您永远不会初始化size结构的成员,因此它只是随机垃圾,并且您将超出数组的范围。这似乎也没有多大意义,因为您还有一个top成员,如果您这样做,它将不会被更新。似乎你应该坚持一个top或一个size成员。

于 2013-10-24T00:45:36.610 回答