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

结构体指针指向另一结构体,如何通过前者打印后者的值?附程序说明

如何打印被结构体指针指向的结构体值(栈节点+学生结构体场景)

嘿,我来帮你搞定这个问题!本质上这就是如何通过结构体内部的指针访问另一个结构体成员的问题,结合你提到的栈节点(NODE)和学生结构体(ALUNO)的场景,我给你一步步拆解:

第一步:先明确结构体定义

首先我们把你提到的两个结构体写出来,NODE是带泛型指针和自指向指针的栈节点,ALUNO是被指向的目标结构体:

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

// 学生结构体:被NODE的泛型指针指向
typedef struct {
    int matricula;  // 学号
    char nome[50];  // 姓名
    float nota;     // 成绩
} ALUNO;

// 栈节点结构体:自指向实现栈,带泛型指针存储数据
typedef struct node {
    void* data;          // 泛型指针,指向ALUNO实例
    struct node* next;   // 自指向指针,连接下一个节点
} NODE;

第二步:理解核心访问逻辑

NODE里的data是void*(无类型指针),它可以指向任意类型的数据,但不能直接访问ALUNO的成员。要打印ALUNO的值,必须先把void*强制转换为ALUNO*类型,之后就能像普通结构体指针那样访问成员了。

第三步:结合你提到的辅助函数实现完整流程

我们先实现你说的createNode、preencherNode、pushNode函数,再写专门的打印函数:

1. 创建空节点(createNode)

NODE* createNode() {
    NODE* newNode = (NODE*)malloc(sizeof(NODE));
    if (!newNode) {
        printf("内存分配失败!\n");
        exit(EXIT_FAILURE);
    }
    newNode->data = NULL;
    newNode->next = NULL;
    return newNode;
}

2. 填充节点数据(preencherNode)

把ALUNO的内容存入节点的data指针,注意要先给ALUNO分配内存:

void preencherNode(NODE* node, int mat, const char* nome, float nota) {
    // 为学生数据分配内存
    ALUNO* aluno = (ALUNO*)malloc(sizeof(ALUNO));
    aluno->matricula = mat;
    strcpy(aluno->nome, nome);
    aluno->nota = nota;
    // 让节点的data指向这个学生实例
    node->data = aluno;
}

3. 压入节点到栈顶(pushNode)

实现栈的压入操作,维护栈顶指针:

void pushNode(NODE** top, NODE* newNode) {
    newNode->next = *top;
    *top = newNode;
}

4. 核心:通过NODE打印ALUNO数据

这就是你最关心的部分,强制转换指针后访问成员:

void printAlunoFromNode(NODE* node) {
    // 先判断节点和数据是否为空,避免空指针错误
    if (!node || !node->data) {
        printf("节点为空或无有效数据!\n");
        return;
    }
    // 把void*转成ALUNO*
    ALUNO* aluno = (ALUNO*)node->data;
    // 打印结构体成员
    printf("学号:%d\n", aluno->matricula);
    printf("姓名:%s\n", aluno->nome);
    printf("成绩:%.2f\n", aluno->nota);
}

第四步:完整示例演示

我们写个主函数,把整个流程串起来,看看怎么调用第一个结构体(NODE)打印第二个结构体(ALUNO)的值:

int main() {
    NODE* stackTop = NULL;  // 栈顶指针初始为空

    // 创建第一个节点并填充学生数据
    NODE* node1 = createNode();
    preencherNode(node1, 1001, "Matheus Dias", 8.7);
    pushNode(&stackTop, node1);

    // 创建第二个节点
    NODE* node2 = createNode();
    preencherNode(node2, 1002, "Ana Costa", 9.2);
    pushNode(&stackTop, node2);

    // 打印栈顶节点的学生信息(通过NODE访问ALUNO)
    printf("=== 栈顶学生信息 ===\n");
    printAlunoFromNode(stackTop);

    // 打印下一个节点的学生信息(顺着自指向指针遍历)
    printf("\n=== 第二个学生信息 ===\n");
    printAlunoFromNode(stackTop->next);

    // 记得释放内存,避免内存泄漏
    NODE* temp;
    while (stackTop) {
        temp = stackTop;
        stackTop = stackTop->next;
        free(temp->data);  // 先释放ALUNO的内存
        free(temp);        // 再释放NODE的内存
    }

    return 0;
}

关键总结

  • 必须对void*类型的指针做强制类型转换,才能访问目标结构体的成员
  • 要确保data指针已经指向有效的ALUNO内存(比如通过preencherNode分配了内存),否则会触发空指针异常
  • 如果是遍历栈结构(自指向的节点链),只需要顺着next指针逐个访问每个NODE,重复转换和打印步骤即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:42:46