经典数据结构沉思录(二):数组和链表

记录关于C/C++的自学路线 文章目录一、前言二、C/C++语言学习1.C/C++语言三、编程四大件1.数据结构与算法2.计算机网络3.操作系统4.设计模式与SQL数据库编程四、总结 一、前言 博主,一名小硕,记录下从化学到机械到计算机的踩坑记录。这篇博文目的其一是为了记录下自己的学习经历,其二是为了与大家分享和交流心得。以下就分享下个人的部分学习过程。 二、C/C++语言学习 1.C/C++语言 C语言的学习,应该学习如下内容:编译四步骤(预处理、编译、汇编、链接)、变量、条件循环、结构体、字符串、函数、指针和内存管理等。其中最. 阅读详情

经典数据结构沉思录(二):数组和链表

 

特别声明:此系列博文代码编译环境需为DEV-C++、G++或VS等支持C++99标准的,VC6.0不支持。

经典数据结构涵盖了多种抽象数据类型(ADT),其中包括栈、队列、有序列表、排序表、哈希表及分散表、树、优先队列、集合和图等。对于每种情况,都可以选用数组或某一种链表数据结构来实现其抽象数据类型(ADT)。由于数组和链表几乎是建立所有ADT的基础,所以称数组与链表为基本数据结构。

一、数组

也许聚集数据最常用的方法是利用数组,虽然C++提供了对数组的内嵌式支持,但是这种支持并非没有缺点。在C++中,数组并不是一级数据类型,也没有有关数组求值的表达式。结果,既不能把数组用途一个函数的实际值参数,也不能从一个函数返回一个数组值;还不能把一个数组赋给另一个数组(当然,利用指向数组的指针可以做到)。另外,数组下标是从0~N-1的范围(N为数组元素个数),对数组下标表达式也不提供越界检查。最后,在编译期间一个数组的规模大小是静态和固定的,除非程序员显式使用动态内存分配。

数组这些特性有一部分源于这样一个事实,在C++中,就指向某一T类型的指针T *ptr而言,仅仅从指针本身来说,也不可能说清它是指向一个T类型变量的单一实例还是指向一个T类型的数组。而且,即使知道指针指向一个数组,也无法确定该数组中元素的实际数目。

我们将用面向对象的设计模式来思考数据结构及相关和算法,在本系列后续的博文中也将基于面向对象来设计和实现。统一的设计思路将使得后续博文中出现的程序能够建立于前面博文的程序之上。

我们第一个基本的数组结构Array的设计包含了两个域:data、和length,其中data是一个指向数组数据的指针,length表示数组长度。考虑到Array存储的数据类型的不确定性,我们借助于C++的泛型特性进行设计,则Array的类定义如下:

template <class T>
class Array
{
    protected:
        /*指向的数据*/ 
        T* data;
        /*数组长度*/
        unsigned int length;
    
    public:
        /*构造函数及析构函数*/
        Array();
        Array(unsigned int);
        ~Array();
    
        /*拷贝构造函数、等号操作符、下标操作符*/
        Array(Array const&);
        Array& operator = (Array const&);
        T const& operator [] (unsigned int) const;
        T& operator [] (unsigned int);
    
        /*Get方法*/
        T const* Data() const;
        unsigned int Length() const;
    
        /*Set方法*/
        void SetLength(unsigned int);
    };

有了最基本的Array之后,我们就需要对其API函数进行逐个实现,并进行测试。在实际的编码过程中,我们设置了一个全局的.H文件Global.h用于定义一些公共的变量,随着编码工作的进行,我们将不断地更新和扩充Global.h文件。目前Global.h的定义如下,它对于我们本节的数据结构讲解已经够用了。

//Global.h
#ifndef GLOBAL_H_
#define GLOBAL_H_

#include <iostream>
#include <stdexcept>

#define DEFAULT_ARRAY_SIZE 10
#define EXIT_INFO "Press Any Key To Continue!"

using namespace std;

namespace OP
{
    template <class T>
    void swap(T& x, T& y)
    {
        T tmp;
        
        tmp = x;
        x = y;
        y = tmp;
    }
}

#endif

一份完整的Array类C++代码清单如下所示,为了避免与其他命名空间函数或变量重名,而造成不可用的情况,我们自定义了命名空间OP,当然你可以换成其他名字,之所以用OP是因为我比较喜欢看《海贼王》。代码比较清晰,只给出了简单的注释,并没有过多解释,大家都看的懂的~

//Array.h
#ifndef ARRAY_H_
#define ARRAY_H_

#include "Global.h"

namespace OP
{
    /*数组对象*/
    template <class T>
    class Array
    {
    protected:
        /*指向的数据*/ 
        T* data;
        /*数组长度*/
        unsigned int length;
    
    public:
        /*构造函数及析构函数*/
        Array();
        Array(unsigned int);
        ~Array();
    
        /*拷贝构造函数、等号操作符、下标操作符*/
        Array(Array const&);
        Array& operator = (Array const&);
        T const& operator [] (unsigned int) const;
        T& operator [] (unsigned int);
    
        /*Get方法*/
        T const* Data() const;
        unsigned int Length() const;
    
        /*Set方法*/
        void SetLength(unsigned int);
    };
    
    /*默认构造函数*/
    template <class T>
    Array<T>::Array() : 
        data(new T[DEFAULT_ARRAY_SIZE]), 
        length(0)
        {}
   
    /*带参数的构造函数*/
    template <class T>
    Array<T>::Array(unsigned int n) : 
        data(new T[n]), 
        length(n)
        {}
           
    
    /*析构函数*/
    template <class T>
    Array<T>::~Array()
    {
        delete [] data;
    }
    
    /*拷贝构造函数*/
    template <class T>
    Array<T>::Array(Array<T> const& array) : 
        data(new T[array.length]), 
        length(array.length)
        {
            for (unsigned int i = 0; i < length; ++i)
            {
                data[i] = array.data[i];
            }
        }
    
    /*重载=操作符*/
    template <class T>
    Array<T>& Array<T>::operator = (Array const& array)
    {
        if (this != &array)
        {
            delete [] data;
            length = array.length;
            data = new T[length];
            for (unsigned int i = 0; i < length; ++i)
            {
                data[i] = array.data[i];
            }
        }
        
        return *this;
    }
    
    /*重载[]下标操作符,默认为只读类型,数据不可修改*/
    template <class T>
    T const& Array<T>::operator [] (unsigned int position) const
    {      
        if (position >= length)
        {
            throw out_of_range("Invalid Position!");
        }
        return data[position];
    }
    
    /*重载[]下标操作符,数据可修改*/
    template <class T>
    T& Array<T>::operator [] (unsigned int position)
    {
        if (position >= length)
        {
            throw out_of_range("Invalid Position!");
        }
        return data[position];
    }
    
    /*Get方法*/
    template <class T>
    T const* Array<T>::Data() const
    {
        return data;
    }

    template <class T>
    unsigned int Array<T>::Length() const
    {
        return length;
    }
    
    /*当length<newLength时,[length,newLength)区间的元素赋初值为0*/    
    template <class T>
    void Array<T>::SetLength(unsigned int newLength)
    {
        T* const newData = new T[newLength];
        unsigned int const min = length < newLength ? length : newLength;
        for (unsigned int i = 0; i < min; ++i)
        {
            newData[i] = data[i];
        }
        
        /*[length,newLength)区间赋初值*/ 
        for (unsigned int i = min; i < newLength; ++i)
        {
            newData[i] = 0;
        }
        
        delete [] data;
        data = newData;
        length = newLength;
    }
}

#endif

完成了Array的类之后,我们对所有函数进行测试,以保证其能够正常工作。我们实现了一个Test的类,代码清单如下。

//ArrayTest.cpp
#include "Array.h"
#include "string"

using namespace OP;

/*遍历数组*/ 
void traverse(const Array<int>& array);

int main()
{
    /*构造函数测试*/ 
    Array<int> array1(10);
    Array<int> array2;
    
    /*下标操作符测试*/
    for (unsigned int i = 0; i < 10; ++i)
    {
        array1[i] = i*i;
    }
    traverse(array1);
    
    /*=操作符测试*/
    array2 = array1;
    traverse(array2);
    
    /*拷贝构造函数测试*/
    Array<int> array3(array1);
    traverse(array3);
    
    /*设置数组长度测试*/
    array1.SetLength(20);
    traverse(array1);
    array1.SetLength(5);
    traverse(array1);
    
    getchar();
    return 0;
}

/*遍历数组*/
void traverse(const Array<int>& array)
{
    for (unsigned int i = 0; i < array.Length(); ++i)
    {
        cout << array[i] << "  ";
    }
    cout << endl;
}

二、单链表

单链表在所有的基于指针的数据结构中是最基本的,它由一系列动态分配的存储元素组成,且每个元素都含有一个指向后继元素的指针。虽然单链表的表达简洁明晰,但实现形式却可以是多种多样的:循环链表、头节点为空、头节点不为空等;链表插入的方式也可以不同:前插或后插。

我们的LinkedList设计中包含了两个重要的指针:head和tail,分别指向头节点和尾结点,其中头节点不为空,插入方式提供前插和后插两种。LinkedList的设计依赖于链表节点的数据结构ListElement。LinkedList的代码清单如下:

//LinkedList.h
#ifndef LINKEDLIST_H_
#define LINKEDLIST_H_

#include "Global.h"

namespace OP
{
    template <class T>
    class LinkedList;
    
    /*链表节点*/
    template <class T>
    class ListElement
    {
    private:
        /*链表节点数据元素*/
        T datum;
        /*链表节点next指针*/
        ListElement* next;
        /*链表构造函数*/
        ListElement(T const&, ListElement*);
        
    public:
        /*Get方法*/
        T const& Datum() const;
        ListElement const* Next() const;
        
        /*链表对象为友元*/
        friend class LinkedList<T>;
    };
    
    /*链表对象*/
    template <class T>
    class LinkedList
    {
    private:
        /*头节点*/
        ListElement<T>* head;
        /*尾节点*/
        ListElement<T>* tail;
        
    public:
        /*构造函数和析构函数*/
        LinkedList();
        ~LinkedList();
        
        /*拷贝构造函数和赋值函数*/
        LinkedList(LinkedList const&);
        LinkedList& operator=(LinkedList const&);
        
        /*Get方法*/
        ListElement<T> const* Head() const;
        ListElement<T> const* Tail() const;
        
        /*链表是否为空*/
        bool IsEmpty() const;
        /*链表首元素*/
        T const& First() const;
        /*链表尾元素*/
        T const& Last() const;
        
        /*链表首前插一个元素*/
        void Prepend(T const&);
        /*链表尾插入一个元素*/ 
        void Append(T const&);
        /*删除链表中指定元素节点*/ 
        void Extract(T const&);
        /*清空链表*/ 
        void Purge();
        /*后插*/
        void InsertAfter(ListElement<T> const*, T const&);
        /*前插*/
        void InsertBefore(ListElement<T> const*, T const&);
    };
    
    /*构造函数*/
    /*构造函数*/
    template <class T>
    LinkedList<T>::LinkedList() : 
        head(0), 
        tail(0)
        {}
    
    template <class T>
    ListElement<T>::ListElement(T const& _datum, ListElement<T>* _next) : 
        datum(_datum),
        next(_next)
        {}
        
    /*Get方法*/
    template <class T>
    T const& ListElement<T>::Datum() const
    {
        return datum;
    }
    
    template <class T>
    ListElement<T> const* ListElement<T>::Next() const
    {
        return next;
    }
    
    /*销毁链表*/
    template <class T>
    void LinkedList<T>::Purge()
    {
        while (head != 0)
        {
            ListElement<T>* const tmp = head;
            head = head->next;
            delete tmp;
        }
        tail = 0;
    }
    
    /*析构函数*/
    template <class T>
    LinkedList<T>::~LinkedList()
    {
        Purge();
    }
    
    /*Get方法*/
    template <class T>
    ListElement<T> const* LinkedList<T>::Head() const
    {
        return head;
    }
    
    template <class T>
    ListElement<T> const* LinkedList<T>::Tail() const
    {
        return tail;
    }
    
    /*是否为空*/
    template <class T>
    bool LinkedList<T>::IsEmpty() const
    {
        return head == 0;
    }
    
    /*链表首元素*/
    template <class T>
    T const& LinkedList<T>::First() const
    {
        if (head == 0)
        {
            throw domain_error("List Is Empty!");
        }
        return head->datum;
    }
    
    /*链表尾元素*/
    template <class T>
    T const& LinkedList<T>::Last() const
    {
        if (tail == 0)
        {
            throw domain_error("List Is Empty!");
        }
        return tail->datum;
    }
    
    /*前插*/
    template <class T>
    void LinkedList<T>::Prepend(T const& item)
    {
        ListElement<T>* const tmp = new ListElement<T>(item, head);
        if (head == 0)
        {
            tail = tmp;
        }
        head = tmp;
    }
    
    /*后插*/
    template <class T>
    void LinkedList<T>::Append(T const& item)
    {
        ListElement<T>* const tmp = new ListElement<T>(item, 0);
        if (head == 0)
        {
            head = tmp;
        }
        else
        {
            tail->next = tmp;
        }
        tail = tmp;
    }
    
    /*拷贝构造函数*/
    template <class T>
    LinkedList<T>::LinkedList(LinkedList<T> const& linkedList) : 
        head(0), 
        tail(0)
    {
        ListElement<T> const* ptr;
        for (ptr = linkedList.head; ptr != 0; ptr = ptr->next)
        {
            Append(ptr->datum);
        }
    }
    
    /*赋值构造函数*/
    template <class T>
    LinkedList<T>& LinkedList<T>::operator = (LinkedList<T> const& linkedList)
    {
        if (&linkedList != this)
        {
            Purge();
            ListElement<T> const* ptr;
            for (ptr = linkedList.head; ptr != 0; ptr = ptr->next)
            {
                Append(ptr->datum);
            }
        }
        return *this;
    }
    
    /*删除该元素节点*/
    template <class T>
    void LinkedList<T>::Extract(T const& item)
    {
        ListElement<T>* ptr = head;
        ListElement<T>* prevPtr = 0;
        while (ptr != 0 && ptr->datum != item)
        {
            prevPtr = ptr;
            ptr = ptr->next;
        }
        if (ptr == 0)
        {
            cout << "Item not Found!" << endl;
            return;
        }
        if (ptr == head)
        {
            head = ptr->next;
        }
        else
        {
            prevPtr->next = ptr->next;
        }
        if (ptr == tail)
        {
            tail = prevPtr;
        }
        delete ptr;
    }
    
    /*在节点arg处前插入一个节点*/
    template <class T>
    void LinkedList<T>::InsertAfter(ListElement<T> const* arg, T const& item)
    {
        ListElement<T>* ptr = const_cast<ListElement<T>*>(arg);
        if (ptr == 0)
        {
            throw invalid_argument("Invalid Position!");
        }
        ListElement<T>* const tmp = new ListElement<T>(item, ptr->next);
        ptr->next = tmp;
        if (tail == ptr)
        {
            tail = tmp;
        }
    }
    
    /*在节点arg处后插入一个节点,这里使用了一个技巧,先实现前插,后将节点数据进行交换*/
    template <class T>
    void LinkedList<T>::InsertBefore(ListElement<T> const* arg, T const& item)
    {
        /*先实现前插,后将节点数据进行交换*/
        ListElement<T>* ptr = const_cast<ListElement<T>*>(arg);
        if (ptr == 0)
        {
            throw invalid_argument("Invalid Position!");
        }
        ListElement<T>* const tmp = new ListElement<T>(item, ptr->next);
        ptr->next = tmp;
        if (tail == ptr)
        {
            tail = tmp;
        }
        
        /*交换数据实现前插*/
        swap(tmp->datum, ptr->datum);
    }
}

#endif

完成了LinkedList的类之后,我们对所有函数进行测试,以保证其能够正常工作。我们实现了一个Test的类,代码清单如下。

//LinkedListTest.cpp
#include "Global.h"
#include "LinkedList.h"

using namespace OP;

void traverse(LinkedList<int>& linkedList);

int main()
{
    /*构造函数测试*/
    LinkedList<int> l1;
    
    /*后插函数测试*/ 
    for (int i = 0; i < 10; ++i)
    {
        l1.Append(i + 1);
    }
    traverse(l1);
    
    /*拷贝构造函数测试*/
    LinkedList<int> l2(l1);
    traverse(l2);
    
    /*前插函数测试*/
    LinkedList<int> l3;
    for (int i = 0; i < 10; ++i)
    {
        l3.Prepend(i + 1);
    }
    traverse(l3);
    
    /*后插函数测试*/
    l1.InsertAfter(l1.Head()->Next(), -1);
    traverse(l1);
    
    /*前插函数测试*/
    l1.InsertBefore(l1.Head()->Next()->Next(), -2);
    traverse(l1);
    
    /*删除节点函数测试*/
    l1.Extract(1);
    traverse(l1);
    l1.Extract(10);
    traverse(l1);
    l1.Extract(5);
    traverse(l1);
    l1.Extract(1);
    traverse(l1);
    
    getchar();
    return 0;
}

/*遍历链表*/
void traverse(LinkedList<int>& linkedList)
{
    ListElement<int> const* ptr;
    for (ptr = linkedList.Head(); ptr != 0; ptr = ptr->Next())
    {
        cout << ptr->Datum() << "  ";
    }
    cout << endl;
}

博文的撰写参考了《数据结构与算法-面向对象的C++设计模式》一书,再此向该书作者表示致敬!本系列博文将继续基于面向对象对经典的数据结构进行设计和封装,并用C++实现,请持续关注本博客~

【福建dem】原始高程数据tif格式 DEM(Digital Elevation Model,数字高程模型)是一种地理信息系统中的关键数据集,它提供了地表地形的三维信息,通常用于分析地貌特征、模拟水文过程、规划建设、灾害预警等多个领域。这种数据对于地理分析非常有价值,例如,它可以用于计算坡度、坡向、地形粗糙度等地形特征,或者进行洪水模拟、地质灾害评估、太阳能辐射分析等。“福建dem原始高程数据tif格式”是研究和理解福建省地形地貌的重要资源,结合GIS工具,可以揭示丰富的地理信息,为科研、工程和决策提供有力支持。 阅读详情

相关推荐

深入理解C++23的Deducing this特性(上):基础概念与语法详解

C++23标准中引入的"Deducing this"特性是一项重大革新,它不仅改变了我们编写成员函数的方式,还为模板元编程和设计模式实现带来了新的可能。

weixin_61470881的博客 1332

C++之string类型详解

目录 1.声明一个C++字符串 2.字符串操作函数 2.1 C++字符串和C字符串的转换 2.2 大小和容量函数 2.3元素存取 2.4比较函数 2.5 更改内容 2.6提取子串和字符串连接 2.7输入输出操作 2.8搜索与查找 之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必担心内存是否足够、字符串长度等等,而且作为一个泛型类出现,他集成的操作函数足以完成我们大多数情况下(甚至是100%)的需要。我们可以用 = 进行赋值操作,== 进

weixin_36670529的博客 4487

避坑指南:为什么你的conda环境装不上Mamba?从CUDA到ABI的深度排查

本文深入解析conda环境中安装Mamba架构时常见的CUDA版本冲突、ABI不匹配等问题,提供从基础检查到深度排查的系统化解决方案。针对`causal-conv1d`和`mamba-ssm`安装失败场景,详细讲解PyTorch版本绑定、编译器工具链兼容性等关键技术要点,并给出预编译wheel选择、动态链接库配置等实用修复方案。

weixin_33738555的博客 345

out_of_range 标准异常

#include #include using namespace std; class 学生 { public: 学生(int 年龄) { if(年龄 150) throw out_of_range("年龄不能小于0或大于150"); this->年龄 = 年龄; } private: int 年龄; }; int main() { try { 学生 小

qq_31248551的博客 3049

Xilinx SDK调试与FPGA硬件验证全流程解析

本文详细解析了从Vivado导出硬件到Xilinx SDK进行调试与FPGA硬件验证的全流程。重点阐述了正确导出包含bitstream的硬件平台、创建合适的SDK工程、配置Debug会话以编程FPGA,并介绍了串口验证、自定义IP测试以及使用ILA进行软硬件联合调试的高级技巧,帮助开发者高效完成FPGA系统的软硬件协同开发与问题排查。

weixin_28327051的博客 309

Windows 11安装realtek audio control

Windows 11安装realtek audio control,解决无法链接RPC问题

m0_46144825的博客 8万+

高频知识——C++进阶知识(高级教程)

参考链接:https://www.runoob.com/cplusplus/cpp-interfaces.html 之前分别介绍了C++的基本语法,面向对象的设计方法,下面介绍一下C++的一些高级教程,也是面试的高频问题。 1 文件和流 iostream标准库,它提供了cin和cout方法分别用于从标准输入读取流和向标准输出写入流。 从文件读取流和向文件写入流。需要用到 C++ ...

wulitaotao96的博客 1万+

4、LTE无人机认证:保障通信安全的新方案

本文针对LTE网络中无人机通信存在的安全风险,提出了一种基于可信第三方GCS的新型认证协议。该协议通过非对称加密和哈希函数保护IMSI等敏感信息,防止身份泄露、中间人攻击、拒绝服务攻击和位置追踪等威胁。利用Scyther工具对协议进行形式化分析,验证了其在机密性、一致性和活性等方面的安全属性,证明该方案能有效提升无人机在LTE网络中的通信安全性与隐私保护能力。

pink的博客 59

C++异常处理

C++异常处理 异常,让一个函数可以在发现自己无法处理的错误时抛出一个异常,希望它的调用者可以直接或者间接处理这个问题。但传统错误的处理技术,检查到一个错误,返回退出码或者终止程序等等。此时我们只知道程序有错误,但不能更加清楚知道是很忙错误,所以使用异常,就是把错误和处理分开,由库函数抛出异常,由调用者捕获这个异常,调用者可以知道程序函数库调用出现了错误,并根据错误去处理,而是否终止程序就由调用...

King逍灬遥 783

UNet 改进(39):结合残差连接与CBAM注意力机制的unet模型

本文提出了一种改进的UNet架构,通过融合残差连接和CBAM注意力机制来增强医学图像分割性能。该网络保留UNet的U形结构,但将基础模块替换为ResidualBlock和CBAM的组合:残差块通过快捷连接解决梯度消失问题,CBAM模块结合通道和空间注意力机制突出重要特征。整体架构采用编码器-解码器设计,包含5个下采样和上采样阶段,通过跳跃连接融合多尺度特征。实验表明,这种改进显著提升了原始UNet的性能,特别适用于需要精细边界的医学图像分割任务。

2401_82355416的博客 1012

线程池详解(通俗易懂超级好)

目标 【理解】线程池基本概念 【理解】线程池工作原理 【掌握】自定义线程池 【应用】java内置线程池 【应用】使用java内置线程池完成综合案例 线程池 线程池基础 线程池使用 线程池综合案例 4.学员练习 5.线程池总结 概念介绍 1:什么是线程池 2:为什么使用线程池 3:线程池有哪些优势 什么是池 什么是线程池 线程池其实就是一种多线程处理形式,处理过程中可以将任务添加到队列中,然后在创建线程后自动启动这些任务。这里的线程就是我们前面学过的线程,这里的任务就是我们前面学过的实现了Runna.

拉格朗日的学习笔记 12万+

我在代码随想录|写代码总结篇| 数组 |链表|哈希表|字符串|双指针法|栈与队列|二叉树|回溯算法|贪心算法|动态规划|单调栈

因为想要成为代码大神所以开始了我代码随想录的刷题过程。

2303_79299383的博客 866

RK3588 部署 ArcFace(r100)人脸识别模型:ONNX 转 RKNN 全流程详解

本文介绍了将ArcFace人脸识别模型转换为RKNN格式并部署到RK3588 NPU的方法。ArcFace是主流的人脸特征提取模型,适用于1:1比对和1:N检索等场景。文章详细说明了模型特点(输入112x112 RGB图像,输出512维特征向量)及转换步骤:首先使用torch2onnx将PyTorch模型转为ONNX格式,再通过RKNN工具进行量化转换。提供了完整的Python转换代码,包括预处理配置、模型加载、构建和导出过程。该方法能有效提升边缘设备上的人脸识别实时性,适用于门禁、考勤等应用场景。

J。 415

如何提升C++水平?

你希望系统地提升自己的 C++ 编程水平,并想知道有哪些适合的书籍可以作为学习参考。提升 C++ 水平是一个循序渐进的过程,需要结合理论学习、大量实践和代码阅读,我会按学习阶段给你梳理清晰的路径和对应的书籍推荐。

人邮异步社区 2608

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

新手集合--嵌入式linux学习路线--三大阶段

微信公众号:二进制人生 专注于嵌入式linux开发。 本文持续更新,第一版先面世,转发请保留出处:二进制人生。这个学习路线是遵照大多数人的认知规律来的, 第一阶段 1.1 C语言入门 入门选一本简单的、薄一点、不要出错的书就可以了,例如谭浩强老爷子的书,选太厚的容易打击你的信心和学习兴趣,谭老爷子的书虽然被很多人喷,但对于初学者来说还是比较合适的。在入门之后才建议去看C语言的经典教程: 《C Primer Plus》 这本书比较厚,知识点比较全,可以用于查漏补缺。 《C程序设计语言》(Th.

二进制君 2万+

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

std::out_of_range异常的解决方案

std::out_of_range 是 C++ 标准库中的一个异常类,它表示尝试访问的容器元素索引超出了容器的有效范围。这个异常通常与 STL(Standard Template Library)容器,如 std::vector、std::string、std::array 等一起使用,当尝试通过 at() 成员函数访问一个不存在的元素时,就会抛出此异常。

2301_79779756的博客 3325

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

C++ 异常处理总结

一、 参考文献: 【1】C++异常处理:https://www.runoob.com/cplusplus/cpp-exceptions-handling.html

灰太狼的小秘密 3700

对std::out_of_range抛出异常进行处理

对std::out_of_range抛出异常进行处理 #include    #include    #include    using namespace std;   int main() {       vector int> a;       a.push_back(1);       try {           a.at(1);  

wxqian25的专栏 2万+

vs2017c语言未声明标识符,错误:在vscode上使用未声明的标识符'out_of_range'

错误消息Vector.cpp:9:49: error: expected ';' after expressionif (i < 0 || size() <= i) throw out_of_range{"Vector::operator[]"};^;Vector.cpp:9:37: error: use of undeclared identifier 'out_of_range'i...

weixin_42533910的博客 1223

对‘std::__throw_out_of_range_fmt(car const*, ...)@GLIBCXX_3.4.20’未定义的引用

cmake编译报错: libgflags.so:对‘std::__throw_out_of_range_fmt(char const*, ...)@GLIBCXX_3.4.20’未定义的引用 先将g++版本修改,然后 在CMakeLists.txt添加编译选项 set(CMAKE_CXX_COMPILER g++) ...

宁静致远的博客 6256

C++异常

C++异常1 异常的基本概念2 比较C语言中处理异常的方法3 异常的语法3.1 异常的基本语法3.2 异常严格类型匹配3.3 栈解旋(unwinding)3.4 异常的接口声明3.5 异常变量的生命周期3.6 异常的多态使用 1 异常的基本概念 Bjarne Stroustrup说:提供异常的基本目的就是为了处理上面的问题。基本思想是:让一个函数在发现了自己无法处理的错误时抛出(throw)一个异常,然后它的(直接或者间接)调用者能够处理这个问题。也就是《C++ primer》中说的:将问题检测和问题处理相

linuxcpp_的博客 579

std::out_of_range 抛出抛出异常

[code=cpp] // out_of_range example #include // std::cerr #include // std::out_of_range #include // std::vector  int main (void) { std::vectorint> myvector(

xiyangyanging2的博客 4824

关于部分编译器out_of_range报错的解决

今天在使用CodeBlocks编译器时,对于下面的代码public: SmallInt(int i=0):val(i){ if(i<0||i>255) throw out_of_range("error"); } 编译器报错: error: 'out_of_range' w...

weixin_34080903的博客 1729

数据结构与算法系列之一:八大排序之归并排序

转载请注明作者和出处:http://blog.youkuaiyun.com/u011475210 个人博客:https://wordzzzz.github.io/ && https://wordzzzz.gitee.io/ 代码地址:https://github.com/WordZzzz/Note/tree/master/DS-A 博客作者:WordZzzz,一只热爱技术的文艺青年 归并排序 前

WordZzzz 1927
上一篇: 我们为什么会对富二代有偏见?
下一篇: 树形结构的数据库表Schema设计
MONKEY_D_MENG
博客等级 码龄17年 705粉丝 97原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值