堆栈和引用传递
Stack and passing by reference
假设我有这个结构。
typedef struct Symbol {
char* name;
/* Other variables declared here... */
struct Symbol *next;
}Symbol;
我想要做的是将这些 Symbol 中的一些插入堆栈中。再说其他A.D.T。这些 Symbol 将被插入。
因此,出于这个原因,我创建了一个 func
类型的结构来处理我的堆栈,如下所示:
typedef struct func{
Symbol* sym;
struct func* next
}func;
并声明了一个指向堆栈 func* funcstack;
的指针,它将用作我的堆栈的 head。
现在处理栈操作的函数如下
/**
* @brief
*/
func* push_func(func* head, Symbol* ret) {
func* tmp = (func*)malloc(sizeof(func));
if (!tmp) {
fprintf(stderr, "push_func: Allocation error!\n");
exit(-1);
}
tmp->sym = ret;
tmp->next = head;
head = tmp;
return head;
}
/**
* @brief
*/
func* pop_func(func* head, Symbol* ret) {
if (!head) {
printf("pop_func: Trying to pop from empty funcstack!!\n");
exit(-1);
}
func* tmp = head;
ret = head->sym;
head = head->next;
free(tmp);
return head;
}
/**
* @brief
*/
func* top_func(func* head, Symbol* ret) {
if (!head) {
printf("top_func: Trying to top from empty funcstack!!\n");
exit(-1);
}
else {
ret = head->sym;
return head;
}
}
到目前为止,我想澄清一下我的实现是否正确。虽然,我认为肯定缺少某些东西。
我这样称呼push
:
Symbol* f = malloc(sizeof(Symbol));
f->name = strdup("Hello");
funcstack = push_func(funcstack, f);
在我的实施过程中,我这样调用 top
和 pop
:
Symbol* f;
funcstack = top_func(funcstack, f);
funcstack = pop_func(funcstack, f);
出于测试目的,我在该点下方添加了一个 printf("f->name = %s", f->name);
。从理论上讲,此时 f
应该指向一个 特定的符号 因为我的堆栈 不应该 在该点是空的这就是所谓的。所以我希望我的 printf()
打印这样的东西: f->name = hello
但是我得到 garbage (f->name = �E�)
为什么会这样?我该如何解决这个问题?我认为答案在 call-by-reference
和 call-by-value
中,我在处理自声明数据类型时无法理解。我使用 C 作为我的实现语言。
这只是@TomKarzes 回答的转发
您没有在 top_func 和 pop_func 中使用 ret。您只是在做一个本地作业,该作业在 return 时被丢弃。如果你想使用 ret 来 return 一些东西,那么你需要分配给 *ret。所以你需要添加一个间接级别,这样它就是一个Symbol **,然后在调用时传递f的地址。然后函数可以分配给 *ret 并且 f 将在调用者中更新。
您没有在 top_func
和 pop_func
中使用 ret
。您只是在做一个本地作业,该作业在 return 时被丢弃。如果你想使用 ret
到 return 的东西,那么你需要分配给 *ret
。所以你需要添加一个间接级别,所以它是一个 Symbol **
,然后在你调用时传递 f
的地址。然后函数可以分配给 *ret
并且 f
将在调用者中更新。 –
假设我有这个结构。
typedef struct Symbol {
char* name;
/* Other variables declared here... */
struct Symbol *next;
}Symbol;
我想要做的是将这些 Symbol 中的一些插入堆栈中。再说其他A.D.T。这些 Symbol 将被插入。
因此,出于这个原因,我创建了一个 func
类型的结构来处理我的堆栈,如下所示:
typedef struct func{
Symbol* sym;
struct func* next
}func;
并声明了一个指向堆栈 func* funcstack;
的指针,它将用作我的堆栈的 head。
现在处理栈操作的函数如下
/**
* @brief
*/
func* push_func(func* head, Symbol* ret) {
func* tmp = (func*)malloc(sizeof(func));
if (!tmp) {
fprintf(stderr, "push_func: Allocation error!\n");
exit(-1);
}
tmp->sym = ret;
tmp->next = head;
head = tmp;
return head;
}
/**
* @brief
*/
func* pop_func(func* head, Symbol* ret) {
if (!head) {
printf("pop_func: Trying to pop from empty funcstack!!\n");
exit(-1);
}
func* tmp = head;
ret = head->sym;
head = head->next;
free(tmp);
return head;
}
/**
* @brief
*/
func* top_func(func* head, Symbol* ret) {
if (!head) {
printf("top_func: Trying to top from empty funcstack!!\n");
exit(-1);
}
else {
ret = head->sym;
return head;
}
}
到目前为止,我想澄清一下我的实现是否正确。虽然,我认为肯定缺少某些东西。
我这样称呼push
:
Symbol* f = malloc(sizeof(Symbol));
f->name = strdup("Hello");
funcstack = push_func(funcstack, f);
在我的实施过程中,我这样调用 top
和 pop
:
Symbol* f;
funcstack = top_func(funcstack, f);
funcstack = pop_func(funcstack, f);
出于测试目的,我在该点下方添加了一个 printf("f->name = %s", f->name);
。从理论上讲,此时 f
应该指向一个 特定的符号 因为我的堆栈 不应该 在该点是空的这就是所谓的。所以我希望我的 printf()
打印这样的东西: f->name = hello
但是我得到 garbage (f->name = �E�)
为什么会这样?我该如何解决这个问题?我认为答案在 call-by-reference
和 call-by-value
中,我在处理自声明数据类型时无法理解。我使用 C 作为我的实现语言。
这只是@TomKarzes 回答的转发
您没有在 top_func 和 pop_func 中使用 ret。您只是在做一个本地作业,该作业在 return 时被丢弃。如果你想使用 ret 来 return 一些东西,那么你需要分配给 *ret。所以你需要添加一个间接级别,这样它就是一个Symbol **,然后在调用时传递f的地址。然后函数可以分配给 *ret 并且 f 将在调用者中更新。
您没有在 top_func
和 pop_func
中使用 ret
。您只是在做一个本地作业,该作业在 return 时被丢弃。如果你想使用 ret
到 return 的东西,那么你需要分配给 *ret
。所以你需要添加一个间接级别,所以它是一个 Symbol **
,然后在你调用时传递 f
的地址。然后函数可以分配给 *ret
并且 f
将在调用者中更新。 –