当前位置:首页 > 技术 > 正文内容

C语言中的结构体、指针与基础数据结构详解

访客 技术 2026年7月4日 1

结构体与指针的基本用法

在C语言中,结构体(struct)允许我们将多个不同类型的数据组合成一个自定义类型。这类似于高级语言中的对象概念,但更加轻量和底层。例如,要表示一名学生的信息,我们可以将姓名、年龄和成绩封装在一个结构体中。

#include <stdio.h>

// 定义学生信息结构体
struct Student {
    char name[64];
    int age;
    double score;
};

int main() {
    // 声明并初始化结构体变量
    struct Student s1 = {"张三", 20, 88.5};

    // 直接访问成员
    printf("姓名: %s, 年龄: %d, 成绩: %.1f\n", s1.name, s1.age, s1.score);

    return 0;
}

当处理大型结构体或需要在函数间共享数据时,直接传递整个结构体会消耗较多内存和时间。此时使用指针更为高效。指针存储的是变量的内存地址,通过它可以间接访问和修改目标数据。

#include <stdio.h>

struct Student {
    char name[64];
    int age;
    double score;
};

int main() {
    struct Student s1 = {"李四", 21, 92.0};
    struct Student *ptr = &s1;  // 指针指向s1

    // 使用 -> 操作符访问成员
    printf("姓名: %s, 年龄: %d, 成绩: %.1f\n", ptr->name, ptr->age, ptr->score);

    return 0;
}

链表:动态数据组织方式

链表是一种由节点串联而成的线性结构,每个节点包含数据域和指向下一个节点的指针域。相比数组,链表无需连续内存空间,插入和删除操作更灵活。

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

// 链表节点定义
struct ListNode {
    int value;
    struct ListNode *next;
};

// 打印链表所有元素
void display(struct ListNode *head) {
    while (head != NULL) {
        printf("%d ", head->value);
        head = head->next;
    }
    printf("\n");
}

int main() {
    // 创建三个节点
    struct ListNode *first = (struct ListNode*)malloc(sizeof(struct ListNode));
    struct ListNode *second = (struct ListNode*)malloc(sizeof(struct ListNode));
    struct ListNode *third = (struct ListNode*)malloc(sizeof(struct ListNode));

    first->value = 10;
    first->next = second;

    second->value = 20;
    second->next = third;

    third->value = 30;
    third->next = NULL;

    display(first);  // 输出: 10 20 30

    // 释放内存
    free(first);
    free(second);
    free(third);

    return 0;
}

栈:后进先出的操作模型

遵循"后进先出"原则,常用于递归调用、表达式求值等场景。其核心操作是入栈(push)和出栈(pop),通常用数组模拟实现。

#include <stdio.h>
#define STACK_SIZE 100

int stack[STACK_SIZE];
int topIndex = -1;  // 栈顶位置标记

void push(int item) {
    if (topIndex >= STACK_SIZE - 1) {
        printf("栈溢出!\n");
        return;
    }
    stack[++topIndex] = item;
}

int pop() {
    if (topIndex < 0) {
        printf("栈为空!\n");
        return -1;
    }
    return stack[topIndex--];
}

int main() {
    push(100);
    push(200);
    printf("弹出: %d\n", pop());  // 输出 200
    printf("弹出: %d\n", pop());  // 输出 100
    return 0;
}

队列:先进先出的数据流管理

队列采用"先进先出"机制,适用于任务调度、广度优先搜索等应用。它维护两个指针:front 表示队首,rear 表示队尾。

#include <stdio.h>
#define QUEUE_CAPACITY 100

int queue[QUEUE_CAPACITY];
int frontPos = -1, rearPos = -1;

void enqueue(int val) {
    if (rearPos == QUEUE_CAPACITY - 1) {
        printf("队列已满!\n");
        return;
    }
    if (frontPos == -1) frontPos = 0;
    queue[++rearPos] = val;
}

int dequeue() {
    if (frontPos == -1 || frontPos > rearPos) {
        printf("队列为空!\n");
        return -1;
    }
    return queue[frontPos++];
}

int main() {
    enqueue(5);
    enqueue(15);
    printf("取出: %d\n", dequeue());  // 输出 5
    printf("取出: %d\n", dequeue());  // 输出 15
    return 0;
}

二叉树:分层结构的典型代表

二叉树是一种非线性结构,每个节点最多有两个子节点:左子树和右子树。它广泛应用于查找算法、堆排序等领域。

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

struct TreeNode {
    int key;
    struct TreeNode *leftChild;
    struct TreeNode *rightChild;
};

// 创建新节点
struct TreeNode* createNode(int value) {
    struct TreeNode* node = (struct TreeNode*)malloc(sizeof(struct TreeNode));
    node->key = value;
    node->leftChild = NULL;
    node->rightChild = NULL;
    return node;
}

// 前序遍历:根 → 左 → 右
void preorderTraversal(struct TreeNode* root) {
    if (root != NULL) {
        printf("%d ", root->key);
        preorderTraversal(root->leftChild);
        preorderTraversal(root->rightChild);
    }
}

int main() {
    struct TreeNode* root = createNode(1);
    root->leftChild = createNode(2);
    root->rightChild = createNode(3);
    root->leftChild->leftChild = createNode(4);
    root->leftChild->rightChild = createNode(5);

    printf("前序遍历结果: ");
    preorderTraversal(root);  // 输出: 1 2 4 5 3
    printf("\n");

    return 0;
}
标签: 结构体
返回列表

上一篇:Java并发编程中的七种锁机制详解

没有最新的文章了...

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。