场景

1.链表在C/C++里使用非常频繁, 因为它非常使用, 可作为天然的可变数组. push到末尾时对前面的链表项不影响. 反观C数组和std::vector, 一个是静态大小, 一个是增加多了会对之前的元素进行复制改写(线程非常不安全).

2.通常创建链表都是有next这样的成员变量指向下一个项, 通过定义一个head,last来进行链表创建. 参考函数 TestLinkCreateStupid().

说明

1.其实很早就知道另一种创建方式, 但是一直没总结. 没见过的童鞋看看以下创建链表的方式你用了哪一种. linus说了不会第一种的TestLinkCreateClever()根本不会用指针(看来我真不会用指针). 这种方式在循环里根本不用判断, 可见效率有多高.

// test_shared.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <memory>
#include <string>
#include <iostream>

typedef struct stage_tag {
    int                 data_ready;     /* Data present */
    long                data;           /* Data to process */
    struct stage_tag    *next;          /* Next stage */
} stage_t;

// 高效率的链表创建方式
stage_t* TestLinkCreateClever(int stages)
{
    stage_t *head = NULL,*new_stage = NULL,*tail = NULL;
    stage_t **link = &head; // 区别在这个指针地址变量上,它起到绑定新的stage的作用.
    for(int i =0; i<stages;++i)
    {
        new_stage = (stage_t*)malloc(sizeof(stage_t));
        new_stage->data_ready = 0;
        new_stage->data = i;

        *link = new_stage; // 把新的stage赋值给link指向的指针地址
        link = &new_stage->next; // 绑定下一个的指针地址
    }

    tail = new_stage;
    *link = NULL;

    return head;
}

// 低效率的链表创建方式
stage_t* TestLinkCreateStupid(int stages)
{
    stage_t *head = NULL,*new_stage = NULL,*tail = NULL;
    for(int i =0; i<stages;++i)
    {
        new_stage = (stage_t*)malloc(sizeof(stage_t));
        new_stage->data_ready = 0;
        new_stage->data = i;
        new_stage->next = NULL;

        if(tail)
            tail->next = new_stage;
        else
            head = new_stage;

        tail = new_stage;
    }
    return head;
}

int _tmain(int argc, _TCHAR* argv[])
{
    std::cout << "=== TestLinkCreateClever ===" << std::endl;
    auto first = TestLinkCreateClever(10);
    while(first)
    {
        std::cout << "data: " << first->data << std::endl;
        first = first->next;
    }

    std::cout << "=== TestLinkCreateStupid ===" << std::endl;
    auto second = TestLinkCreateStupid(10);
    while(second)
    {
        std::cout << "data: " << second->data << std::endl;
        second = second->next;
    }
    return 0;
}

参考

  1. Programming with POSIX Threads

[数据结构]_[C/C++]_[链表的最佳创建方式]的更多相关文章

  1. day16_函数作用域_匿名函数_函数式编程_map_reduce_filter_(部分)内置函数

    20180729    补充部分代码 20180727    上传代码 #!/usr/bin/env python # -*- coding:utf-8 -*- # ***************** ...

  2. 二、多线程基础-乐观锁_悲观锁_重入锁_读写锁_CAS无锁机制_自旋锁

    1.10乐观锁_悲观锁_重入锁_读写锁_CAS无锁机制_自旋锁1)乐观锁:就像它的名字一样,对于并发间操作产生的线程安全问题持乐观状态,乐观锁认为竞争不总是会发生,因此它不需要持有锁,将 比较-设置 ...

  3. [数据结构-线性表1.2] 链表与 LinkedList<T>(.NET 源码学习)

    [数据结构-线性表1.2] 链表与 LinkedList<T> [注:本篇文章源码内容较少,分析度较浅,请酌情选择阅读] 关键词:链表(数据结构)    C#中的链表(源码)    可空类 ...

  4. Spring_MVC_教程_快速入门_深入分析

    Spring MVC 教程,快速入门,深入分析 博客分类: SPRING Spring MVC 教程快速入门  资源下载: Spring_MVC_教程_快速入门_深入分析V1.1.pdf Spring ...

  5. 基于samba实现win7与linux之间共享文件_阳仔_新浪博客

    基于samba实现win7与linux之间共享文件_阳仔_新浪博客 然后启动samba执行如下指令: /dev/init.d/smb start 至此完成全部配置.

  6. 浅谈 Underscore.js 中 _.throttle 和 _.debounce 的差异

    Underscore.js是一个很精干的库,压缩后只有5.2KB.它提供了几十种函数式编程的方法,弥补了标准库的不足,大大方便了JavaScript的编程. 本文仅探讨Underscore.js的两个 ...

  7. CLOSE-UP FORMALWEAR_意大利进口_2015秋冬_男装发布会_西装图片系列_男装西装设计资料_WeArTrends时尚资讯网_国内最专业的服装设计资讯网站

    CLOSE-UP FORMALWEAR_意大利进口_2015秋冬_男装发布会_西装图片系列_男装西装设计资料_WeArTrends时尚资讯网_国内最专业的服装设计资讯网站 CLOSE-UP FORMA ...

  8. 聚焦设计交易与商业落地 DANG·DHUB设计师平台上线【图】_品牌资讯_服饰_太平洋时尚网

    聚焦设计交易与商业落地 DANG·DHUB设计师平台上线[图]_品牌资讯_服饰_太平洋时尚网 聚焦设计交易与商业落地 DANG·DHUB设计师平台上线

  9. 联系我们_你我想法_【有男度】UNANDU 100%进口 全球设计师品牌精汇 男装_男装搭配_时尚男装_品牌男装_男装搭配技巧_男装网站

    联系我们_你我想法_[有男度]UNANDU 100%进口 全球设计师品牌精汇 男装_男装搭配_时尚男装_品牌男装_男装搭配技巧_男装网站 联系我们 2012-02-17   国内北京公司总部  邮编 ...

随机推荐

  1. C#配置IIS搭建网站的工具类

    public class IISWorker { public static string HostName = "localhost"; /// <summary> ...

  2. redis在windows平台安装和启动

    官网: https://redis.io/ 中文网站:http://www.redis.net.cn/ 一.下载windows版本的redis 官网没有提供windows版本的下载,只有linux版本 ...

  3. [USACO19JAN]Exercise Route

    题目 这题的数据有点水,暴力合并\(set\)好像过了 分析一下这个题的性质,发现我们一条非树边就会形成一个环,而我们要求选择两个非树边,就会形成两个环,要求不走重复的点,就是说我们需要走一个大环,且 ...

  4. C/C++心得-理解指针

    上一篇笔者用自己那不是怎么好理解的逻辑介绍了内存和C中的基本数据类型,现在笔者再根据自己重新所学来说说C语言中的指针. 理解指针才能真正的算C语言入门.也许是我大学期间太关注前端UE,也许是当初开始学 ...

  5. empty() isset() isnull() 比较

    有关 PHP 的 empty(),isset() 还有 is_null() 这三个函数的用法讨论得已经很多了,而且很多资料也未必能说得很清楚.这里再重复一次,但不是从概念去说,直接用程序例子来说话,应 ...

  6. write函数过程解析

    write函数作为用户向终端或者文件进行写数据的重要函数,有着重要的作用. |------|          |---------|   |---------| |----------| | wri ...

  7. VM中Centos安装

    本例中的vm是12版本的. VM设置 首先是vm的设置,相当于是买电脑的过程 首先文件 -> 新建虚拟机 然后 然后 然后 然后 然后 然后 然后 然后 然后 然后 然后 然后 然后 点击完成之 ...

  8. vue路由页面加载的几种方法~

    懒加载 (1)定义:懒加载也叫延迟加载,即在需要的时候进行加载,随用随载. (2)为什么需要懒加载: 在单页应用中,如果没有应用懒加载,运用webpack打包后的文件将会异常的大,造成进入首页时,需要 ...

  9. c#(IronPython)调用Python方法

    直接一段代码演示 public void StartTCP() { ScriptEngine engine = Python.CreateEngine(); var paths = engine.Ge ...

  10. Java : java基础(5) Socket网络编程

    使用 DatagramSocket 创建一个 UDP协议的Socket, 用DatagramPacket创建一个数据包,可以指定ip和端口号以及包的数据,用socket.send()可以发送这个数据包 ...