)
一.學習語法函數(shù)重載什么是函數(shù)重載呢--簡單的說其實就是C支持同一作用域中出現(xiàn)同名函數(shù)但是要求這些參數(shù)不同或者返回值不同。這些不同包括函數(shù)傳參的個數(shù)類型和順序。有了函數(shù)重載C函數(shù)就表現(xiàn)出了多態(tài)行為使用更靈活。c語言不支持同一作用域出現(xiàn)同名函數(shù)的。#includeiostream using namespace std; // 1、參數(shù)類型不同 int Add(int left, int right) { cout int Add(int left, int right) endl; return left right; } double Add(double left, double right) { cout double Add(double left, double right) endl; return left right; } // 2、參數(shù)個數(shù)不同 void f() { cout f() endl; } void f(int a) { cout f(int a) endl; } // 3、參數(shù)類型順序不同 void f(int a, char b) { cout f(int a,char b) endl; } void f(char b, int a) { cout f(char b, int a) endl; } // 返回值不同不能作為重載條件因為調(diào)?時也?法區(qū)分 //void fxx() //{} // //int fxx() //{ // return 0; //} // 下?兩個函數(shù)構(gòu)成重載 // f()但是調(diào)?時會報錯存在歧義編譯器不知道調(diào)?誰 void f1() { cout f() endl; } void f1(int a 10) { cout f(int a) endl; } int main() { Add(10, 20); Add(10.1, 20.2); f(); f(10); f(10, a); f(a, 10); return 0; }引用引用是c比較特殊的概念引用相當于給變量起別名編譯器不會為引用變量開辟內(nèi)存空間它和它引用的變量共用一塊內(nèi)存空間引用的使用類型引用別名 引用int main() { int a 5; int _a a; //這里_a就是a的引用 }這里_a 和a是一個地址引用的特性1.引用在定義是必須初始化2.一個變量可以有多個引用3.引用一但引用一個實體再也不能引用其他實體C規(guī)定在函數(shù)傳參和返回值時如果是傳值傳參和傳值返回。編譯器會主動申請創(chuàng)建變量的引用再傳到函數(shù)中或者再傳到函數(shù)外。這個創(chuàng)建變量的引用會調(diào)用拷貝構(gòu)造函數(shù)。(后面再講)引用的使用1.引用在實踐中的作用主要是用于引用傳參和引用做返回值中減少拷貝提高效率和改變引用對象同時改變被引用對象。2.引用傳擦和指針傳參功能是類似的引用傳參相對更方便一些3.引用做返回值情況復雜。4.引用和指針在實踐中是相輔相成的各有特點功能有重疊性互相不能替代。其實在編譯器層面上引用和指針生成的指令是一樣的我們在使用時要特別關(guān)注引用是變量別名指針需要解引用才能訪問變量。const引用在c中把常量(類似 1 2)他的數(shù)據(jù)類型是const int,--不能修改的int型變量1.可以引用一個const對象但是必須加上const引用const引用也可以引用普通對象但const限制后不能修改對象內(nèi)容---對象的訪問權(quán)限只能縮小不能放大int _a a*3; double d 12.3; int _d d;//這里有類型轉(zhuǎn)換2.上述代碼的a*3,和類型轉(zhuǎn)換都會產(chǎn)生一個臨時變量存儲中間值也就是說_a和_b都是臨時對象的聲明而C規(guī)定臨時變量有常性這里權(quán)限放大了。要使用常引用3.所謂的臨時變量其實就是編譯器需要一個空間暫存表達式的求值結(jié)果時臨時創(chuàng)建的一個未命名的對象C中把這個對象稱為臨時對象指針和引用的關(guān)系1.語法上說引用是一個變量的別名沒有開空間指針是存儲了變量的地址需要開空間2.在匯編語言上引用的定義和指針的定義是一樣的3.引用在使用時必須要進行初始化且一旦初始化之后不能在修改引用對象指針不同可以改變存儲的地址4.引用可以直接訪問對象指針需要解引用5.sizeof()不一樣--如果是引用其結(jié)果是引用類型的大小如果是指針其結(jié)果是存儲地址的字節(jié)數(shù)6.引用很少有空引用指針常出現(xiàn)這個問題incline函數(shù)incline函數(shù)修飾的函數(shù)叫內(nèi)聯(lián)函數(shù)編譯時c編譯器會在調(diào)用的地方展開內(nèi)聯(lián)函數(shù)這樣內(nèi)斂函數(shù)不需要創(chuàng)建棧幀提高了效率C設(shè)計這個incline是為了替代宏函數(shù)(#define 返回類型函數(shù)名a,b((a)(b)))incline函數(shù)是對于編譯器是一個建議incline不支持聲明和定義分開。nullptr在c語言中NULL是一個宏可以看到代碼#ifndef NULL #ifdef __cplusplus #define NULL 0 #else #define NULL ((void *)0) #endif #endifC中把NULL定義為0在C語言中NULL既能做0也能當無類型指針(void*)的常量。但是我們c如果繼續(xù)延用這一NULL我們寫一個函數(shù)重載的時候兩個函數(shù)名相同我們都去傳NULL這個變量編譯器會調(diào)用參數(shù)是int的函數(shù)還是調(diào)用參數(shù)是指針的呢為了解決這一問題C規(guī)定NULL只能是0nullptr當成指針nullptr是一種特殊類型的字面量它可以轉(zhuǎn)換成任意其他類型的指針類型。使用nullptr定義空指針可以避免轉(zhuǎn)換的問題因為nullptr只能隱式的轉(zhuǎn)換為指針類型而不能轉(zhuǎn)換成證書類型#includeiostream using namespace std; void f(int x) { cout f(int x) endl; } void f(int* ptr) { cout f(int* ptr) endl; } int main() { f(0); // 本想通過f(NULL)調(diào)?指針版本的f(int*)函數(shù)但是由于NULL被定義成0調(diào)?了f(int x)因此與程序的初衷相悖。 f(NULL); f((int*)NULL); // 編譯報錯error C2665: “f”: 2 個重載中沒有?個可以轉(zhuǎn)換所有參數(shù)類型 // f((void*)NULL); f(nullptr); return 0; }