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。