C程序中函數名與宏名稱同名



C語言中,函數名稱和宏名稱可以相同。可以參考下面的示例程序。
///////////////////////////////////////////test.cpp
#include <stdio.h>




void print(int value) {
    printf("%d\n", value);
}




#define print(x)  printf("hello");    \
                print(x)




int main() {
    print(23);




    return 0;
}
上面的程序在vc和gcc下都可以運行,輸出結果是:hello23。
究其原因,我們知道編譯器編譯C語言程序時,先執行預編譯,然後再執行編譯、彙編和鏈接等步驟。預編譯階段質主要處理宏,而編譯階段同名的宏已經被替換掉了,故而此時是不存在標識符衝突的。
但是,函數名稱和宏名稱同名是有前提的,同名的宏定義必須在同名函數實體之下。再請參考下面示例程序。
/////////////////////////test.cpp
#include <stdio.h>


#define print(x)  printf("hello");    \
                print(x)




void print(int value) {
    printf("%d\n", value);
}




int main() {
    print(23);




    return 0;
}
這個程序是編譯不過去的,因爲宏定義在同名函數定義之前,預編譯到print函數時,其名稱也被當做宏進行處理,預編譯完畢後,編譯器編譯是程序顯然是不對的。如果程序的文件名稱是test.c,則linux環境可以通過命令gcc -E test.c > test.i,可以看到預編譯結果,有心者可以自己分析下,仔細看看print函數的預編譯結果。
如果要定義一個與函數名同名的函數,我們須在函數定義之後再定義宏,似乎不太優雅,沒有別的方法麼?有的,多文件實現之。有多文件及其源碼如下:
/////////////////////////print.h
#ifndef __PRINT_H__
#define __PRINT_H__




void print(int value);




#endif




/////////////////////////print.cpp
#include "print.h"
#include <stdio.h>




void print(int value) {
printf("%d\n", value);
}




/////////////////////////print_inf.h
#ifndef __PRINT_INF_H__
#define __PRINT_INF_H__




#include "print.h"




//print macro
#define print(x)printf("hello"); \
print(x) //print function




#endif








/////////////////////////test.cpp
#include "print_inf.h"
#include <stdio.h>

int main() {
print(23);




return 0;
}
編譯程序命令是gcc test.c print.c -o test,運行程序test,輸出是hello23。
okay,問題又一次解決。此時,可能有一個疑問,宏與函數同名,有什麼用?還是僅僅爲了炫耀?
考慮如下場景,如果程序庫print版本更新,我覺得print.h中的print函數功能有限,需要擴充一下,實現一個print_ex函數,而此時我沒有定義一個print宏,調用這個print函數的地方改怎麼辦?
當然可以把調用舊版本print函數的代碼都更新爲print_ex函數,當然,你得費力費心。
但是,如果舊版本庫做的比較好,而且考慮周全,已經定義了一個與print函數同名的print宏呢?我是不是僅僅把print宏中的print函數更改爲print_ex就可以了?是不是很方便?而且,不管新版本的函數名稱如何更改,因爲一個宏的存在,調用print庫用戶不必關心新版本更新了那些內容,也無需更改代碼,僅僅重新編譯程序即可。新的示例代碼如下:
/////////////////////////print.h
#ifndef __PRINT_H__
#define __PRINT_H__




void print(int value);
void print_ex(int value);




#endif




/////////////////////////print.cpp
#include "print.h"
#include <stdio.h>




void print(int value) {
printf("%d\n", value);
}




void print_ex(int value) {
printf("%d\n", value + 10);
}




/////////////////////////print_inf.h
#ifndef __PRINT_INF_H__
#define __PRINT_INF_H__




#include "print.h"




//print macro
#define print(x)printf("hello"); \
print_ex(x) //print function




#endif




/////////////////////////test.cpp
#include <stdio.h>
#include "print_inf.h"




int main() {
    print(23);




    return 0;
}
上面編譯程序命令同樣是gcc test.c print.c -o test,運行程序test,輸出是hello33。



















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