c++編程基礎個人筆記(二)

1.函數

  • C++的函數返回值類型可以是除數組外的其他任何類型;
  • C++的參數列表中,方括號指出的參數其實並不是數組,而是指針。
int sum_arr(int arr[], int n);

2.函數指針

  • 函數指針的聲明
// 一般聲明
double pam(int);
double (*pf)(int);
pf = pam;
// 聲明指針數組
double (*pf[3])(int) = {pam1, pam2, pam3}; //pam1,pam2,pam3 are three functions with same features
// auto聲明指針數組
auto pa = pf;
// typedef進行聲明
typedef double (*p_fun)(int);
p_fun pf = pam;
p_fun pf[5];
  • 函數指針的調用,函數指針可以通過*解除引用調用,也可以像函數名一樣直接調用;
double pam(int);
double (*pf)(int);
pf = pam;
double x = (*pf)(5);
double x = pf(5); // this is the same to the code above.

3.內聯函數

  • inline 內聯函數通過直接用函數代碼替換函數調用,提高了程序的運行速度;
  • 代碼簡短、非遞歸的函數建議使用inline;
  • 內聯函數與宏

宏是通過文本替換來實現,不能按值傳遞,而內聯函數可以。

#define SQUARE(x) ((x)*(x)) // SQUARE(c++) = (c++)*(c++), 調用後C將遞增兩次,而如果定義爲內聯函數,則c將先計算值,再遞增一次

4.引用變量

  • 引用是已定義的變量的別名,使用引用做形參,調用時將直接使用原始數據,不使用副本;
  • 數據量大時,使用引用可以大大節省內存空間。
  • &:左值引用,&&:右值引用。
  • 對於傳遞的值而不做修改的函數

如果數據對象很小,則按值傳遞;

如果數據對象數組,則只能使用指針,通常使用指向const的指針;

如果數據對象很大,則使用const指針或const引用;

如果數據對象是類對象,則使用const引用。

  • 對於修改調用函數中數據的函數

如果數據對象是內置數據類型或數組,則使用指針;

如果數據對象是結構,則使用指針或引用;

如果數據對象是類對象,則使用引用。

5.儘量使用const

  • const 可以避免由於無意間修改數據而導致的編程錯誤;
  • const形參可以處理const和非const實參,非const形參只能處理非const數據;
  • 使用const引用可以避免原始數據被修改。

6.默認參數

  • 對於帶參數列表的函數,必須從右向左添加默認值。
  • 對某個默認參數時,需爲參數右邊的所有參數提供默認值。
int harpo(int n, int m = 4, int j =5); // valid
int chico(int n, int m = 4, int j); // not valid
beeps = harpo(1); // valid
beeps = harpo(1,,6);// not valid
beeps = harpo(1,2,6); //valid

7.函數重載的特徵標必須不同--參數列表不同。

8.函數模板

  • 格式,老的格式用class,新的格式用typenam,c++11都兼容兩種格式
template <typename T>
  • 具體化優先常規模塊,而非模板函數優先具體化和常規模板
//非模板
void Swap(job &, job &);
//常規模板
template <typename T>;
void Swap(T &, T &);
//顯式具體化
template <> void Swap<job>(job &, job &);
template <> void Swap(job &, job &);//job可省略
//顯示實例化
template void Swap<int>(int, int);  // ---實例化即爲直接調用
  • 關鍵字decltype
//用於執行語句
decltype(x) y; //make the same type as x
//用於返回值
auto h(int x, float y) ->double; //return type is double
template<typename T1, typename T2>
auto gt(T1, T2) -> decltype(x + y) { //return type is the same to (x + y)
    return x + y;
}

9.存儲持續性、作用於和鏈接性

  • 局部變量: 存儲於棧中,LIFO(後進先出),函數或代碼塊創建到釋放期間持續,作用域爲該函數或代碼塊內;
  • 靜態存儲持續性:程序運行過程中均存在;全局變量作用域爲所有文件,static定義於文件內,代碼塊外時,作用域爲當前文件,static定義於代碼塊內時,作用域爲當前代碼塊;
  • 線程存儲持續性:通過thread_local聲明,該線程持續;
  • 動態持續性:存儲於堆中,new-delete期間持續。

10.static說明符

  • 變量持續性:變量將在整個程序運行過程持續,其值能被持續更改;
  • 作用域:限定變量作用域爲當前文件或當前代碼塊。

11.mutable說明符:當結構或類變量爲const時,其某個成員也可以被修改。

struct data {
    char name[30];
    mutable int accesses; //accesses can be modified
}
const data veep = {"hello world",0};
veep.accesses = 1; //allowed

12.volatile 限定符:變量直接從內存地址取值,不進行緩存,防止被優化。

13.new作爲定位運算符時,可以將變量地址創建到指定地址中。

struct chaff {
    char dross[20];
    int slag;
};
char buffer[100];
int *p1 = new (buffer) chaff; //place structure in buffer
int *p1 = new (buffer) int[20]; //place int array in buffer 

14.名稱空間

  • 名稱空間可以是全局的,也可以位於另一個名稱空間中,但不能位於代碼塊中;
  • using聲明由被限定的名稱和關鍵字using組成,using編譯指令則通過namespace,被限定的名稱和關鍵字using 組成。using 聲明導入名稱空間中部分成員變量或函數,而using編譯指令則導入名稱空間中所有成員;
namespace Jill {  // create namespace Jill
    double pail;
    double fetch;
    int pal;
    struct Well { ...};
}

namespace Jill {  // add goose into namespace Jill
    char * goose(const char *);
}
int para = 1;
using namespace Jill; // using compile code
using Jill::fetch; //using declaration
::para = 2; //global parameter.
  • 原則:使用已命名的名稱空間中的變量,而不是使用外部全局變量;
  • 原則:使用已命名的名稱空間中的變量,而不是使用靜態全局變量;
  • 原則:不要在頭文件中使用using編譯指令;
  • 原則:導入名稱時,首選使用作用域解析運算符或using聲明的方法。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章