日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

鸡窝里飞出伪凤凰

發(fā)布時(shí)間:2025/3/20 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 鸡窝里飞出伪凤凰 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

  不少初學(xué)者在寫代碼時(shí)喜歡一main()到底——把所有的代碼都寫在main()函數(shù)中。代碼在作繭自縛的main()函數(shù)“迷宮”中像沒頭蒼蠅一樣左沖右突,寫到哪兒算哪兒。忙活了半天之后,終于成功“突圍”——可以運(yùn)行程序了,然后就一臉輕松。但是卻把main()函數(shù)弄得凌亂不堪,一地雞毛,形同雞窩。
  這種代碼是一種“爬行”式思維的產(chǎn)物,是人類思維的一種返祖現(xiàn)象。人類在學(xué)會(huì)直立行走之前就是按照這種方式思考的。俗話說,站得高才能看得遠(yuǎn)。而匍匐在地上爬行,只能得到臟、亂、差的代碼。
  這種代碼有一種變形,就是在一地雞毛的main()中可能會(huì)冷不丁地突然竄出一個(gè)令人眼前一亮的自定義函數(shù)調(diào)用,猶如一地雞毛的雞窩里仿佛要飛出一只金鳳凰似的。這樣的代碼多半出自那種半生不熟的新手,他們并不是自覺自愿地而往往是被強(qiáng)迫地使用一下自定義函數(shù)。這就使得代碼產(chǎn)生了一種滑稽的喜感,猶如一只小狗被要求站立起來作揖一樣,站立一秒鐘之后,很快就會(huì)重新伏到地上繼續(xù)爬行。下面的代碼就是一例:

/*例8.8 將數(shù)組a中的n個(gè)整數(shù)按相反順序存放*/
#include <stdio.h>
int main( void )
{void inv(int x[],int n);
int i, a[10]={3,7,9,11,0,6,7,5,4,2};
printf("The original array:\n");
for(i=0;i<10;i++)
printf("%d ",a[i]);
printf("\n");
inv(a,10);
printf("The array has been vnverted:\n");
for(i=0;i<10;i++)
printf("%d ",a[i]);
printf("\n");
return 0;
}

void inv(int *x,int n)
{int *p,temp,*i,*j,m=(n-1)/2;
i=x;j=x+n-1;p=x+m;
for(;i<=p;i++,j--)
{temp=*i;*i=*j;*j=temp;}
return ;
}

      ————譚浩強(qiáng) ,《C程序設(shè)計(jì)》(第四版),清華大學(xué)出版社, 2010年6月,p241
  首先來看main():
  一進(jìn)門就可以看到main()函數(shù)的頭上頂著一條條幅——不是“北京歡迎您”,而是函數(shù)類型聲明“void inv(int x[],int n);”。這樣做的效果是使得main()顯得更加凌亂,并且有讓main()函數(shù)獨(dú)霸inv()函數(shù)使用權(quán)之嫌。因?yàn)槠渌a中的其他函數(shù)若需要調(diào)用inv()函數(shù)還得重新進(jìn)行函數(shù)類型聲明。這種不加思索地把函數(shù)類型說明隨便塞在某個(gè)地方的做法,絕不可能是出于事先周密思考權(quán)衡的結(jié)果,其原因估計(jì)多半只是為了對(duì)付編譯器的類型檢查而已。和下面的寫法對(duì)比一下,就不難發(fā)現(xiàn)函數(shù)類型聲明塞在函數(shù)內(nèi)部的荒謬性:

View Code #include <stdio.h>
void inv(int x[],int n);
int main( void )
{
/*……*/
}

  顯然,后者不但能完全實(shí)現(xiàn)樣本代碼的功能,而且main()更清爽,此外代碼的其他部分若需要調(diào)用inv()也不需要無謂地再次寫函數(shù)類型聲明了。
再繼續(xù)往下看

View Code printf("The original array:\n");
for(i=0;i<10;i++)
printf("%d ",a[i]);
printf("\n");

  一地雞毛!在main()這樣重要的地方忙活雞毛蒜皮是庸人最擅長的事情。其原因在于:思想一直是在代碼層面上爬行,而又缺乏代碼重構(gòu)的意識(shí)。這是違背結(jié)構(gòu)化程序設(shè)計(jì)原則的一個(gè)報(bào)應(yīng)。結(jié)構(gòu)化程序設(shè)計(jì)要求“自頂向下”地思考,要達(dá)到這個(gè)境界,前提是要“站直了,別趴下”。一直趴著絕對(duì)寫不出優(yōu)雅,簡(jiǎn)潔的代碼。優(yōu)秀的代碼首先要站得高,其次很忌諱把事做“絕”。再往下看

View Code inv(a,10);

  前后都是一地雞毛,唯獨(dú)這個(gè)充分且簡(jiǎn)潔的函數(shù)調(diào)用猶如金鳳一樣擺出了一副展翅欲飛的優(yōu)美姿態(tài)。贊一個(gè)!再繼續(xù)看

View Code printf("The array has been vnverted:\n");
for(i=0;i<10;i++)
printf("%d ",a[i]);
printf("\n");

  天哪!竟然寫出了和前面一模一樣的代碼!對(duì)于任何合格的程序員來說,這絕對(duì)是一種恥辱。這和車轱轆話來回說沒什么區(qū)別。這使得main()即使蒼蠅沒來下蛆就已經(jīng)臟亂得腐敗不堪了。當(dāng)然,有些人對(duì)此是不介意的。“不干不凈,吃了沒病”,你沒辦法對(duì)那些在垃圾桶里尋找食物的人說清楚什么叫做衛(wèi)生。“不干不凈,吃了沒病”這種想法在程序設(shè)計(jì)界的翻版“只要程序能運(yùn)行”,你同樣也無法和有些人說清楚代碼為什么應(yīng)該簡(jiǎn)潔優(yōu)美,這是沒有辦法的事情。但是,如果把這種丑陋的惡習(xí)寫在教科書里,那就成了一種教唆,我個(gè)人認(rèn)為應(yīng)該判刑。因?yàn)檫@就和《衛(wèi)生》課本里示范如何食用地溝油異曲同工。
  再往后,就是那只從main()中飛出來的inv()函數(shù)的定義了。

View Code void inv(int *x,int n)
{int *p,temp,*i,*j,m=(n-1)/2;
i=x;j=x+n-1;p=x+m;
for(;i<=p;i++,j--)
{temp=*i;*i=*j;*j=temp;}
return ;
}

  首先,把“int *p,temp,*i,*j,m=(n-1)/2;”這幾個(gè)變量定義緊密地寫在“{”之后是一種令人作嘔的風(fēng)格。此外,令人吃驚的是,實(shí)現(xiàn)如此簡(jiǎn)單的功能,居然一口氣使用了5個(gè)“蒙頭蓋臉”的變量——你從名字上絕對(duì)不可能看出這些變量是做什么用的。這也是趴在地上思考的成果。由于事先缺乏充分且有高度的思考,就免不了“東一榔頭西一棒子”地濫用變量(反正變量不要錢)。同樣是由于缺乏縝密的思考,所以使用這些變量只是由于一時(shí)興起,事后代碼作者自己恐怕也弄不清楚究竟這些變量的真正含義。實(shí)際上根本不需要這么多的變量。
  首先來看p,它的作用僅僅是用來表示x+m這個(gè)值,顯然毫無必要,代碼完全可以寫成

View Code void inv(int *x,int n)
{
int temp,*i,*j,m=(n-1)/2;
i=x;j=x+n-1;
for(;i<=x+m;i++,j--)
{temp=*i;*i=*j;*j=temp;}
return ;
}

  再看m,它只是記錄了(n-1)/2這個(gè)在代碼中從沒有改變過的值而已,因而也沒有必要。

View Code void inv(int *x,int n)
{
int temp,*i,*j;
i=x;j=x+n-1;
for(;i<=x+(n-1)/2;i++,j--)
{temp=*i;*i=*j;*j=temp;}
return ;
}

  現(xiàn)在對(duì)代碼走查一下,假設(shè)n的值為3,那么i,j的變化情況為:
  i??????????? ?j??????????
  x????????? x+2????????
  x+1?????x+1
  不難發(fā)現(xiàn),當(dāng)i變化成x+1時(shí),程序進(jìn)行了一次毫無意義的交換。這說明“i<=x+(n-1)/2”這個(gè)表達(dá)式不但在寫法上過于啰嗦,在邏輯上也很非常蹩腳。實(shí)際上只要簡(jiǎn)單地?????????

View Code void inv(int *x,int n)
{
int temp,*i,*j;
for(i=x,j=x+n-1 ; i < j ;i++,j--)
{temp=*i;*i=*j;*j=temp;}
return ;
}

就可以了。
  最后,

View Code {temp=*i;*i=*j;*j=temp;}

不但風(fēng)格上奇丑無比,而且同樣犯了把事做“絕”的毛病——絕則錯(cuò)。
  所以,盡管從main()這個(gè)雞窩里飛了出來,但inv()只是一只“偽”鳳凰而已。
  最后,對(duì)這段代碼重構(gòu)如下:

#include <stdio.h>void inv(int [],int ); void output( int [] , int , char *); void swap ( int * , int * );int main( void ) {int a[10]={3,7,9,11,0,6,7,5,4,2};output(a,10,"The original array:");inv(a,10);output(a,10,"The array has been inverted:");return 0; }void output( int x[] , int n , char *s ) {int i;puts(s);for( i = 0 ; i < n ; i++ )printf("%d ", x[i]);putchar('\n'); }void inv(int *p_begin , int n ) {int *p_end = p_begin + n - 1 ;while ( p_end > p_begin )swap ( p_end -- , p_begin ++ ); }void swap ( int *p , int *q ) {int temp ;temp = *p ;*p = *q ;*q = temp ; }

?

?

總結(jié)

以上是生活随笔為你收集整理的鸡窝里飞出伪凤凰的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。