這章主要介紹了函數的相關信息,但沒有涉及到函數指針高級操作,這章很簡單,以下簡要說下
函數定義
類型名
函數名 (形式參數)
代碼塊
int
func(int a, int b)
{
return a+b;
}
函數聲明
以下爲函數原型的格式
類型名 函數名 (形式參數);
int *func(char *str, int value);
注意,沒有聲明函數原型的函數,會被編譯器缺省認定(默認)返回整型,這對於返回其他類型的函數是很危險的。因此,函數必須要聲明原型。
函數的參數
也叫形(式)參(數),分別爲值傳遞,和指針傳遞。
值傳遞,相當於拷貝實參的值,即使函數改變了拷貝的值,和原來的實參沒影響。
指針傳遞,如指針、數組,改變了形參,同時也改變了實參,因爲指向的內存地址相關聯
#include <stdio.h>
void s1(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
void s2(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
int main(void)
{
int a = 1, b = 2;
s1(a, b); // 值傳遞,沒有交換 a 和 b 的值
printf("a=%d, b=%d\n", a, b);
s2(&a, &b);// 指針傳遞,交換 a 和 b 的值
printf("a=%d, b=%d\n", a, b);
return 0;
}
ADT 和黑盒
抽象數據類型 ADT(Abstract Data Type),可以限制函數和數據定義的作用域,這個技巧也被稱爲黑盒(black box)。其實,用面向對象 OOP
思想這就叫封裝,對外提供接口,用戶不關心裏面的實現。
遞歸
看看下面的代碼,結合書中的圖例,很好理解的
#include <stdio.h>
void binary_to_ascii(unsigned int value)
{
unsigned int quotient;
quotient = value / 10;
if (quotient != 0) {
binary_to_ascii(quotient);
}
putchar(value % 10 + '0');
}
int main(void)
{
int value = 12345;
binary_to_ascii(value);
return 0;
}
之後又介紹了迭代,主要是針對遞歸過程中產生的性能問題進行優化,這個主要看算法實現了,這裏就不展開了。
可變參數列表
正常使用參數時,參數是固定的,如果要可變,需要引入 stdarg
頭文件,並且使用va_list
類型和三個宏 va_start
, va_arg
, va_end
,結合實例看的更清楚些
#include <stdio.h>
#include <stdarg.h>
float average(int n_values, ...)
{
va_list var_arg;
int count;
float sum = 0;
va_start(var_arg, n_values);
for (count=0; count<n_values; count++) {
sum += va_arg(var_arg, int);
}
va_end(var_arg);
return sum / n_values;
}
int main(void)
{
printf("%f\n", average(1, 2, 3, 4, 5)); // 這裏的值可以動態變化
return 0;
}