C++筆記(2)

2018.04.01

1.函數調用堆棧的過程:

   

2.函數的返回值怎麼帶出來?
   (1)字節數<=4字節,eax   (2)(>4)&&(<=8)字節,eax/[ebx][edx]可選     (3)>8字節,產生臨時量
      臨時量:臨時量在函數調用之前產生,調用之前爲臨時量分配一塊地址;在進行壓棧時,給一個存放臨時量的地址信息的段,從而通過此地址找到臨時量;一層一層的進行循環拷貝賦值。
3.參數帶默認值的函數:
(1)int sum(int a,int b,int c=90)
        {
            int a=20,b=30;
            sum(10,a,b);/*b:mov eax,dword ptr[ebp-8];push eax*/
            sum(10,a);/*最後一項直接調用默認值,push dword ptr[ebp-8]*/
            //所以以上兩種調用效率不同
            
            sum(10,20,30);
            sum(10,20);
            //沒有效率上的差異,立即數只有一行結合
        }
(2)函數定義或聲明時都可以給參數默認值,且默認值只能給一個。
(3)帶有默認值參數的調用可以給一部分參數默認值,並且自右向左賦值。
(4)int sum(int a,int b=90,int c);
        int sum(int a,int b,int c=90);
        int main(){...sum(10,20);...}    錯誤
        int sum(int a,int b,int c=90);
        int sum(int a,int b=90,int c);
        int main(){...sum(10,20);...}    正確
        函數執行從上到下。
4.(1)static和inline的異同?
           相同點:都是當前文件可見;
           不同點:static修飾符號在符號表中產生符號,但符號都是local,鏈接器不處理,不參與符號解析;而inline函數修飾的變量是不產生符號的。
   (2)define和inline的區別?
            define:在預編譯階段,直接進行宏替換,不做任何安全性檢查;在debug下不可以調試
            inline:發生在編譯階段,有完整的類型安全檢查,在debug下可以調試
   (3)普通函數和inline函數的區別?
           a.inline要修飾函數定義,不要修飾函數聲明,無意義!!
           b.inline函數的處理過程:在函數的調用點,將函數的代碼展開,相當於沒有函數棧幀開闢回退的過程,也就是沒有函數調用開銷,在會變語言下沒有調用函數的call指令。
           c.inline:是建議編譯器儘可能地被處理成inline函數,成功與否看編譯器,但最終作用域都會變,如遞歸前加inline是不可能變成內聯函數的。
inline int sum(int a, int b)//a
{
     return a + b;
}
int main()
{
     int ret = sum(10, 20);//int ret = 10 + 20;//b
     return 0;
}

5.C++函數的重載?C語言不能重載
bool compare(short a, short b)
{
     cout << "compare_short_short" << endl;
     return a > b;
}
bool compare(float a, float b)
{
     cout << "compare_float_float" << endl;
     return a > b;
}
bool compare(char* a, char* b)
{
     cout << "compare_char*_char*" << endl;
     return strcmp(a, b) > 0;
}
int main()
{
      compare(10, 20);  //產生call指令
      compare(10.0, 20.0);  // call
      compare("10", "20");  // call
}

(1)函數名相同,參數列表的參數個數或類型不同,就可以構成一組重載函數(因爲參與函數的函數名和參數列表會參與符號解析),不能僅通過函數返回值類型來區分函數重載;
(2)函數的重載和匹配發生在函數的編譯階段;
(3)一組函數要構成重載,必須處在同一作用域下,處在不同作用域下的函數不可以構成重載(因爲調用函數默認調用離調用點最近的作用域上的函數是在編譯過程進行的),在函數內部可以聲明函數,但不可定義函數,此時在調用變量時默認時調用本地作用域的聲明,要訪問全局變量時,加上“::”符號;
(4)const和volatile對重載函數參數的影響。
C++的多態:靜態的多態(編譯時期的多態):函數重載,模板
                     動態的多態(運行時期的多態):繼承,虛函數
6.C++如何調用C語言寫的接口
   (1)extern “C”:告訴編譯器裏面括的符號都是在C編譯器下產生的,所以,你給我生成它符號的時候,應該按照C語言的規則生成符號;
   (2)爲了方便起見,也可以將#include“xx.c”頭文件寫到extern“C”{}中,在預編譯階段頭文件就展開了,裏面的方法都以C的形式生成符號。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章