【指针与结构体的使用详解】

发布于:2025-07-01 ⋅ 阅读:(15) ⋅ 点赞:(0)

指针与结构体的使用详解(C语言)

在C语言中,结构体(struct)指针(pointer) 是两个非常重要的概念。将它们结合使用,可以实现很多复杂的数据结构,比如链表、树、图等。


一、结构体基本使用

1. 定义结构体

struct Person {
    char name[50];
    int age;
    float height;
};

这定义了一个名为 Person 的结构体类型,包含三个成员:名字、年龄、身高。


2. 声明结构体变量

struct Person p1;

也可以用 typedef 简化:

typedef struct {
    char name[50];
    int age;
    float height;
} Person;

Person p2;  // 直接使用 Person 类型

二、指针与结构体的结合使用

1. 定义结构体指针

struct Person *ptr;

或使用 typedef 后的简写:

Person *ptr;

2. 给结构体指针分配内存

ptr = (Person*)malloc(sizeof(Person));

注意:使用完后记得释放内存:

free(ptr);

3. 访问结构体成员(两种方式)

  • 点运算符(.):用于普通结构体变量
  • 箭头运算符(->):用于结构体指针
Person p;
p.age = 20;

Person* ptr = &p;
ptr->age = 25;  // 等价于 (*ptr).age = 25;

三、指针与结构体在链表中的典型应用

链表是最经典的结构体与指针结合使用的例子。

1. 定义链表结构体

typedef struct Node {
    int data;
    struct Node* next;  // 指向下一个节点
} Node, *LinkList;
  • Node 表示链表节点;
  • LinkList 是指向 Node 的指针,常用于表示链表头指针。

2. 创建链表节点

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

3. 尾插法创建链表

LinkList createList() {
    int value;
    LinkList head = NULL, tail = NULL;

    printf("请输入整数序列(输入9999结束):\n");
    while (1) {
        scanf("%d", &value);
        if (value == 9999) break;

        Node* newNode = createNode(value);
        if (head == NULL) {
            head = tail = newNode;
        } else {
            tail->next = newNode;
            tail = newNode;
        }
    }
    return head;
}

4. 打印链表

void printList(LinkList head) {
    Node* current = head;
    while (current != NULL) {
        printf("%d -> ", current->data);
        current = current->next;
    }
    printf("NULL\n");
}

5. 主函数调用

int main() {
    LinkList list = createList();
    printList(list);

    // 释放内存(可选)
    Node* current = list;
    while (current != NULL) {
        Node* temp = current;
        current = current->next;
        free(temp);
    }

    return 0;
}

四、你可能遇到的问题与解答


❓1. typedef struct Node { ... } Node, *LinkList; 是什么意思?

  • Node 是结构体类型别名,等价于 struct Node
  • LinkList 是指向 Node 的指针别名,等价于 Node*
  • 常用于链表定义,简化写法。

示例

LinkList head;  // 等价于 Node* head;

❓2. 为什么用指针访问结构体成员要用 -> 而不是 .

  • . 用于普通结构体变量;
  • ->(*ptr). 的简写方式,用于结构体指针。

示例

Node node;
node.data = 10;  // 正确

Node* ptr = &node;
ptr->data = 20;  // 正确
(*ptr).data = 30;  // 也正确,但写法麻烦

❓3. malloc 是做什么的?为什么结构体要动态分配?

  • malloc 是在堆上分配内存;
  • 结构体变量如果在函数中定义,函数结束后就会被释放;
  • 使用 malloc 可以在函数外部继续访问结构体内容。

示例

Node* createNode(int value) {
    Node* node = (Node*)malloc(sizeof(Node));
    node->data = value;
    node->next = NULL;
    return node;
}

❓4. 为什么要用 typedef

  • 简化结构体声明;
  • 避免每次都写 struct Node
  • 提高代码可读性和可维护性。

不使用 typedef:

struct Node {
    int data;
    struct Node* next;
};
struct Node* head;

使用 typedef:

typedef struct Node {
    int data;
    struct Node* next;
} Node;

Node* head;

❓5. Node* head = NULL;LinkList head = NULL; 是一样的吗?

✅ 是的,它们是等价的。

  • Node* headLinkList head 都是结构体指针;
  • LinkListNode* 的别名。

五、完整示例代码

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

// 定义链表结构体
typedef struct Node {
    int data;
    struct Node* next;
} Node, *LinkList;

// 创建节点
Node* createNode(int value) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = value;
    newNode->next = NULL;
    return newNode;
}

// 创建链表(尾插法)
LinkList createList() {
    int value;
    LinkList head = NULL, tail = NULL;

    printf("请输入整数序列(输入9999结束):\n");
    while (1) {
        scanf("%d", &value);
        if (value == 9999) break;

        Node* newNode = createNode(value);
        if (head == NULL) {
            head = tail = newNode;
        } else {
            tail->next = newNode;
            tail = newNode;
        }
    }
    return head;
}

// 打印链表
void printList(LinkList head) {
    Node* current = head;
    while (current != NULL) {
        printf("%d -> ", current->data);
        current = current->next;
    }
    printf("NULL\n");
}

// 主函数
int main() {
    LinkList list = createList();
    printList(list);

    // 释放内存
    Node* current = list;
    while (current != NULL) {
        Node* temp = current;
        current = current->next;
        free(temp);
    }

    return 0;
}

六、总结

概念 说明
struct 定义结构体类型,封装多个不同类型的变量
typedef 给结构体类型取别名,简化代码
-> 用指针访问结构体成员时使用
malloc 动态分配内存,用于创建结构体节点
Node* / LinkList 都是结构体指针,用于链表操作

✅ 你可能需要练习的场景

  • 创建双向链表(含 prevnext 指针)
  • 使用结构体模拟学生管理系统
  • 用结构体和指针实现栈、队列

网站公告

今日签到

点亮在社区的每一天
去签到