C语言 这里我通过一个指针结构栈* sp值方法,那么如何在堆栈代码中修改值?



在这段代码中,我通过struct stack * sp作为按值调用,如果它通过按值方法,那么它如何更新函数中的值,如果我错过了一些东西,然后帮助找出?

#include<stdio.h>    
#include<conio.h>

struct stack{
int size ;
int top;
int * arr;
};//creating structures 
void traversal(struct stack *sp){
for(int i=0;i<=sp->top;i++){
printf("%dn",sp->arr[i]);
}
}

int isEmpty(struct stack* ptr){
if(ptr->top == -1){
return 1;
}
else{
return 0;
}
}

int isFull(struct stack* ptr){
if(ptr->top == ptr->size - 1){
return 1;
}
else{
return 0;
}
}

void push(struct stack* ptr, int val){
if(isFull(ptr)){
printf("Stack Overflow! Cannot push %d to the stackn", val);
}
else{
ptr->top=ptr->top+1;//how it gets update when i pass by value
ptr->arr[ptr->top] = val;
}
}

int pop(struct stack* ptr){
if(isEmpty(ptr)){
printf("Stack Underflow! Cannot pop from the stackn");
return -1;
}
else{
int val = ptr->arr[ptr->top];
ptr->top=ptr->top-1;//ptr pass by value how it gets update 
return val;
}
}

int main(){
**struct stack *sp** = (struct stack *) malloc(sizeof(struct stack));//local pointer variable
sp->size = 10;
sp->top = -1;
sp->arr = (int *) malloc(sp->size * sizeof(int));
printf("Stack has been created successfullyn");
push(sp,10);//pass by value in push
push(sp,200);//pass by value in push
traversal(sp);    
printf("the %d element from stack is poppedn",pop(sp));
printf("the %d element from stack is poppedn",pop(sp));
traversal(sp);
return 0;
}

现在,在这段代码中,push和pop修改top和数组,正如我所说的,我通过值调用传递,但它们也在上面的代码中被修改,但是如何修改呢?

你的代码似乎包含一些错误,所以让我先解决这些问题:

  1. main()函数你已经声明了这个**struct stack *sp** = (struct stack *) malloc(sizeof(struct stack))。这是错误的,会产生错误。您似乎想通过值传递sp,声明sp的正确方法是执行struct stack *sp = (struct stack *) malloc(sizeof(struct stack))

你似乎主要对sp指向的结构体如何被你为实现堆栈所做的函数修改感到困惑,让我们通过main()看看会发生什么。

main():

int main(){

struct stack *sp = (struct stack *) malloc(sizeof(struct stack));//local pointer variable

sp->size = 10;
sp->top = -1;
sp->arr = (int *) malloc(sp->size * sizeof(int));

printf("Stack has been created successfullyn");

push(sp,10);//pass by value in push
push(sp,200);//pass by value in push

traversal(sp);
printf("the %d element from stack is poppedn",pop(sp));      
printf("the %d element from stack is poppedn",pop(sp));
traversal(sp);
return 0;
}

那么我将分解它是如何工作的:

首先在main()中我们有一个指向struct stack类型结构体的指针:

struct stack *sp = (struct stack *) malloc(sizeof(struct stack));

这个结构体有一定的内存分配给它,sp存储了这个结构体的地址。

接下来在main()中,将10存储在sp所指向的结构体中名为size的成员中:

sp->size = 10;

还将-1存储在sp指向的结构体top成员中:

sp->top = -1;

最后为这一行的堆栈分配一些内存,在本例中为10个int分配40 bytes:

sp->arr = (int *) malloc(sp->size * sizeof(int));

现在转到函数调用:

你写的是push(sp,10)

让我们进一步细分,看看push()

push():

void push(struct stack* ptr, int val){
if(isFull(ptr)){
printf("Stack Overflow! Cannot push %d to the stackn", val);
}
else{
ptr->top=ptr->top+1;//how it gets update when i pass by value
ptr->arr[ptr->top] = val;
}
}

push()有两个形参,一个是指向结构体的指针,另一个是整数值。

push(sp,10)

现在您将sp传递给第一个参数struct stack* ptr,请记住sp保存着您在main()中为其分配内存的结构体的地址。

你现在把这个地址给struct stack* ptr,这是一个指向push()函数的本地指针。push()结束后,struct stack* ptr将被销毁。

考虑到这一点,你是按值传递sp,因为你实际上并没有传递sp本身(sp的地址),你是将sp指向/持有的地址传递给struct stack* ptr的副本。

现在,因为你传递了sp持有/指向的结构体的地址,这个地址可以被修改。