(C++)list列表相关基础用法(C++教程)(STL库基础教程)

源代码:

#include <iostream>
#include <list>using namespace std;int main(){list<int> numbers={10,20,30};numbers.push_front(5);numbers.push_back(40);auto it =numbers.begin();advance(it,2);numbers.insert(it,15);cout<<"该列表的数为:";for(int num:numbers){cout<<num<<"\t";}numbers.remove(15);numbers.push_front(99);numbers.sort();cout<<endl;cout<<"该列表的数为:";for(int num:numbers){cout<<num<<"\t";}
}

运行结果:

该列表的数为:5 10      15      20      30      40
该列表的数为:5 10      20      30      40      99
请按任意键继续. . .

代码详解与相关知识:

C++ std::list 代码解析及与C语言的对比

原始代码解析

#include <iostream>
#include <list>using namespace std;int main(){// 初始化一个包含3个元素的listlist<int> numbers = {10, 20, 30};// 在头部插入元素5numbers.push_front(5);// 在尾部插入元素40numbers.push_back(40);// 获取迭代器并前进2个位置auto it = numbers.begin();advance(it, 2);// 在指定位置插入15numbers.insert(it, 15);// 输出当前列表cout << "该列表的数为:";for(int num : numbers){cout << num << "\t";}// 删除所有值为15的元素numbers.remove(15);// 在头部插入99numbers.push_front(99);// 排序列表numbers.sort();// 输出最终列表cout << endl;cout << "该列表的数为:";for(int num : numbers){cout << num << "\t";}
}

代码执行流程

  1. 初始化列表:[10, 20, 30]

  2. 头部插入5:[5, 10, 20, 30]

  3. 尾部插入40:[5, 10, 20, 30, 40]

  4. 在位置2插入15:[5, 10, 15, 20, 30, 40]

  5. 删除15:[5, 10, 20, 30, 40]

  6. 头部插入99:[99, 5, 10, 20, 30, 40]

  7. 排序后:[5, 10, 20, 30, 40, 99]

C语言实现对比

C语言链表实现(等效功能)

#include <stdio.h>
#include <stdlib.h>typedef struct Node {int data;struct Node* prev;struct Node* next;
} Node;Node* createNode(int value) {Node* newNode = (Node*)malloc(sizeof(Node));newNode->data = value;newNode->prev = NULL;newNode->next = NULL;return newNode;
}void insertFront(Node** head, int value) {Node* newNode = createNode(value);if (*head == NULL) {*head = newNode;return;}newNode->next = *head;(*head)->prev = newNode;*head = newNode;
}void insertBack(Node** head, int value) {Node* newNode = createNode(value);if (*head == NULL) {*head = newNode;return;}Node* temp = *head;while (temp->next != NULL) {temp = temp->next;}temp->next = newNode;newNode->prev = temp;
}void insertAt(Node** head, int position, int value) {if (position == 0) {insertFront(head, value);return;}Node* newNode = createNode(value);Node* temp = *head;for (int i = 0; temp != NULL && i < position - 1; i++) {temp = temp->next;}if (temp == NULL) {free(newNode);return;}newNode->next = temp->next;if (temp->next != NULL) {temp->next->prev = newNode;}temp->next = newNode;newNode->prev = temp;
}void deleteValue(Node** head, int value) {Node* current = *head;while (current != NULL) {if (current->data == value) {if (current->prev != NULL) {current->prev->next = current->next;} else {*head = current->next;}if (current->next != NULL) {current->next->prev = current->prev;}Node* toDelete = current;current = current->next;free(toDelete);} else {current = current->next;}}
}void printList(Node* head) {Node* temp = head;while (temp != NULL) {printf("%d\t", temp->data);temp = temp->next;}printf("\n");
}// 简化的排序实现(实际应该用更高效的排序)
void sortList(Node** head) {if (*head == NULL || (*head)->next == NULL) return;int swapped;Node* ptr1;Node* lptr = NULL;do {swapped = 0;ptr1 = *head;while (ptr1->next != lptr) {if (ptr1->data > ptr1->next->data) {int temp = ptr1->data;ptr1->data = ptr1->next->data;ptr1->next->data = temp;swapped = 1;}ptr1 = ptr1->next;}lptr = ptr1;} while (swapped);
}int main() {Node* head = NULL;// 初始化三个节点insertBack(&head, 10);insertBack(&head, 20);insertBack(&head, 30);// 头部插入5insertFront(&head, 5);// 尾部插入40insertBack(&head, 40);// 在位置2插入15insertAt(&head, 2, 15);printf("该列表的数为:");printList(head);// 删除值为15的节点deleteValue(&head, 15);// 头部插入99insertFront(&head, 99);// 排序sortList(&head);printf("该列表的数为:");printList(head);// 释放内存(实际应用中需要完整实现)return 0;
}

C++与C实现的关键区别

特性C++ std::listC语言实现
内存管理自动管理(RAII)需手动malloc/free
类型安全模板实现,类型安全void*可能造成类型不安全
代码复杂度简洁,高级抽象冗长,需处理底层细节
功能完整性提供完整成员函数(sort, merge等)需自行实现所有功能
异常安全强异常安全保证无异常处理机制
迭代器提供标准迭代器需手动用指针遍历
性能优化经过高度优化实现质量取决于程序员
可维护性接口稳定,文档完善维护成本高
线程安全不同实例可并发访问完全无线程安全保证
扩展性可轻松与其他STL组件配合需额外工作与其他模块集成

关键差异详解

1. 内存管理

  • C++:利用构造函数/析构函数自动管理内存

    {list<int> myList; // 自动初始化// ... 使用list ...
    } // 自动释放所有内存
  • C:需手动分配和释放

    Node* head = NULL; // 初始化
    // ... 使用链表 ...
    // 必须手动释放所有节点
    while (head != NULL) {Node* temp = head;head = head->next;free(temp);
    }

2. 迭代器 vs 指针

  • C++迭代器

    for (auto it = myList.begin(); it != myList.end(); ++it) {cout << *it << " ";
    }
  • C指针遍历

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

3. 高级操作

  • C++内置算法

    myList.sort();    // 内置排序
    myList.unique();  // 去重
    myList.merge(otherList); // 合并
  • C需手动实现

    sortList(&head);  // 自己实现的排序
    removeDuplicates(&head); // 自己实现的去重
    mergeLists(&head1, &head2); // 自己实现的合并

4. 类型安全

  • C++模板

    list<string> stringList; // 只能存储字符串
    stringList.push_back(10); // 编译错误
  • C无类型检查

    typedef struct Node {void* data; // 无类型安全
    } Node;Node* node = (Node*)malloc(sizeof(Node));
    node->data = (void*)10; // 可能造成问题

为什么选择C++ list?

  1. 开发效率:减少样板代码,专注业务逻辑

  2. 安全性:自动内存管理避免内存泄漏

  3. 可维护性:标准接口更易于理解和维护

  4. 性能:标准库实现通常经过充分优化

  5. 可扩展性:与其他STL组件无缝协作

何时需要用C实现?

  1. 嵌入式系统等受限环境(无STL支持)

  2. 需要完全控制内存布局和分配策略

  3. 与现有C代码库集成

  4. 特殊性能需求(如自定义内存池)

现代C++改进(C++11/14/17)

  1. 初始化列表

    list<int> nums = {1, 2, 3}; // C++11
  2. 自动类型推导

    auto it = nums.begin(); // 不需要写list<int>::iterator
  3. emplace操作

    nums.emplace_back(10); // 避免临时对象构造
  4. 范围for循环

    for (int num : nums) { ... } // 简洁遍历
  5. 结构化绑定(C++17)

    for (auto& [index, value] : enumerate(nums)) { ... }

理解这些差异有助于根据项目需求选择合适的实现方式。对于大多数现代C++项目,std::list是更优的选择,而在特定场景下可能需要考虑C实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/87986.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/87986.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring CGLIB私有方法访问成员变量为null问题

场景 代码 RestController public class TestJob {Autowiredprivate XxService xxService;XxlJob("testCGLIB")private void doTest(){System.out.println("方法调用");System.out.println("成员变量注入:"(xxService!null));this.doInnerTest()…

Paimon本地表查询引擎LocalTableQuery详解

LocalTableQueryLocalTableQuery 是 Paimon 中实现本地化、带缓存的表查询的核心引擎。它的主要应用场景是 Flink 中的 Lookup Join。当 Flink 作业需要根据一个流中的 Key 去关联一个 Paimon 维表时&#xff0c;LocalTableQuery 可以在 Flink 的 TaskManager 节点上&#xff0…

使用协程简化异步资源获取操作

异步编程的两种场景 在异步编程中&#xff0c;回调函数通常服务于两种不同场景&#xff1a; 一次性资源获取&#xff1a;等待异步操作完成并返回结果。持续事件通知。监听并响应多个状态变更。 Kotlin为这两种场景提供了解决方案&#xff1a;使用挂起函数简化一次性资源获取…

ABP VNext + Cosmos DB Change Feed:搭建实时数据变更流服务

ABP VNext Cosmos DB Change Feed&#xff1a;搭建实时数据变更流服务 &#x1f680; &#x1f4da; 目录ABP VNext Cosmos DB Change Feed&#xff1a;搭建实时数据变更流服务 &#x1f680;TL;DR ✨&#x1f680;1. 环境与依赖 &#x1f3d7;️2. 服务注册与依赖注入 &…

STM32-定时器

定时器&#xff1a;有4个独立通道&#xff1a;输入捕获&#xff1b;输出比较PWM生成&#xff1b;单脉冲模式输出&#xff1b;可通外部信号控制定时器&#xff08;TIMx-ETR&#xff09;&#xff1b;支持针对定时的增量&#xff08;正交&#xff09;编码器、霍尔传感器电路通用定…

Windows Server 2019--职业技能大赛B模块Windows服务器配置样题

一、赛题说明 &#xff08;一&#xff09;竞赛介绍 请详细阅读网络拓扑图&#xff0c;为所有计算机修改默认防火墙以便允许ICMP和相应的流量&#xff0c;不允许直接关闭主机的防火墙。除了CD-ROM/HDD驱动器&#xff0c;请不要修改虚拟机本身的硬件设置。 &#xff08;二&…

vue3+Echarts实现立体柱状图

Echarts柱状图中文网&#xff1a;https://echarts.apache.org/examples/zh/index.html#chart-type-bar 效果展示&#xff1a; 主要实现过程是三部分的组合&#xff0c;最上面是一个椭圆&#xff0c;中间是正常的柱子&#xff0c;下方再加上一个椭圆&#xff0c;就出来立体的效…

【UE5】虚幻引擎小百科

一、类名前面的大写字母的含义是什么UE5常见前缀分类表前缀含义实例用于AActorACharacter&#xff0c;AWeaponBase可放入世界中的对象&#xff08;有位置、可碰撞等&#xff09;UUObject派生类UUserWidget&#xff0c;UWeaponComponent引擎对象、逻辑模块&#xff0c;不具备Tra…

【Linux系统】vim编辑器 | 编译器gcc/g++ | make/Makefile

1. vim编辑器一、历史发展与Vim vs Vi的区别起源与演进Vi&#xff08;1976年&#xff09; &#xff1a;由Bill Joy开发&#xff0c;嵌入BSD Unix系统&#xff0c;是首个面向屏幕的文本编辑器&#xff0c;但功能有限&#xff08;如无多级撤销&#xff09;。Vim&#xff08;1991年…

国产飞腾主板,赋能网络安全防御硬手段

​ 当前&#xff0c;网络安全形势严峻&#xff0c;网络攻击手段不断翻新&#xff0c;从数据泄露到电脑中毒&#xff0c;企业、机构乃至国家的数字资产都面临着巨大风险。在此背景下&#xff0c;国产硬件技术的突破对筑牢网络安全防线意义重大。 高能计算机基于市场需求&#…

Spring AI 概述与架构设计

目录一、前言二、简介三、核心能力概览四、理解模块架构图五、模型适配能力六、最小应用示例七、与传统 LLM 调用相比八、总结九、参考一、前言 在 AI 正以前所未有的速度“下沉”到各类系统与业务的当下&#xff0c;Spring 官方推出的 Spring AI 项目&#xff0c;为 Java 开发…

UI前端与数字孪生融合新领域:智慧环保的污染源监测与治理

hello宝子们...我们是艾斯视觉擅长ui设计、前端开发、数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩!一、引言&#xff1a;数字孪生重构智慧环保的技术范式在环境污染治理压力持续增大的背景下&…

【go/wails】wails入门系列(一)环境安装与demo

文章目录说在前面go安装nodejs安装wails创建项目运行说在前面 操作系统&#xff1a;win11go版本&#xff1a;1.24.4nodejs版本&#xff1a;v22.16.0wails版本&#xff1a;v2.10.1 go安装 官网 这里 下载安装即可 nodejs 官网 这里 下载安装即可 安装wails 设置go国内代理g…

linux qt 使用log4cpp库

一、日志库下载 下载地址&#xff1a;https://log4cpp.sourceforge.net/二、日志库解压&#xff0c;编译 1.将文件夹解压出来2.进入文件夹内部&#xff0c;打开终端3.终端中依次输入以下命令 mkdir build ./configure --prefix$(pwd)/build make make install 一般来说不会报错…

探索阿里云Data Integration:数据同步的魔法工具

引言在当今数字化时代&#xff0c;数据已成为企业的核心资产&#xff0c;如同企业发展的 “燃料”&#xff0c;驱动着业务的增长与创新。从用户行为数据到业务运营数据&#xff0c;从市场趋势数据到供应链数据&#xff0c;每一个数据点都蕴含着巨大的价值&#xff0c;能够为企业…

【Java面试】Redis的poll函数epoll函数区别?

Redis 在选择 poll 和 epoll 时主要基于性能需求、连接规模、操作系统支持等因素。以下是具体场景的对比与选择建议&#xff1a;1. 何时使用 poll 函数&#xff1f;适用场景&#xff1a; 跨平台兼容性需求&#xff1a;poll 在几乎所有操作系统&#xff08;如 Windows、BSD、Lin…

RPC--RPCHandler的实现

在RPC框架中&#xff0c;Handler用于接收RpcRequest&#xff0c;经过处理后返回RpcResponseSlf4jpublic class RpcRequestHandler {private final ServiceProvider serviceProvider;//获取一个单例模式的服务提供类public RpcRequestHandler() {serviceProvider SingletonFact…

C#读取文件夹和文件列表:全面指南

C#读取文件夹和文件列表&#xff1a;全面指南 在 C# 开发中&#xff0c;经常需要获取文件夹中的文件列表或子文件夹结构&#xff0c;例如文件管理器、批量处理工具、备份程序等场景。本文将详细介绍 C# 中读取文件夹和文件列表的各种方法&#xff0c;包括基础操作、递归遍历、过…

从小白到进阶:解锁linux与c语言高级编程知识点嵌入式开发的任督二脉(1)

【硬核揭秘】Linux与C高级编程&#xff1a;从入门到精通&#xff0c;你的全栈之路&#xff01;第一部分&#xff1a;初识Linux与环境搭建&#xff0c;玩转软件包管理——嵌入式开发的第一道“坎”嘿&#xff0c;各位C语言的“卷王”们&#xff01;你可能已经习惯了在Windows或m…

.net开源库SignalR

.NET开源库SignalR&#xff1a;打造实时Web应用的利器 在当今的Web开发领域&#xff0c;实时性已经成为了许多应用的核心需求。无论是实时聊天、实时数据监控还是实时游戏&#xff0c;都需要服务器能够及时地将数据推送给客户端。而.NET开源库SignalR&#xff0c;正是满足这一…