2013年3月15日 星期五

[C語言]計算三角形面積

還記得前幾天的程式語言課,除了那討人厭的Debug以外,還有一項令人很頭痛的題目是計算三角形面積的題目嗎?



因為前幾天有人跟我要了原始碼想研究看看,於是就打算寫篇自己解題方法讓大家"參考"。

原始題目是:
輸入三角形三邊長a, b,c,利用海龍公式求三角形面積 area,並輸出至小數點3 位數
海龍公式
s = ( a + b + c) / 2;
area = sqrt ( s * (s‐a) * (s‐b) * (s‐c) );

首先看到題目後,先考慮整個程式中可能要用到多少變數,而當中又是使用哪些類型的變數。

觀察後可以發現可能用到的變數有:三邊長(假設叫做a、b、c)、面積(假設叫做area)、三邊長合的一半(假設叫做s)

接著決定變數型態,邊長的部分可以是整數,也可以是帶有小數的數值,考慮到較廣的應用範圍這點,採用float(浮點數)吧!至於s和area,看看那精美的開根號和除2,這兩個可以直接毫不考慮用float(浮點數)!

於是我們的變數宣告可以寫成:
float a,b,c,s,area;
當然你也可以為他們決定初始值,而寫成
float a=0,b=0,c=0,s=0,area=0;

接著再考慮另一件事情,我要用到那些函數? 這攸關要寫下那些標頭檔,程式碼本身當然是越精簡越好,沒有用到的標頭檔當然就不要多寫。
要用到什麼函數,和程式的功能有關。今天要寫的是三角形面積計算,所以必然要有輸入的功能,那麼就會用到"scanf"這個函數;計算時要用到開根號功能,則要使用"sqrt"這個函數;而我們要顯示訊息告知使用者該輸入什麼以及檢視結果,就要用到"printf"囉!最後讓畫面暫停不至於消失掉,則就要用到system這個函數囉

或許剛開始學寫程式沒辦法直接反應該用那些函數,不過透過常常練習事先預想程式當中可能用到的功能,久而久之就能很快在腦中架構出程式基本模型。

整理一下會用到的函數
1.printf =>輸出
2.scanf =>輸入
3.sqrt =>開根號
4.system =>暫停

其中printf和scanf包含在stdio.h這個標頭檔當中;而system包含於stdlib.h;sqrt包含在math.h。於是我們的標頭檔可以這樣寫:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

有人會問,這些標頭檔要背嗎?我個人認為是不用背每個標頭檔裡面含的所有函數,但至少知道需要system時找stdlib.h;printf&scanf找stdio.h;要數學有關的找math.h。

好的以上都是前置作業,準備就緒之後,其實你的程式已經完成一大半了,剛剛把所有需要的材料都找齊了,現在只需要組裝他們。

首先要求使用者輸入邊長的資訊,基於便於使用者的想法,我傾向逐步引導使用者輸入每個資料。這邊要使用printf提示使用者;scanf讓使用者輸入。

這邊複習一下prinf的用法:
輸出字串時:printf ("你想顯示的內容");
輸出變數時:printf ("格式",變數1,變數2,.......);
混合輸出時:printf ("你想顯示的內容+格式+.....",變數1,變數2,....);
我們來看一下實際例子:
#include <stdio.h>
#include <stdlib.h>

void main(void)
{
	int interge=111;
	float floating=1.234567;
	printf("這一行是純粹輸出字串\n");
	printf("下一行是輸出整數的變數\n");
	printf("%d\n",interge);
	printf("下一行輸出浮點數的變數,並顯示全部小數\n");
	printf("%f \n",floating);
	printf("下一行是顯示浮點數的變數,並顯示3位小數\n");
	printf("%1.3f \n",floating);
	printf("這一行是變數和字串混合顯示,小數顯示5位,整數:%d,小數:%1.5f\n",interge,floating);
	system("pause");
}
輸出結果

對照的輸出結果與程式碼,可以發現我們利用%f、%d控制變數顯示的位置,如果在當中加入數字,則影響數字顯示的位數。例如%1.5f,當中的5就是控制小數部分只顯示5位。更詳細的部分可以參考課本p89~p92。

接著複習一下scanf的用法為scanf("格式",變數);

scanf("變數1資料型態+變數2資料型態+.....",&變數1,&變數2,.....);
例如:
#include <stdio.h>
#include <stdlib.h>

void main(void)
{
	int interge=111;
	float floating=1.234567;
	printf("請分別輸入整數及浮點數,格視為「整數:浮點數」");
	scanf("%d:%f",&interge,&floating);
	printf("第一個變數(整數)為%d,第二個變數(浮點數)為%f\n",interge,floating);
	system("pause");
}

輸出結果
這個例子可以發現我們可以在scanf當中,是當的控制格式部分我們可以讓使用者一次輸入多個變數。例子當中,我們以「:」去分隔%d及%f的同時,表示使用者以這個方式去輸入時會分別被讀取到%d及%f所代表的變數(interge及floating)。

話雖如此我並不建議在這次的題目中使用這種方法來讓使用者輸入變數,畢竟要引導使用者,所以我選擇一次只讓使用者輸入一個。以下是我的寫法:
printf("請輸入三角形邊長 a = ");
scanf("%f",&a);
printf("請輸入三角形邊長 b = ");
scanf("%f",&b);
printf("請輸入三角形邊長 c = ");
scanf("%f",&c);
輸出結果

到這邊是引導使用者輸入的部分,接著是計算部分。根據海龍公式的定義:
s = (a + b + c) / 2
面積 = [s(s-a)(s-b)(s-c)]^(1/2)
s的部分直接依照數學定義去輸入即可,而面積用到開平方根,而平方根的函數為sqrt,依此計算的部分我們可以寫成
s = (a+b+c)/2;
area = sqrt(s*(s-a)*(s-b)*(s-c));
最後利用printf將計算結果輸出
printf("三角形面積為 = %1.3f\n",area);

所以完整的程式碼是:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

float a,b,c,s,area;

void main(void) 
{
	printf("請輸入三角形邊長 a = ");
	scanf("%f",&a);
	printf("\n請輸入三角形邊長 b = ");
	scanf("%f",&b);
	printf("\n請輸入三角形邊長 c = ");
	scanf("%f",&c);
	s = (a+b+c)/2;
	area = sqrt(s*(s-a)*(s-b)*(s-c)); 
	printf("\n三角形面積為 = %1.3f\n",area);
	system("pause");
}

沒有留言:

張貼留言