【问题标题】:push and pop using array of doubles使用双精度数组推送和弹出
【发布时间】:2013-09-18 22:49:09
【问题描述】:

我有一个任务要求我用随机变量填充堆栈并以 FILO 顺序将它们弹出。虽然我设法仅使用 int 类型使其工作,但似乎现在我需要更改它以实现一个双精度数组,它会使用 double 类型填充数组并继续弹出双精度数堆叠直到它为空并打印它们。我试过只改变这两个函数的类型,但不断出错,我不知道为什么。顺便说一句,这是我到目前为止所拥有的。任何帮助将不胜感激。

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

#define STACK_SIZE  10

#define STACK_FULL   -2
#define STACK_EMPTY -1
#define NORMAL          0

int myerror = NORMAL;

void push(double [],
          double,   // input - data being pushed onto the stack
          double **,    // input/output - pointer to pointer to the top of stack
          int);     // constant - maximum capacity of stack

double          // output - data being popped out from the stack
pop(double [],  // input/output - the stack
    double **); // input/output - pointer to pointer to top of stack

void push(double stack[],
          double item,
          double **top,
          int max_size)
{
    stack[++(**top)] = item;
}

double pop(double stack[],
           double **top)
{
    return stack[(**top)--];
    return 0.0;
}

int main()
{
    double s[STACK_SIZE];
    double *s_top = NULL;

    srand(time(NULL));
    char randChar = ' ';
    double i = 0;
    double j=0;
    double randNum = 0;

    for (i = 0; i < STACK_SIZE; i++){
        randNum = 33 + (double)(rand() % ((126-33)+ 1 ));
        randChar = (double) randNum;
        push(s,randChar, &(*s_top), STACK_SIZE);

        printf ("Random characters: %c\n", randChar);}

    printf("-----------\n");

    for(j=STACK_SIZE; j>0; j--){
        printf("Random characters: %c\n", pop(s, & *s_top));
    }

    return 0;
}

顺便说一句,这些是错误

stack.c:在函数“push”中:stack.c:28:错误:数组下标不是 一个整数stack.c:在函数'pop'中:stack.c:35:错误:数组 下标不是整数stack.c:在函数'main'中:stack.c:42: 警告:初始化使指针从整数而不进行强制转换 stack.c:53:警告:从不兼容传递“push”的参数 3 指针类型 stack.c:60:警告:传递“pop”的参数 2 不兼容的指针类型 stack.c:60:警告:格式“%c”需要 输入“int”,但参数 2 的类型为“double” stack.c:60:警告: 格式“%c”需要类型“int”,但参数 2 的类型为“double”

基本上这是我在使用整数类型之前所拥有的并且它正在工作,现在他给出了指示并希望我们将其更改为双精度类型,我试图将它们合并但无济于事。

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

#define STACK_SIZE 10
#define STACK_EMPTY -1

void push(char [], // input/ouput - the stack
          char,    // input - data being pushed onto the stack
          int *,   // input/output - pointer to the index of the top of stack
          int);    // constant - maximum size of stack

char           // output - data being popped out from the stack
pop(char [],  // input/output - the stack
    int *);   // input/output - pointer to the index of the top of stack

void push(char stack[],
          char item,
          int *top,
          int max_size){

    stack[++(*top)] = item;

}

char pop(char stack[],
         int *top){


    return stack[(*top)--];

    // Return STACK_EMPTY if the stack is empty.

    return STACK_EMPTY;
}

int main(){
    char s[STACK_SIZE];
    int s_top = STACK_EMPTY; // Pointer points to the index of the top of the stack

    srand(time(NULL));

    char randChar = ' ';
    int i = 0;
    int j=0;
    int randNum = 0;

    for (i = 0; i < STACK_SIZE; i++){
        randNum = 33 + (int)(rand() % ((126-33)+ 1 ));
        randChar = (char) randNum;
        push(s,randChar, &s_top, STACK_SIZE);

        printf ("Random characters: %c\n", randChar);}

    printf("-----------\n");

    for(j=STACK_SIZE; j>0; j--){
        printf("Random characters: %c\n", pop(s, &s_top));
    }


    return 0;
}

好的,这就是他要求我们做的,我认为这会更容易

“您之前在堆栈上实现了 push 和 pop 操作,在这里,您被要求再次执行此操作,但有 4 个主要更改,如下所述:

  • 堆栈将采用双精度数组的形式。
  • push() 的第三个参数和 pop() 的第二个参数将 采用双**顶部的形式,即指向存储当前栈顶元素地址的指针。

  • 为您创建了一个全局整数变量 myerror。它的值可以是 STACK_FULL、STACK_EMPTY 和 NORMAL。在你的 push() 和 pop() 函数中使用这个变量来通知 main() 函数操作的状态。 "

【问题讨论】:

  • 你读过错误吗?你能把它们贴出来吗?看起来您将top 转换为双精度,但它是一个索引,因此它应该保持为整数。虽然,如果它是一个索引而不是堆栈指针,我不明白为什么它是一个双指针(就像两个 *s 而不是一个)。
  • 栈顶不应该是double,应该是正则整数类型。它也不应该是一个指针到指针。并且弹出功能甚至不需要传递堆栈数组。如果遇到它应该返回错误状态,如果没有发生则简单地减少堆栈顶部。 top 函数应该拉栈顶值(但我相信你的导师有其他想法)。
  • ++(**top)??我可以看到你想要做什么,但我不明白为什么它是双指针或 double...
  • 老师给我们的部分说明说我们应该使用指向指针的指针,我对他的意思有点困惑
  • @user233942 对于静态堆栈,您不需要双指针,因此您的讲师的作业是使用双指针的非常糟糕的应用。您所需要的只是基指针(堆栈数组)和顶部索引(整数)和一些指针数学。我知道你如何可以使用一个,但这样做毫无意义。

标签: c arrays


【解决方案1】:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define STACK_SIZE 10

typedef struct
{
    double items[STACK_SIZE];
    double* next;
} Stack;

void init(Stack* s)
{
    s->next = s->items;
}

void push(Stack* s, double val)
{
    if (s->next >= s->items + STACK_SIZE)
       fprintf(stderr, "stack overflow\n");
    else
    {
        *s->next++ = val;
        printf("push %g\n", val);
    }
}

void pop(Stack* s)
{
    if (s->next == s->items)
       fprintf(stderr, "stack underflow\n");
    else
        printf("pop %g\n", *--s->next);
}

int main(void)
{
    Stack s;
    init(&s);

    srand(time(NULL));

    for (int i = 0; i < STACK_SIZE; i++)
        push(&s, (double)rand());

    printf("-----------\n");

    for (int i = 0; i < STACK_SIZE; i++)
        pop(&s);

    return 0;
}     

【讨论】:

    【解决方案2】:

    我相当有信心这符合本次任务的预期。请注意使用按地址指针参数(即指向指针的指针)来记住堆栈顶部的位置。双指针在你第一次真正使用时有点令人生畏,老实说,这是一个如何使用双指针的非常糟糕的例子。

    请注意,使用 ptr-to-ptr 数组基的唯一真正用途是测试您已经拥有多少元素的限制。正如我所说,有点无意义。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    
    #define STACK_SIZE  10
    
    #define STACK_FULL   -2
    #define STACK_EMPTY -1
    #define NORMAL          0
    
    int push(double stack[], double value, double **top, int sizemax)
    {
        if (*top - stack < sizemax)
        {
            **top = value;
            ++*top;
            return NORMAL;
        }
        return STACK_FULL;
    }
    
    int pop(double stack[], double **top, double *result)
    {
        if (*top - stack > 0)
        {
            --*top;
            *result = **top;
            return NORMAL;
        }
        return STACK_EMPTY;
    }
    
    
    int main()
    {
        double s[STACK_SIZE];
        double *s_top = s;
        double randNum = 0;
        double i = 0;
    
        srand((unsigned)time(NULL));
    
        for (i = 0; i < STACK_SIZE; i++)
        {
            randNum = 33 + (double)(rand() % ((126-33)+ 1 ));
            printf("Random value: %f\n", randNum);
            push(s, randNum, &s_top, STACK_SIZE);
        }
    
        printf("-----------\n");
    
        while (pop(s, &s_top, &randNum) != STACK_EMPTY)
            printf("Random value: %f\n", randNum);
    
        return 0;
    }
    

    这样做很容易出错,因为您可以为堆栈顶部传递任何您喜欢的值,即使是从未使用基地址s[] 初始化的值。使用int 偏移量(当然是按地址)比使用双指针要好得多。因此,我说它不适合这项任务的原因之一。


    关于您发布的代码。我可以把它撕掉,但很明显你对指针算术或 ptr-to-ptr 情况不满意(尤其是在它们不适合的作业中,我想)。然而,有些事情值得注意。

    1. 任何时候你看到自己这样做:&amp;(*(var)) 你就知道有些不对劲。它既不正确,也无法编译。有趣的是,相反的顺序不是未定义的,而是毫无意义的:*(&amp;(var)) 等价于var

    2. 所有这些函数都应该返回状态或值。请注意我对 pop 所做的更改。此外,通常一个函数有empty()top() 之类的函数,用于堆栈、队列、列表等。正确的返回值允许我按照上面代码中定义的方式编写最终的while-loop

    3. 注意printf() 说明符。当您将所有“char”替换为“double”(无论如何都不会工作)时,您从未更改过您的,因此将double 发送到printf(),它需要一个整数类型。它不会崩溃,但它肯定也不会是正确的输出。 (如果您犯了相反的错误,将char 发送到%f 说明符,可能会崩溃)。

    4. 不要全局替换数据类型并期望您的代码只是编译。很少有那么简单(正如您发现的那样)。

    5. 根据此处发布的代码判断,查看您的 char 实现是否存在类似问题。

    希望对你有帮助。

    【讨论】:

    • 是的,我相信这就是他想要的,我将如何运行上述推送和弹出操作,直到用户指定他希望它结束​​?
    • @user233942 无关的问题。那是一个用户输入循环。花一些时间在你的课本上。我敢肯定,他们会有样品。
    • 好的,谢谢你的帮助和指点,很清楚很有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-07
    • 1970-01-01
    • 1970-01-01
    • 2020-10-14
    • 2012-04-08
    • 1970-01-01
    相关资源
    最近更新 更多