2017-02-26 80 views
2

我寫了這個代碼:爲什麼在代碼中使用宏會導致錯誤,我該如何解決?

#include <stdio.h> 

#define fctrl(N) ((N==1)? (N) : (N*fctrl(N-1))) 

int main() 
{ 
    int m,n=7; 
    m = fctrl(n); 
    printf("fctrl is %d\n",m); 
    return 0; 
} 

在編譯時,我得到了以下錯誤:

/tmp/ccRODXnZ.o: In function `main': 
/home//Desktop/fctrl/fctrl.c:8: undefined reference to `fctrl' 
collect2: error: ld returned 1 exit status 

爲什麼顯示這個錯誤,我該怎麼解決這個問題?

+3

Makros do not recuesively。 –

+0

非常感謝。 @Stephan Lechner – Tree

+0

謝謝@ Lazcano – Tree

回答

1

宏不由「實際」C編譯器處理。宏由c-preprocessor進行處理,它只是一種文本替換機制,因此類似於函數的表達式被定義爲一個宏,並且作爲一個函數工作,並不會導致正常的函數行爲。

預處理髮生後,你的程序將採取以下結構,

#include <stdio.h> 

int main() 
{ 
    int m,n=7; 
    m = ((n==1)? (n) : (n*fctrl(n-1))); 
    printf("fctrl is %d\n",m); 
    return 0; 
} 

你應該問自己的問題是在哪裏被定義FCTRL功能?答案很明顯,它沒有被定義爲,這就是你爲什麼得到undefined reference to 'fctrl'錯誤的主要原因。

在終端上使用cpp -nostdinc {filename}gcc -E -nostdinc {filename}命令,您將會知道發生了什麼。順便說一下,-nostdinc用於禁止包含系統頭文件。 cpp是調用C/C++預處理程序的程序,儘管事實上C/C++預處理程序可以用於更多目的而不僅僅是C/C++文本替換機制。 gcc -E選項與cpp命令給出相同的結果。在Unix的早期,預處理器和編譯器曾經是獨立的程序。它們捆綁在當今的操作系統中。

+0

非常感謝您的親切和詳細的解釋! @nomadov – Tree

2

您試圖定義一個模擬遞歸函數的宏,但宏不支持遞歸,因此錯誤。

我會用一個函數來代替,但是您總是在C preprocessor, recursive macros中閱讀更多內容。

+1

非常感謝! @gsamaras – Tree

相關問題