程式設計師考試補課筆記-第七天 (轉)

worldblog發表於2007-12-13
程式設計師考試補課筆記-第七天 (轉)[@more@]
  今天終於都講到C語言比較後的範圍了,""說是C語言的一切真的沒錯(可能有吧,我不知道)。很多書上都說著函式是C語言根本,就是說函式是構成C語言的。看以下這個:
main()
{
  printf("Hello World");
}
  main()就是C語言裡最特殊的一個函式,是構成整個程式的關鍵。在C裡首先就是要找出這個主函式才開始編譯,好了,說了一些書上原來的東西。現在我們就來看看C語言裡的函式究竟是怎麼的,如果我們從基礎的說起也沒有什麼意思。那麼我們就從函式的另一個特點說起,"遞迴函式"相信很多人都知道這個吧,看過老潭的教程應該都知道他經典的第一個遞迴程式吧:
int abc(int n)
{
  int s;
  if(n >1) s= n*abc(n-1);
  else s=1;
  return (s);
}
  從這個源程式很容易就看出有一個同自己名字的函式在裡面,所以以後我們看到一個函式里面自己就是遞迴函式了。而且我們看一個遞迴函式就主要就是看它是否一個返回的條件,就好像一條又黑又深的山洞,我們前去探險如果往到底就一定要回頭,就算是更深的也要返回啊!所以我們判定一個遞迴函式是否成立也常常是看它的返回條件。至於上面的那個源程式我也不想多說了,應該大家也看得明白。
這裡就看看另一個利用遞迴函式做的題目吧,就是諾漢塔(老潭的書上也是有的)。
#include

void move(char x,char y)
{
  printf("%c--&gt%cn",x,y);
}

void hanoi (int n,char one ,char two,char three)
{
  if(n==1) move (one ,three);
  else
  {
    hanoi (n-1,one,three,two);
    move(one,three);
    hanoi(n-1,two,one,three);
  }
}

main()
{
  int m;
  printf("input the number of diskes:");
  scanf("%d",&m);
  printf("the step to moving %3d diskes:n",m);
  hanoi(m,'A','B','C');
}
/*執行情況如下:
input the number of diskes:3 回車
the step to moving 3 diskes:
A--&gtC
A--&gtB
C--&gtB
A--&gtC
B--&gtA
B--&gtC
A--&gtC

書上說hanoi(n-1,one,three,two);是把"one"上的n-1個往"two"上移,接著move(one,three);然後是hanoi(n-1,two,one,three)即把"two"上的n-1個往"three"上移;
|h(2,1,3,2)|h(1,1,2,3)=>move(1,3) |      | move(1,2) |      |h(1,3,1,2)=>move(3,2) |move(1,3) |
h(3,1,2,3) | |h(1,2,3,1)=>move(2,1) |       h(2,2,1,3)|move(2,3) |       |h(1,1,2,3)=>move(1,3) |
*/
  注意以上是網上一個網友寫的,並不是我寫的。諾漢塔最不同的就是它多次呼叫自己,所以看起來也比較複雜一點。當時我在看這條程式的時候也是看了老半天也看不懂,最好我在網上看到一位朋友說他自己是真的拿了一些碟子自己試著移來看看,後來我也自己試著看,效果真的挺好(我當然沒有笨那這麼大的碟子啦,用我的光碟寫上大、中、小),大家不訪也試試看。加上看了上面這個圖我也比較清晰了,我要感謝那位網友才行,你們說是嗎?這個程式一定要自己慢慢去理解它,祝大家早日理解它吧。遞迴函式部份我因為不太懂也不能說些什麼了,現在來看看函式的另一個內容吧,就是函式的引數呼叫。我這裡先給出一個程式先吧:
int abc(int a,int b)
{
  a=a=b; return( a+b );
}

main()
{
  int xy[]={3,5};
  int s;
  s=abc(xy[0],xy[1]);
}
  這裡的將xy[0]和xy[1]分別傳入形參裡,這裡要說的一點就是和其它高階語言不同的,C語言的函式呼叫都是單向傳遞的。限實參傳了給形參之後並不會返回到傳進來的實參的,所以我們務必記住這點。又如下面一題:
int abc(int a[])
{
  int i,j; 
  /* 排序 */
}
main()
{
  int x[5]={3,5,1,2,4}
  abc(x);
/* 輸出 */
}
  這條源程式可為什麼會改變實參的數值呢?老潭的書裡說的很明白,說是因為這是地址傳遞,但是我們老師不太認同這點,他說這個也應該是值傳遞,只不過這個值是比較特殊的一個值,是地址,所以傳到形參時可以透過呼叫這個地址指向的元素而已。如果按老潭的這樣說以下這條程式都叫地址傳遞啦?
int abc(int *p)
{
  *p=10;
}

main()
{
  int a=20,*w;
  w=&a;
  abc(w); /*abc(&a)*/
  printf("%d",a);
}
  指標P也只是一個值而已,這個值是地址。如果說這是地址傳遞,那不是應該w的地址傳給形參嗎?剩下來的大家自己想想吧。(這裡也不能夠說誰對誰錯)
  接下來說說變數的類別,其實這個知識點也挺容易理解的,不過可能給C語言太多的這樣的關係弄的糊塗了。C語言裡有變數的型別,變數的儲存類別,變數的全域性性還是區域性性,是靜態的還是動態的呢。一切都是C語言變數的東西,我們這回也該好好的結束了它。(我們大家一齊看書吧)
  很對不起大家,因為今天我的眼有點問題(可能看看太久了)。所以不要再繼續和大家進一步講講儲存類別,這裡有一條源程式大家看看吧,我不行了,我要好好休息一下才行了。
int abc(int a)
{
int i,j;
scanf("%d%d",&i,&j);
if(i>j)
{
int k=1,i=2,j=3;
pirntf("%dn",i*3);
printf("%dn",j*10);
}
printf("%d",k);
}


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-992828/,如需轉載,請註明出處,否則將追究法律責任。

相關文章