欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++11語法之右值引用的示例講解

 更新時(shí)間:2022年04月04日 11:14:33   作者:^jhao^  
右值引用,一般是在深拷貝的類,實(shí)現(xiàn)移動(dòng)構(gòu)造和移動(dòng)賦值,能夠解決左值引用無法做到的傳返回值的效率問題,下面跟隨小編一起學(xué)習(xí)下C++11語法之右值引用的問題

一、{}的擴(kuò)展

在原先c++的基礎(chǔ)上,C++11擴(kuò)展了很多初始化的方法。

#include<iostream>
using namespace std;
struct A
{
	int _x;
	int _y;
};
int main()
	int a[] = { 1,2,3,4,5 };
	
	int a1[] { 1,2,3,4,5 };
	int* p = new int[5]{ 1,2,3,4,5 };
	A b = { 1,2 };//初始化
	A b2[5]{ {1,1},{2,2},{3,3},{4,4},{5,5} };
	A* pb = new A{ 1,2 };
	A* pb2 = new A[5]{ {1,1},{2,2},{3,3},{4,4},{5,5} };
	return 0;
}

結(jié)果:

全部初始化正常,vs下指針后面跟數(shù)字可以表示顯示多少個(gè)。

除了上面的 new[]{}我認(rèn)為是比較有意義的,很好的解決了new的對(duì)象沒有構(gòu)造函數(shù)又需要同時(shí)創(chuàng)建多個(gè)對(duì)象的場景。

除了上面的,下面的這種方式底層實(shí)現(xiàn)不相同。

initializer_list的講解:

vector<int> v{1,2,3,4};

跳轉(zhuǎn)initializer_list實(shí)現(xiàn)

實(shí)際上上面就是通過傳參給initializer_list對(duì)象,這個(gè)對(duì)象相當(dāng)于淺拷貝了外部的{1,2,3,4}的頭指針和尾指針,這樣vector的構(gòu)造函數(shù)就可以通過迭代器遍歷的方式一個(gè)個(gè)的push_back到自己的容器當(dāng)中。上述過程initializer_list是很高效的,因?yàn)樗簧婕皽\拷貝指針和一個(gè)整形。

#include <iostream>
template <class T>
class initializer_list
{
public:
    typedef T         value_type;
    typedef const T&  reference; //注意說明該對(duì)象永遠(yuǎn)為const,不能被外部修改!
    typedef const T&  const_reference;
    typedef size_t    size_type;
    typedef const T*  iterator;  //永遠(yuǎn)為const類型
    typedef const T*  const_iterator;
private:
    iterator    _M_array; //用于存放用{}初始化列表中的元素
    size_type   _M_len;   //元素的個(gè)數(shù)
    
    //編譯器可以調(diào)用private的構(gòu)造函數(shù)?。?!
    //構(gòu)造函數(shù),在調(diào)用之前,編譯會(huì)先在外部準(zhǔn)備好一個(gè)array,同時(shí)把a(bǔ)rray的地址傳入模板
    //并保存在_M_array中
    constexpr initializer_list(const_iterator __a, size_type __l)
    :_M_array(__a),_M_len(__l){};  //注意構(gòu)造函數(shù)被放到private中!
    constexpr initializer_list() : _M_array(0), _M_len(0){} // empty list,無參構(gòu)造函數(shù)
    //size()函數(shù),用于獲取元素的個(gè)數(shù)
    constexpr size_type size() const noexcept {return _M_len;}
    //獲取第一個(gè)元素
    constexpr const_iterator begin() const noexcept {return _M_array;}
    //最后一個(gè)元素的下一個(gè)位置
    constexpr const_iterator end() const noexcept
    {
        return begin() + _M_len;
    }  
};

而{}初始化,和{}調(diào)用initializer_list組合起來是可以讓初始化變得方便起來的,下面的m0用了initializer_list進(jìn)行初始化,但還是比較麻煩。但m1用了{(lán)}進(jìn)行單個(gè)對(duì)象初始化加initializer_list的組合之后變得方便快捷起來。

#include<map>
int main()
{
	map<int, int> m0 = { pair<int,int>(1,1), pair<int,int>(2,2), pair<int,int>(3,3) };
	
	map<int, int> m1= { {1,1},{2,2},{3,3} };
	return 0;
}

小總結(jié):

一個(gè)自定義類型調(diào)用{}初始化,本質(zhì)是調(diào)用對(duì)應(yīng)的構(gòu)造函數(shù);自定義類型對(duì)象可以使用{}初始化,必須要有對(duì)應(yīng)的參數(shù)類型和個(gè)數(shù);STL容器支持{}初始化,則容器必須有一個(gè)initializer_list作為參數(shù)的構(gòu)造函數(shù)。

二、C++11一些小的更新

auto:
定義變量前加auto表示自動(dòng)存儲(chǔ),表示不用管對(duì)象的銷毀,但是默認(rèn)定義的就是自動(dòng)類型,所以這個(gè)關(guān)鍵字后面就不這樣用了,C++11中改成了自動(dòng)推導(dǎo)類型。

#include<cstring>
int main()
{
	int i = 10;
	auto p = &i;
	auto pf = strcmp;

	cout << typeid(p).name() << endl;
	cout << typeid(pf).name() << endl;
	return 0;
}

結(jié)果:

int *
int (__cdecl*)(char const *,char const *)

decltype

auto只能推導(dǎo)類型,但推導(dǎo)出來的類型不能用來定義對(duì)象,decltype解決了這點(diǎn),推導(dǎo)類型后可以用來定義對(duì)象。
decltype(表達(dá)式,變量),不能放類型!

#include<cstring>
int main()
{
	int i = 10;
	auto p = &i;
	auto pf = strcmp;

	decltype(p) pi;//int*
	pi = &i;
	cout << *pi << endl;//10
	return 0;
}

nullptr

NULL在C中是0,是int類型。C++11添加nullptr表示((void*)0),避免匹配錯(cuò)參數(shù)。

范圍for

支持迭代器就支持范圍for

新容器

array,沒啥用,靜態(tài)的數(shù)組,不支持push_back,支持方括號(hào),里面有assert斷言防止越界,保證了安全。

foward_list,沒啥用,單鏈表,只能在節(jié)點(diǎn)的后面插入。

unordered_map,很有用,后面講

unordered_set,很有用,后面講

三、右值引用

左值
作指示一個(gè)數(shù)據(jù)表達(dá)式(變量名或解引用的指針)。
左值可以在賦值符號(hào)左右邊,右值不能出現(xiàn)在賦值符號(hào)的左邊。

const修飾符后的左值,不能給他賦值,但是可以取他的地址。左值引用就是給左值的引用,給左值取別名。

左值都是可以獲取地址,基本都可以可以賦值
但const修飾的左值,只能獲取地址,不能賦值。

右值?
右值也是一個(gè)數(shù)據(jù)的表達(dá)式,如字面常量,表達(dá)式返回值,傳值返回的函數(shù)的返回值(不能是左值引用返回)。右值不能取地址,不能出現(xiàn)在賦值符號(hào)的左邊。

關(guān)鍵看能不能取地址

給右值取別名就用右值引用,右值引用是左值了,放在賦值符號(hào)的左邊了。

右值不能取地址,但是給右值引用后,引用的變量是可以取地址的,并且可以修改!
右值引用存放的地方在棧的附近。

int main()
{
	int&& rra = 10;
	//不想被修改 const int&& rra
	cout << &rra << endl;
	rra = 100;
	return 0;
}

左值引用總結(jié):

  • 左值引用只能引用左值,不能引用右值。
  • 但是const修飾的左值引用既可以引用左值,又可以引用右值。在沒有右值引用的時(shí)候就必須采用這種方式了。
  • 左值最重要的特征是都可以取地址,即使自定義類型也有默認(rèn)的取地址重載。

右值引用總結(jié):
右值引用只能引用右值,不能引用左值。
右值引用可以引用move以后的左值。

左值引用可以接著引用左值引用,右值引用不可以。
原因:右值引用放到左邊表示他已經(jīng)是一個(gè)左值了,右值引用不能引用左值!

int main()
{
	int a = 10;
	int& ra = a;
	int& rb = ra;
	int&& rra = 10;
	int&& rrb = rra;//err:無法從“int”轉(zhuǎn)換為“int && "
	return 0;
}

匹配問題:

void func(const int& a)
{
	cout << "void func(const int& a)" << endl;
}
void func(int&& a)
	cout << "void func(int&& a)" << endl;
int main()
	int a = 10;
	func(10);
	func(a);
	return 0;

右值在有右值引用會(huì)去匹配右值引用版本!

右值真正的用法

本質(zhì)上引用都是為了減少拷貝,提高效率。而左值引用解決了大部分的場景,但是左值引用在傳值返回的時(shí)候比較吃力,由右值引用來間接解決。

左值引用在引用傳參可以減少拷貝構(gòu)造,但是返回值的時(shí)候避免不了要調(diào)用拷貝構(gòu)造。

傳參用左值拷貝和右值拷貝都一樣,但是返回值如果用右值引用效率會(huì)高,并且通常左值引用面臨著對(duì)象出了作用域銷毀的問題。所以這就是右值引用的一個(gè)比較厲害的用法。

返回對(duì)象若出了作用域不存在,則用左值引用返回和右值引用返回都是錯(cuò)誤的。

std::move是將對(duì)象的狀態(tài)或者所有權(quán)從一個(gè)對(duì)象轉(zhuǎn)移到另一個(gè)對(duì)象,只是轉(zhuǎn)移,沒有內(nèi)存的搬遷或者內(nèi)存拷貝,所以可以提高利用效率,改善性能。所以當(dāng)作函數(shù)返回值的時(shí)候如果對(duì)象不存在左值引用和右值引用都會(huì)報(bào)錯(cuò)!

場景:返回的對(duì)象在局部域中棧上存在,返回該對(duì)象必須用傳值返回,并且有返回對(duì)象接受,這個(gè)時(shí)候編譯器優(yōu)化,將兩次拷貝構(gòu)造優(yōu)化成一次拷貝構(gòu)造。

測試用的string類

#include<assert.h>
namespace ljh
{
	class string
	{
	public:
		typedef char* iterator;
		iterator begin()
		{
			return _str;
		}
		iterator end()
		{
			return _str + _size;
		}
		string(const char* str = "")
			:_size(strlen(str))
			, _capacity(_size)
		{
			//cout << "string(char* str)" << endl;
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}
		// s1.swap(s2)
		void swap(string& s)
		{
			::swap(_str, s._str);
			::swap(_size, s._size);
			::swap(_capacity, s._capacity);
		}
		// 拷貝構(gòu)造
		string(const string& s)
			:_str(nullptr)
		{
			cout << "string(const string& s) -- 深拷貝" << endl;
			string tmp(s._str);
			swap(tmp);
		}
		// 賦值重載
		string& operator=(const string& s)
		{
			cout << "string& operator=(string s) -- 深拷貝" << endl;
			string tmp(s);
			swap(tmp);
			return *this;
		}
		// 移動(dòng)構(gòu)造
		/*string(string&& s)
			:_str(nullptr)
			, _size(0)
			, _capacity(0)
		{
			cout << "string(string&& s) -- 移動(dòng)語義" << endl;
			swap(s);
		}*/
		// 移動(dòng)賦值
		string& operator=(string&& s)
		{
			cout << "string& operator=(string&& s) -- 移動(dòng)語義" << endl;
			swap(s);
			return *this;
		}
		~string()
		{
			delete[] _str;
			_str = nullptr;
		}
		char& operator[](size_t pos)
		{
			assert(pos < _size);
			return _str[pos];
		}
		void reserve(size_t n)
		{
			if (n > _capacity)
			{
				char* tmp = new char[n + 1];
				strcpy(tmp, _str);
				delete[] _str;
				_str = tmp;
				_capacity = n;
			}
		}
		void push_back(char ch)
		{
			if (_size >= _capacity)
			{
				size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
				reserve(newcapacity);
			}
			++_size;
			_str[_size] = '\0';
		}
		//string operator+=(char ch)
		string& operator+=(char ch)
		{
			push_back(ch);
			return *this;
		}
		const char* c_str() const
		{
			return _str;
		}
	private:
		char* _str;
		size_t _size;
		size_t _capacity; // 不包含最后做標(biāo)識(shí)的\0
	};
}

臨時(shí)變量如果是4/8字節(jié),通常在寄存器當(dāng)中,但是如果是較大的內(nèi)存,會(huì)在調(diào)用方的函數(shù)棧幀中開辟一塊空間用于接受,這就是臨時(shí)對(duì)象。

臨時(shí)對(duì)象存在的必要性
當(dāng)我們不需要接受返回值,而是對(duì)返回的對(duì)象進(jìn)行直接使用,這個(gè)時(shí)候被調(diào)用的函數(shù)中的對(duì)象出了函數(shù)棧幀就銷毀了,所以在棧幀銷毀前會(huì)將對(duì)象拷貝到調(diào)用方棧幀的一塊空間當(dāng)中,我們可以用函數(shù)名對(duì)這個(gè)臨時(shí)對(duì)象直接進(jìn)行操作的(通常不能修改這個(gè)內(nèi)存空間,臨時(shí)變量具有常性)。

分析下面幾組圖片代碼的效率

不可避免的,下面的這個(gè)過程必然要調(diào)用兩次拷貝構(gòu)造,編譯器對(duì)于連續(xù)拷貝構(gòu)造優(yōu)化成不生成臨時(shí)對(duì)象,由func::ss直接拷貝給main的str,我們?nèi)绻挥星懊嫠鶎W(xué)的左值引用,func中的string ss在出了func后銷毀,這個(gè)時(shí)候引用的空間被銷毀會(huì)出現(xiàn)問題,這個(gè)時(shí)候顯得特別無力。
在連續(xù)的構(gòu)造+拷貝構(gòu)造會(huì)被編譯器進(jìn)行優(yōu)化,這個(gè)優(yōu)化要看平臺(tái),但大部分平臺(tái)都會(huì)做這個(gè)處理。

結(jié)果:

即使下面這種情況,在main接受沒有引用的情況下,依舊會(huì)調(diào)用一次拷貝構(gòu)造,跟上面并沒有起到一個(gè)優(yōu)化的作用。

結(jié)果:

解決方案:添加移動(dòng)構(gòu)造,添加一個(gè)右值引用版本的構(gòu)造函數(shù),構(gòu)造函數(shù)內(nèi)部講s對(duì)象(將亡值)的內(nèi)容直接跟要構(gòu)造的對(duì)象交換,效率很高?。?/p>

string(string&& s):_str(nullptr), _size(0), _capacity(0){cout << "string(string&& s) -- 移動(dòng)語義" << endl;swap(s);}

有了移動(dòng)構(gòu)造,對(duì)于上面的案例就變成了一次拷貝構(gòu)造加一次移動(dòng)構(gòu)造。**編譯器優(yōu)化后將ss判斷為將亡值,直接移動(dòng)構(gòu)造str對(duì)象,不產(chǎn)生臨時(shí)對(duì)象了,就只是一次移動(dòng)構(gòu)造,效率升高??!**同理移動(dòng)賦值!

結(jié)果:

下面情況是引用+移動(dòng)構(gòu)造,但是編譯器優(yōu)化就會(huì)判斷ss出了作用域還存在,反而會(huì)拿ss拷貝構(gòu)造str,這個(gè)時(shí)候起不到優(yōu)化的作用!

結(jié)果:

以上采用將對(duì)象開辟在堆上或靜態(tài)區(qū)都能夠采用引用返回解決問題,但是有一個(gè)壞處?
引入多線程的概念,每個(gè)線程執(zhí)行的函數(shù)當(dāng)中若有大量的堆上的數(shù)據(jù)或者靜態(tài)區(qū)的數(shù)據(jù),相當(dāng)于臨界資源變多,要注意訪問臨界資源要加鎖。而每個(gè)棧區(qū)私有棧,會(huì)相對(duì)好些

右值:
1、內(nèi)置類型表達(dá)式的右值,純右值。
2、自定義類型表達(dá)式的右值,將亡值。

將亡值:

string(string&& s)
			:_str(nullptr)
			, _size(0)
			, _capacity(0)
		{
			cout << "string(string&& s) -- 移動(dòng)語義" << endl;
			swap(s);
		}
int main()
{
	ljh::string& str = func2();
	vector<ljh::string> v;
	v.push_back("1234656");//傳進(jìn)去的就是右值,是用"1234656"構(gòu)造一個(gè)string對(duì)象傳入,就是典型的將亡值
}

移動(dòng)構(gòu)造:
將亡值在出了生命周期就要銷毀了,構(gòu)造的時(shí)候可以將資源轉(zhuǎn)移過要構(gòu)造的對(duì)象,讓將亡的對(duì)象指向NULL,相當(dāng)于替它掌管資源。移動(dòng)構(gòu)造不能延續(xù)對(duì)象的生命周期,而是轉(zhuǎn)移資源。且移動(dòng)構(gòu)造編譯器不優(yōu)化本質(zhì)是一次拷貝構(gòu)造+一次移動(dòng)構(gòu)造(從將亡值(此時(shí)返回值還是一個(gè)左值)給到臨時(shí)變量),再有臨時(shí)變量給到返回值接受對(duì)象(移動(dòng)構(gòu)造);
編譯器優(yōu)化做第一次優(yōu)化,會(huì)將將亡值當(dāng)作右值,此時(shí)要進(jìn)行兩次移動(dòng)構(gòu)造,編譯器第二次優(yōu)化,直接進(jìn)行一次移動(dòng)構(gòu)造,去掉生成臨時(shí)對(duì)象的環(huán)節(jié)。
只有需要深拷貝的場景,移動(dòng)構(gòu)造才有意義,跟拷貝構(gòu)造一樣,淺拷貝意義不大。

move的真正意義:
表示別人可以將這個(gè)資源進(jìn)行轉(zhuǎn)移走。

int main()
{
//為了防止這種情況,也要添加移動(dòng)賦值。
	ljh::string str1;
	str1 = "123456";
}

c++11的算法swap的效率跟容器提供的swap效率一樣了。

vector提供的插入的右值引用版本,就是優(yōu)化了傳右值情況,如果C++98則需要拷貝放入,而有右值就可以直接移動(dòng)構(gòu)造。兩個(gè)接口的效率差不多。
大多數(shù)容器的插入接口都做了右值引用版本??!

完美轉(zhuǎn)發(fā)

模板函數(shù)或者模板類用的&&即萬能引用。
模板中的&&不代表右值引用,而是萬能引用,其既能接收左值又能接收右值。模板的萬能引用只是提供了能夠接收同時(shí)接收左值引用和右值引用的能力。而forward才能將這種右值特性保持下去。

但是引用類型的唯一作用就是限制了接收的類型,后續(xù)使用中都退化成了左值,

此時(shí)右值在萬能引用成為左值,可能會(huì)造成本身右值可以移動(dòng)構(gòu)造,卻變成左值只能拷貝構(gòu)造了。
Fun(std::forward<T>(t));才能夠保證轉(zhuǎn)發(fā)的時(shí)候值的特性

void Fun(int &x){ cout << "左值引用" << endl; }
void Fun(const int &x){ cout << "const 左值引用" << endl; }
void Fun(int &&x){ cout << "右值引用" << endl; }
void Fun(const int &&x){ cout << "const 右值引用" << endl; }
void Func(int x) {
 // ......
}
template<typename T>
void PerfectForward(T&& t) {
 Fun(t);
}
int main()
{
 PerfectForward(10);           // 右值
 int a;
 PerfectForward(a);            // 左值
 PerfectForward(std::move(a)); // 右值
 const int b = 8;
 PerfectForward(b);      // const 左值
 PerfectForward(std::move(b)); // const 右值
 return 0; }

默認(rèn)成員函數(shù)

C++11 新增了兩個(gè):移動(dòng)構(gòu)造函數(shù)和移動(dòng)賦值運(yùn)算符重載。

現(xiàn)在有8個(gè):構(gòu)造函數(shù),析構(gòu)函數(shù),拷貝構(gòu)造,拷貝賦值,取地址,const取地址移動(dòng)構(gòu)造,移動(dòng)賦值。

移動(dòng)構(gòu)造函數(shù)的默認(rèn)生成的要求比較嚴(yán)格:
如果你沒有自己實(shí)現(xiàn)移動(dòng)構(gòu)造函數(shù),且沒有實(shí)現(xiàn)析構(gòu)函數(shù) 、拷貝構(gòu)造、拷貝賦值重載都沒有實(shí)現(xiàn)。那么編譯器會(huì)自動(dòng)生成一個(gè)默認(rèn)移動(dòng)構(gòu)造。默認(rèn)生成的移動(dòng)構(gòu)造函數(shù),對(duì)于內(nèi)置類型
成員會(huì)執(zhí)行逐成員按字節(jié)拷貝,自定義類型成員,則需要看這個(gè)成員是否實(shí)現(xiàn)移動(dòng)構(gòu)造,如
實(shí)現(xiàn)了移動(dòng)構(gòu)造就調(diào)用移動(dòng)構(gòu)造沒有實(shí)現(xiàn)就調(diào)用拷貝構(gòu)造。
如果你提供了移動(dòng)構(gòu)造或者移動(dòng)賦值,編譯器不會(huì)自動(dòng)提供拷貝構(gòu)造和拷貝賦值。
同理移動(dòng)賦值。

即對(duì)于深拷貝的類,最好所有的構(gòu)造,析構(gòu),拷貝,賦值重載,移動(dòng)拷貝,移動(dòng)賦值都寫上。

總結(jié)

左值引用通常在傳參和傳返回值的過程中減少拷貝,這是利用左值引用的語法特性。一般做不到的部分,通常選擇傳參的時(shí)候傳引用也可以解決,不通過返回值接受。
右值引用,一般是在深拷貝的類,實(shí)現(xiàn)移動(dòng)構(gòu)造和移動(dòng)賦值,能夠解決左值引用無法做到的傳返回值的效率問題。

到此這篇關(guān)于C++11語法之右值引用的文章就介紹到這了,更多相關(guān)C++11右值引用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++基礎(chǔ)概念講述

    C++基礎(chǔ)概念講述

    這篇文章主要介紹了C++基礎(chǔ)概念,??本次為C++的一個(gè)開篇,重點(diǎn)是更好的理解C++相對(duì)于其他編程語言的一個(gè)特性,之后會(huì)持續(xù)更新,本次專欄計(jì)劃是掌握C++的基礎(chǔ)語法以及常用特性,并且從細(xì)節(jié)上去理解,需要的朋友可以參考一下
    2021-12-12
  • C/C++回調(diào)函數(shù)介紹

    C/C++回調(diào)函數(shù)介紹

    回調(diào)函數(shù)就是一個(gè)通過函數(shù)指針調(diào)用的函數(shù)。如果你把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個(gè)函數(shù),當(dāng)這個(gè)指針被用為調(diào)用它所指向的函數(shù)時(shí),我們就說這是回調(diào)函數(shù)
    2013-10-10
  • 怎樣用cmd運(yùn)行C程序

    怎樣用cmd運(yùn)行C程序

    這篇文章主要介紹了怎樣用cmd運(yùn)行C程序?今天就來和大家分享一下用cmd運(yùn)行C程序的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • matlab模擬退火算法單約束車間流水線調(diào)度解決實(shí)現(xiàn)及示例

    matlab模擬退火算法單約束車間流水線調(diào)度解決實(shí)現(xiàn)及示例

    這篇文章主要為大家介紹了matlab模擬退火算法求解單約束車間流水線調(diào)度的實(shí)現(xiàn)及示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-02-02
  • 詳解C語言函數(shù)返回值解析

    詳解C語言函數(shù)返回值解析

    這篇文章主要介紹了詳解C語言函數(shù)返回值解析的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • 純c實(shí)現(xiàn)異常捕獲try-catch組件教程示例

    純c實(shí)現(xiàn)異常捕獲try-catch組件教程示例

    這篇文章主要為大家介紹了純c實(shí)現(xiàn)異常捕獲try-catch組件教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • C語言數(shù)據(jù)結(jié)構(gòu)之迷宮求解問題

    C語言數(shù)據(jù)結(jié)構(gòu)之迷宮求解問題

    這篇文章主要為大家詳細(xì)介紹了C語言數(shù)據(jù)結(jié)構(gòu)之迷宮求解問題,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-03-03
  • C語言實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)(文件操作)

    C語言實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)(文件操作)

    這篇文章主要介紹了C語言實(shí)現(xiàn)學(xué)生信息管理系統(tǒng),增加了文件操作,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • C++命令行解析包gflags的使用教程

    C++命令行解析包gflags的使用教程

    這篇文章主要給大家介紹了關(guān)于C++命令行解析包gflags的使用教程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • C++實(shí)現(xiàn)二叉樹非遞歸遍歷算法詳解

    C++實(shí)現(xiàn)二叉樹非遞歸遍歷算法詳解

    在C++中,二叉樹非遞歸遍歷是一種常用的算法,可避免遞歸過程中的系統(tǒng)開銷和棧溢出問題。非遞歸遍歷算法利用棧數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn),可以實(shí)現(xiàn)前序、中序和后序遍歷,是C++程序員必備技能之一
    2023-04-04

最新評(píng)論