堆叠并通过引用传递

时间:2016-05-31 09:54:25

标签: c struct scope stack pass-by-reference

我们说我有这个结构。

typedef struct Symbol {
    char* name;
    /* Other variables declared here... */
    struct Symbol *next;
}Symbol;

我想要做的是在堆栈中插入一些符号。除了A.D.T.这些符号将被插入。 因此,我创建了一个类型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);

在我的实施过程中,我这样称呼toppop

Symbol* f;
funcstack = top_func(funcstack, f);
funcstack = pop_func(funcstack, f);

出于测试目的,我在这一点下添加了printf("f->name = %s", f->name);。从理论上讲,此时,f应该指向特定符号,因为我的堆栈不应该在被调用的点处为空。所以我希望我的printf()打印出这样的内容:f->name = hello但是我得到垃圾(f-> name =�E�)

为什么会这样?我怎么能解决这个问题呢?我认为答案在call-by-referencecall-by-value中存在,在处理自我声明的数据类型时我无法理解。我使用 C 作为我的实现语言。

2 个答案:

答案 0 :(得分:3)

您未在rettop_func中使用pop_func。你只是在做一个本地的作业,在返回时会被丢弃。如果您希望使用ret返回某些内容,则需要指定*ret。因此,您需要添加一个间接级别,以便它是Symbol **,然后在拨打电话时传递f的地址。然后,函数可以分配给*retf将在调用者中更新。 -

答案 1 :(得分:0)

这只是来自@TomKarzes答案的转贴

你没有在top_func和pop_func中使用ret。你只是在做一个在返回时被丢弃的本地任务。如果您希望使用ret返回某些内容,则需要指定* ret。因此,您需要添加一个间接级别,以便它是符号**,然后在拨打电话时传递f的地址。然后函数可以分配给* ret,f将在调用者中更新。