91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++中指針,引用和STL的示例分析

發布時間:2022-02-24 13:37:37 來源:億速云 閱讀:171 作者:小新 欄目:開發技術

這篇文章主要介紹C++中指針,引用和STL的示例分析,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

    對象的定義:對象是指一塊能存儲數據并具有某種類型的內存空間

    一個對象a,它有值和地址;運行程序時,計算機會為該對象分配存儲空間,來存儲該對象的值,通過該對象的地址,來訪問存儲空間中的值。

    指針、引用

    指針

    類型名 * 指針變量名;

    每個變量都被存放在從某個內存地址(以字節為單位)開始的若干個字節中;"指針",也稱作"指針變量",大小為4個字節(或8個字節)的變量,其內容代表一個內存地址;通過指針,能夠對該指針指向的內存區域進行讀寫。

    int * p;    //p是一個指針,變量p的類型是int *
    T * p;    //T可以是任何類型的名字,比如int, double
    p     的類型:    T*
    *p    的類型:    T
    通過表達式 *p,可以讀寫從地址p開始的sizeof(T)個字節
    *p    等價于存放在地址p處的一個T類型的變量
    *     間接引用運算符
    sizeof(T*)    4字節(64位計算機上可能8字節)
    char ch2 = 'A'
    char *pc = &ch2;    //使得pc指向變量ch2
    &: 取地址運算符
    &x: 變量x的地址(即指向x的指針),對于類型為T的變量x,&x表示變量x的地址(即指向x的指針)
    &x的類型是T*

    指針的作用 

    使用指針,就有自由訪問內存空間的手段

    不需要通過變量,就能對內存直接進行操作。通過指針,程序能訪問的內存區域就不僅限于變量所占據的數據區域。

    指針的相互賦值

    不同類型的指針,如果不經過強制類型轉換,不能直接互相賦值。

    指針的運算

    • 兩個同類型的指針變量,可以比較大小(比較的是地址空間的大小)

    • 兩個同類型的指針變量,可以相減(相減值為地址空間差值除以sizeof(T))

    • 指針變量加減一個整數的結果是指針

    p: T*類型的指針
    n: 整數類型的變量或常量
    p + n: T*類型的指針,指向地址(地址 p + n * sizeof(T))
    n + p, p - n, *(p + n), *(p - n) 分別為地址和地址指向的值
    eq:
    int a = 10;
    int b = 15;
    int * p = &a;    //0x61fe04
    int * q = &b;    //0x61fe00
    int * ans = p + 2;    //0x61fe0c
    int k = *(p - 1);    //15
    • 指針變量可以自增、自減 (p++, ++p, p--, --p)即p指向的地址n + sizeof(T)或者n - sizeof(T)

    • 指針可以用下標運算符"[]"進行運算

    p是一個T*類型的指針
    n是整數類型的變量或常量
    p[n]等價于*(p + n)

    空指針 

    地址0不能訪問。指向地址0的指針就是空指針

    可以用"NULL"關鍵字對任何類型的指針進行賦值。NULL實際上就是整數0,值為NULL的指針就是空指針

    int *pn = NULL;
    char *pc = NULL;
    int *p2 = 0;

    指針作為函數參數(形參是實參的一個拷貝)

    指針和數組

    數組的名字是一個指針常量(指向數組的起始地址)

    T a[N];
    a的類型是T*
    可以用a給一個T*類型的指針賦值
    a是編譯時其值就確定了的常量,不能夠對a進行賦值

    作為函數形參時,T *p和 T p[]等價

    void Func(int *p){ cout << sizeof(p); }void Func(int p[]){ cout << sizeof(p); }

    引用

    類型名 & 引用名 = 某變量名;(定義了一個引用,將其初始化為引用某個變量)

    int n = 4;
    int & r = n; //r引用了n, r的類型是int &v

    某個變量的引用,等價于這個變量,相當于該變量的一個別名

    • 定義引用時一定要將其初始化成引用某個變量

    • 初始化后,它就一直引用該變量,不會再引用別的變量

    • 引用只能引用變量,不能引用常量和表達式

    引用作為函數的返回值

    int n = 4;
    int & SetValue() 
    {
        return n;
    }
    int main()
    {
        SetValue() = 40;
        cout << n;    //輸出是40
        return 0;
    }

    常引用

    定義引用時,前面加const關鍵字,即為"常引用"

    int n;
    const int & r = n;    //r的類型是const int &
    不能通過常引用去修改其引用的內容:
    int n = 100;
    const int & r = n;
    r = 200;    //編譯錯誤
    n = 300;    //ok

    常引用和非常引用的轉換

    const T &和 T &是不同的類型,T &類型的引用或T類型的變量可以用來初始化const T &類型的引用;const T類型的常變量和const T &類型的引用則不能用來初始化T &類型的引用。

    STL

    STL中六大組件

    容器(Container,一種數據結構(包含一組元素或元素集合的對象),基本容器:向量(vector), 雙端隊列(deque), 列表(list), 集合(set), 多重集合(multiset), 映射(map), 多重映射(multimap)。

    序列式容器(Sequence containers),其中每個元素均有固定位置--取決于插入時機和地點,和元素值無關(vector, deque, list)

    關聯式容器(Associative containers),元素位置取決于特定的排序準則以及元素值,和插入次序無關(set, multiset, map, multimap)

    迭代器(Iterator)

    迭代器Iterator,用來在一個對象集群(collection of objects)的元素上進行遍歷。這個對象集群或許是一個容器,或許是容器的一部分。迭代器的主要好處是,為所有容器提供了一組很小的公共接口。迭代器以++進行累進,以*進行提領,因而類似于指針,可以將其視為一種smart pointer。

    例如++操作可以遍歷至集群內的下一個元素。至于如何完成,取決于容器內部的數據組織形式。

    每種容器都提供自己的迭代器,而這些迭代器能夠了解容器內部的數據結構

    算法(Algorithm)

    用來處理群集內的元素。它們可以出于不同的目的而搜尋、排序、修改、使用那些元素。通過迭代器的協助,我們可以只需編寫一次算法,就可以將它應用于任意容器,這是因為所有的容器迭代器都提供一致的接口。

    仿函數(Functor)

    適配器(Adaptor)

    提供三種順序容器適配器:queue(FIFO隊列),priority_queue(優先級隊列),stack(棧)。

    適配器對容器進行包裝,使其表現出另外一種行為。倘若要使用適配器,需要加入頭文件

    分配器(Allocator)

    常用容器用法介紹

    vector

    一個數組必須有固定的長度,在開數組的時候,此長度就被靜態地確定下來。但vector卻是數組的"加強版",vector理解為一個"變長數組"

    事實上,vector的實現方式是基于倍增思想的:假如vector的實際長度為n,m為vector當前的最大長度,那么在加入一個元素的時候,先看一下,假如當前的n=m,則再動態申請一個2m大小的內存。反之,在刪除的時候,如果n&ge;m/2,則再釋放一半的內存。

    #include<vector>
    vector<int>vec;
    vector<pair<int, int> >vec_pair;
    struct node{ ... };
    vector<node>vec_node;

    vec.begin(), vec.end()        返回vector的首尾迭代器

    vec.front(), vec.back()        返回vector的首尾元素

    vec.push_back()                從vector末尾加入一個元素

    vec.size()        返回vector當前的長度(大小)

    vec.pop_back()        從vector末尾刪除一個元素

    vec.empty()        返回vector是否為空,1為空,0不為空

    vec.clear()        清空vector             

    vector容器是支持隨機訪問的,可以像數組一樣用[]取值。   

    vector<int>vec;
    vec.push_back(5);
    vec.push_back(2);
    cout << vec.back() << endl;
    for(vector<int>::iterator iter = vec.begin(); iter != vec.end(); iter++)
    {
        cout << *iter << endl;
    }

    vector修改值 

    • 有迭代器,使用迭代器修改        auto iter = v.begin(),        *iter = 1

    • 使用索引進行修改    v[0] = 1

    deque(雙端隊列)

    #include&lt;deque&gt;deque&lt;int&gt;q

    q.begin(), q.end()        返回deque的首尾迭代器

    q.front(), q.back()        返回deque的首尾元素

    q.push_back()        從隊尾入隊一個元素

    q.push_front()        從隊頭入隊一個元素

    q.pop_back()        從隊尾出隊一個元素

    q.pop_front()        從隊頭出隊一個元素

    q.size()z        隊列中元素個數

    q.clear()        清空隊列

    deque支持隨機訪問,可以像數組下標一樣取出其中的一個元素。即q[i]

    deque容器可以被應用到SPFA算法的SLF優化:SPFA算法的優化方式

    set

    set滿足互異性,set集合中的元素是默認升序的(set容器自動有序和快速添加、刪除的性質是由其內部實現:紅黑樹(平衡樹的一種))

    #include<set>
    set<int>s
    set<pair<int, int> >s;

    s.empty()        返回集合是否為空,是為1,否為0

    s.size()        返回當前集合的元素個數

    s.clear()        清空當前集合

    s.begin(), s.end()        返回集合的首尾迭代器(迭代器是一種指針。這里需要注意的是,由于計算機區間“前閉后開”的結構,begin()函數返回的指針指向的的確是集合的第一個元素。但end()返回的指針卻指向了集合最后一個元素后面一個元素。) 

    s.insert(k)        集合中加入元素k

    s.erase(k)        集合中刪除元素k

    s.find(k)        返回集合中指向元素k的迭代器。如果不存在這個元素,就返回s.end(),這個性質可以用來判斷集合中有沒有這個元素。

    s.lower_bound()        返回集合中第一個大于等于關鍵字的元素

    s.upper_bound()        返回集合中第一個嚴格大于關鍵字的元素

    multiset(有序多重集合)

    s.erase(k)       

    erase(k)函數在set容器中表示刪除集合中元素k。但在multiset容器中表示刪除所有等于k的元素。

    倘若只刪除這些元素中的一個元素

    if((it = s.find(a)) != s.end())
        s.erase(it);
    if中的條件語句表示定義了一個指向一個a元素的迭代器,如果這個迭代器不等于s.end(),
    就說明這個元素的確存在,就可以直接刪除這個迭代器指向的元素。

    s.count(k)        count(k)函數返回集合中元素k的個數,為multiset所獨有。 

    map

    可以根據鍵值快速地找到這個映射出的數據, map容器的內部實現是一棵紅黑樹

    #include<map>
    map<int, char> mp;
    建立一個從整型變量到字符型變量的映射
    map<int, char>mp;
    //插入
    mp[1] = 'a';
    mp.insert(map<int, char>::value_type(2, 'b'));
    mp.insert(pair<int, char>(3, 'c'));
    mp.insert(make_pair<int, char>(4, 'd'));
    //查找
    mp[3] = 't';    //修改鍵值對中的值
    map<int, char>::iterator iter;
    iter = mp.find(3);
    iter->second = 'y';
    cout << iter->second << endl;
    //刪除
    mp.erase(2);    //刪除鍵值對
    //遍歷
    for(map<int, char>::iterator iter = mp.begin(); iter != mp.end(); iter++)
    {
        cout << iter->first << endl;
        cout << iter->second << endl;
    }

    mp.begin(), mp.end()        返回首尾迭代器 

    mp.clear()        清空函數操作

    mp.size()        返回容器大小

    queue(FIFO)

    #include<queue>queue<int>q;queue<pair<int, int> >q;#include<queue>
    queue<int>q;
    queue<pair<int, int> >q;

    q.front(), q.back()        返回queue的首尾元素

    q.push()        從queue末尾加入一個元素

    q.size()        返回queue當前的長度(大小)

    q.pop()        從queue隊首刪除一個元素

    q.empty()        返回queue是否為空,1為空,0不為空

    priority_queue

    優先隊列在隊列的基礎上,將其中的元素加以排序。其內部實現是一個二叉堆。優先隊列即為將堆模板化,將所有入隊的元素排成具有單調性的一隊,方便我們調用。

    大根堆聲明就是將大的元素放在堆頂的堆。優先隊列默認實現的就是大根堆。

    小根堆聲明就是將小的元素放在堆頂的堆。

    #include<queue>
    priority_queue<int>q;        //大根堆
    priority_queue<string>q;
    priority_queue<pair<int, int> >q;    
    priority_queue<int, vector<int>, less<int> >q;    //大根堆
    priority_queue<int, vector<int>, greater<int> >q;    //小根堆

    q.top()        返回priority_queue的首元素

    q.push()        向priority_queue中加入一個元素

    q.size()        返回priority_queue當前的長度(大小)

    q.pop()        從priority_queue末尾刪除一個元素

    q.empty()        返回priority_queue是否為空,1為空,0不為空 

    stack(棧)

    #include&lt;stack&gt;stack&lt;int&gt; st;stack&lt;pair&lt;int, int&gt; &gt; st;

    st.top()        返回stack的棧頂元素

    st.push()        從stack棧頂加入一個元素

    st.size()        返回stack當前的長度(大小)

    st.pop()        從stack棧頂彈出一個元素

    st.empty()        返回stack是否為空,1為空,0不為空

    string(字符串操作)

    其實string容器就是一個字符串

    操作string字符陣列
    聲明字符串string schar s[100]
    取得第i個字符s[i]s[i]
    字符串長度s.length(), s.size()strlen(s) 不計\0
    讀取一行getline(cin, s)gets(s)
    設成某字符串s = "TCGS"strcpy(s, "TCGS")
    字符串相加s = s + "TCGS"strcat(s, "TCGS")
    字符串比較s == "TCGS"strcmp(s, "TCGS")

    重載運算符

    C++語言中已經給出的運算符(算數運算符和邏輯運算符)只是針對C++語言中已經給定的數據類型進行運算。倘若我們想要對我們自定義數據類型進行運算的話,則需要重載運算符,我們可以把重載運算符理解為對已有的運算符的一種重新定義。

    重載運算符的實現

    語法格式如下
    <返回類型> operator <運算符符號>(<參數>)
    {
        <定義>;
    }
    //定義結構體
    struct node
    {
        int id;
        double x, y;
    }; 
    //重載運算符"<"
    bool operator < (const node &a, const node &b)  
    {
        if(a.x != b.x)
            return a.x < b.x;
        else
            return a.y < b.y;
    }

    以上是“C++中指針,引用和STL的示例分析”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    c++
    AI

    务川| 将乐县| 邳州市| 云龙县| 林周县| 郓城县| 庐江县| 中西区| 平顶山市| 应用必备| 壤塘县| 新和县| 屏东县| 卫辉市| 高台县| 文水县| 莱芜市| 京山县| 宜州市| 冕宁县| 陇川县| 筠连县| 大悟县| 嘉荫县| 平阳县| 普兰店市| 鄱阳县| 兴和县| 大城县| 芷江| 连平县| 石首市| 行唐县| 安岳县| 来凤县| 贵南县| 濮阳市| 南皮县| 德安县| 湟中县| 武安市|