You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中为何能通过->访问无变量名的二叉树结构体成员?

关于二叉树指针无变量名访问的疑问

先看这段C语言代码:

#include <stdio.h>
#include <stdlib.h>

struct node 
{
    int data;
    struct node *left, *right;
};

struct node *givetree()
{
    struct node *newnode = (struct node*)malloc(sizeof(struct node));
    char choice;
    
    printf("Enter data : ");
    scanf("%d",&newnode->data);
    
    printf("\nWanna fill left of %d ? (y/n) : ",newnode->data);
    scanf("%c",&choice);
    
    if(choice == 'y')
    newnode->left = givetree();
    
    printf("\nWanna fill right of %d ? (y/n) : ",newnode->data);
    scanf("%c",&choice);    

    if(choice == 'y')
    newnode->right = givetree();
    
    return newnode;
}

int main(void) {
    struct node *root = givetree();
    printf("\nThis works : %d",root->left->left->data);

    return 0;
}

疑问

printf("\nThis works : %d",root->left->left->data);这行代码为何能正常运行?该二叉树通过递归创建,root指针接收根节点的指针,但递归函数的局部变量名在函数执行完毕后已销毁,root为何还能访问名为left的结构体成员?我知道这些数据仍存在内存中,但为何没有变量名也能访问?


解答

核心是要分清变量名和内存地址的区别:

  • 你用malloc分配的内存位于堆区,堆内存不会随函数执行结束自动释放,只要没调用free,这块内存里的结构体数据就一直存在。
  • 函数里的局部变量newnode是栈上的指针变量,函数执行完后这个变量名确实会被销毁,但它指向的堆内存地址已经被返回出去了——递归时父节点的newnode->left会接收子节点返回的地址,最终main里的root拿到了根节点的堆内存地址。
  • root->left->left->data的访问逻辑是顺着地址找:root存着根节点的地址,通过它找到根节点结构体,结构体里的left成员是左子节点的地址,再顺着这个地址找到左子节点,它的left又是下一层节点的地址,最终就能拿到对应节点的data值。整个过程不需要依赖函数里的局部变量名,只要内存地址有效就行。

另外提个小问题:你这段代码里的scanf("%c",&choice)有坑——输入完数字按回车的换行符会被当成%c的输入,导致判断逻辑出错,建议改成scanf(" %c",&choice)(注意前面的空格,用来跳过空白字符)。


内容的提问来源于stack exchange,提问作者Rishav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 21:45:29