首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我需要使用&在此堆栈实现中传递指向结构的指针

为什么我需要使用&在此堆栈实现中传递指向结构的指针
EN

Stack Overflow用户
提问于 2015-07-08 23:53:37
回答 2查看 159关注 0票数 1

在下面的程序中,我需要使用&-operator将一个参数传递给一个函数,尽管我希望它是一个指针,并且该函数需要一个指针。我为什么要这么做?

该程序使用C中的链接列表和不完整类型实现了一个简单的堆栈。以下是三个必要的文件:

stack.h

代码语言:javascript
复制
#ifndef STACK_H
#define STACK_H

#include <stdbool.h>

struct Stack {
        int number;
        struct Stack *next;
};

/*
 * We declare a pointer to a Stack structure thereby making use of incomplete
 * types. Clients that pull in stack.h will be able to declare variables of type
 * pstack which are pointers to Stack structures. */
typedef struct Stack *pstack;

bool is_empty(pstack *s);
void make_empty(pstack *s);
void push(pstack *s, int new_num);
int pop(pstack *s);

#endif /* STACK_H */

stack.c

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"

bool is_empty(pstack *s)
{
        return !s;
}

void make_empty(pstack *s)
{
        if (!is_empty(s))
                pop(s);
}

int pop(pstack *s)
{
        struct Stack *tmp;
        int i;

        if (is_empty(s)) {
                exit(EXIT_FAILURE);
        }
        tmp = *s;
        i = (*s)->number;
        *s = (*s)->next;
        free(tmp);
        return i;
}

void push(pstack *s, int new_num)
{
        struct Stack *new_node = malloc(sizeof(struct Stack));
        if (!new_node) {
                exit(EXIT_FAILURE);
        }
        new_node->number = new_num;
        new_node->next = *s;
        *s = new_node;
}

stackclient.c

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"

int main(void)
{
  pstack s1;
  int n;

  push(&s1, 1);
  push(&s1, 2);

  n = pop(&s1);
  printf("Popped %d from s1\n", n);
  n = pop(&s1);
  printf("Popped %d from s1\n", n);

  exit(EXIT_SUCCESS);
}

再一次,我认为通过使用

代码语言:javascript
复制
typedef struct Stack *pstack;

以及随后在main()

代码语言:javascript
复制
pstack s1;

我声明一个指向链接列表Stack的指针,因此只需使用

代码语言:javascript
复制
push(s1, 1);

但我真的需要用

代码语言:javascript
复制
push (&s1, 1);

为什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-07-08 23:55:07

所有函数都声明为将pstack*作为参数,这实际上是指向指向Stack结构的指针的指针。只需使用pstack。在这些函数的实现中,您还需要将(*s)的实例替换为s

编辑:正如注释中指出的那样,您实际上在函数实现中写入(*s),并依赖此行为来获得正确性,因此需要将参数保留为pstack*。从概念上讲,这是因为堆栈变量(s1)实际上是堆栈本身的顶部,因此必须由pushpop修改。

票数 4
EN

Stack Overflow用户

发布于 2015-07-09 00:20:18

您需要在pstack *s中使用void push(pstack *s, int new_num) (指向p堆栈的指针),根据您的实现代码,如果要使用pstack s( p堆栈),则不会正确返回new_node

push()中插入节点的两种可能方法

  1. 如果插入到头,它应该是*s = new_node
  2. 如果插入到尾,它可能是s->next = new_node

返回到代码,如果要使用push(s1, 1);,例如,

代码语言:javascript
复制
 //If only use pstack s, the new_node can not be pushed.
 void push(pstack s, int new_num) //it is a wrong implementation for demo
 {
        struct Stack *new_node = malloc(sizeof(struct Stack));
        if (!new_node) {
                exit(EXIT_FAILURE);
        }
        new_node->number = new_num;
        new_node->next = s;
        s = new_node;// WRONG! here, the new_node cannot be kept by s
                     // two typical node insert ways:
                     // 1)if insert to head, it should be *s = new_node
                     // 2)if insert to tail, it could be s->next = new_node
                     //Now, Your code applied the #1 way, so need *s 
 }

因此,应该输入pstack *s,并使用push (&s1, 1);调用

代码语言:javascript
复制
 void push(pstack *s, int new_num)//it is the correct version the same as your post
 {
        struct Stack *new_node = malloc(sizeof(struct Stack));
        if (!new_node) {
                exit(EXIT_FAILURE);
        }
        new_node->number = new_num;
        new_node->next = *s;
        *s = new_node;//here, the new_node could be kept by *s
 }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31305828

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档