The document discusses functions in C language. It explains that functions can be divided into built-in functions and user-defined functions. Built-in functions are provided by the compiler as a "black box" that can be called, while user-defined functions are created by the user according to needs. User-defined functions have benefits like reusability, modularity and readability. It also talks about function prototypes, definitions, parameters, arguments, scope, and call by value and call by address.
5. Make
each
day
count
要使⽤內建函式,必須在程式開頭處使⽤ #include 前置指令含入內建函
式的標頭檔
#include <stdio.h>
#include <math.h>
#define PI 3.14159
void std_func(){
double r;
int x;
printf("n x:角度值 t r:弳度值 t sin tt csc");
printf("n========================================================");
for(x = 30; x <= 150; x += 30){
r = PI * (x / 180.0);
printf("n %3d tt %.5f t %.5f t %.5f", x, r, sin(r), 1 / sin(r));
}
}
內建函式 2/2
5
11. Make
each
day
count
函式定義 (function definition) 就是函式的程式區塊,語法如下:
例如:
_Bool isPrime(int n) {
for (i = 2; i <= sqrt(n); i++) {
if (n % i == 0) break;
}
return (i > sqrt(n));
}
自訂函式 2/3
11
函式傳回值之資料型別,
若函式沒有傳回值則將ret_type指定為 void
自訂函式名稱
傳給函式的引數,其格式如同變數宣告;
如果沒有引數,則函式名稱後接空括號
指令敘述,
就是函式的實作 (implements)
有傳回值時,必須使用 return 敘述回傳資料
12. Make
each
day
count
呼叫函式
完成函式定義後,就可以將該函式當成⼀個新的指令敘述使⽤
_Bool isPrime(int); //函式原型宣告
int main(int argc, char* argv[]){
int num;
printf("輸入整數值:");
scanf("%d", &num);
if (isPrime(num))
printf("%d是質數", num);
else
printf("%d不是質數", num);
}
_Bool isPrime(int n){
for (i = 2; i <= sqrt(n); i++){
if (n % i == 0) break;
}
return (i > sqrt(n));
}
自訂函式 3/3
12
呼叫函式
返回主程式
13. Make
each
day
count
傳值呼叫 (call by value )
主程式把資料值複製⼀份給函式之引數保存 (另⼀個記憶體位置的值),因
此函式中不管如何存取引數資料,都不會影響到主程式的資料值
函式引數的傳遞方式 1/6
13
10
20
10
20
&num1
&a
&num2
&b
call_by_value(num1, num2);
主程式變數 函式引數
void call_by_value(int a,int b){
...
}
14. Make
each
day
count
void swap_by_value(int a, int b){
int temp;
printf("a = %d, b = %dn", a, b);
temp = a;
a = b;
b = temp;
printf("a = %d, b = %dn", a, b);
}
void main(){
int num1 = 10, num2 = 20;
printf("num1 = %d, num2 = %dn", num1, num2);
swap_by_value(num1, num2);
printf("num1 = %d, num2 = %dn", num1, num2);
}
函式引數的傳遞方式 2/6
14
15. Make
each
day
count
傳址呼叫 (call by address)
主程式把儲存資料的記憶體位置傳到函式之引數,因此引數與主程式是共
⽤同⼀個記憶體位置之資料,
void call_by_address(int* a, int* b){
...
}
函式引數的傳遞方式 3/6
15
10
20
&num1
&num2
&num1
&a
&num2
&b
call_by_address(&num1, &num2);
主程式變數 函式引數
*a
*b
&取址運算子:&num表示變數num的記憶體位址
*指標運算子:*a表示到變數a所指示的記憶體位址讀取資料
1
2
1
2
19. Make
each
day
count
int bubble_sort(int data[], int n){
int i, j, flag, temp;
for (i = 0; i < n - 1; i++){ //n個數字排序,只⽤n-1回合
flag = 0; //每回合清除交換旗號
for (j = 0; j < n – i - 1; j++) {
if (data[j] > data[j + 1]) {
temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
flag = 1; //表示發生過交換
}
}
if (flag == 0) break; //此回合沒有發生交換,表示資料己排序
}
}
Lab 設計泡泡排序函式 1/2
19
20. Make
each
day
count
測試泡泡排序
void main(){
int n, i;
int *data;
printf("Number of data: ");
scanf("%d", &n);
data = (int *)malloc(n * sizeof(int));
printf("Numbers to be sorted: ");
for(i = 0; i < n; i++)
scanf("%d", &data[i]);
printf("n");
bubble_sort(data, n);
printf("Numbers Sorted: ");
for(i = 0; i < n; i++)
printf("%d ", data[i]);
free(data);
}
Lab 設計泡泡排序函式 2/2
20
21. Make
each
day
count
#include <stdio.h>
void find_bound(int n, int data[], int *min, int *max){
//設計函式,從data[]找出最大值及最小值
}
void main(){
int i, n, max, min, *data;
printf("輸入資料個數:");
scanf("%d", &n);
data = (int *)malloc(n * sizeof(int));
printf("輸入%d筆整數值(數值間以空白鍵區隔):", n);
for (i = 0; i < n; i++) scanf("%d", &data[i]);
find_bound(...); //呼叫find_bound()函式,...必須改為參數群
printf("最大值為%d%,最小值為%d", max, min);
free(data);
}
實作練習 設計尋找極值函式 1/2
21
22. Make
each
day
count
遞迴函式, 簡單地說就是⼀個呼叫自己的函式
計算 1 加到 N
疊代 (iterative) 方式
int sum(int n){
int i, sum = 0;
for (i = 1; i <= n; i++)
sum = sum + i;
return sum;
}
遞迴函式 (Recursive) 1/6
23
30. Make
each
day
count
資料交換函式
void swap(int *a, int *b){
int temp;
temp = *a;
*a = *b;
*b = temp;
}
快速排序函式
void quick_sort(int data[], int left, int right){
int pivot, leftmark, rightmark;
if (left >= right) return;
pivot = data[left];
leftmark = left + 1;
rightmark = right;
Lab 快速排序 (Quick Sort) 3/5
31
left right
pivot
leftmark rightmark
31. Make
each
day
count
while (1){
while (leftmark <= right){
if (data[leftmark] > pivot) break;
leftmark++;
}
while (rightmark > left){
if (data[rightmark] < pivot) break;
rightmark--;
}
if (leftmark > rightmark) break;
swap(&data[leftmark], &data[rightmark]);
}
swap(&data[left], &data[rightmark]);
quick_sort(data, left, rightmark - 1);
quick_sort(data, rightmark + 1, right);
}
Lab 快速排序 (Quick Sort) 4/5
32
left right
pivot
leftmark rightmark
leftmark
rightmark
32. Make
each
day
count
測試快速排序
void main(){
int n, i;
int *data;
printf("Number of data: ");
scanf("%d", &n);
data = (int *)malloc(n*sizeof(int));
printf("Numbers to be sorted: ");
for(i = 0; i < n; i++){
scanf("%d", &data[i]);
}
printf("n");
quick_sort(data, 0, n);
printf("Numbers Sorted: ");
for(i = 0; i < n; i++){
printf("%d ", data[i]);
}
}
Lab 快速排序 (Quick Sort) 5/5
33
33. Make
each
day
count
有三根杆⼦A,B,C。A杆上有 N 個 (N>1) 穿孔圓盤,盤的尺寸由下
到上依次變小。要求按下列規則將所有圓盤移至 C 杆:
每次只能移動⼀個圓盤
大盤不能疊在小盤上面
提示:可將圓盤臨時置於 B 杆,也可將從 A 杆移出的圓盤重新移回 A 杆,
但都必須遵循上述兩條規則
Lab 解河內塔 1/4
34
36. Make
each
day
count
void hanoi(int n, char A, char B, char C){
if (n == 1) {
printf(“%3d: 將圓盤 %d 從 %c 移到 %cn", ++time, n, A, C);
}
else {
hanoi(n - 1, A, C, B);
printf(“%3d: 將圓盤 %d 從 %c 移到 %cn", ++time, n, A, C);
hanoi(n - 1, B, A, C);
}
}
Lab 解河內塔 4/4
37
37. Make
each
day
count
變數的有效範圍 (scope) 是指哪些程式碼可以存取此變數的值
變數的生命期 (life cycle)是變數的值會保留多久
C 程式如果擁有多個函式,變數在那裡宣告,決定變數的有效範圍及
生命期。C 語言的變數依照有效範圍可以分為兩種:
區域變數 (local variables)
在程式區塊中宣告的變數是⼀種區域變數,例如:在函式中宣告的變數或
參數,區域變數只能在宣告的函式中使⽤,在函式之外的程式碼並不能存
取此變數。
全域變數 (global variables)
在 C 程式檔的函式之外宣告的變數是⼀種全域變數,例如:在函式外宣告
變數,整個程式檔案都可以存取此變數,如果全域變數沒有指定初值,預
設值是 0
變數的有效範圍與生命期 1/8
38
38. Make
each
day
count
#include <stdio.h>
int x=10; //global x
int main(int argc, char** argv) {
int y = 20; //y local to block 1
...
for () {
int z = 30; //z local to block 2
...
}
}
void func(){
int x = 40; //x local to block 3
...
}
變數的有效範圍與生命期 2/8
39
1
2
3
41. Make
each
day
count
#include <stdio.h>
void myfunc() {
int x = 10; //區域變數
static int y = 10; //靜態區域變數
x++;
y++;
printf("x = %d, ty = %dn", x, y);
}
void main(int argc, char** argv) {
for (int i = 0; i < 5; i++)
myfunc();
}
變數的有效範圍與生命期 5/8
42