<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
#include<iostream> using namespace std; inline double square(double x){ return x*x; } int main(){ cout<<square(2.2)<<endl; }
其實就是在函數宣告或者定義前加上關鍵字inline
。
參照實際上就是定義一個別名。看看下面程式碼:
#include<iostream> using namespace std; int main(){ int a=50; int &b=a;//定義並初始化,這裡b是a的參照。 cout<<"a:"<<a<<endl; cout<<"b:"<<b<<endl; cout<<"address of a:"<<&a<<endl; cout<<"address of b:"<<&b<<endl; b=100; cout<<"a:"<<a<<endl; cout<<"b:"<<b<<endl; int c=200; b=c;//試圖將b作為c的參照。行不通。 cout<<"a:"<<a<<endl; cout<<"b:"<<b<<endl; cout<<"c:"<<c<<endl; cout<<"address of a:"<<&a<<endl; cout<<"address of b:"<<&b<<endl; cout<<"address of c:"<<&c<<endl; }
a:50
b:50
address of a:0x61fe14
address of b:0x61fe14
a:100
b:100
a:200
b:200
c:200
address of a:0x61fe14
address of b:0x61fe14
address of c:0x61fe10
a和b的資料地址是一樣的,這說明b相當於a的別名,我們改變b的值,也會改變a的值,而且後面我們試圖將b轉變為c的參照,但是行不通,b=c這個程式碼做的是賦值語句,相當於a=c.
參照和指標的區別
參照在宣告的時候必須初始化
int &b;
這句話是不允許的。
參照的本質就是指標常數。因為參照變數一旦初始化就不能更改。
int &b=a
和int* const p=&a
這兩句中b
和*p
是一模一樣的。
參照作為函數引數
#include<iostream> using namespace std; void swap(int &a,int &b){ int c; c=a; a=b; b=c; } int main(){ int a=2; int b=3; swap(a,b); cout<<a<<b<<endl; }
可以看出把參照作為引數的函數,只需在宣告時,把引數設定成參照即可。
臨時變數
試想一下,在引數傳遞過程中,我們把常數或者錯誤型別的實參,傳給參照引數,會發生什麼?這個參照引數會變成這個實參的參照嗎?顯然不會,因為常數不能修改,參照是錯誤的,正如int &a=2;
會報錯一樣;錯誤型別的實參,也不能直接參照。
為了解決這個事,c++允許臨時變數的產生。但是隻有const參照才會產生臨時變數,const參照不允許變數發生賦值。
總結來說,臨時變數的產生條件是,在傳參給const參照引數時:
實參不是左值.(左值指的是const變數 和 常規變數。)
實參型別不正確且可型別轉換。
所以說,為了使得參照引數傳遞的相容性和安全性,請多使用const。
#include<iostream> using namespace std; double square(const double &a){ return a*a*a; } int main(){ int a=3; cout<<square(3+a)<<endl; }
可以看出來這裡square函數可以接受非左值,型別錯誤的實參。
你可能覺得這樣做很複雜,直接使用按值傳參就行了。double square(double a)
和double square(const double &a)
,從效果來說,這兩一樣,但是我們使用第二種傳參的好處是高效,試想一下我們同時傳一個double型別的變數,const參照傳參不需要資料的拷貝,更快。
右值參照
採用 && 來對右值做參照,這麼做的目的是用來實現移動語意。
#include<iostream> using namespace std; int main(){ double a=3.1; double && b=a*1.2+2.3; cout<<b<<endl; b=3; cout<<a<<endl; cout<<b<<endl; }
6.02
3.1
3
結構參照
參照非常適合於結構和類
#include<iostream> using namespace std; struct apple { string name; double weight; }; apple & swap(apple &a, apple &b){ apple temp; temp=a; a=b; b=temp; return a; } int main(){ apple a={"Bob",230}; apple b={"Alice",190}; swap(a,b); cout<<"a:"<<endl<<"name:"<<a.name<<endl<<"weight:"<<a.weight<<endl<<endl; cout<<"b:"<<endl<<"name:"<<b.name<<endl<<"weight:"<<b.weight<<endl<<endl; swap(swap(a,b),b); cout<<"a:"<<endl<<"name:"<<a.name<<endl<<"weight:"<<a.weight<<endl<<endl; cout<<"b:"<<endl<<"name:"<<b.name<<endl<<"weight:"<<b.weight<<endl<<endl; swap(swap(swap(a,b),b),b); swap(swap(a,b),b); cout<<"a:"<<endl<<"name:"<<a.name<<endl<<"weight:"<<a.weight<<endl<<endl; cout<<"b:"<<endl<<"name:"<<b.name<<endl<<"weight:"<<b.weight<<endl<<endl; }
a:
name:Alice
weight:190b:
name:Bob
weight:230a:
name:Alice
weight:190b:
name:Bob
weight:230a:
name:Bob
weight:230b:
name:Alice
weight:190
swap()函數的返回值是一個參照變數,所以swap(swap(swap(a,b),b),b)
是合法的,且它等價於swap(a,b)
。
為何要返回參照?高效。 因為傳統返回機制,會把返回結果複製到一個臨時位置。 但是應該避免返回 函數終止時不再存在的記憶體單元參照。例如避免返回臨時變數的參照。
預設引數指的是函數呼叫中省略了實參時自動使用的一個值。
如何設定預設值?必須通過函數原型。 例如這裡的void display(int a,int n=999);
這裡n=999 就是預設引數 預設引數的作用是,不給這個引數傳參時,他會採用預設值。
#include<iostream> using namespace std; void display(int a,int n=999); int main(){ display(1); display(3,31); } void display(int a,int n){ cout<<a<<endl; cout<<n<<endl; }
1
999
3
31
預設引數能讓我們使用不同數目的引數呼叫同一個函數,而函數過載能讓我們使用多個同名的函數。
函數過載的關鍵是函數的參數列–也稱函數特徵標。如果兩個函數的名字和特徵標相同,那麼這兩個函數就完全相同。C++允許定義名稱相同,函數特徵標不同的函數,這就是所謂的函數過載。
#include<iostream> using namespace std; struct apple{ string name; double weight; }; void print(int); void print(double); void print(char *); void print(apple &a,string str="apple",double w=100); int main(){ int a=2; double b=3.14; char c[10]="hello!"; apple d; print(a); print(b); print(c); print(d); print(d,"Alice",250); } void print(int a){ cout<<"int ="<<a<<endl; } void print(double a){ cout<<"double ="<<a<<endl; } void print(char * a){ cout<<"char* ="<<a<<endl; } void print(apple &a,string str,double b){ a.name=str; a.weight=b; cout<<"the name:"<<a.name<<endl; cout<<"the weight:"<<a.weight<<endl; }
int =2
double =3.14
char* =hello!
the name:apple
the weight:100
the name:Alice
the weight:250
可以看出來print
函數有多個過載,現代編譯器會根據你傳遞的引數型別,而選擇最匹配的函數。
關於函數過載的一些細節
double cube(double x);
和double cube(double &x);
是不能共存的。void display(char* a);
和void display(const char* a);
是函數過載。long gronk(int,float);
和double gronk(int,float);
是不能共存的。函數過載的shortcoming
函數過載在實現同函數名多種功能的同時,也應當付出代價。
標準型別轉化、強制匹配能力下降。
#include<iostream> using namespace std; void print(double); void print(char *); int main(){ int a=2; double b=3.14; char c[10]="hello!"; print(a); print(b); print(c); } void print(double a){ cout<<"double ="<<a<<endl; } void print(char * a){ cout<<"char* ="<<a<<endl; }
double =2
double =3.14
char* =hello!
可以看出來這裡print(a)
這裡a是int型別,編譯器會將其型別轉化成double,然後呼叫對應函數。
但是,我們稍微改動一下程式碼
#include<iostream> using namespace std; void print(int); void print(double); void print(char *); int main(){ int a=2; double b=3.14; char c[10]="hello!"; print(a); print(b); print(c); print(12L); } void print(int a){ cout<<"int ="<<a<<endl; } void print(double a){ cout<<"double ="<<a<<endl; } void print(char * a){ cout<<"char* ="<<a<<endl; }
這段程式碼中print(12L);
會報錯,因為12L
是long型別的常數,如果我們試著強制匹配會發現,12L
既可以轉化成int型別,也可以轉化成double型別,從而編譯器不知道到底呼叫哪個函數。
不要濫用函數過載
僅當函數基本執行相同的任務,但使用不同型別的資料時,才應當使用函數過載。
到此這篇關於C++範例分析行內函式與參照變數及函數過載的使用的文章就介紹到這了,更多相關C++行內函式內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45