《工作筆記一》C++函數式宏定義的使用

什麼是宏定義?

通常宏定義的格式爲:#define 標識符 字符串 相信大家都見過非常多了,通常我們編譯過程中的預處理(預編譯)工作又叫宏展開,將代碼中的宏名替換爲字符串。

爲什麼要用宏函數?

宏函數雖然在處理複雜的函數(例如遞歸函數)時宏會降低代碼的執行效率,但是對於邏輯簡單的函數來說,準確的使用宏函數往往能提高程序的執行效率,因爲在主函數中調用普通函數的時候需要進行入棧跟出棧操作,而宏函數不用,宏函數只是進行簡單的直接替換,所以能對代碼的執行效率有一定的提升。當然也有不好的一面,使用了宏函數跟使用普通函數比較起來生成的目標文件會比較大,因爲宏函數的直接插入導致在代碼中多了一份拷貝。

什麼是宏函數?

宏函數其實就是上面的字符串寫成一個完整的函數體。下面寫一個大家熟悉的宏函數?

#define MIN(x, y) ((x < y) ? x : y)

是不是經常有見到!
下面我們來對一個簡單的普通函數跟宏函數做個對比:

#include <iostream>

// 宏函數
// 寫法1 (調用該宏前必須存在min變量)
#define MYFUNC(x, y)\
{\
    min = x < y ? x : y;\
}\

// 寫法2
#define MYFUNC2(x, y, min)\
{\
    min = x < y ? x : y;\
}\

// 普通函數
void MyFunc(const int x, const int y, int &min)
{
    // 通過引用獲取x跟y的最小值
    min = x < y ? x : y;   
}

int main(void)
{
    int x = 1, y = 2, min = 0;
    MyFunc(x, y, min);
    std::cout << "MyFunc: " << min << std::endl;

    x = 3, y = 4;
    MYFUNC(x, y);
    std::cout << "MYFUNC: " << min << std::endl;

    x = 5, y = 6;
    MYFUNC2(x, y, min);
    std::cout << "MYFUNC2: " << min << std::endl; 

    return 0;
}
輸出結果:
MyFunc: 1
MYFUNC: 3
MYFUNC2: 5

因爲宏的參數替換是直接替換的,所以寫法一是可行的。
上面的對比還無法看出宏函數的多少優勢,那接下來我們進行對函數進行改造,將函數作爲參數傳入到我們的參數裏面。

#include <iostream>
#include <string>

// 寫法1
// 調用該宏前必須存在min變量
#define MYFUNC(x, y, fun1)\
{\
    min = x < y ? x : y;\
    fun1("MYFUNC", x, y);\
}\

// 寫法2
#define MYFUNC2(x, y, min)\
{\
    min = x < y ? x : y;\
    printfun("MYFUNC2", x, y);\
}\

typedef void(*Fun1)(const std::string, const int, const int);
void printfun(const std::string str, const int x, const int y)
{
    // 用於輸出x+y的值
    int sum = x + y;
    std::cout << str << " sum is : " << sum << std::endl;
}

// 普通函數
void MyFunc(const int x, const int y, int &min, Fun1 fun1)
{
    // 通過引用獲取x跟y的最小值
    min = x < y ? x : y;   

    fun1("MyFunc", x, y);
}


int main(void)
{
    int x = 1, y = 2, min = 0;
    MyFunc(x, y, min, printfun);
    std::cout << "MyFunc: " << min << std::endl;

    x = 3, y = 4;
    MYFUNC(x, y, printfun);
    std::cout << "MYFUNC: " << min << std::endl;

    x = 5, y = 6;
    MYFUNC2(x, y, min);
    std::cout << "MYFUNC2: " << min << std::endl; 

    return 0;
}
運行結果:
MyFunc sum is : 3
MyFunc: 1
MYFUNC sum is : 7
MYFUNC: 3
MYFUNC2 sum is : 11
MYFUNC2: 5

因爲要將函數作爲參數進行傳遞,所以這裏我用到了函數模板Fun1,可以發現如果使用宏函數的話是不需要使用函數模板的,但是使用普通函數的話是必須使用的,因爲這裏必須將函數作爲參數進行傳遞,而宏函數因爲是直接替換到代碼裏面的所以這裏可以直接使用,當然也可以將函數傳到宏的參數裏,但是宏的參數是不需要參數類型的,所以這裏使用宏函數的話可以幫我們減少挺多的工作量,與此同時還能提高程序的效率,當然要注意別寫錯!別寫錯!

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