實 習 內 容 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
實 習 目 標 |
1. 運用標準函數庫 (standard library functions) 2. 練習運用函數實行由上而下的程序化程式設計 (top-down design) 3. 運用函數來模組化程式 4. 有輸入參數 (input parameters) 的函數 5. 有輸出參數 (output parameters) 的函數 6. 比較複雜的 scanf() 輸入格式 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1. |
運用標準函數庫裡的函數: math.h
stdlib.h
考慮以下餘弦定理: 請完成下面程式: 運用標準函數庫中的函數, 由 a, b, c 三個邊長計算 b, c 的夾角 d (單位是角度 ) #include <stdio.h> #include <________> int main(void) { double pi, a, b, c, d; pi = ______; // tan(pi/4) = 1 a = 1.82; b = 1.65; c = 1.45; d = ______________________; // 計算夾角 d (單位:角度) printf("The lengths of the three sides are %f, %f, and %f\n", a, b, c); printf("The angle between side b and side c is %f degrees\n", d); return 0; } |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2. |
由上而下 (top-down) 逐步分解的程式設計方法:
/* Program to Draw a Stick Figure */ #include <stdio.h> /* 函數原型 (Function prototypes) */ void draw_circle(void); /* Draws a circle */ void draw_intersect(void); /* Draws intersecting lines */ void draw_base(void); /* Draws a base line */ void draw_triangle(void); /* Draws a triangle */ int main(void) { /* Draw a circle. */ draw_circle(); /* Draw a triangle. */ draw_triangle(); /* Draw intersecting lines. */ draw_intersect(); return (0); } /* * Draws a circle */ void draw_circle(void) { printf(" * \n"); printf(" * * \n"); printf(" * * \n"); } /* * Draws intersecting lines */ void draw_intersect(void) { printf(" / \\ \n"); /* 在字串中兩個 '\' 代表單一的 '\' */ printf(" / \\ \n"); printf("/ \\\n"); } /* * Draws a base line */ void draw_base(void) { printf("-------\n"); } /* * Draws a triangle */ void draw_triangle(void) { draw_intersect(); draw_base(); }
這個步驟裡我們寫的函數是不傳遞任何資料進去的函數, 函數的參數都是 void, 使用這種函數不見得是因為函數要呼叫很多次, 可以省下重複的程式碼, 而是因為
你可以嘗試把上面這個程式改成在 main() 裡面完成所有的功能, 不使用任何函數, 如此可以感覺一下兩個程式之間的差異。 你也可以參考一下這個以前沒有運用函數寫出來的程式...閱讀這個程式, 同時去修改這個程式所要花費的力氣, 我自己保守估計和一個5000列的結構化、模組化的程式差不多... |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3. |
有輸入參數 (input parameters) 的函數: 沒有參數的函數, 每次呼叫所完成的事情一定一模一樣, 當然效果有限, 如果能夠有一些參數, 每一次呼叫這個函數時都針對不同的資料或是命令來處理的話, 這個函數的功能就大得多了 請接續步驟一裡計算角度的程式, 寫一個 calculate_angle() 函數針對不同邊長的三角形計算夾角 d, 這個函數需要傳入三個 double 型態的參數 a, b, c; 同時會傳回計算出來的角度, 你需要寫類似下面這樣的函數定義: double calculate_angle(double aParam, double bParam, double cParam) { double d; /* 函數裡需要用來存放資料的變數一定要在函數裡定義 */ double pi=________; /* 計算夾角 d */ d = acos(aParam*aParam - bParam*bParam - ... )/(-2*bParam*...))/pi * 180; return d; } 如此則 main() 函數裡面相關的敘述變成 a = 1.82; b = 1.65; c = 1.45; d = calculate_angle(a, b, c); // 計算夾角 d (單位:角度)請注意:
練習到這裡, 請回顧一下, 程式裡運用函數的好處有哪些呢? |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
4. |
再做一個運用函數模組化程式的例子, 同時也看到如何寫有輸出參數 (output parameters) 的函數: 下面這個程式計算並且印出如上圖中多個墊圈(washer)的總重量, 程式的輸入是每一個墊圈的 內徑, 外徑, 厚度, 材質的密度和墊圈的數量 01 /* 02 * Computes the weight of a batch of flat washers. 03 */ 04 05 #include <stdio.h> 06 07 #define PI 3.14159 08 09 int main(void) 10 { 11 double hole_diameter; /* input - diameter of hole */ 12 double edge_diameter; /* input - diameter of outer edge */ 13 double thickness; /* input - thickness of washer */ 14 double density; /* input - density of material used */ 15 double quantity; /* input - number of washers made */ 16 double weight; /* output - weight of washer batch */ 17 double hole_radius; /* radius of hole */ 18 double edge_radius; /* radius of outer edge */ 19 double rim_area; /* area of rim */ 20 double unit_weight; /* weight of 1 washer */ 21 22 /* Get the inner diameter, outer diameter, and thickness.*/ 23 printf("Inner diameter in centimeters> "); 24 scanf("%lf", &hole_diameter); 25 printf("Outer diameter in centimeters> "); 26 scanf("%lf", &edge_diameter); 27 printf("Thickness in centimeters> "); 28 scanf("%lf", &thickness); 29 30 /* Get the material density and quantity manufactured. */ 31 printf("Material density in grams per cubic centimeter> "); 32 scanf("%lf", &density); 33 printf("Quantity in batch>"); 34 scanf("%lf", &quantity); 35 36 /* Compute the rim area. */ 37 hole_radius = hole_diameter / 2.0; 38 edge_radius = edge_diameter / 2.0; 39 rim_area = PI * edge_radius * edge_radius - 40 PI * hole_radius * hole_radius; 41 42 /* Compute the weight of a flat washer. */ 43 unit_weight = rim_area * thickness * density; 44 45 /* Compute the weight of the batch of washers. */ 46 weight = unit_weight * quantity; 47 48 /* Display the weight of the batch of washers. */ 49 printf("\nThe expected weight of the batch is %.2f", weight); 50 printf(" grams.\n"); 51 52 return (0); 53 } Inner diameter in centimeters> 1.2 Outer diameter in centimeters> 2.4 Thickness in centimeters> 0.1 Material density in grams per cubic centimeter> 7.87 Quantity in batch> 1000 The expected weight of the batch is 2670.23 grams.
void inputData(double *, double *, double *); // 函數名稱以及參數型態的預先定義 我們以後在課堂裡還會再詳細解釋上面這個機制, 如果你有疑問也可以先嘗試尋求你比較可以接受的解釋
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
5. |
測試比較複雜的 scanf() 輸入格式: 請利用 scanf() 函數,由鍵盤讀取下列指定格式的資料到記憶體的變數裡面, 並且列印到螢幕上:
例如: #include <stdio.h> int main(void) { int num1, num2; double num3; scanf("%d%d%lf", &num1, &num2, &num3); printf("number1 = %d, number2 = %d, number3 = %f\n", num1, num2, num3); return 0; } |