Like Share Discussion Bookmark Smile

J.J. Huang   2019-11-19   C C 語言技術 <201910>   瀏覽次數:次   DMCA.com Protection Status

C語言 - 第二十六章 | 函式入門 - 行內函式

行內函式

內聯函式是一種編譯最佳化的方式。
對於一些內容較為簡短又常使用的函式,編譯器在程式設計師的建議(使用關鍵字inline)下,可以將指定的函式插入並取代每一處呼叫該函式的地方,從而減少呼叫函式耗費的時間。

參考例子C語言 - 第二十四章 | 函式入門 - 函式簡介

1
2
3
4
5
6
7
8
9
// power() 函式
int power(int n, int p) {
int r = 1;
for(int i = 0; i < p; i++) {
r *= n;
}

return r;
}

在呼叫函式時會需要分配記憶空間因而需要額外的資源負擔,像power()這樣的小函式,可以「建議」編譯器將之設定為行內函式(Inline function),如果建議被採納,則該函式會自動在呼叫點展現為程式碼,行內函式建議可以直接定義於標頭檔案中。

1
2
3
// math.h
int power_two(int);
int power(int, int);

配合標頭檔案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// math.c
#include "math.h"

int power_two(int num) {
return power(num, 2); // 可能被編譯器展開編譯
}

inline int power(int n, int p) {
int r = 1;
for(int i = 0; i < p; i++) {
r *= n;
}

return r;
}

使用gcc,在math.c中,power()可能在註解的地方被展開編譯,不過,在math.c以外的其他程式中若撰寫了power(),只會被當成一般函式呼叫,並不會有inline的效果。

主函式不變

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include "math.h"

int main() {
int num = 0;
int pow = 0;

printf("輸入數值:");
scanf("%d", &num);

printf("輸入平方:");
scanf("%d", &pow);

printf("%d 平方:%d\n", num, power_two(num));
printf("%d 的 %d 次方 %d\n", num, pow, power(num, pow));

return 0;
}

inline只能建議編譯器,也就是說建議並不一定會被採納,這視編譯器而定,像是使用到gotostatic變數、迴圈、switch等,編譯器可能不接受inline的建議,遞迴函式也無法在呼叫點展開,一個數千行的函式也不適合在呼叫點展開,如果編譯器拒絕將函式展開,它會將該函式視為一般函式進行編譯,inline的建議會被忽略。

C99inline規則,與GNUinline規則有所不同,詳情可參考(Inline Functions In C)[http://www.greenend.org.uk/rjk/tech/inline.html]。


註:以上參考了
引數傳遞、傳回值
C的內聯函式(inline function)
我有所不知的 static inline function