學習筆記1 從C到C++
本篇文章是學習c++面向物件程式設計前遇到的一些需要注意的知識點,因此做個記錄>=<。。。
引用返回&傳值返回
-
引用返回 &
C++中,在預設情況下,當函式返回一個值時:
return expression;
expression被求值,並將該值拷貝到臨時儲存空間,以便函式呼叫者訪問。這種返回方式稱為傳值返回
例如:當呼叫以下函式int val1() { //... return i; }
時,i的值將拷貝到臨時儲存空間,呼叫者獲得的是i的一個副本,也就是說,如果呼叫函式val1:j = val1();
,則i的值將拷貝到臨時儲存空間,然後再拷貝到j。
引用返回
例如:當呼叫以下函式
```c
int& val2()
{
//...
return i;
}
```
的返回型別為int&.當return語句執行後,呼叫者可以直接訪問i。
例如:以如下方式呼叫函式val2
:j = val2();
,則i的值直接拷貝到j中,與傳值返回不同的是,僅產生一個副本。
- 警告
例如函式:
int& f()
{
int i;
//...
//**** ERROR:i已經不存在了
return i;
}
包含了一個錯誤。當f返回i時,i已經不存在了(因為i是區域性變數)。
行內函數
關鍵字:inline
行內函數類似於巨集拓展。當處理器拓展一個巨集時,它將用巨集定義替換每個巨集。當巨集替換或函式拓展完成後,再執行程式,這樣避免了函式呼叫的開銷,程式可以更有效地執行。使用巨集或行內函數的缺點是,如果函式很大,或很多地方都呼叫了這個函式,程式的可執行碼將變得很大。
行內函數的拓展是通過編譯器完成的。當前處理器拓展一個巨集時,它只是進行簡單的文字替換,而不考慮程式碼的語義。而編譯器拓展行內函數時,需要考慮語義。
inline
函式從宣告開始到檔案結束都是可見的。
如下程式:
#include<iostream>
using namespace std;
inline void swap(int& a,int& b)
{
int t;
t=a;
a=b;
b=t;
}
int main()
{
int i=7,j=-3;
swap(i,j);
cout<<i<<" "<<j<<endl;
return 0;
}
編譯器接受以內聯方式拓展swap函式的請求,對程式碼swap(i,j);
來說不產生函式呼叫操作,因為swap
是行內函數,編譯器用swap
的實現程式碼來替代這一行程式碼。
new和delete操作符
new、new[]、delete和delete[]操作符用於動態分配和釋放儲存空間。操作符new分配一個空間;new[]分配一個數組;delete釋放由new分配的單一空間;*delete[]釋放由new[]*分配的陣列。這些操作符與C語言中的函式malloc、calloc和free。不同的是,**new、new[]、delete和delete[]**是內建的操作符,而不是庫函式。而且,new和delete還是關鍵字。
-
分配一個int儲存空間,如果new分配成功,則表示式:
new int
例如:
int* intptr = new int;
-
分配一個int動態陣列。
例如:int_ptr = new int[50];
-
delete釋放由new分配的儲存空間,例如:
delete int_ptr;
-
**delete[]釋放由new[]**分配的儲存空間,例如:
delete[] int_ptr;
混用c和c++的輸入/輸出功能
可使用函式ios::sync_with_stdio();
來消除這種隱患。
例如程式碼:
#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
int a=2,b=5;
ios::sync_with_stdio();
printf("%d ",a);
cout<<b<<'\n';
return 0;
}