2009年12月28日 星期一

奇妙的費氏數列和C++的解法

小傢伙要我看看費氏數列的C++程式怎麼寫…
我想她只是丟個事給我這無聊老頭作作,免得我老人吃呆了,她要提早退休照顧我…哈哈
(就跟丟一根骨頭給一隻老狗玩玩,隨意打發一下…)
為什麼我這麼說呢,因為很多C的書都有這類範例,只要肯上圖書館,甚至肯在Google 上用對了關鍵字去「咕狗」一下,一定可以找到不同解法…
所以,她問我這題一定只是隨便應付我一下而已…我想…
另外一個可能是,她創造力太豐富,不想看別人的解法,想自己兜兜看…

好了,先「咕狗」一下「費氏數列」,在有水準(所以比較可靠)的維基百科上看到定義,以及說明,雖是只是大略的瞄了一下,不禁肅然起敬,真是簡潔完美…各位可以參考如下 維基百科中文-費氏數列 英文的更棒,還有螺旋圖呢
  • F0 = 0
  • F1 = 1
  • Fn = Fn - 1 + Fn - 2

由上三式簡單關係,可知若要以迴圈來解,應該是先把第零、第一項先寫好,再用第三式來寫迴圈。因為,每次迴圈都需要前兩項,所以,第一個迴圈必須由F2開始。迴圈無法處理n=0,或n=1的狀況,它們要由特例來處理。

下面是第一個嘗試,前面的#include省略不列,主要試的是咖啡色的判斷結構,看能不能正確的把第0,第1項和其餘的分開。

int main()

{

int n,f;

printf("Input n to find fab# :");

scanf("%d",&n);

if (n==0){ f=0; }

else if (n==1){ f=1; }

else {f=999;}

printf("Fibonacci #= %d \n",f);

system("PAUSE");

return EXIT_SUCCESS;

}



下面這程式就在「其餘的」部份,架起迴圈。(我把頭、尾省掉了)

int n, f, f_2, f_1, i;

/* f=費氏數 Fn ,

f_1=費氏數之前一項 Fn-1 ,

f_2=費氏數之前2 Fn-2 ,*/

printf("Input n to find fab# :");

scanf("%d",&n);

f_2=0; f_1=1;

if (n==0){ f=f_2; }

else if (n==1){ f=f_1; }

else {

for (i=2;i<=n;i++){

f=f_2+f_1;

f_2=f_1;

f_1=f;

}

}

printf("Fibonacci #= %d \n",f);



在課本中,有一累似的解法,它寫成函式,將來更好叫用。不過,n=0時,答案可能不一樣?

#include

#include

int f(int); //計算費氏數列

int main(void)

{

int n;

printf("Input n:");

scanf("%d",&n);

printf("f(%d) = %d\n",n,f(n));

system("pause"); //使程式暫停在執行畫面讓我們看到結果

}

int f(int n)

{

int i,sum,pre,fi;

pre = 0;

fi = 1;

for(i=1;i

sum = pre + fi; //加出下一項

pre = fi; //紀錄前一項

fi = sum; //i

}

return fi;

}

2009年12月26日 星期六

關於C++中的 Void

(1)
void放在函數前面,表示這個函數沒有傳回值。
如 void push(char dey)沒有特別指定返回值型態時,則是預設為int。
例如 push(char dey) 等效於 int push(char dey)。

When used as a function return type, the void keyword specifies that the function does not return a value.

(2)
void放在參數列,則表示這個函數沒有輸入的參數。
例如 char pop(void),它等效於 char pop()。

When used for a function's parameter list, void specifies that the function takes no parameters.

(3)
When used in the declaration of a pointer, void specifies that the pointer is "universal."
If a pointer's type is void *, the pointer can point to any variable that is not declared with the const or volatile keyword.
A void pointer cannot be dereferenced unless it is cast to another type.
A void pointer can be converted into any other type of data pointer.
A void pointer can point to a function, but not to a class member in C++.

關於system("PAUSE")和return EXIT_SUCCESS的意思

(1)

小傢伙問,寫 return EXIT_SUCCESS 和 寫 return 0 有沒有差別 ?

我上google 用 return EXIT_SUCCESS 查了一下(詳下面綠字),它和return 0 同義。因為在header檔中,有定義EXIT_SUCCESS =0,所以它是值為0的常數。

在文字(非視窗)中跑C最後要向系統說,我跑完了。這就是return EXIT_SUCCESS的用意,傳給系統一個值。

EXIT_SUCCESS 肯定是被宏定义了. 可以找一下头文件中的定义. 应该是有下面的语句的: #define EXIT_SUCCESS 0

(2)

在google 打入 system("PAUSE");得到如下面綠字的解答。它是向作業系統發一個指令PAUSE,意思是等使用者敲一個鍵才會繼續。一般程式執行到完就直接結束文字視窗,所以操作者會來不及觀察文字視窗的資料,為了有個停頓,等操作者「看夠了」,才按一個鍵來結束視窗,就要用PAUSE這個命令。PAUSE不是C的指令,是作業系統的命令,所以要靠C語言提供的system()這個函式來叫用它。

system就是從程序中調用系统命令(和shell命令)。 system("pause")就是從程序中調用“pause”命令; 而“pause”这个系统命令的功能很简单,就是在命令行上输出一行类似于“Press any key to exit”的字,等待用户按一个键,然后返回。

(3)結論:  >> 有什麼問題時,學著有系統的去找答案。還有,要投時間和心進去。

用C語言寫一個n*n乘法表。

小傢伙不會用C寫 N*N的乘法表程式。而我呢,一輩子從沒真正寫過一個C程式。但是下學期我要教C;之前K過一些,最近也看了一點。於是下午把Dev C++裝起來,開始試這個程式。
對寫過其它程式的我來說,雙迴圈不是很難的,但是C的語法不熟,所以根據經驗,要一點一點試。

以下把試的過程大致的展示出來,想告訴學程式的朋友,如何一次試一點,慢慢把它搞懂。
可以把下面的程式,一個個複製到程式裏,自己試試。

先讓程式的結果「可以看見」,所以先試printf。

第一個程式只是試輸出指令 printf及迴圈for,其實裏面有一個小錯,編譯看看就知道。剛學語言,規則多,不好記,很容易錯。所以,程式愈小愈好。其實這第一個程式就出了好幾次錯誤,才一步步改成下面的樣子。頭尾是抄書上第一個例子。中間咖啡色的才是我試的部份。

#include

#include

int main(void)

{

int MAX

for(i=1;i<=MAX;i++)

printf("Index i = d% \n",i);

system("PAUSE");

return EXIT_SUCCESS;

}




第二次我是試加入由鍵盤輸入數值的指令,也是犯了好幾次錯才修成這樣。

int main(void)

{

int MAX, i ;

printf("key in the matrix size 1<= MAX <=9 : \n");

scanf("%d",&MAX);

printf("MAX = %d i= %d \n\n",MAX,i);

for(i=1;i<=MAX;i++)

printf("Index i = %d \n",i);

system("PAUSE");

return EXIT_SUCCESS;

}



第三次只是為了把for迴圈本體改成大括弧以便裝內迴圈,也是曾犯了忘記加;的錯。

int main(void)

{

int MAX, i ;

printf("key in the matrix size 1<= MAX <=9 : \n");

scanf("%d",&MAX);

printf("MAX = %d i= %d \n\n",MAX,i);

for(i=1;i<=MAX;i++)

{

printf("Index i = %d \n",i);

}

system("PAUSE");

return EXIT_SUCCESS;

}




第四次加個內迴圈,再測…有錯,因忘了宣告 j

int main(void)

{

int MAX, i ;

printf("key in the matrix size 1<= MAX <=9 : \n");

scanf("%d",&MAX);

printf("MAX = %d i= %d \n\n",MAX,i);

for(i=1;i<=MAX;i++)

{

for(j=1;j<=MAX;j++)

{

printf("Index i = %d , j= %d \n",i,j);

}

}

system("PAUSE");

return EXIT_SUCCESS;

}




第五次加了宣告,OK, 第六次加印乘積,且每完成一內迴圈加印一行空白,讓結果好看些…

int main(void)

{

int MAX, i ,j;

printf("key in the matrix size 1<= MAX <=9 : \n");

scanf("%d",&MAX);

printf("MAX = %d i= %d \n\n",MAX,i);

for(i=1;i<=MAX;i++)

{

for(j=1;j<=MAX;j++)

{

printf("%d*%d=%d \n",i,j,i*j);

}

printf("\n");

}

system("PAUSE");

return EXIT_SUCCESS;

}



第七次,試著把乘積排整齊些,讓乘積的個位數對齊…

int main(void)

{

int MAX, i ,j;

printf("key in the matrix size 1<= MAX <=9 : \n");

scanf("%d",&MAX);

printf("MAX = %d i= %d \n\n",MAX,i);

for(i=1;i<=MAX;i++)

{

for(j=1;j<=MAX;j++)

{

printf("%2d*%2d=%3d \n",i,j,i*j);

}

printf("\n");

}

system("PAUSE");

return EXIT_SUCCESS;

}



第八次,也是調印出的排版,讓表格可以在螢幕寬度內印完,並且和上端的鍵入值隔開些…。
算是大功告成了。
都是一些小錯誤,慢慢一個一個累積經驗,把它掌握。
一次搞清楚一小點,持之以恒的,把它理清就是你的了。

int main(void)

{

int MAX, i ,j;

printf("key in the matrix size 1<= MAX <=9 : \n");

scanf("%d",&MAX);

printf("\n\n\n");

for(i=1;i<=MAX;i++)

{

for(j=1;j<=MAX;j++)

{

printf("%d*%d=%2d ",i,j,i*j);

}

printf("\n");

}

system("PAUSE");

return EXIT_SUCCESS;

}