C++之list容器模擬實(shí)現(xiàn)方式
總述
list模擬實(shí)現(xiàn)主要包括四個(gè)類(lèi):節(jié)點(diǎn)類(lèi)、迭代器類(lèi)、反向迭代器類(lèi)、list類(lèi)。
list底層結(jié)構(gòu):
因?yàn)閘ist的底層空間不連續(xù),所以迭代器不能使用原生態(tài)的指針,將節(jié)點(diǎn)類(lèi)型的指針?lè)庋b成類(lèi),重載解引用及自增等常用操作。list可以保存多種數(shù)據(jù)類(lèi)型,所以這些類(lèi)都寫(xiě)成類(lèi)模板
一、節(jié)點(diǎn)類(lèi)
list底層是帶頭結(jié)點(diǎn)的雙向循環(huán)鏈表,先實(shí)現(xiàn)節(jié)點(diǎn)類(lèi),給成類(lèi)模板的形式,便于插入不同類(lèi)型的數(shù)據(jù)。
template<class T> struct ListNode { ListNode<T>* prev; ListNode<T>* next; T data;//要在鏈表中保存的數(shù)據(jù)類(lèi)型 ListNode(const T& value = T()) :prev(nullptr) , next(nullptr) , data(value) { } };
定義新節(jié)點(diǎn)的方法:
ListNode<變量類(lèi)型>*變量名=new ListNode(value);
二、迭代器類(lèi)
迭代器類(lèi)模板有三個(gè)參數(shù)
- T:迭代器指向的元素類(lèi)型
- Ref:返回的引用類(lèi)型
- Ptr:返回的指針類(lèi)型
Ref和Ptr一般不寫(xiě)成T&和T*。
成員變量
迭代器類(lèi)的成員變量就是節(jié)點(diǎn)類(lèi)型的指針
Node* _pNode;//成員變量,節(jié)點(diǎn)類(lèi)型指針
構(gòu)造函數(shù)
編譯器默認(rèn)的構(gòu)造函數(shù)是無(wú)參的,構(gòu)造函數(shù)需要給出
ListIterator(Node* pNode = nullptr) :_pNode(pNode) {}
*重載
返回節(jié)點(diǎn)中保存的數(shù)據(jù)
Ref operator*() { return _pNode->data; }
->重載
返回節(jié)點(diǎn)中保存的數(shù)據(jù)的地址
Ptr operator->() { return &_pNode->data; }
->的重載只對(duì)內(nèi)置類(lèi)型有意義:
“++”
前置++
返回值是迭代器自身類(lèi)型的引用,前面已經(jīng)將ListIterator<T, Ref, Ptr>重命名位Self,表示迭代器自身的類(lèi)型。
Self& operator++() { _pNode = _pNode->next; return *this; }
后置++
定義臨時(shí)變量,返回自增前的值
Self operator++(int) { Self temp(*this); _pNode = _pNode->next; return temp; }
“–”
與++原理相同
Self& operator--() { _pNode = _pNode->prev; return (*this); } Self operator--(int) { Self temp(*this); _pNode = _pNode->prev; return temp; }
“==“和”!=”
比較兩個(gè)迭代器中封裝的指針
bool operator!=(const Self& it) { return _pNode != it._pNode; } bool operator==(const Self& it) { return _pNode == it._pNode; }
三、反向迭代器類(lèi)
反向迭代器可以對(duì)迭代器類(lèi)進(jìn)行復(fù)用
因?yàn)轭?lèi)外訪問(wèn)靜態(tài)成員變量時(shí)也會(huì)使用類(lèi)名::變量名的方式,所以對(duì)迭代器類(lèi)中的Reference和Pointer進(jìn)行重命名時(shí)要加上typename,明確告訴編譯器要重命名的是一個(gè)數(shù)據(jù)類(lèi)型。否則編譯器會(huì)報(bào)錯(cuò):
成員變量
反向迭代器對(duì)迭代器類(lèi)進(jìn)行復(fù)用
private: Iterator _it;//正向迭代器
*重載
反向迭代器的解引用要做特殊處理,返回的是對(duì)迭代器–的值
Reference operator*() { //*做特殊處理,先--,再解引用返回 auto temp = _it; --temp; return *temp; }
->重載
復(fù)用*的重載,返回value的地址
Pointer operator->() { return &(operator*()); }
“++”
反向迭代器的++即為正向迭代器的–
Self operator++() { --_it; return *this; } Self operator++(int) { Self temp(*this); --_it; return *this; }
“- -”
反向迭代器的–用正向迭代器的++替代
Self operator--() { ++_it; return *this; } Self operator--(int) { Self temp(*this); ++_it; return temp; }
" == " 和"!="
比較反向迭代器類(lèi)中保存的正向迭代器,復(fù)用正向迭代器中的比較方法
bool operator==(const Self& rit) { return _it == rit; } bool operator!=(const Self& rit) { return _it == rit._it; }
四、list類(lèi)
成員變量
list的成員變量只有一個(gè)head指針,指向鏈表的第一個(gè)節(jié)點(diǎn)
private: Node* head;
構(gòu)造相關(guān)
空對(duì)象
list() { CreatHead(); }
創(chuàng)造頭節(jié)點(diǎn)的方法:
//提供一個(gè)創(chuàng)造頭結(jié)點(diǎn)的方法 void CreatHead() { //調(diào)用節(jié)點(diǎn)類(lèi)的構(gòu)造方法 head = new Node(); head->next = head; head->prev = head; }
0000000
new申請(qǐng)空間,令head指向這段空間,head的next和prev都指向自己。
n個(gè)T類(lèi)型元素
調(diào)用push_back方法,創(chuàng)造頭節(jié)點(diǎn)后,不斷進(jìn)行尾插直到元素個(gè)數(shù)等于n
list(int n, const T& value = T()) { CreatHead(); for (int i = 0; i < n; ++i) { push_back(value); } }
拷貝構(gòu)造
復(fù)用push_back
list(const list<T>& l) { CreatHead(); auto it = l.cbegin(); while (it != l.cend()) { push_back(*it); it++; } }
迭代器構(gòu)造
將迭代器構(gòu)造方法寫(xiě)成函數(shù)模板,可以傳入不同類(lèi)型的迭代器來(lái)構(gòu)造list對(duì)象
template<class InputIterator> list(InputIterator first, InputIterator last) { CreatHead(); while (first != last) { push_back(*first); first++; } }
賦值運(yùn)算符重載
與拷貝構(gòu)造寫(xiě)法相同
list<T>& operator=(const list<T>& l) { if (this != &l) { clear();//先清空當(dāng)前對(duì)象中的節(jié)點(diǎn) auto it = l.cbegin(); while (it != l.cend()) { push_back(*it); it++; } } return *this; }
析構(gòu)
清空當(dāng)前對(duì)象,釋放頭節(jié)點(diǎn)空間,將頭節(jié)點(diǎn)置空
~list() { clear(); delete head; head = nullptr; }
迭代器
正向迭代器
begin
此處的iterator是對(duì)ListIterator<T, T&, T*>的重命名,這里會(huì)返回一個(gè)ListIterator<T, T&, T*>類(lèi)對(duì)象
iterator begin() { //iterator it(head->next); //return it; //head->next是傳遞給迭代器類(lèi)對(duì)象構(gòu)造函數(shù)的參數(shù),調(diào)用iterator的構(gòu)造函數(shù) return iterator(head->next);//構(gòu)造匿名對(duì)象返回 }
end
iterator end() { return iterator(head); }
const類(lèi)型迭代器
iterator和const_iterator 是兩個(gè)不同的類(lèi):
兩者使用的是相同的類(lèi)模板,但是傳遞的參數(shù)不同,最終實(shí)例化的也是不同的類(lèi)。
cbegin&cend
const_iterator cbegin()const { return const_iterator(head->next); } const_iterator cend()const { return const_iterator(head); }
反向迭代器
rbegin&rend
返回正向迭代器的end和begin
reverse_iterator rbegin() { ?? ?return reverse_iterator(end()); } reverse_iterator rend() { ?? ?return reverse_iterator(begin()); }
crbegin&crend
復(fù)用正向迭代器的cend和cbegin
const_reverse_iteraotr crbegin()const { ?? ?return const_reverse_iteraotr(cend()); } const_reverse_iteraotr crend()const { ?? ?return const_reverse_iteraotr(cbegin()); }
容量操作
size
遍歷鏈表,統(tǒng)計(jì)節(jié)點(diǎn)個(gè)數(shù)
size_t size() { ?? ?auto it = cbegin(); ?? ?size_t count = 0; ?? ?while (it != cend()) ?? ?{ ?? ??? ?++count; ?? ??? ?++it; ?? ?} ?? ?return count; }
empty
如果head->next是head本身則表明鏈表為空
bool empty() { ?? ?return head->next == head; }
resize
改變節(jié)點(diǎn)個(gè)數(shù),若新的節(jié)點(diǎn)個(gè)數(shù)大于舊的,則調(diào)用push_back填充元素;若新的節(jié)點(diǎn)個(gè)數(shù)小于原來(lái)的調(diào)用pop_back尾刪
元素訪問(wèn)
front
復(fù)用迭代器解引用的方法,返回begin()位置元素
T& front() { return *begin(); } const T& front()const { return *cbegin(); }
back
back表示最后一個(gè)元素,但是end()指向的是最后一個(gè)元素的下一個(gè)位置,需要定義臨時(shí)變量,不能直接對(duì)end()進(jìn)行- -。
T& back() { auto it = end(); //return --end()//錯(cuò)誤寫(xiě)法 it--; return *it; } const T& back()const { auto it = end(); it--; return *it; }
打印鏈表
定義一個(gè)打印鏈表的函數(shù)模板,檢驗(yàn)方法。通過(guò)迭代器遍歷鏈表,打印每一個(gè)節(jié)點(diǎn)的數(shù)據(jù)。
template<class T> void PrintList(const list<T>& l) { auto it = l.cbegin(); while (it != l.cend()) { cout << *it << " "; ++it; } cout << endl; }
元素修改
尾插與尾刪
push_back
復(fù)用insert方法在end位置插入
void push_back(const T& value) { insert(end(), value); }
pop_back
先判斷鏈表是否為空,復(fù)用erase方法在end的前一個(gè)位置進(jìn)行插入
void pop_back() { if (empty()) { return; } auto it = end(); it--; erase(it); }
頭插與頭刪
復(fù)用insert與erase方法,在begin()位置進(jìn)行插入或刪除
void push_front(const T& value = T()) { insert(begin(), value); } void pop_front() { erase(begin()); }
?insert
任意位置的插入:申請(qǐng)新節(jié)點(diǎn),連接新節(jié)點(diǎn)與鏈表,斷開(kāi)舊的連接。
這里傳入的參數(shù)是一個(gè)迭代器類(lèi)對(duì)象,不能直接進(jìn)行操作,要對(duì)對(duì)象中封裝的_pNode指針進(jìn)行操作。
返回值是新插入的節(jié)點(diǎn)的迭代器,所以要用申請(qǐng)的新節(jié)點(diǎn)的指針newnode構(gòu)造一個(gè)迭代器類(lèi)對(duì)象返回,不能直接返回newnode
iterator insert(iterator Insertpos, const T& value) { Node* newnode = new Node(value); Node* pos = Insertpos._pNode;//_pNode是節(jié)點(diǎn)類(lèi)型的指針 newnode->next = pos; newnode->prev = pos->prev; newnode->prev->next = newnode; pos->prev = newnode; //return newnode; //?迭代器是封裝的Node*指針,此時(shí)不能再返回newnode return iterator(newnode);//構(gòu)造匿名對(duì)象返回 }
?erase
任意位置的刪除:分別改變前后兩個(gè)節(jié)點(diǎn)的next和prev指針的指向即可
iterator erase(iterator Erasepos) { Node* pos = Erasepos._pNode; Node* ret = pos->next; pos->prev->next = pos->next; pos->next->prev = pos->prev; delete pos; return iterator(ret); }
區(qū)間刪除:復(fù)用單個(gè)節(jié)點(diǎn)刪除的方法,遍歷要?jiǎng)h除的區(qū)間。
要用接收erase的返回值,防止迭代器失效
iterator erase(iterator first, iterator last) { auto it = first; while (it != last) { //it=erase(it); //后置++會(huì)構(gòu)造臨時(shí)對(duì)象返回,不會(huì)導(dǎo)致迭代器失效 erase(it++); } return it; }
clear&swap
- clear復(fù)用erase區(qū)間刪除的方法,從begin刪除到end位置;
- swap方法調(diào)用標(biāo)準(zhǔn)庫(kù)中的swap,交換兩個(gè)鏈表的頭節(jié)點(diǎn)。
void clear() { erase(begin(), end()); } void swap(list<T>& l) { std::swap(head, l.head); }
附:完整list類(lèi),含測(cè)試用例
#include<iostream> #include<vector> using namespace std; namespace ZH { / //節(jié)點(diǎn)類(lèi)模板, template<class T> struct ListNode { ListNode<T>* prev; ListNode<T>* next; T data; ListNode(const T& value = T()) :prev(nullptr) , next(nullptr) , data(value) { } }; / //迭代器類(lèi)模板 //list的迭代器不能使用原生態(tài)的指針,要進(jìn)行封裝 //T:迭代器指向的元素類(lèi)型 //Ref:給operator*使用,返回引用類(lèi)型,不要寫(xiě)成T& //Ptr:返回值使用,不要寫(xiě)成T* template<class T,class Ref,class Ptr> class ListIterator { public: typedef ListNode<T> Node;//化簡(jiǎn)節(jié)點(diǎn)類(lèi)的名字 typedef Ref Reference;//在反向迭代器類(lèi)中使用 typedef Ptr Pointer; typedef ListIterator<T, Ref, Ptr> Self;//簡(jiǎn)化迭代器類(lèi)的名字 //構(gòu)造函數(shù) ListIterator(Node* pNode=nullptr) :_pNode(pNode) {} //重載部分需要使用的運(yùn)算符即可:*、->、++、--、== Ref operator*() { return _pNode->data; } //T為自定義類(lèi)型時(shí)有意義, Ptr operator->() { return &_pNode->data; } //前置++,返回值是迭代器自身類(lèi)型的引用 Self& operator++() { _pNode = _pNode->next; return *this; } //后置 Self operator++(int) { Self temp(*this); _pNode = _pNode->next; return temp; } Self& operator--() { _pNode = _pNode->prev; return (*this); } Self operator--(int) { Self temp(*this); _pNode = _pNode ->prev; return temp; } //迭代器能進(jìn)行比較 bool operator!=(const Self& it) { return _pNode != it._pNode; } bool operator==(const Self& it) { return _pNode == it._pNode; } Node* _pNode;//成員變量,節(jié)點(diǎn)類(lèi)型指針 }; //反向迭代器類(lèi)模板,對(duì)迭代器進(jìn)行復(fù)用 template<class Iterator> class ListReverseIterator { public: //typedef Iterator::Reference Reference; //typedef Iterator::Pointer Pointer; typedef typename Iterator::Reference Reference;//typename指定Reference是Iterator中的數(shù)據(jù)類(lèi)型 typedef typename Iterator::Pointer Pointer; typedef ListReverseIterator<Iterator> Self; ListReverseIterator(Iterator it) : _it(it) { } Reference operator*() { //*做特殊處理,先--,再解引用返回 auto temp = _it; --temp; return *temp; } Pointer operator->() { return &(operator*()); } Self operator++() { --_it; return *this; } Self operator++(int) { Self temp(*this); --_it; return *this; } Self operator--() { ++_it; return *this; } Self operator--(int) { Self temp(*this); ++_it; return temp; } bool operator==(const Self& rit) { return _it == rit; } bool operator!=(const Self& rit) { return _it == rit._it; } private: Iterator _it;//正向迭代器 }; template<class T> class list { typedef ListNode<T> Node; //typedef Node* iterator;//不能使用Node*作迭代器 //迭代器 typedef ListIterator<T, T&, T*> iterator; typedef ListIterator< T, const T&, const T*> const_iterator; typedef ListReverseIterator<iterator> reverse_iterator; typedef ListReverseIterator<const_iterator> const_reverse_iteraotr; public: /// //構(gòu)造 list() { CreatHead(); } list(int n, const T& value=T()) { CreatHead(); for (int i = 0; i < n; ++i) { push_back(value); } } list(const list<T>& l) { CreatHead(); auto it = l.cbegin(); while (it != l.cend()) { push_back(*it); it++; } } //迭代器區(qū)間構(gòu)造 template<class InputIterator> list(InputIterator first, InputIterator last) { CreatHead(); while (first != last) { push_back(*first); first++; } } //賦值運(yùn)算符重載 list<T>& operator=(const list<T>& l) { if (this != &l) { clear();//先清空當(dāng)前對(duì)象中的節(jié)點(diǎn) auto it = l.cbegin(); while (it != l.cend()) { push_back(*it); it++; } } return *this; } ~list() { clear(); delete head; head = nullptr; } public: //迭代器 iterator begin() { //iterator it(head->next); //return it; //iterator是對(duì)ListIterator<T, T&, T*>的重命名 //這里會(huì)返回一個(gè)ListIterator<T, T&, T*>類(lèi)對(duì)象 //head->next是傳遞給迭代器類(lèi)對(duì)象構(gòu)造函數(shù)的參數(shù),調(diào)用iterator的構(gòu)造函數(shù) return iterator(head->next);//構(gòu)造匿名對(duì)象返回 } iterator end() { return iterator(head); } //const類(lèi)型迭代器 const_iterator cbegin()const { return const_iterator(head->next); } const_iterator cend()const { return const_iterator(head); } //反向迭代器 //反向迭代器的成員變量是一個(gè)迭代器類(lèi)對(duì)象 //end()即為傳遞給反向迭代器類(lèi)構(gòu)造函數(shù)的參數(shù) reverse_iterator rbegin() { return reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } //反向const類(lèi)型迭代器 const_reverse_iteraotr crbegin()const { return const_reverse_iteraotr(cend()); } const_reverse_iteraotr crend()const { return const_reverse_iteraotr(cbegin()); } / //容量 size_t size() { auto it = cbegin(); size_t count = 0; while (it != cend()) { ++count; ++it; } return count; } bool empty() { return head->next == head; } void resize(int newsize,const T& value=T()) { size_t oldsize = size(); if (newsize > oldsize) { while (oldsize++<newsize) { push_back(value); } } if (newsize < oldsize) { while (oldsize-- < newsize) { pop_back(); } } } /// //元素訪問(wèn) T& front() { return *begin(); } const T& front()const { return *cbegin(); } T& back() { auto it = end(); it--; return *it; } const T& back()const { auto it = end(); it--; return *it; } / //元素修改 void push_back(const T& value) { insert(end(), value); } void pop_back() { if (empty()) { return; } auto it = end(); it--; erase(it); } void push_front(const T& value = T()) { //Node* pos = head->next; /*Node* newnode = new Node(value); newnode->next = head->next; newnode->prev = head; head->next->prev = newnode; head->next = newnode;*/ //復(fù)用insert insert(begin(), value); } void pop_front() { erase(begin()); } //?insert // iterator是ListIterator<T, T&, T*> iterator insert(iterator Insertpos, const T& value) { Node* newnode = new Node(value); Node* pos = Insertpos._pNode;//_pNode是節(jié)點(diǎn)類(lèi)型的指針 newnode->next = pos; newnode->prev = pos->prev; newnode->prev->next = newnode; pos->prev = newnode; //return newnode; //?迭代器是封裝的Node*指針,此時(shí)不能再返回newnode return iterator(newnode);//構(gòu)造匿名對(duì)象返回 } //?erase iterator erase(iterator Erasepos) { Node* pos = Erasepos._pNode; Node* ret = pos->next; pos->prev->next = pos->next; pos->next->prev = pos->prev; delete pos; return iterator(ret); } iterator erase(iterator first, iterator last) { auto it = first; while (it != last) { //it=erase(it); erase(it++); } return it; } void clear() { erase(begin(), end()); } void swap(list<T>& l) { std::swap(head, l.head); } private: //提供一個(gè)創(chuàng)造頭結(jié)點(diǎn)的方法 void CreatHead() { //調(diào)用節(jié)點(diǎn)類(lèi)的構(gòu)造方法 head = new Node(); head->next = head; head->prev = head; } private: Node* head; }; template<class T> void PrintList(const list<T>& l) { auto it = l.cbegin(); while (it != l.cend()) { cout << *it << " "; ++it; } cout << endl; } } void Test1() { ZH::list<int> l1; ZH::list<int> l2(3, 1); PrintList(l2); ZH::list<int> l3(l2.begin(), l2.end()); PrintList(l3); vector<int> v{ 0,1,2,3,4 }; ZH::list<int> l4(v.begin(), v.end()); PrintList(l4); } void Test2() { vector<int> v{ 1,2,3,4 }; ZH::list<int> L1(v.begin(), v.end()); L1.push_back(5); L1.push_back(6); L1.push_front(0); PrintList(L1); L1.pop_back(); L1.pop_front(); PrintList(L1); L1.erase(--L1.end()); PrintList(L1); } void Test3() { ZH::list<int> L1; L1.push_back(1); L1.push_back(2); L1.push_back(3); L1.push_front(0); PrintList(L1); L1.resize(6, 5); PrintList(L1); } struct A { int a; int b; int c; }; void Test4() { A aa{ 1,2,3 }; A bb{ 4,5,6 }; A cc{ 7,8,9 }; ZH::list<A> L; L.push_back(aa); L.push_back(bb); L.push_back(cc); auto it = L.begin(); while (it != L.end()) { //?it->得到的是節(jié)點(diǎn)的地址 //本應(yīng)是it->->a,編譯器做了特殊處理 cout << it->a << " "; it++; } cout << endl; } void Test5() { ZH::list<int> L1; L1.push_back(0); L1.push_back(1); L1.push_back(2); L1.push_back(3); PrintList(L1); cout << L1.back() << endl; cout << L1.front() << endl; cout << L1.size() << endl; L1.clear(); cout << L1.size() << endl; } void Test6() { ZH::list<int> L1; L1.push_back(0); L1.push_back(1); L1.push_back(2); L1.push_back(3); PrintList(L1); //區(qū)間刪除 /*L1.erase(L1.begin(), L1.end()); PrintList(L1);*/ ZH::list<int> L2; L2.push_back(1); L2.push_back(2); L2.push_back(3); L2.push_back(4); L2.push_back(5); PrintList(L2); L1.swap(L2); PrintList(L1); PrintList(L2); } int main() { Test6(); system("pause"); return 0; }
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C++ 回調(diào)接口設(shè)計(jì)和二進(jìn)制兼容詳細(xì)
再開(kāi)發(fā)視頻編輯 SDK,SDK的回調(diào)接口設(shè)計(jì)成 C 風(fēng)格,結(jié)構(gòu)中放著一些函數(shù)指針,既然對(duì)外接口是 C++,為什么不直接使用 C++ 的虛函數(shù)?這篇文章便對(duì)這一問(wèn)題做個(gè)詳細(xì)介紹,需要的朋友可以參考一下2021-09-09利用C語(yǔ)言如何實(shí)現(xiàn)一些簡(jiǎn)單圖形的打印
這篇文章主要給大家介紹了關(guān)于利用C語(yǔ)言如何實(shí)現(xiàn)一些簡(jiǎn)單圖形的打印的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12解讀堆排序算法及用C++實(shí)現(xiàn)基于最大堆的堆排序示例
把待排序的數(shù)組構(gòu)造出最大堆是進(jìn)行堆排序操作的基本方法,這里將帶大家來(lái)解讀堆排序算法及用C++實(shí)現(xiàn)基于最大堆的堆排序示例,首先從堆排序的概念開(kāi)始:2016-06-06C++與QML進(jìn)行數(shù)據(jù)交互實(shí)現(xiàn)方式介紹
迫于無(wú)奈開(kāi)始寫(xiě)android的程序,以前使用QWidget的方式試過(guò),雖然界面可以實(shí)現(xiàn),但是最后調(diào)用攝像頭時(shí),未能成功,再?zèng)]有繼續(xù)。這幾天開(kāi)始使用qml進(jìn)行嘗試,在使用的過(guò)程中,其中的一個(gè)難點(diǎn),就是在qml與c++中數(shù)據(jù)的交互2022-09-09C語(yǔ)言實(shí)現(xiàn)散列表(哈希Hash表)實(shí)例詳解
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)散列表(哈希Hash表)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-06-06C程序函數(shù)調(diào)用&系統(tǒng)調(diào)用
這篇文章主要介紹了C程序函數(shù)調(diào)用&系統(tǒng)調(diào)用,需要的朋友可以參考下2016-09-09c++標(biāo)準(zhǔn)庫(kù)讀寫(xiě)ini文件的實(shí)現(xiàn)示例
本文介紹了一個(gè)完整的INI文件類(lèi)的實(shí)現(xiàn),包含讀取和寫(xiě)入操作,通過(guò)IniFile.h頭文件和IniFile.cpp實(shí)現(xiàn)文件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-10-10C語(yǔ)言變長(zhǎng)數(shù)組 struct中char data[0]的用法詳解
下面小編就為大家?guī)?lái)一篇C語(yǔ)言變長(zhǎng)數(shù)組 struct中char data[0]的用法詳解。小編覺(jué)得挺不錯(cuò)的現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-01-01解析VC中創(chuàng)建DLL,導(dǎo)出全局變量,函數(shù)和類(lèi)的深入分析
本篇文章是對(duì)VC中創(chuàng)建DLL,導(dǎo)出全局變量,函數(shù)和類(lèi)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05