




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第1頁
解開程序員面試筆試的秘密
陳正沖編著
石虎審閱
=================================第2頁
第3頁
最近面試了一些人,包括應(yīng)屆本科、碩士和工作多年的程序員,
在問到C語言相關(guān)的問題的時(shí)候,總是沒幾個(gè)人能完全答上我的問
題。甚至一些工作多年,簡(jiǎn)歷上寫著“最得意的語言是C語言”,“對(duì)
C有很深的研究”,“精通C語言”的人也答不完全我的問題,甚至有
個(gè)別人我問的問題一個(gè)都答不上。于是我就想起了我去年閑的使用寫
的這本小冊(cè)子。
這本小冊(cè)子已經(jīng)在我電腦里睡了一年大覺了。并非沒有出版社愿
意出版,而是幾個(gè)大的出版社都認(rèn)為書寫得不錯(cuò),但太薄,利潤(rùn)太低,
所以要求我加厚到300頁以上。我拒絕加厚,并為此和幾個(gè)出版社僵
持了一年多。我認(rèn)為經(jīng)典的東西一定要精煉,不要廢話。這次由于面
試別人,所以終于記起了我還寫過這么一本小冊(cè)子。想了想,還是決
定掛到網(wǎng)上免費(fèi)讓大家看得了。并為此專門為本書開了個(gè)博客,以方
便和讀者交流。博客地址:
http://blog.csdn.net/dissection_c
作者簡(jiǎn)介:
陳正沖:湖南沅江人,畢業(yè)于長(zhǎng)春光學(xué)精密機(jī)械學(xué)院(長(zhǎng)春理工
大學(xué))數(shù)學(xué)系。目前從事嵌入式軟件開發(fā)和管理方面的工作。
石虎:湖南沅江人,畢業(yè)于吉林大學(xué)計(jì)算機(jī)系。目前為大連交通
大學(xué)計(jì)算機(jī)系講師。
===================================第4頁
我遇到過很多程序員和計(jì)算機(jī)系畢'也的學(xué)生,也給很多程序員和計(jì)算機(jī)系畢業(yè)的學(xué)生講
解過《高級(jí)
C
語言程序設(shè)計(jì)》。每期班開課前,我總會(huì)問學(xué)生:你感覺
C
語言學(xué)得怎么樣?
難嗎?指針明白嗎?數(shù)組呢??jī)?nèi)存管理呢?往往學(xué)生回答說:感覺還可以,
C
語言不難,指
針很明白,數(shù)組很簡(jiǎn)單,內(nèi)存管理也不難。一般我會(huì)再問一個(gè)問題:通過這個(gè)班的學(xué)習(xí),
你想達(dá)到什么程度?很多學(xué)生回答:精通
C
語言0我告訴他們:我很無奈,也很無語。因
為我完全在和一群業(yè)余者或者是
C
語言愛好者在對(duì)話。你們大學(xué)的計(jì)算機(jī)教育根本就是在
浪費(fèi)你們的時(shí)間,念了幾年大學(xué),連
C
語言的門都沒摸著。現(xiàn)在大多數(shù)學(xué)校計(jì)算機(jī)系都開
T
C
、
C++
、
Java
、
C#
等等語言,好像什么都學(xué)了,但是什么都不會(huì),更可悲的是有些大學(xué)
居然取消了
C
語言課程,認(rèn)為其過時(shí)了。我個(gè)人的觀點(diǎn)是“十鳥在林,不如一鳥在手”,真
正把
C
語言整明白了再學(xué)別的語言也很簡(jiǎn)單,如果
C
語言都沒整明白,別的語言學(xué)得再好
也是花架子,因?yàn)槟悴⒉涣私獾讓邮窃趺椿厥隆.?dāng)然我也從來不認(rèn)為一個(gè)沒學(xué)過匯編的人
能真正掌握
C
語言的真諦。我個(gè)人一直認(rèn)為,普通人用
C
語言在
3
年之下,一般來說,還
沒掌握
C
語言;
5
年之下,一般來說還沒熟悉
C
語言;
10
年之下,談不上精通。所以,我
告訴我的學(xué)生:聽完我的課,遠(yuǎn)達(dá)不到精通的目標(biāo),熟悉也達(dá)不到,掌握也達(dá)不到。那能
達(dá)到什么目標(biāo)?
領(lǐng)你們進(jìn)入
c
語言的大門。入門之后的造化如何在于你們自己。不過我
可以告訴你們一條不是捷徑的捷徑:把一個(gè)鍵盤的
F10
或
F11
按壞,當(dāng)然不能是垃圾鍵盤。
往往講到這里,學(xué)生眼里總是透露著疑慮。
C
語言有這么難嗎?我的回答是:不難。但
你就是用不明白。學(xué)生說:以前大學(xué)老師講
C
語言,我學(xué)得很好。老師講的都能聽懂,考
試也很好。平時(shí)練習(xí)感覺自己還不錯(cuò),工作也很輕松找到了。我告訴學(xué)生:聽明白,看明
白不代表你懂了,你懂了不代表你會(huì)用了,你會(huì)用了不代表你能用明白,你能用明白不代
表你真正懂了!什么時(shí)候表明你真正懂了呢?你站在我這來,把問題給下面的同學(xué)講明白,
學(xué)生都聽明白了,說明你真正懂了。否則,你就沒真正懂,這是檢驗(yàn)懂沒懂的唯一標(biāo)準(zhǔn)。
冰山大家都沒見過,但總聽過或是電影里看過吧?如果你連《泰坦尼克》都沒看過,那你
也算個(gè)人物(開個(gè)玩笑)。《泰坦尼克》里的冰山給泰坦尼克造成了巨大的損失。你們都是
理工科的,應(yīng)該明白冰山在水面上的部分只是總個(gè)冰山的
1/8
o我現(xiàn)在就告訴你們,
C
語言
就是這座冰山。你們現(xiàn)在僅僅是摸到了水面上的部分,甚至根本不知道水面下的部分。我
希望通過我的講解,讓你們摸到水面下的部分,讓你們知道
C
語言到底是什么樣子。
從現(xiàn)在開始,除非在特殊情況下,不允許用
printf
這個(gè)函數(shù)。為什么呢?很多學(xué)生寫完
代碼,直接用
printf
打印出來,發(fā)現(xiàn)結(jié)果不對(duì)。然后就舉手問我
老師,我的結(jié)果為什么不
對(duì)啊?連調(diào)試的意識(shí)都沒有!大多數(shù)學(xué)生根本就不會(huì)調(diào)試,不會(huì)看變量的值,內(nèi)存的值。
只知道
printf
出來結(jié)果不對(duì),卻不知道為什么不對(duì),怎么解決。這種情況還算好的。往往很
多時(shí)候
printf
出來的結(jié)果是對(duì)的,然后呢,學(xué)生也理所當(dāng)然的認(rèn)為程序沒有問題。是這樣嗎?
往往不是,往后看,你能看到例子的。永遠(yuǎn)給我記住一點(diǎn):結(jié)果對(duì),并不代表程序真正沒
有問題。所以,以后盡量不要用
printf
函數(shù),要去看變量的值,內(nèi)存的值。當(dāng)然,在我們目
前的編譯器里,變量的值,內(nèi)存的值對(duì)了就代表你程序沒問題嗎?也不是,往后,你也會(huì)
看到例子的。
這個(gè)時(shí)候呢,學(xué)生往往會(huì)莫名其妙。這個(gè)老師有問題吧。大學(xué)里我們老師都教我們?cè)趺?/p>
用
printf
,告訴我們要經(jīng)常用
printf
.這也恰恰是大學(xué)教育失敗的地方之一。很多大學(xué)老師根
本就沒真正用
C
語言寫過幾行代碼,更別說教學(xué)生調(diào)試代碼了。不調(diào)試代碼,不按
F10
或
F11
水平永遠(yuǎn)也無法提上來,所以,要想學(xué)好一門編程語言,最好的辦法就是多調(diào)試。你去一
個(gè)軟件公司轉(zhuǎn)轉(zhuǎn),去看人家的鍵盤,如果發(fā)現(xiàn)鍵盤上的
F10
或
FU
錚亮錚亮,毫無疑問,
此機(jī)的主人曾經(jīng)或現(xiàn)在是開發(fā)人員(這里僅指寫代碼的,不上升到架構(gòu)設(shè)計(jì)類的開發(fā)人員),
第5頁
否則,必是非開發(fā)人員。
非常有必要申明,本人并非什么學(xué)者或是專家,但本人是數(shù)學(xué)系畢業(yè),所以對(duì)理論方面
比較擅長(zhǎng)。講解的時(shí)候會(huì)舉很多例子來盡量使學(xué)生明白這個(gè)知識(shí)點(diǎn),至于這些例子是否恰
當(dāng)則是見仁見智的問題了。但是一條,長(zhǎng)期的數(shù)學(xué)訓(xùn)練使得本人思維比較嚴(yán)謹(jǐn),講解一些
知識(shí)點(diǎn)尤其是一些概念性原理性的東西時(shí)會(huì)摳的很細(xì)、很嚴(yán),這?點(diǎn)相信讀者會(huì)體會(huì)得到
的。本書是我平時(shí)講解
C
語言的一些心得和經(jīng)驗(yàn),其中有很多我個(gè)人的見解或看法。經(jīng)過
多期培訓(xùn)班的實(shí)踐,發(fā)現(xiàn)這樣講解得比較透徹,學(xué)生聽得明白。很多學(xué)生聽完課后告訴我:
我有生以來聽課從來都沒有聽得這么透徹,這么明白過。也有業(yè)余班的學(xué)生甚至辭掉本職
工作來聽我的課的。
當(dāng)然,關(guān)于
C
語言的這么多經(jīng)驗(yàn)和心得的積累并非我一人之力。借用一句名言:我只
不過是站在巨人的肩膀上而已。給學(xué)生做培訓(xùn)的時(shí)候我參考得比較多的書有:
Kernighanfe
Ritchie
的《
TheCProgrammingLanguage
》;
Linden
的《
ExpertCProgramming
》;
Andrew&
Koening
《
CTrapsandPitfalls
》;
SteveMaguire
的《
WriteCleanCode
》;
SteveMcConnell
的
《
CodeComplete.SecondEdition
》;林銳的《高質(zhì)量
C++/C
編程指南》。這些書都是經(jīng)典之
作,但卻都有著各自的缺陷。讀者往往需要同時(shí)閱讀這些書才能深刻的掌握某一知識(shí)點(diǎn)。
我的講課的試圖時(shí)候融各家之長(zhǎng),再加上我個(gè)人的見解傳授給學(xué)生。還好,學(xué)生反映還可
以,至少還沒有出亂子。這些書飽含著作者的智慧,每讀i遍都有不同的收獲,我希望讀
者能讀上十遍。另外,在編寫本書時(shí)也參考了網(wǎng)上一些無名高手的文章,這些高手的文章
見解深刻,使我受益匪淺。這里要感謝這些大師們,如果不是他們,肯怕我的
C
語言的水
平也僅僅是入門而已。
學(xué)習(xí)
C
語言,這兒本書如果真正啃透了,水平不會(huì)差到哪。與其說本書是我授課的經(jīng)
驗(yàn)與心得,不如說本書是我對(duì)這些大師們智慧的解讀。本書并不是從頭到尾講解
C
語言的
基礎(chǔ)知識(shí),所以,本書并不適用于
C
語言零基礎(chǔ)的人。本書的知識(shí)要比般的
C
語言書說
講的深的多,其中有很多問題是各大公司的面試或筆試題。所以本書的讀者應(yīng)該是中國(guó)廣
大的計(jì)算機(jī)系的學(xué)生和初級(jí)程序員。如果本書上面的問題能真正明白
80%
,作為一個(gè)應(yīng)屆
畢業(yè)生,肯怕沒有一家大公司會(huì)拒絕你。當(dāng)然,書內(nèi)很多知識(shí)也值得計(jì)算機(jī)教師或是中高
級(jí)程序員參考。尤其書內(nèi)的一些例子或比方,如果能被廣大教師用于課堂,我想對(duì)學(xué)生來
說是件非常好的事情。有人說電影是一門遺憾的藝術(shù),因?yàn)樵诰庉嬐瓿芍罂偰芑蚨嗷蛏?/p>
的發(fā)現(xiàn)一些本來可以做得更好的缺陷。講課同樣也如此,每次講完課之后總能發(fā)現(xiàn)自己某
些地方或是沒有講到,或是沒能講透徹或是忘了舉一個(gè)輕淺的例子等等。整理本書的過程
也是,為了盡量精煉,總是猶豫一些東西的去留。限于作者水平,書中難免有些遺漏甚至
錯(cuò)誤,希望各位讀者能予指教。作者
Mail:dissection_c@163.com.
陳正沖
2008
年
6
月
23
日
第6頁
第一章關(guān)鍵字
....9
1.1
,最寬恒大量的關(guān)鍵字
----auto..........................................................................
..................11
1.2
,最快的關(guān)鍵字
----register......................................................................
...........................11
1.2.1
,皇帝身邊的小太監(jiān)
寄存器
................................................................................11
1.2.2
,使用
register
修飾符的注意點(diǎn)
................................................................................11
1.3
,最名不符實(shí)的關(guān)鍵字
----static........................................................................
...................12
1.3.1
,修飾變量
................................12
1.3.2
,修飾函數(shù)
................................13
1.4
,基本數(shù)據(jù)類型
----short
、
int
、
long
、
char
、
float
、
double.............................................13
1.4.1
,數(shù)據(jù)類型與
模子
..................14
1.4.2
,變量的命名規(guī)則
....................14
1.5
,最冤枉的關(guān)鍵字
----sizeof........................................................................
..........................18
1.5.1
,常年被人誤認(rèn)為函數(shù)
...........18
1.5.2
sizeof
int
)
*p
表示什么意思?
...........................................................................18
1.4
signed
、
unsigned
關(guān)鍵字
................19
1.6
if
、
else
組合
.....................................20
1.6.1
bool
變量與
零值
進(jìn)行比較
...................................................................................2
0
1.6.2,float
變量與
零值
,,
進(jìn)行比較
.21
1.6.3
,指針變量與
零值
進(jìn)行比較
..................................................................................2
1
1.6.4
else
到底與哪個(gè)
if
配對(duì)呢?
...................................................................................2
2
1.6.5
if
語句后面的分號(hào)
...............23
1.6.6
,使用
if
語句的其他注意事項(xiàng)
.................................................................................24
1.7
switch
、
case
組合
............................24
1.7.1
,不要拿青龍偃月刀去削蘋果
.................................................................................24
1.7.2
9
case
關(guān)鍵字后面的值有什么要求嗎?
.................................................................25
1.7.3
case
語句的排列順序
...........25
1.7.4
,使用
case
語句的其他注意事項(xiàng)
.............................................................................27
1.8
do
、
while
、
for
關(guān)鍵字
...................28
1.8.1
break
與
continue
的區(qū)別
....28
1.8.2
,循環(huán)語句的注意點(diǎn)
...............29
1.9
goto
關(guān)鍵字
.......................................30
1.10
void
關(guān)鍵字
.....................................31
1.10.1
voida
?
.............................31
1.10
return
關(guān)鍵字
..................................34
1.11
const
關(guān)鍵字也許該被替換為
readolny..........................................................................3
4
1.11.2
,節(jié)省空間,避免不必要的內(nèi)存分配,同時(shí)提高效率
.....................................35
1.12
,最易變的關(guān)鍵字
----volatile......................................................................
.......................36
1.13
,最會(huì)帶帽子的關(guān)鍵字
----extern........................................................................
..............37
1.14
struct
關(guān)鍵字
...................................38
1.14.1
,空結(jié)構(gòu)體多大?
.................38
1.14.2
,柔性數(shù)組
..............................39
1.14.3
struct
與
class
的區(qū)別
........40
1.15
union
關(guān)鍵字
...................................40
=========================第7頁
1.15.1
,大小端模式對(duì)
union
類型數(shù)據(jù)的影響
...............................................................40
1.15.2
,如何用程序確認(rèn)當(dāng)前系統(tǒng)的存儲(chǔ)模式?
..........................................................41
1.16
enum
關(guān)鍵字
...................................42
1.16.1,
枚舉類型的使用方法
..........43
1.16.2
,枚舉與
#define
宏的區(qū)別
....43
1.17
,偉大的縫紉師
----typedef
關(guān)鍵字
.44
1.17.1
,關(guān)于馬甲的笑話
.................44
1.17.2
,歷史的誤會(huì)
也許應(yīng)該是
typerename.............................................................44
1.17.3
typedef
與
#define
的區(qū)別
...45
1.17.4
#defineaint[10]
與
typedefinta[10]
.................................................................46
第二章符號(hào)
.....49
2.1
,注釋符號(hào)
............................................50
2.1.1
,兒個(gè)似非而是的注釋問題
...50
2.1.2
y=x/*p............................................................................
........................................51
2.1.3
,怎樣才能寫出出色的注釋
...51
2.1.3.1
,安息吧,路德維希
凡
貝多芬
....................................................................51
2.1.3.2
f
windows
大師們用注釋討論天氣問題
......................................................51
2.1.3.3
,出色注釋的基本要求
..................................................................................5
2
2.2
,接續(xù)符和轉(zhuǎn)義符
...............................53
2.3
,單引號(hào)、雙引號(hào)
...............................54
2.4
,邏輯運(yùn)算符
.......................................54
2.5
,位運(yùn)算符
............................................55
2.5.1
,左移和右移
............................55
2.5.2
0x01?2+3
的值為多少?
...55
2.6
,花括號(hào)
................................................5
6
2.7
++
操作符
....................................56
2.7.1
++i+++i+++i.......................................................................
.....................................57
2.7.2
,貪心法
....................................57
2.8
2/(-2)
的值是多少?
..........................58
2.9
,運(yùn)算符的優(yōu)先級(jí)
...............................58
2.9.1,
運(yùn)算符的優(yōu)先級(jí)表
................58
2.9.2
,一些容易出錯(cuò)的優(yōu)先級(jí)問題
.................................................................................60
第三章預(yù)處理
..61
3.1
,宏定義
................................................6
2
3.1.1
,數(shù)值宏常量
............................62
3.1.2
,字符串宏常量
........................62
3.1.3
,用
define
宏定義注釋符號(hào)?
.................................................................................63
3.1.4
,用
define
宏定義表達(dá)式
......63
3.1.5
,宏定義中的空格
...................64
3.1.6
#undef............................................................................
............................................64
3.2
,條件編譯
............................................65
3.3
,文件包含
............................................66
3.4
#error
預(yù)處理
....................................66
3.5
#line
預(yù)處理
......................................67
第8頁
3.6
#pragma
預(yù)處理
................................67
3.6.8
#pragmapack......................................................................
....................................69
3.6.8.1
,為什么會(huì)有內(nèi)存對(duì)齊?
..............................................................................70
3.6.8.2
,如何避免內(nèi)存對(duì)齊的影響
..........................................................................70
3.7,#
運(yùn)算符
................................................7
2
3.8
##
預(yù)算符
............................................72
第四章指針和數(shù)組
...........................................74
4.1
,指針
...74
4.1.1
,指針的內(nèi)存布局
....................74
4.1.2
*
與防盜門的鑰匙
...............75
4.1.3
int*p=NULL
和
*p=NULL
有什么區(qū)別?
............................................................75
4.1.4
,如何將數(shù)值存儲(chǔ)到指定的內(nèi)存地址
.............................................................................76
4.1.5
,編譯器的
bug
.......................77
4.1.6
,如何達(dá)到手中無劍、胸中也無劍的地步
...................................................................78
4.2
,數(shù)組
...78
4.2.1
,數(shù)組的內(nèi)存布局
......................78
4.2.3
,數(shù)組名
a
作為左值和右值的區(qū)別
..................................................................................79
4.3
,指針與數(shù)組之間的恩恩怨怨
...........80
4.3.1
,以指針的形式訪問和以下標(biāo)的形式訪問
...................................................................80
4.3.1.1
,以指針的形式訪問和以下標(biāo)的形式訪問指針
........................................81
4.3.1.2
,以指針的形式訪問和以卜標(biāo)的形式訪問數(shù)組
........................................81
4.3.2
a
和
&a
的區(qū)別
.......................81
4.3.3
,指針和數(shù)組的定義與聲明
...83
4.3.3.1
,定義為數(shù)組,聲明為指針
..........................................................................83
4.3.3.2
,定義為指針,聲明為數(shù)組
..........................................................................85
4.3.4
,指針和數(shù)組的對(duì)比
...............85
4.4
,指針數(shù)組和數(shù)組指針
.......................86
4.4.1
,指針數(shù)組和數(shù)組指針的內(nèi)存布局
.........................................................................86
4.4.3
,再論
a
和
&a
之間的區(qū)別
....87
4.4.4
,地址的強(qiáng)制轉(zhuǎn)換
...................88
4.5
,多維數(shù)組與多級(jí)指針
.......................90
4.5.1
,二維數(shù)組
................................91
4.5.1.1
,假想中的二維數(shù)組布局
..............................................................................91
4.5.1.2
,內(nèi)存與尺子的對(duì)比
....91
4.5.1.3
9
&p[4][2]-&a[4][2]
的值為多少?
.............................................................92
4.5.2
,二級(jí)指針
................................93
4.5.2.1
,二級(jí)指針的內(nèi)存布局
...................................................................................9
3
4.6
,數(shù)組參數(shù)與指針參數(shù)
.......................94
4.6.1
,一維數(shù)組參數(shù)
........................94
4.6.1.1
,能否向函數(shù)傳遞一個(gè)數(shù)組?
......................................................................94
4.6.1.2
,無法向函數(shù)傳遞一個(gè)數(shù)組
..........................................................................96
4.6.2
,一級(jí)指針參數(shù)
........................97
4.6.2.1
,能否把指針變量本身傳遞給一個(gè)函數(shù)
.....................................................97
4.6.2.2
,無法把指針變量本身傳遞給一個(gè)函數(shù)
.....................................................98
二二二二二===二二二二二二二二二二二二二二二==二=====二==第9頁
4.6.3
,二維數(shù)組參數(shù)與二維指針參數(shù)
.............................................................................99
4.7
,函數(shù)指針
..........................................100
4.7.1
,函數(shù)指針的定義
..................100
4.7.2
,函數(shù)指針的使用
..................101
4.7.2.1
,函數(shù)指針使用的例子
.................................................................................101
4.2.7.2
*(int*)&p----
這是什么?
..........................................................................102
4.7.3
(*(void(*)())0)()------
這是什么?
........................................................................102
4.7.4
,函數(shù)指針數(shù)組
......................103
4.7.5
,函數(shù)指針數(shù)組的指針
.........104
第五章內(nèi)存管理
..................................................107
5.1
,什么是野指針
.....................................107
5.2
,棧、堆和靜態(tài)區(qū)
................................107
5.3
,常見的內(nèi)存錯(cuò)誤及對(duì)策
..................108
5.3.1
,指針沒有指向一塊合法的內(nèi)存
....................................................................................108
5.3.1.1
,結(jié)構(gòu)體成員指針未初始化
................................................................................108
5.3.1.2
,沒有為結(jié)構(gòu)體指針分配足夠的內(nèi)存
.............................................................109
5.3.1.3
,函數(shù)的入口校驗(yàn)
......109
5.3.2
,為指針分配的內(nèi)存太小
.....110
5.3.3
,內(nèi)存分配成功,但并未初始化
.....................................................................................110
5.3.4
,內(nèi)存越界
.................................111
5.3.5
內(nèi)存泄漏
..............................Ill
5.3.5.1
,告老還鄉(xiāng)求良田
.....112
5.3.5.2
,如何使用
malloc
函數(shù)
................................................................................112
5.3.5.3
,用
malloc
函數(shù)申請(qǐng)
0
字節(jié)內(nèi)存
................................................................113
5.3.5.4
,內(nèi)存釋放
...................113
5.3.5.5
,內(nèi)存釋放之后
..........114
5.3.6
,內(nèi)存已經(jīng)被釋放了,但是繼續(xù)通過指針來使用
..............................................114
第六章函數(shù)
....115
6.1
,函數(shù)的由來與好處
.........................116
6.2
,編碼風(fēng)格
..........................................116
6.2,
函數(shù)設(shè)計(jì)的一般原則和技巧
...........121
6.4
,函數(shù)遞歸
..........................................123
6.4.1
,一個(gè)簡(jiǎn)單但易出錯(cuò)的遞歸例子
...........................................................................123
6.4.2
,不使用任何變量編寫
strlen
函數(shù)
.........................................................................124
第七章文件結(jié)構(gòu)
...........................................127
7.1
,文件內(nèi)容的一般規(guī)則
.....................127
7.2
,文件名命名的規(guī)則
.........................130
===================================第10頁
每次講關(guān)鍵字之前,我總是問學(xué)生:
C
語言有多少個(gè)關(guān)鍵字?
sizeof
怎么用?它是函數(shù)
嗎?有些學(xué)生不知道
C
語言有多少個(gè)關(guān)鍵字,大多數(shù)學(xué)生往往告訴我
sizeof
是函數(shù),因?yàn)?/p>
它后面跟著一對(duì)括號(hào)。當(dāng)投影儀把這
32
個(gè)關(guān)鍵字投到幕布上時(shí),很多學(xué)生表情驚訝。有些
關(guān)鍵字從來沒見過,有的驚訝
C
語言關(guān)鍵字竟有
32
個(gè)之多。更有甚者,說大學(xué)老師告訴他
們
sizeof
是函數(shù),沒想到它居然是關(guān)鍵字!由此可想而知,大學(xué)的計(jì)算機(jī)教育是多么失敗!
表
(1.DC
語言標(biāo)準(zhǔn)定義的
32
個(gè)關(guān)鍵字
關(guān)鍵字意義
auto
聲明自動(dòng)變量,缺省時(shí)編譯器一般默認(rèn)為
auto
int
聲明整型變量
double
聲明雙精度變量
long
聲明長(zhǎng)整型變量
char
聲明字符型變量
float
聲明浮點(diǎn)型變量
short
聲明短整型變量
signed
聲明有符號(hào)類型變量
unsigned
聲明無符號(hào)類型變量
struct
聲明結(jié)構(gòu)體變量
union
聲明聯(lián)合數(shù)據(jù)類型
enum
聲明枚舉類型
static
聲明靜態(tài)變量
switch
用于開關(guān)語句
case
開關(guān)語句分支
default
開關(guān)語句中的
其他
,,
分支
break
跳出當(dāng)前循環(huán)
register
聲明寄存器變量
const
聲明只讀變量
volatile
說明變量在程序執(zhí)行中可被隱含地改變
typedef
用以給數(shù)據(jù)類型取別名
(
當(dāng)然還有其他作用
)
第11頁
下面的篇幅就一一講解這些關(guān)鍵字。但在講解之前先明確兩個(gè)概念:
什么是定義?什么是聲明?它們有何區(qū)別
?
舉個(gè)例子:
A)inti
B)externinti
(
關(guān)于
extern
,后面解釋
)
哪個(gè)是定義?哪個(gè)是聲明?或者都是定義或者都是聲明?我所教過的學(xué)生兒乎沒有?
人能回答上這個(gè)問題。這個(gè)十分重要的概念在大學(xué)里從來沒有被提起過!
什么是定義:所謂的定義就是
(
編譯器
)
創(chuàng)建一個(gè)對(duì)象,為這個(gè)對(duì)象分配一塊內(nèi)存并給它
取上一個(gè)名字,這個(gè)名字就是我們經(jīng)常所說的變量名或?qū)ο竺5⒁猓@個(gè)名字一旦和
這塊內(nèi)存匹配起來
(
可以想象是這個(gè)名字嫁給了這塊空間,沒有要彩禮啊。
,它們就同
生共死,終生不離不棄。并且這塊內(nèi)存的位置也不能被改變。-個(gè)變量或?qū)ο笤谝欢ǖ膮^(qū)
域內(nèi)(比如函數(shù)內(nèi),全局等)只能被定義一次,如果定義多次,編譯器會(huì)提示你重復(fù)定義
同一個(gè)變量或?qū)ο蟆?/p>
什么是聲明:有兩重含義,如下:
第一重含義:告訴編譯器,這個(gè)名字已經(jīng)匹配到一塊內(nèi)存上了
(
伊人已嫁,吾將何去何
從?何以解憂,唯有稀粥
)
,下面的代碼用到變量或?qū)ο笫窃趧e的地方定義的。聲明可以出
現(xiàn)多次。
第二重含義:告訴編譯器,我這個(gè)名字我先預(yù)定了,別的地方再也不能用它來作為變量
名或?qū)ο竺1热缒阍趫D書館自習(xí)室的某個(gè)座位上放了一本書,表明這個(gè)座位已經(jīng)有人預(yù)
訂,別人再也不允許使用這個(gè)座位。其實(shí)這個(gè)時(shí)候你本人并沒有坐在這個(gè)座位上。這種聲
明最典型的例子就是函數(shù)參數(shù)的聲明,例如:
voidfun(inti,chare);
好,這樣一解釋,我們可以很清楚的判斷
:A)
是定義;
B)
是聲明。
那他們的區(qū)別也很清晰了。記住,
extern
聲明變量是在其他文件正聲明
(
也可以看做是引用變量
)
return
子程序返回語句
(
可以帶參數(shù),也可不帶參數(shù)
)
void
聲明函數(shù)無返回值或無參數(shù),聲明空類型指針
continue
結(jié)束當(dāng)前循環(huán),開始下一輪循環(huán)
do
循環(huán)語句的循環(huán)體
while
循環(huán)語句的循環(huán)條件
if
條件語句
else
條件語句否定分支
與
if
連用
)
for
一種循環(huán)語句
(
可意會(huì)不可言傳
)
goto
無條件跳轉(zhuǎn)語句
sizeof
計(jì)算對(duì)象所占內(nèi)存空間大小
第12頁
(
auto
:它很寬恒大量的,你就當(dāng)它不存在吧。編譯器在默認(rèn)的缺省情況下,所有變量
都是
auto
的。
register
:這個(gè)關(guān)鍵字請(qǐng)求編譯器
的將變量存在
CPU
內(nèi)部寄存器中而不是通過內(nèi)
存尋址訪問以提高效率。注意是
。你想想,一個(gè)
CPU
的寄存器也就那么
幾個(gè)或幾十個(gè),你要是定義了很多很多
register
變量,它累死也可能不能全部把這些變量放
入寄存器吧,輪也可能輪不到你。
不知道什么是寄存器?那見過太監(jiān)沒有?沒有?其實(shí)我也沒有。沒見過不要緊,見過就
麻煩大了。
,大家都看過古裝戲,那些皇帝們要閱讀奏章的時(shí)候,大臣總是先將奏章交
給皇帝旁邊的小太監(jiān),小太監(jiān)呢再交給皇帝同志處理。這個(gè)小太監(jiān)只是個(gè)中轉(zhuǎn)站,并無別
的功能。
好,那我們?cè)俾?lián)想到我們的
CPU
CPU
不就是我們的皇帝同志么?大臣就相當(dāng)于我們
的內(nèi)存,數(shù)據(jù)從他這拿出來。那小太監(jiān)就是我們的寄存器了(這里先不考慮
CPU
的高速緩
存區(qū))。數(shù)據(jù)從內(nèi)存里拿出來先放到寄存器,然后
CPU
再從寄存器里讀取數(shù)據(jù)來處理,處理
完后同樣把數(shù)據(jù)通過寄存器存放到內(nèi)存里,
CPU
不直接和內(nèi)存打交道。這里要說明的一點(diǎn)
是
小太監(jiān)是主動(dòng)的從大臣手里接過奏章,然后主動(dòng)的交給皇帝同志,但寄存器沒這么自覺,
它從不主動(dòng)干什么事。一個(gè)皇帝可能有好些小太監(jiān),那么一個(gè)
CPU
也可以有很多寄存器,
不同型號(hào)的
CPU
擁有寄存器的數(shù)量不一樣。
為啥要這么麻煩啊?速度!就是因?yàn)樗俣取<拇嫫髌鋵?shí)就是一塊一塊小的存儲(chǔ)空間,只
不過其存取速度要比內(nèi)存快得多。進(jìn)水樓臺(tái)先得月嘛,它離
CPU
很近,
CPU
一伸手就拿到
數(shù)據(jù)了,比在那么大的一塊內(nèi)存里去尋找某個(gè)地址上的數(shù)據(jù)是不是快多了?那有人問既然
它速度那么快,那我們的內(nèi)存硬盤都改成寄存器得了唄。我要說的是:你真有錢!
雖然寄存器的速度非常快,但是使用
register
修飾符也有些限制的:
register
變量必須是
能被
CPU
寄存器所接受的類型。意味著
register
變量必須是一個(gè)單個(gè)的值,并且其長(zhǎng)度應(yīng)小
于或等于整型的長(zhǎng)度。而且
register
變量可能不存放在內(nèi)存中,所以不能用取址運(yùn)算符“
&
來獲取
register
變量的地址。
=====================================第13頁
不要誤以為關(guān)鍵字
static
很安靜,其實(shí)它?一點(diǎn)也不安靜。這個(gè)關(guān)鍵字在
C
語言里主要有
兩個(gè)作用,
C++
對(duì)它進(jìn)行了擴(kuò)展。
第一個(gè)作用:修飾變量。變量又分為局部和全局變量,但它們都存在內(nèi)存的靜態(tài)區(qū)。
靜態(tài)全局變量,作用域
,其他文件即使用
extern
聲明也沒法
使用他。準(zhǔn)確地說作用域是從定義之處開始,到文件結(jié)尾處結(jié)束,在定義之處前面的那些
代碼行也不能使用它。想要使用就得在前面再加
extern***
o惡心吧?要想不惡心,很簡(jiǎn)單,
直接在文件頂端定義不就得了。
靜態(tài)局部變量,在函數(shù)體里面定義的,就只能在這個(gè)函數(shù)里用了,同一個(gè)文檔中的其他
函數(shù)也用不了。由于被
static
修飾的變量總是存在內(nèi)存的靜態(tài)區(qū),所以即使這個(gè)函數(shù)運(yùn)行結(jié)
束,這個(gè)靜態(tài)變量的值還是不會(huì)被銷毀,函數(shù)下次使用時(shí)仍然能用到這個(gè)值。
staticintj;
voidfunl
(
void
)
(
staticinti=O;
i++;
)
voidfun2
(
void
j=0;
j++;
}
intmain()
(
for(k=0;k<10;k++)
(
funl();
fun2();
}
returnO;
=====================================第14頁
}
i
和
J
的值分別是什么
y
為什么?
第二個(gè)作用:修飾函數(shù)。函數(shù)前加
static
使得函數(shù)成為靜態(tài)函數(shù)。但此處
“static"
的含義
不是指存儲(chǔ)方式,而是指對(duì)函數(shù)的作用域僅局限于本文件
(
所以又稱內(nèi)部函數(shù)
)
o使用內(nèi)部函
數(shù)的好處是:不同的人編寫不同的函數(shù)時(shí),不用擔(dān)心自己定義的函數(shù),是否會(huì)與其它文件
中的函數(shù)同名。
關(guān)鍵字
static
有著不尋常的歷史。起初,在
C
中引入關(guān)鍵字
static
是為了表示退出?個(gè)
塊后仍然存在的局部變量。隨后,
static
在
C
中有了第二種含義:用來表示不能被其它文件
訪問的全局變量和函數(shù)。為了避免引入新的關(guān)鍵字,所以仍使用
static
關(guān)鍵字來表示這第二
種含義。
當(dāng)然,
C++
里對(duì)
static
賦予了第三個(gè)作用,這里先不討論,有興趣的可以找相關(guān)資料研
究。
C
語言包含的數(shù)據(jù)類型如下圖所示:
C
數(shù)
據(jù)
類
型
基本類型
構(gòu)造類型
指針類型
空類型
void
數(shù)值類型
字符類型
char
枚舉類型
enum
整
型
浮點(diǎn)型
單精度型
float
雙精度型
double
短整型
short
長(zhǎng)整型
long
整型
int
數(shù)組
結(jié)構(gòu)體
struct
共用體
union
第15頁
short
int
、
long
、
char
、
float
、
double
這六個(gè)關(guān)鍵字代表
c
語言里的六種基本數(shù)據(jù)類型。
怎么去理解它們呢
?
舉個(gè)例子:見過藕煤球的那個(gè)東西吧?
(
沒見過?煤球總見過吧
)
o那個(gè)
東西叫藕煤器,拿著它在和好的煤堆里這么一咔,一個(gè)煤球出來了。半徑
12cm
12
個(gè)孔。
不同型號(hào)的藕煤器咔出來的煤球大小不一樣,孔數(shù)也不一樣。這個(gè)藕煤器其實(shí)就是個(gè)
O
現(xiàn)在我們聯(lián)想一下,
short
、
int
、
long
、
char
、
float
、
double
這六個(gè)東東是不是很像不同
類型的藕煤器啊?拿著它們?cè)趦?nèi)存上咔咔咔,不同大小的內(nèi)存就分配好了,當(dāng)然別忘了給
它們?nèi)€(gè)好聽的名字。在
32
位的系統(tǒng)上
short
咔出來的內(nèi)存大小是
2
個(gè)
byte
int
咔出來的
內(nèi)存大小是
4
個(gè)
byte
long
咔出來的內(nèi)存大小是
4
個(gè)
byte
float
咔出來的內(nèi)存大小是
4
個(gè)
byte
double
咔出來的內(nèi)存大小是
8
個(gè)
byte
char
咔出來的內(nèi)存大小是
1
個(gè)
byte
。(注意這里指一
般情況,可能不同的平臺(tái)還會(huì)有所不同,具體平臺(tái)可以用
sizeof
關(guān)鍵字測(cè)試一下)
很簡(jiǎn)單吧?咔咔咔很爽吧?是很簡(jiǎn)單,也確實(shí)很爽,但問題就是你咔出來這么多內(nèi)存塊,
你總不能給他取名字叫做
xl,x2,x3,x4,x5???
或者長(zhǎng)江
1
號(hào),長(zhǎng)江
2
號(hào)
吧。它們長(zhǎng)得這么像
(
不
是你家的老大,老二,老三
,過一陣子你就會(huì)忘了到底哪個(gè)名字和哪個(gè)內(nèi)存塊匹配了
(
到
底誰嫁給誰了啊?
*_*)
。所以呢,給他們?nèi)?個(gè)好的名字絕時(shí)重要。下面我們就來研究研究
取什么樣的名字好。
一般規(guī)則:
【規(guī)則
1-1
]命名應(yīng)當(dāng)直觀且可以拼讀,可望文知意,便于記憶和閱讀。
標(biāo)識(shí)符最好采用英文單詞或其組合,不允許使用拼音。程序中的英文單詞一般不要太復(fù)
雜,用詞應(yīng)當(dāng)準(zhǔn)確。
【規(guī)則
1-2
1命名的長(zhǎng)度應(yīng)當(dāng)符合“
min-length&&max-information
”原則。
C
是一種簡(jiǎn)潔的語言
命名也應(yīng)該是簡(jiǎn)潔的。例如變量名
MaxVal
就比
MaxValueUntilOverflow
好用。標(biāo)識(shí)符的長(zhǎng)度一般不要過長(zhǎng),較長(zhǎng)的單詞可通過去掉
元音
,,
形成縮寫。
另外,英文詞盡量不縮寫,特別是非常用專業(yè)名詞,如果有縮寫,在同一系統(tǒng)中對(duì)同一
單詞必須使用相同的表示法,并且注明其意思。
【規(guī)貝I」
1-3
]當(dāng)標(biāo)識(shí)符由多個(gè)詞組成時(shí),每個(gè)詞的第一個(gè)字母大寫,其余全部小寫。比如:
intCurrentVal
?
這樣的名字看起來比較清晰,遠(yuǎn)比一長(zhǎng)串字符好得多。
【規(guī)則
1-4
]盡量避免名字中出現(xiàn)數(shù)字編號(hào),如
Valuel,Value2
等,除非邏輯上的確需要編
號(hào)。比如驅(qū)動(dòng)開發(fā)時(shí)為管腳命名,非編號(hào)名字反而不好。
初學(xué)者總是喜歡用帶編號(hào)的變量名或函數(shù)名,這樣子看上去很簡(jiǎn)單方便,但其實(shí)是一顆
顆定時(shí)炸彈。這個(gè)習(xí)慣初學(xué)者一定要改過來。
第16頁
【規(guī)則
1-5
]對(duì)在多個(gè)文件之間共同使用的全局變量或函數(shù)要加范圍限定符
(
建議使用模塊名
(
縮寫
)
作為范圍限定符
)
O
(GUI_
etc)
標(biāo)識(shí)符的命名規(guī)則:
【規(guī)則
1-6
]標(biāo)識(shí)符名分為兩部分:規(guī)范標(biāo)識(shí)符前綴
(
后綴
)+
含義標(biāo)識(shí)。非全局變量可以
不用使用范圍限定符前綴。
【規(guī)則
1-7
]作用域前綴命名規(guī)則。
【規(guī)則
1-8
]數(shù)據(jù)類型前綴命名規(guī)則。
No.
標(biāo)識(shí)符類型作用域前綴
IGlobalVariableg
2FileStaticVariable(native)n
3FunctionStaticVariablef
4AutoVariablea
5GlobalFunctiong
6StaticFunctionn
No.PrefixSuffixDataTypeExamp1eRemark
lbtbitBitbtVariable;
2bbooleanbooleanbVariable;
3ccharcharcVariable;
4iintintiVariable;
5sshort[int]short[int]sVariable;
61long[int]long[int]1Variable;
7uunsigned[int]unsigned[int]uiVariable;
8ddoubledoubledVariable;
9ffloatfloatfVariable;
=====================第17頁
【規(guī)則
1-9
)含義標(biāo)識(shí)命名規(guī)則,變量命名使用名詞性詞組,函數(shù)命名使用動(dòng)詞性詞組。
例如:
變量含義標(biāo)識(shí)符構(gòu)成:目標(biāo)詞
+
動(dòng)詞
(
的過去分詞
)+[
狀語
]+[
目的地
]
10ppointervoid*vpVariable;
指針前綴
1IwoidvoidvVariable;
13stenumenumAstVariable;
14ststructstructAstVariable;
15stunionunionAstVariable;
16fpfunction
point
void(*fpGetModeFuncList_a[])(void)
17_aarrayofcharcVariable_a[TABLE_MAX];
18
_st
,pst
typedef
enum/struct/u
nion
typedefstructSM_EventOpt
(
unsignedchar
unsignedint
char
}SM_EventOpt_st,*SM_EventOpt_pst;
當(dāng)自定義
結(jié)構(gòu)數(shù)據(jù)
類型時(shí)使
用
_st
后
綴;
當(dāng)自定義
結(jié)構(gòu)數(shù)據(jù)
類型為指
針類型時(shí)
使用
_pst
后綴;
No
變量名目標(biāo)詞動(dòng)詞
(
的過去分詞
)
狀語目的地含義
IDataGotFromSDDataGotFromSD
從
SD
中取
得的數(shù)據(jù)
2DataDeletedFromSDDataDeletedFromSD
從
SD
中刪
除的數(shù)據(jù)
變量名動(dòng)詞
(
一般現(xiàn)時(shí)
)
目標(biāo)詞狀語目的地含義
IGetDataFromSDGetDataFromSD
從
SD
中取
得數(shù)據(jù)
2DeleteDataFromSDDeleteDataFromSD
從
SD
中刪
除數(shù)據(jù)
=================================第18頁
函數(shù)含義標(biāo)識(shí)符構(gòu)成:動(dòng)詞
(
一般現(xiàn)時(shí)
)+
目標(biāo)詞
+[
狀語
]+[
目的地
]
【規(guī)則
1-10
]程序中不得出現(xiàn)僅靠大小寫區(qū)分的相似的標(biāo)識(shí)符。
例如:
intx,X;
變量
X
與
X
容易混淆
voidfoo(intx);
函數(shù)
foo
與
FOO
容易混淆
voidFOO(floatx);
這里還有一個(gè)要特別注意的就是
1
(數(shù)字
1
)和
1
(小寫字母
1
)之間,
0
(數(shù)字
0
)和
o
(小寫字母
o
)之間的區(qū)別。這兩對(duì)真是很難區(qū)分的,我曾經(jīng)的一個(gè)同事就被這個(gè)問題折騰
了一次。
【規(guī)則
1-11
1--個(gè)函數(shù)名禁止被用于其它之處。
例如:
#inc1ude,zc_standards.h〃
voidfoo(intp1)
(
intx=p1;
)
voidstatic_p(void)
(
intfoo=lu;
}
【規(guī)則
1-12
)所有宏定義、枚舉常數(shù)、只讀變量全用大寫字母命名,用下劃線分割單詞。
例如:
constintMAX_LENGTH=100;//
這不是常量,而是?個(gè)只讀變量,具體請(qǐng)往后看
#defineFILE_PATH
/usr/tmp
【規(guī)貝I」
1-13
]考慮到習(xí)慣性問題,局部變量中可采用通用的命名方式,僅限于
n
j
等作
為循環(huán)變量使用。
一定不要寫出如下這樣的代碼:
intp;
chari;
intc;
char*a;
===================================第19頁
一般來說習(xí)慣上用
n,m,i,j,k
等表示
int
類型的變量;
ch
等表示字符類型變量;
a
等表
示數(shù)組;
P
等表示指針。當(dāng)然這僅僅是一般習(xí)慣,除了
i,j,k
等可以用來表示循環(huán)變量外,別
的字符變量名盡量不要使用。
【規(guī)貝I」
1-14
]定義變量的同時(shí)千萬千萬別忘了初始化。定義變量時(shí)編譯器并不一定清空了
這塊內(nèi)存,它的值可能是無效的數(shù)據(jù)。
這個(gè)問題在內(nèi)存管理那章有非常詳細(xì)的討論,請(qǐng)參看。
【規(guī)則
1-15
1不同類型數(shù)據(jù)之間的運(yùn)算要注意精度擴(kuò)展問題,一般低精度數(shù)據(jù)將向高精度
數(shù)據(jù)擴(kuò)展。
sizeof
是關(guān)鍵字不是函數(shù),其實(shí)就算不知道它是否為
32
個(gè)關(guān)鍵字之一時(shí),我們也可以
借助編譯器確定它的身份。看下面的例子:
inti=O
A),sizeof(int)
B)
sizeof(i)
0
sizeofint
D)
sizeofi
毫無疑問,
32
位系統(tǒng)下
A)
B)
的值為
4
o那
0
的呢?
D)
的呢?
在
32
位系統(tǒng)下,通過
VisualC++6.0
或任意?編譯器調(diào)試,我們發(fā)現(xiàn)
D)
的結(jié)果也為
4
O
咦?
sizeof
后面的括號(hào)呢?沒有括號(hào)居然也行,那想想,函數(shù)名后面沒有括號(hào)行嗎?山此輕
易得出
sizeof
絕非函數(shù)。
好,再看
0
。編譯器怎么怎么提示出錯(cuò)呢?不是說
sizeof
是個(gè)關(guān)鍵字,其后面的括號(hào)
可以沒有么?那你想想
sizeofint
表示什么啊?
int
前面加一個(gè)關(guān)鍵字?類型擴(kuò)展?明顯不
正確,我們可以在
int
前加
unsigned
9
const
等關(guān)鍵字但不能加
sizeof
。好,記住:
sizeof
在
計(jì)算
所占空間大小時(shí),括號(hào)可以省略,而計(jì)算
(
)
大小時(shí)不能省略。一般情況下,
咱也別偷這個(gè)懶,乖乖的寫上括號(hào),繼續(xù)裝作一個(gè)“函數(shù)”,做一個(gè)“披著函數(shù)皮的關(guān)鍵字”。
做我的關(guān)鍵字,讓人家認(rèn)為是函數(shù)去吧。
sizeof
(
int
)
*p
表示什么意思?
留幾個(gè)問題
(
講解指針與數(shù)組時(shí)會(huì)詳細(xì)講解
)
32
位系統(tǒng)下:
int*p=NULL;
sizeof(p)
的值是多少?
sizeof(*p)
呢?
=====================================第20頁
inta[100];
sizeof(a)
的值是多少?
sizeof(a[100])
呢?
//
請(qǐng)尤其注意本例。
sizeof(&a)
呢?
sizeof(&a[0])
呢?
intb[100];
voidfun(intb[100])
(
sizeof(b);//sizeof(b)
的值是多少?
)
我們知道計(jì)算機(jī)底層只認(rèn)識(shí)
0
、
1.
任何數(shù)據(jù)到了底層都會(huì)變計(jì)算轉(zhuǎn)換成
0
、
1.
那負(fù)數(shù)怎么
存儲(chǔ)呢?肯定這個(gè)“
”號(hào)是無法存入內(nèi)存的,怎么辦?很好辦,做個(gè)標(biāo)記。把基本數(shù)據(jù)類
型的最高位騰出來,用來存符號(hào),同時(shí)約定如下:最高位如果是
1
,表明這個(gè)數(shù)是負(fù)數(shù),其
值為除最高位以外的剩余位的值添上這個(gè)“
”號(hào);如果最高位是
0
,表明這個(gè)數(shù)是正數(shù),
其值為除最高位以外的剩余位的值。
這樣的話,一個(gè)
32
位的
signedint
類型整數(shù)其值表示法范圍為:
-1
?
8
位的
31
2
31
2
char
類型數(shù)其值表示的范圍為
-1
。一個(gè)
32
位的
unsignedint
類型整數(shù)其值表示法
7
2
7
2
范圍為:
0
-1
8
位的
char
類型數(shù)其值表示的范圍為
0
-1
。同樣我們的
signed
關(guān)
32
2
8
2
鍵字也很寬恒大量,你也可以完全當(dāng)它不存在,編譯器缺省默認(rèn)情況下數(shù)據(jù)為
signed
類型
的。
上面的解釋很容易理解,下面就考慮一下這個(gè)問題:
intmainO
(
chara[1000];
inti;
for(i=0;i<1000;i++)
(
a[i]=-l-i;
}
printfstrlen(a));
returnO;
第21頁
此題看上去真的很簡(jiǎn)單,但是卻鮮有人答對(duì)。答案是
255
o別驚訝,我們先分析分析。
for
循環(huán)內(nèi),當(dāng)
i
的值為
0
時(shí),
a[0]
的值為
-1
=關(guān)鍵就是
-1
在內(nèi)存里面如何存儲(chǔ)。
我們知道在計(jì)算機(jī)系統(tǒng)中,數(shù)值一律用補(bǔ)碼來表示(存儲(chǔ))。主要原因是使用補(bǔ)碼,可
以將符號(hào)位和其它位統(tǒng)一處理;同時(shí),減法也可按加法來處理。另外,兩個(gè)用補(bǔ)碼表示的數(shù)
相加時(shí),如果最高位(符號(hào)位)有進(jìn)位,則進(jìn)位被舍棄。正數(shù)的補(bǔ)碼與其原碼一致;負(fù)數(shù)的
補(bǔ)碼:符號(hào)位為
1
,其余位為該數(shù)絕對(duì)值的原碼按位取反,然后整個(gè)數(shù)加
1
O
按照負(fù)數(shù)補(bǔ)碼的規(guī)則,可以知道
-1
的補(bǔ)碼為
Oxff
-2
的補(bǔ)碼為
Oxfe.......
當(dāng)
i
的值為
127
時(shí),
a[127]
的值為
-128
,而
-128
是
char
類型數(shù)據(jù)能表示的最小的負(fù)數(shù)。當(dāng)
i
繼續(xù)增加,
a[128]
的值肯定不能是
-129
。因?yàn)檫@時(shí)候發(fā)生了溢出,
-129
需要
9
位才能存儲(chǔ)下來,而
char
類型
數(shù)據(jù)只有
8
位,所以最高位被丟棄。剩下的
8
位是原來
9
位補(bǔ)碼的低
8
位的值,即
0x7f
O
當(dāng)
i
繼續(xù)增加到
255
的時(shí)候,
-256
的補(bǔ)碼的低
8
位為
0
O然后當(dāng)
i
增加到
256
時(shí),
-257
的補(bǔ)
碼的低
8
位全為
1
,即低八位的補(bǔ)碼為
Oxff
,如此又開始一輪新的循環(huán)
按照上面的分析,
a[0]
到
a[254]
里面的值都不為
0
,而
a[255]
的值為
0
O
strlen
函數(shù)是計(jì)
算字符串長(zhǎng)度的,并不包含字符串最后的‘
\0
'。而判斷一個(gè)字符串是否結(jié)束的標(biāo)志就是看
是否遇到'
\0
'。如果遇到'
\0
’,則認(rèn)為本字符串結(jié)束。
分析到這里,
strlen(a)
的值為
255
應(yīng)該完全能理解了。這個(gè)問題的關(guān)鍵就是要明白
char
類型默認(rèn)情況下是有符號(hào)的,其表示的值的范圍為
[-128,127]
,超出這個(gè)范圍的值會(huì)產(chǎn)生溢
出。另外還要清楚的就是負(fù)數(shù)的補(bǔ)碼怎么表示。弄明白了這兩點(diǎn),這個(gè)問題其實(shí)就很簡(jiǎn)單了。
留三個(gè)問題:
1
),按照我們上面的解釋,那
-0
和
+0
在內(nèi)存里面分別怎么存儲(chǔ)?
2
),
inti=-20;
unsignedj=10;
i+j
的值為多少?為什么?
3
),下面的代碼有什么問題?
unsigned!;
for(i=9;i>=0;i一)
(
printf("%u'n",i);
}
if
語句很簡(jiǎn)單吧。嗯,的確很簡(jiǎn)單。那我們就簡(jiǎn)單的看下面幾個(gè)簡(jiǎn)單的問題:
bool
變量與“零值”進(jìn)行比較的
if
語句怎么寫?
===================================第22頁
boolbTestFlag=FALSE;//
想想為什么一般初始化為
FALSE
比較好?
A),if(bTestFl
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 嶺南師范學(xué)院《峨眉武術(shù)2》2023-2024學(xué)年第二學(xué)期期末試卷
- 四川長(zhǎng)江職業(yè)學(xué)院《升學(xué)與就職指導(dǎo)》2023-2024學(xué)年第二學(xué)期期末試卷
- 上海工商職業(yè)技術(shù)學(xué)院《跨國(guó)公司管理》2023-2024學(xué)年第二學(xué)期期末試卷
- 四川省瀘州市瀘縣一中2025年高三5月選考模擬考試物理試題含解析
- 景德鎮(zhèn)藝術(shù)職業(yè)大學(xué)《小學(xué)教育專業(yè)導(dǎo)論與職業(yè)生涯規(guī)劃》2023-2024學(xué)年第二學(xué)期期末試卷
- 沙洲職業(yè)工學(xué)院《科技英語翻譯》2023-2024學(xué)年第二學(xué)期期末試卷
- 深圳大學(xué)《合唱》2023-2024學(xué)年第二學(xué)期期末試卷
- 四川化工職業(yè)技術(shù)學(xué)院《道路橋梁工程施工技術(shù)》2023-2024學(xué)年第二學(xué)期期末試卷
- 寧波諾丁漢大學(xué)《園藝生態(tài)學(xué)》2023-2024學(xué)年第二學(xué)期期末試卷
- 二零二五版銷售提成合同書
- 傷寒論全398條全文-順序
- 超市投資預(yù)算表
- 2024年貴州路橋集團(tuán)有限公司招聘筆試參考題庫附帶答案詳解
- 2024年南昌市面向社會(huì)政府專職消防文員招聘筆試參考題庫附帶答案詳解
- 2024年湖南省各市州湘能農(nóng)電服務(wù)有限公司招聘筆試參考題庫含答案解析
- 腫瘤放療與免疫治療聯(lián)合模式探索
- 三年級(jí)下冊(cè)面積單位換算練習(xí)200道及答案
- 熱分析技術(shù)應(yīng)用
- 《游園》(教案)-高中語文統(tǒng)編版必修下冊(cè)
- 《勞動(dòng)用工常見風(fēng)險(xiǎn)》課件
- 正大天虹方矩管鍍鋅方矩管材質(zhì)書
評(píng)論
0/150
提交評(píng)論