第一篇:study WW C總結(jié)
指針,數(shù)組,類型的識(shí)別,參數(shù)可變的函數(shù)。一.指針。
它的本質(zhì)是地址的類型。在許多語(yǔ)言中根本就沒有這個(gè)概念。但是它卻正是C靈活,高效,在面向過程的時(shí)代所向披靡的原因所在。因?yàn)镃的內(nèi)存模型基本上對(duì)應(yīng)了現(xiàn)在von Neumann(馮·諾伊曼)計(jì)算機(jī)的機(jī)器模型,很好的達(dá)到了對(duì)機(jī)器的映射。不過有些人似乎永遠(yuǎn)也不能理解指針【注1】。
注1:Joel Spolsky就是這樣認(rèn)為的,他認(rèn)為對(duì)指針的理解是一種aptitude,不是通過訓(xùn)練就可以達(dá)到的
http://004km.cn/wiki/APL_programming_language
下面有一段是這樣的: APL is renowned for using a set of non-ASCII symbols that are an extension of traditional arithmetic and algebraic notation.These cryptic symbols, some have joked, make it possible to construct an entire air traffic control system in two lines of code.Because of its condensed nature and non-standard characters, APL has sometimes been termed a “write-only language”, and reading an APL program can feel like decoding an alien tongue.Because of the unusual character-set, many programmers used special APL keyboards in the production of APL code.Nowadays there are various ways to write APL code using only ASCII characters.在C++中有函數(shù)重載(overload)可以用來區(qū)別不同函數(shù)參數(shù)的調(diào)用,但它還是不能表示任意數(shù)量的函數(shù)參數(shù)。
在標(biāo)準(zhǔn)C語(yǔ)言中定義了一個(gè)頭文件專門用來對(duì)付可變參數(shù)列表,它包含了一組宏,和一個(gè)va_list的typedef聲明。一個(gè)典型實(shí)現(xiàn)如下【注14】: typedef char* va_list;#define va_start(list)list =(char*)&va_alist #define va_end(list)#define va_arg(list, mode)((mode*)(list += sizeof(mode)))[-1] 注14:你可以查看C99標(biāo)準(zhǔn)7.15節(jié)獲得詳細(xì)而權(quán)威的說明。也可以參考Andrew Konig的《C陷阱與缺陷》的附錄A。ANSI C還提供了vprintf函數(shù),它和對(duì)應(yīng)的printf函數(shù)行為方式上完全相同,只不過用va_list替換了格式字符串后的參數(shù)序列。至于它是如何實(shí)現(xiàn)的,你在認(rèn)真讀完《The C Programming Language》后,我相信你一定可以do it yourself!使用這些工具,我們就可以實(shí)現(xiàn)自己的可變參數(shù)函數(shù),比如實(shí)現(xiàn)一個(gè)系統(tǒng)化的錯(cuò)誤處理函數(shù)error。它和printf函數(shù)的使用差不多。只不過將stream重新定向到stderr。在這里我借鑒了《C陷阱與缺陷》的附錄A的例子。實(shí)現(xiàn)如下: #include #include
void error(char* format, …){ va_list ap;va_start(ap, format);fprintf(stderr, ―error: ―);vfprintf(stderr, format, ap);va_end(ap);fprintf(stderr, ―n‖);exit(1);} 你還可以自己實(shí)現(xiàn)printf: #include int printf(char* format, …){ va_list ap;va_start(ap, format);int n = vprintf(format, ap);va_end(ap);return n;} 我還專門找到了VC7.1的頭文件看了一下,發(fā)現(xiàn)各個(gè)宏的具體實(shí)現(xiàn)還是有區(qū)別的,跟很多預(yù)處理(preprocessor)相關(guān)。其中va_list就不一定是char*的別名。typedef struct { char *a0;/* pointer to first homed integer argument */ int offset;/* byte offset of next parameter */ } va_list;其它的定義類似。
經(jīng)常在Windows進(jìn)行系統(tǒng)編程的人一定知道函數(shù)調(diào)用有好幾種不同的形式,比如__stdcall,__pascal,__cdecl。在Windows下_stdcall,__pascal是一樣的,所以我只說一下__stdcall和__cdecl的區(qū)別。
(1)__stdcall表示被調(diào)用端自身負(fù)責(zé)函數(shù)引數(shù)的壓棧和出棧。函數(shù)參數(shù)個(gè)數(shù)一定的函數(shù)都是這種調(diào)用形式。
例如:int fun(char c, double d),我們?cè)趍ain函數(shù)中使用它,這個(gè)函數(shù)就只管本身函數(shù)體的運(yùn)行,參數(shù)怎么來的,怎么去的,它一概不管。自然有main負(fù)責(zé)。不過,不同的編譯器的實(shí)現(xiàn)可能將參數(shù)從右向左壓棧,也可能從左向右壓棧,這個(gè)順序我們是不能加于利用的【注15】。
注15:你可以在Herb Sutter的《More Exceptional C++》中的條款20:An Unmanaged Pointer Problem, Part 1:Parameter Evaluation找到相關(guān)的細(xì)節(jié)論述。
(2)__cdecl表示調(diào)用端負(fù)責(zé)被調(diào)用端引數(shù)的壓棧和出棧。參數(shù)可變的函數(shù)采用的是這種調(diào)用形式。
為什么這種函數(shù)要采用不同于前面的調(diào)用形式呢?那是因?yàn)開_stdcall調(diào)用形式對(duì)它沒有作用,被調(diào)用端根本就無法知道調(diào)用端的引數(shù)個(gè)數(shù),它怎么可能正確工作?所以這種調(diào)用方式是必須的,不過由于參數(shù)參數(shù)可變的函數(shù)本身不多,所以用的地方比較少。
對(duì)于這兩種方式,你可以編制一些簡(jiǎn)單的程序,然后反匯編,在匯編代碼下面你就可以看到實(shí)際的區(qū)別,很好理解的!重載函數(shù)有很多匹配(match)規(guī)則調(diào)用。參數(shù)為―…‖的函數(shù)是匹配最低的,這一點(diǎn)在Andrei Alexandrescu的驚才絕艷之作《Modern C++ Design》中就有用到,參看Page34-35,2.7―編譯期間偵測(cè)可轉(zhuǎn)換性和繼承性‖。后記:
C語(yǔ)言的細(xì)節(jié)肯定不會(huì)只有這么多,但是這幾個(gè)出現(xiàn)的比較頻繁,而且在C語(yǔ)言中也是很重要的幾個(gè)語(yǔ)言特征。如果把這幾個(gè)細(xì)節(jié)徹底弄清楚了,C語(yǔ)言本身的神秘就不會(huì)太多了。C語(yǔ)言本身就像一把異常鋒利的剪刀,你可以用它做出非常精致優(yōu)雅的藝術(shù)品,也可以剪出一些亂七八糟的廢紙片。能夠?qū)⒁患淦饔玫匠錾袢牖鞘切枰獣r(shí)間的,需要多長(zhǎng)時(shí)間?不多,請(qǐng)你拿出一萬(wàn)個(gè)小時(shí)來,英國(guó)Exter大學(xué)心理學(xué)教授麥克.侯威專門研究神童和天才,他的結(jié)論很有意思:―一般人以為天才是自然而生、流暢而不受阻的閃亮才華,其實(shí),天才也必須耗費(fèi)至少十年光陰來學(xué)習(xí)他們的特殊技能,絕無例外。要成為專家,需要擁有頑固的個(gè)性和堅(jiān)持的能力……每一行的專業(yè)人士,都投注大量心血,培養(yǎng)自己的專業(yè)才能。‖【注16】
注16:臺(tái)灣女作家、電視節(jié)目主持人吳淡如《拿出一萬(wàn)個(gè)小時(shí)來》?!蹲x者》2003.1期。―不用太努力,只要持續(xù)下去。想擁有一輩子的專長(zhǎng)或興趣,就像一個(gè)人跑馬拉松賽一樣,最重要的是跑完,而不是前頭跑得有多快?!?推薦兩本書:
K&R的《The C Programming language》,Second Edition。Andrew Konig的《C陷阱與缺陷》。本文從中引用了好幾個(gè)例子,一本高段程序員的經(jīng)驗(yàn)之談。
但是對(duì)純粹的初學(xué)者不太合適,如果你有一點(diǎn)程序設(shè)計(jì)的基礎(chǔ)知識(shí),花一個(gè)月的時(shí)間好好看看這兩本書,C語(yǔ)言本身就不用再花更多的精力了
第一章 概述
1. C語(yǔ)言的特點(diǎn)
①語(yǔ)言簡(jiǎn)潔、緊湊,使用方便、靈活。共有32個(gè)關(guān)鍵字,9種控制語(yǔ)句。②運(yùn)算符豐富,公有34種運(yùn)算符。
③數(shù)據(jù)結(jié)構(gòu)豐富,數(shù)據(jù)類型有:整型、實(shí)型、字符型、數(shù)組、指針、結(jié)構(gòu)體、共用體等。④具有結(jié)構(gòu)化的控制語(yǔ)句(如if…else、while、do…while、switch、for)⑤語(yǔ)法限制不太嚴(yán)格,程序設(shè)計(jì)自由度大。
⑥允許直接訪問物理地址,能進(jìn)行位(bit)操作,可以直接對(duì)硬件操作。⑦生成目標(biāo)代碼質(zhì)量高,程序執(zhí)行效率高。⑧可移植性好。2. C語(yǔ)言的用途
C雖不擅長(zhǎng)科學(xué)計(jì)算和管理領(lǐng)域,但對(duì)操作系統(tǒng)和系統(tǒng)實(shí)用程序以及對(duì)硬件進(jìn)行操作方面,C有明顯的優(yōu)勢(shì)?,F(xiàn)在很多大型應(yīng)用軟件也用C編寫。
第二章 數(shù)據(jù)類型、運(yùn)算符與表達(dá)式
1. C的數(shù)據(jù)類型
C的數(shù)據(jù)類型包括:整型、字符型、實(shí)型或浮點(diǎn)型(單精度和雙精度)、枚舉類型、數(shù)組類型、結(jié)構(gòu)體類型、共用體類型、指針類型和空類型。2. 常量與變量
常量其值不可改變,符號(hào)常量名通常用大寫。變量其值可以改變,變量名只能由字母、數(shù)字和下劃線組成,且第一個(gè)字符必須為字母或下劃線。否則為不合法的變量名。變量在編譯時(shí)為其分配相應(yīng)存儲(chǔ)單元。3. 整型數(shù)據(jù)
整型常量的表示方法:十進(jìn)制不用說了,八進(jìn)制以0開頭,如0123,十六進(jìn)制以0x開頭,如0x1e。整型變量分為:基本型(int)、短整型(short int)、長(zhǎng)整型(long int)和無符號(hào)型。不同機(jī)器上各類數(shù)據(jù)所占內(nèi)存字節(jié)數(shù)不同,一般int型為2個(gè)字節(jié),long型為4個(gè)字節(jié)。4. 實(shí)型數(shù)據(jù)
實(shí)型常量表示形式:十進(jìn)制形式由數(shù)字和小數(shù)點(diǎn)組成(必須有小數(shù)點(diǎn)),如:0.12、.123、123.、0.0等。指數(shù)形式如123e3代表123×10的三次方。
實(shí)型變量分為單精度(float)和雙精度(double)兩類。在一般系統(tǒng)中float型占4字節(jié),7位有效數(shù)字,double型占8字節(jié),15~16位有效數(shù)字。5. 字符型數(shù)據(jù)
字符變量用單引號(hào)括起來,如'a','b'等。還有一些是特殊的字符常量,如'n','t'等。分別代表?yè)Q行和橫向跳格。
字符變量以char 來定義,一個(gè)變量只能存放一個(gè)字符常量。
字符串常量是由雙引號(hào)括起來的字符序列。這里一定要注意'a'和“a”的不同,前者為字符常量,后者為字符串常量,c規(guī)定:每個(gè)字符串的結(jié)尾加一個(gè)結(jié)束標(biāo)志'