首页 智能家居

C 语言指针、结构体、链表:构建高效数据结构基石

分类:智能家居
字数: (8572)
阅读: (7183)
内容摘要:C 语言指针、结构体、链表:构建高效数据结构基石,

在日常开发中,我们经常需要处理各种各样的数据,而如何高效地组织和管理这些数据,就显得至关重要。数据结构学习(1),我们先从 C 语言的基础也是核心部分入手:指针、结构体、链表。它们是构建更复杂数据结构和算法的基础,也是理解操作系统、数据库等底层原理的敲门砖。

指针:C 语言的灵魂

指针是 C 语言的精髓所在,也是很多初学者觉得难以理解的地方。简单来说,指针就是一个变量,它存储的是另一个变量的内存地址。通过指针,我们可以直接访问和修改内存中的数据,这使得 C 语言具有了强大的灵活性和控制力。

指针的声明和使用

int a = 10; // 定义一个整型变量 a
int *p;    // 声明一个指向整型变量的指针 p
p = &a;     // 将变量 a 的地址赋值给指针 p

printf("a 的值:%d\n", a);      // 输出 a 的值
printf("a 的地址:%p\n", &a);    // 输出 a 的地址
printf("p 的值:%p\n", p);      // 输出 p 的值(a 的地址)
printf("*p 的值:%d\n", *p);     // 输出 p 指向的内存地址的值(a 的值)

* 运算符用于解引用,即获取指针指向的内存地址中存储的值。& 运算符用于获取变量的地址

C 语言指针、结构体、链表:构建高效数据结构基石

指针与数组

在 C 语言中,数组名本质上就是一个指向数组首元素的指针。利用指针可以方便地访问数组中的元素。

int arr[5] = {1, 2, 3, 4, 5};
int *ptr = arr; // ptr 指向数组 arr 的首元素

printf("arr[0] 的值:%d\n", arr[0]); // 输出数组第一个元素的值
printf("*ptr 的值:%d\n", *ptr);   // 输出指针 ptr 指向的值(也是数组第一个元素的值)
printf("arr[2] 的值:%d\n", arr[2]); // 输出数组第三个元素的值
printf("*(ptr + 2) 的值:%d\n", *(ptr + 2)); // 指针 ptr 向后移动两个位置,然后解引用

指针的避坑经验

  • 野指针:指针没有被初始化,或者指向的内存已经被释放,此时的指针就是野指针。访问野指针会导致程序崩溃或产生不可预测的结果。初始化指针或者在释放内存后将指针置为 NULL 可以避免野指针。
  • 内存泄漏:使用 malloc 等函数动态分配内存后,如果忘记使用 free 函数释放内存,就会导致内存泄漏。长期运行的程序发生内存泄漏可能会耗尽系统资源。可以使用 valgrind 等工具检测内存泄漏。

结构体:自定义数据类型

结构体是一种复合数据类型,可以将多个不同类型的变量组合在一起,形成一个新的数据类型。这使得我们可以更方便地表示复杂的数据结构,比如用户信息、商品信息等。

C 语言指针、结构体、链表:构建高效数据结构基石

结构体的定义和使用

// 定义一个名为 Person 的结构体
struct Person {
    char name[50]; // 姓名
    int age;       // 年龄
    float height;   // 身高
};

int main() {
    // 声明一个 Person 类型的变量 person1
    struct Person person1;

    // 给 person1 的成员赋值
    strcpy(person1.name, "张三");
    person1.age = 30;
    person1.height = 1.75;

    // 打印 person1 的信息
    printf("姓名:%s\n", person1.name);
    printf("年龄:%d\n", person1.age);
    printf("身高:%.2f\n", person1.height);

    return 0;
}

使用 . 运算符访问结构体的成员。

结构体指针

可以使用指针来操作结构体,这在函数参数传递和动态内存分配时非常有用。

C 语言指针、结构体、链表:构建高效数据结构基石
struct Person *pPerson = &person1; // 声明一个指向 Person 结构体的指针

// 使用 -> 运算符访问结构体指针指向的成员
printf("姓名:%s\n", pPerson->name);
printf("年龄:%d\n", pPerson->age);
printf("身高:%.2f\n", pPerson->height);

使用 -> 运算符通过结构体指针访问其成员。

链表:动态数据结构

链表是一种动态数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。链表可以灵活地插入和删除节点,而不需要像数组那样移动大量的元素。

C 语言指针、结构体、链表:构建高效数据结构基石

链表的定义

// 定义链表节点
struct Node {
    int data;          // 数据
    struct Node *next; // 指向下一个节点的指针
};

链表的基本操作

  • 创建链表:动态分配内存,创建新的节点,并设置节点的数据和指针。
  • 插入节点:在链表的指定位置插入新的节点,需要修改指针的指向。
  • 删除节点:从链表中删除指定的节点,需要修改指针的指向。
  • 遍历链表:从链表的头节点开始,依次访问每个节点的数据。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 定义链表节点
struct Node {
    int data;          // 数据
    struct Node *next; // 指向下一个节点的指针
};

// 创建链表
struct Node* createList() {
    return NULL; // 返回空指针,表示空链表
}

// 插入节点 (头插法)
struct Node* insertNode(struct Node* head, int data) {
    struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); // 分配内存
    if (newNode == NULL) {
        perror("Failed to allocate memory");
        exit(EXIT_FAILURE);
    }
    newNode->data = data;      // 赋值数据
    newNode->next = head;      // 新节点的next指向旧的头节点
    head = newNode;            // 新节点成为新的头节点
    return head;               // 返回新的头节点
}

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

// 释放链表内存
void freeList(struct Node* head) {
    struct Node* current = head;
    while (current != NULL) {
        struct Node* temp = current;
        current = current->next;
        free(temp);
    }
}

int main() {
    struct Node* head = createList(); // 创建空链表

    head = insertNode(head, 10);   // 插入节点
    head = insertNode(head, 20);   // 插入节点
    head = insertNode(head, 30);   // 插入节点

    printList(head);             // 打印链表

    freeList(head);              // 释放链表内存
    head = NULL;                 // 将头指针置空

    return 0;
}

链表的应用场景

链表在许多场景中都有应用,例如:

  • 实现栈和队列:可以使用链表来实现栈和队列这两种常用的数据结构。
  • 动态内存管理:操作系统可以使用链表来管理空闲内存块。
  • 图形图像处理:可以用链表来存储图像的像素数据。

数据结构学习(1) 中的指针、结构体和链表是 C 语言编程的基础,掌握它们对于理解更高级的数据结构和算法至关重要。 熟练运用这些基本功,可以为日后学习 Nginx 反向代理、高并发服务器设计打下坚实基础,甚至在面对宝塔面板的性能瓶颈时,也能从容地进行优化。

C 语言指针、结构体、链表:构建高效数据结构基石

转载请注明出处: 加班到秃头

本文的链接地址: http://m.acea3.store/blog/043149.SHTML

本文最后 发布于2026-04-27 06:27:47,已经过了0天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 猫奴本奴 9 小时前
    结构体那部分讲的挺清晰的,结合实际例子更容易理解。
  • 奶茶续命 6 天前
    链表的操作还是得多练习,尤其是插入和删除节点,一不小心就段错误了。
  • 咸鱼翻身 3 天前
    能不能再详细讲讲双向链表和循环链表啊?感觉实际工作中用的也挺多的。
  • 摆烂大师 5 天前
    链表的操作还是得多练习,尤其是插入和删除节点,一不小心就段错误了。