为什么我需要使用 & 将指针传递给此堆栈实现中的结构
Why do I need to use & to pass a pointer to a struct in this stack implementation
在下面的程序中,我需要使用 &
-operator 将参数传递给函数,尽管我希望它是一个指针,而函数需要一个指针。为什么我需要这样做?
程序在C
中使用链表和不完全类型实现了一个简单的堆栈。以下是三个必要的文件:
stack.h
#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
#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
#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);
}
同样,我认为通过使用
typedef struct Stack *pstack;
之后在 main()
pstack s1;
我正在声明一个指向链表 Stack
的指针,因此只需使用
将 s1
传递给 say push()
就可以了
push(s1, 1);
但我实际上需要使用
push (&s1, 1);
为什么?
你的函数都被声明为以pstack*
作为参数,它实际上是一个指向Stack
结构体的指针。只需使用 pstack
。您还需要在这些函数的实现中将 (*s)
的实例替换为 s
。
编辑: 正如评论中指出的那样,您实际上在函数实现中写入 (*s)
并依赖于此行为的正确性,因此您需要将参数保持为 pstack*
。从概念上讲,这是因为堆栈变量 (s1
) 实际上是堆栈本身的顶部,因此必须由 push
和 pop
.
修改
您需要在void push(pstack *s, int new_num)
中使用pstack *s
(指向pstack的指针),根据您的实现代码,
如果使用 pstack s
( pstack ),new_node
将不会正确返回。
在push()
中插入节点的两种可能方式:
- 如果插入到头部,应该是*s = new_node
- 如果插入到尾部,可以是s->next = new_node
回到代码,如果要使用push(s1, 1);
比如,
//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);
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
}
在下面的程序中,我需要使用 &
-operator 将参数传递给函数,尽管我希望它是一个指针,而函数需要一个指针。为什么我需要这样做?
程序在C
中使用链表和不完全类型实现了一个简单的堆栈。以下是三个必要的文件:
stack.h
#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
#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
#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);
}
同样,我认为通过使用
typedef struct Stack *pstack;
之后在 main()
pstack s1;
我正在声明一个指向链表 Stack
的指针,因此只需使用
s1
传递给 say push()
就可以了
push(s1, 1);
但我实际上需要使用
push (&s1, 1);
为什么?
你的函数都被声明为以pstack*
作为参数,它实际上是一个指向Stack
结构体的指针。只需使用 pstack
。您还需要在这些函数的实现中将 (*s)
的实例替换为 s
。
编辑: 正如评论中指出的那样,您实际上在函数实现中写入 (*s)
并依赖于此行为的正确性,因此您需要将参数保持为 pstack*
。从概念上讲,这是因为堆栈变量 (s1
) 实际上是堆栈本身的顶部,因此必须由 push
和 pop
.
您需要在void push(pstack *s, int new_num)
中使用pstack *s
(指向pstack的指针),根据您的实现代码,
如果使用 pstack s
( pstack ),new_node
将不会正确返回。
在push()
中插入节点的两种可能方式:
- 如果插入到头部,应该是*s = new_node
- 如果插入到尾部,可以是s->next = new_node
回到代码,如果要使用push(s1, 1);
比如,
//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);
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
}