遞迴和尾遞迴

2021-07-25 11:09:04 字數 2120 閱讀 1683

c語言中編譯預處理的三種形式的命令:巨集定義,檔案包含,條件編譯命令。

1、巨集定義主要是:#define,#undef

如下:#define pi 3.1415926                    /*不帶引數的巨集定義*/

#define max(a,b)  a>b?a:b                    /*帶引數的巨集定義*/

說明:巨集定義在c語言與c++語言中是相通的。

下面舉例說明定義巨集failed用於檢測資料的正確性。

①#define的應用:

#define failed(status) ((status)<0)

#include "stdio.h"

void main()

while(failed(d));

} 其中while(failed(d))在編譯之前被無條件替換為while(d<0)。 

巨集定義和呼叫在形式與函式比較相似,但是原理是不同。

②#undef的應用:

#include "stdio.h"

void test();

int main(int argc, char* argv)

printf("%s/n",const_name2);

return 0;

}void test()

在程式的編譯的時候,系統提示如下資訊

error c2065: 'const_name1' : undeclared identifier

出現上述編譯錯誤的原因是,在第二次應用符號常量const_name1時,此符號常量已經被取消定義。

#pragma pack(pop)//恢復對齊狀態為測試該功能,可以使用sizeof()測試結構體的長度!

③#line

此命令主要是為強制編譯器按指定的行號,開始對源程式的**重新編號,在除錯的時候,可以按此規定輸出錯誤**的準確位置。

形式1語法格式如下:

# line constant 「filename」:其作用是使得其後的源**從指定的行號constant重新開始編號,並將當前檔案的名命名為filename。例如下面的程式如下:

#include "stdio.h"

void test();

#line 10 "hello.c"

int main(int argc, char* argv)

printf("%s/n",const_name2);

return 0;

}void test()

提示如下的編譯資訊:hello.c(15) : error c2065: 'const_name1' : undeclared identifier

表示當前檔案的名稱被認為是hello.c, #line 10 "hello.c"所在的行被認為是第10行,因此提示第15行出錯。

形式2語法格式如下:

# line constant:其作用在於編譯的時候,準確輸出出錯**所在的位置(行號),而在源程式中並不出現行號,從而方便程式設計師準確定位。

④運算子#和##

在ansi c中為預編譯指令定義了兩個運算子——#和##。

# 的作用是實現文字替換,例如

#define hi(x) printf("hi,"#x"/n");

void main()

程式的執行結果:hi,john

在預編譯處理的時候, "#x"的作用是將x替換為所代表的字串行。在本程式中x為john,所以構建新串「hi,john」。

##的作用是串連線。例如

#define connect(x,y) x##y

void main()

程式的執行結果為:a1=0 a2=12 a3=4

在編譯之前, connect(a,1)被翻譯為a1, connect(a,2)被翻譯為a2。

⑤預定義常量

__line__:當前源**的行號,為整型常量

__file__:當前編譯程式檔案的名稱,為字串

__date__:編譯程式檔案日期,為字串(」mm dd yyyy"形式,如」 jan 19 1993」)

__time__:編譯程式檔案時間,為字串("hh:mm:ss"形式,如」08:30:23」)

__stdc__:ansi c標誌,整型常量1,說明此程式相容ansi c標準

尾遞迴和線性遞迴

線性遞迴 fac 0 1 fac n n fac n 1 尾遞迴 fac 0,sum sum fac n,sum fac n 1,sum n 尾遞迴定義 函式最後一步呼叫自身,即最後一行 一定是對於自己的乙個遞迴呼叫。erlang尾遞迴這樣帶來的好處是可以讓編譯器做到將遞迴優化,轉化為跳轉指令而不是...

遞迴 尾遞迴

階乘函式 n n n 1 n 2 3 2 1 針對這樣的表述,直譯成乙個過程 define factorial n if n 1 1 n factorial n 1 如果是factorial 6 其計算行為是 factorial 6 6 factorial 5 6 5 factorial 4 6 5...

遞迴 尾遞迴

計算n的階乘 function add n return n function add n 1 斐波那契數列 1 1 2 3 5 8 13.function arr n else 如上例項,但是遞迴有乙個很大的問題,就是在不斷地呼叫自身函式時,每一次呼叫都會存新的資料變數等,如果有成百上千次呼叫,則...