在这段代码中,我通过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和数组,正如我所说的,我通过值调用传递,但它们也在上面的代码中被修改,但是如何修改呢?
你的代码似乎包含一些错误,所以让我先解决这些问题:
- 在
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
持有/指向的结构体的地址,这个地址可以被修改。