C 中的堆栈数组实现 - 理解按引用传递
stack array implementation in C - understanding pass by reference
所以这是一个非常简单的堆栈实现(它是仅包含准系统推送弹出函数的数组)。我试图理解为什么在将值推入数组后我的索引没有改变。我最初将 itop 变量作为 "int itop = 0" 位于 main 中,但由于 itop 值保持为 0,我认为这可能是一个传递引用的问题,其中 C 获取了该值的副本但没有实际上改变了传入的值本身。所以我想好吧,我会在顶部将它设为静态 int(我知道这不是最佳实践,因为不安全的线程行为......)但它仍然行不通。
有人指点我理解这个基本概念吗?谢谢
#include <stdio.h>
void push(int a[], int, int);
int pop(int a[], int);
static int itop = 0;
int main(void){
int stack[100];
push(stack, itop, 1);
push(stack, itop, 2);
printf("index is %d\n", itop);
int p1 = pop(stack, itop);
printf("index is %d\n", itop);
int p2 = pop(stack, itop);
int p3 = pop(stack, itop);
printf("popped elements: %d %d %d\n", p1, p2, p3);
return 0;
}
void push(int a[], int ind, int elem){
a[ind++] = elem;
}
int pop(int a[], int ind){
if (ind < 0){
return -1;
}
else {
return a[ind--];
}
}
在 C 中,参数是按值传递的。因此这是错误的:
void push(int a[], int ind, int elem){
a[ind++] = elem; // ind is a local variable here
// modifying it won't have any effect outside
// the push function
}
...
push(foo, bar, elem); // bar won't be modified
你想要这个:
void push(int a[], int *ind, int elem){
a[(*ind)++] = elem;
}
...
push(foo, &bar, elem); // you pass a pointer to bar
// and bar will be modified
pop
需要同样的原则。
这是最基本的C知识。
您没有通过引用传递变量 itop
。您正在按价值传递它。这两个函数都处理变量 itop 的副本,因此更改副本不会影响原始对象。
C 中的引用传递是指通过指针间接传递对象。
函数 pop 在这些语句中也有错误
if (ind < 0){
^^^^^^^
和
return a[ind--];
^^^^^
可以通过以下方式声明和定义函数
void push(int a[], int *ind, int elem){
a[( *ind )++] = elem;
}
int pop(int a[], int *ind){
if (*ind == 0){
return -1;
}
else {
return a[--*ind];
}
}
注意,通常函数 pop 有一个缺点,不允许将 -1 存储在堆栈中,因为函数的返回值 -1 是不明确的,可能意味着错误或堆栈的实际元素.
函数可以这样定义
int pop( int a[], int *ind, int *value )
{
int error = *ind == 0 ? -1 : 0;
if ( error == 0 )
{
*value = a[--*ind];
}
return error;
}
所以这是一个非常简单的堆栈实现(它是仅包含准系统推送弹出函数的数组)。我试图理解为什么在将值推入数组后我的索引没有改变。我最初将 itop 变量作为 "int itop = 0" 位于 main 中,但由于 itop 值保持为 0,我认为这可能是一个传递引用的问题,其中 C 获取了该值的副本但没有实际上改变了传入的值本身。所以我想好吧,我会在顶部将它设为静态 int(我知道这不是最佳实践,因为不安全的线程行为......)但它仍然行不通。
有人指点我理解这个基本概念吗?谢谢
#include <stdio.h>
void push(int a[], int, int);
int pop(int a[], int);
static int itop = 0;
int main(void){
int stack[100];
push(stack, itop, 1);
push(stack, itop, 2);
printf("index is %d\n", itop);
int p1 = pop(stack, itop);
printf("index is %d\n", itop);
int p2 = pop(stack, itop);
int p3 = pop(stack, itop);
printf("popped elements: %d %d %d\n", p1, p2, p3);
return 0;
}
void push(int a[], int ind, int elem){
a[ind++] = elem;
}
int pop(int a[], int ind){
if (ind < 0){
return -1;
}
else {
return a[ind--];
}
}
在 C 中,参数是按值传递的。因此这是错误的:
void push(int a[], int ind, int elem){
a[ind++] = elem; // ind is a local variable here
// modifying it won't have any effect outside
// the push function
}
...
push(foo, bar, elem); // bar won't be modified
你想要这个:
void push(int a[], int *ind, int elem){
a[(*ind)++] = elem;
}
...
push(foo, &bar, elem); // you pass a pointer to bar
// and bar will be modified
pop
需要同样的原则。
这是最基本的C知识。
您没有通过引用传递变量 itop
。您正在按价值传递它。这两个函数都处理变量 itop 的副本,因此更改副本不会影响原始对象。
C 中的引用传递是指通过指针间接传递对象。
函数 pop 在这些语句中也有错误
if (ind < 0){
^^^^^^^
和
return a[ind--];
^^^^^
可以通过以下方式声明和定义函数
void push(int a[], int *ind, int elem){
a[( *ind )++] = elem;
}
int pop(int a[], int *ind){
if (*ind == 0){
return -1;
}
else {
return a[--*ind];
}
}
注意,通常函数 pop 有一个缺点,不允许将 -1 存储在堆栈中,因为函数的返回值 -1 是不明确的,可能意味着错误或堆栈的实际元素.
函数可以这样定义
int pop( int a[], int *ind, int *value )
{
int error = *ind == 0 ? -1 : 0;
if ( error == 0 )
{
*value = a[--*ind];
}
return error;
}