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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

用驴子拖宝马——怎样滥用结构体

發(fā)布時(shí)間:2023/12/18 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用驴子拖宝马——怎样滥用结构体 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
http://www.cnblogs.com/pmer/archive/2012/01/20/2327745.html

買了一輛寶馬,但不知道如何正確使用,找頭驢子拖著寶馬滿世界兜風(fēng)。這情景多半會(huì)讓人感到很滑稽。不正確地使用結(jié)構(gòu)體,代碼同樣會(huì)產(chǎn)生一種滑稽的喜感。
  只有按照合適的方式使用一件物品才能得到恰如其分的效果,而濫用一件物品只能起到適得其反的作用。

/*
題目:
輸入兩個(gè)學(xué)生的學(xué)號(hào)、姓名和成績(jī),輸出成績(jī)較高的學(xué)生的學(xué)號(hào)、姓名和成績(jī)。
*/
#include <stdio.h>

int main()
{struct Student
{ int num;
char name[20];
float score;
}student1,student2;
scanf("%d%s%f",&student1.num,student1.name,&student1.score);
scanf("%d%s%f",&student2.num,student2.name,&student2.score);
printf("The higher score is:\n");
if(student1.score>student2.score)
printf("%d %s %6.2f\n",student1.num,student1.name,student1.score);
else if(student1.score<student2.score)
printf("%d %s %6.2f\n",student2.num,student2.name,student2.score);
else
{printf("%d %s %6.2f\n",student1.num,student1.name,student1.score);
printf("%d %s %6.2f\n",student2.num,student2.name,student2.score);
}
return 0;
}

    ————譚浩強(qiáng) ,《C程序設(shè)計(jì)》(第四版),清華大學(xué)出版社,2010年6月,p299

  首先,這段代碼把結(jié)構(gòu)體的類型聲明寫在了main()之內(nèi),這是讓人感到驚異的。因?yàn)?#xff0c;根據(jù)標(biāo)識(shí)符的作用域原則,這意味著struct Student是一種“局部”的類型,也就是說只能在main()只能使用這種結(jié)構(gòu)體。
  這樣使用結(jié)構(gòu)體其實(shí)反倒不如不使用結(jié)構(gòu)體,因?yàn)榛旧线@樣的寫法只收獲了使用結(jié)構(gòu)體的麻煩:定義結(jié)構(gòu)體類型,臃長(zhǎng)復(fù)雜的成員引用,……,但是,沒有得到任何好處。對(duì)比一下不用結(jié)構(gòu)體的代碼就清楚了:

View Code

  不難看出,后者與前者功能一致,但是更加清爽,代碼也更簡(jiǎn)潔。既然如此,又有什么必要舍近求遠(yuǎn)地使用結(jié)構(gòu)體呢?可見樣本代碼使用結(jié)構(gòu)體完全是一種吃力不討好的行為。之所以吃力不討好,是因?yàn)闃颖敬a并非是正確使用結(jié)構(gòu)體的方式,而是一種錯(cuò)誤方式——只使用了結(jié)構(gòu)體的短處,而沒有發(fā)揮結(jié)構(gòu)體的任何優(yōu)勢(shì)。
  當(dāng)然,后來的這段代碼也并非沒有缺點(diǎn):幾句形式上完全一致但卻有些臃長(zhǎng)的printf()函數(shù)調(diào)用缺乏視覺美感(兩個(gè)scanf()函數(shù)調(diào)用也有同樣的感覺)。可以把這些臃腫的內(nèi)容各自用一個(gè)函數(shù)來實(shí)現(xiàn):

View Code

  這段代碼首先在視覺上比前一個(gè)要更富于美感,這種美感并不是一種裝飾,而是有著更為實(shí)惠的利益,那就是整潔優(yōu)美的代碼更不容易出錯(cuò),即使出錯(cuò)也比看起來爛糟糟的代碼更容易查找和得到改正。
  這段代碼的另一個(gè)優(yōu)勢(shì)在于,如果現(xiàn)在需要修改輸出的格式,比如把%6.2f改為%6.0f,現(xiàn)在只需要修改一處而對(duì)main()函數(shù)部分的代碼毫無影響,而前兩個(gè)代碼則需要修改4處,且修改之處一起糾結(jié)于main()函數(shù)之內(nèi)。俗話說,常在河邊走難免不濕鞋。修改的地方多,工作量大不說,出錯(cuò)的可能性也大。
  現(xiàn)在,你可能會(huì)覺得傳遞的參數(shù)也忒多了些。這個(gè)代碼中傳遞的參數(shù)是3個(gè),如果是7、8個(gè)呢?你可能會(huì)感到非常煩躁。并且,我在前一個(gè)代碼中悄悄的特意留下了一個(gè)小BUG(某個(gè)name2被寫成了name1),你可能根本就沒有察覺。查找這類錯(cuò)誤往往非常困難,比那種“比眼力找差別”的智力游戲還要困難。
  那么,應(yīng)該如何回避這些問題呢?答案顯然是避免分散地傳遞這些參數(shù)。既然這些數(shù)據(jù)在邏輯上從屬于一個(gè)主體,最好把它們都捏合在一起。就像電工布線時(shí)是把兩個(gè)電線擰在一起一樣。你沒見過把火線和地線分別鋪設(shè)的電工吧?
   在代碼中怎樣才能把幾個(gè)在邏輯上從屬于一個(gè)主體的數(shù)據(jù)捏在一起呢?顯然就是結(jié)構(gòu)體。結(jié)構(gòu)體的作用之一就是簡(jiǎn)化函數(shù)之間的參數(shù)傳遞。既然如此,就意味著不只一個(gè)函數(shù)會(huì)使用這種結(jié)構(gòu)體類型,所以絕對(duì)不應(yīng)該把結(jié)構(gòu)體的類型聲明放在某個(gè)函數(shù)內(nèi)部。現(xiàn)在你總應(yīng)該懂得為什么把結(jié)構(gòu)體類型聲明放main()里是一種愚蠢的、似是而非的寫法了吧?
  在使用結(jié)構(gòu)體的前提下對(duì)前一個(gè)代碼繼續(xù)改進(jìn):

View Code

  現(xiàn)在,只需要傳遞一個(gè)參數(shù),傳遞多個(gè)參數(shù)時(shí)個(gè)別實(shí)參寫錯(cuò)的可能性大大降低,代碼也更加簡(jiǎn)潔了。并且,由于結(jié)構(gòu)體各個(gè)參數(shù)在邏輯上從屬于一個(gè)整體,代碼更具有概括力,函數(shù)的意義也更為清晰。

  總之,結(jié)構(gòu)體的意義在于其“整體性”,如果建立了結(jié)構(gòu)體,而只是對(duì)其進(jìn)行了成員運(yùn)算,那么結(jié)構(gòu)體的意義如果不能說是全部喪失,恐怕也可以說是幾乎全部喪失。
  此外要補(bǔ)充一點(diǎn)的是,在結(jié)構(gòu)體尺寸較大的情況下,結(jié)構(gòu)體的賦值可能比較費(fèi)時(shí),這時(shí)可以用傳遞指向結(jié)構(gòu)體指針的辦法來解決。如前面的output()函數(shù),可以寫為

?

View Code

?

?  形參中的第一個(gè)const表示p_std指針?biāo)赶虻慕Y(jié)構(gòu)體對(duì)象不應(yīng)該被函數(shù)改變,第二個(gè)const表示p_std這個(gè)指針本身也不應(yīng)該在函數(shù)中被改變。這種寫法在必須提供給函數(shù)一個(gè)結(jié)構(gòu)體對(duì)象的備份時(shí)并不適用。

??

轉(zhuǎn)載于:https://www.cnblogs.com/swjm119/archive/2012/01/21/2328557.html

總結(jié)

以上是生活随笔為你收集整理的用驴子拖宝马——怎样滥用结构体的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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