- 相關(guān)推薦
c語言讀書筆記
C語言是一門通用計(jì)算機(jī)編程語言,應(yīng)用廣泛。C語言的設(shè)計(jì)目標(biāo)是提供一種能以簡易的方式編譯、處理低級(jí)存儲(chǔ)器、產(chǎn)生少量的機(jī)器碼以及不需要任何運(yùn)行環(huán)境支持便能運(yùn)行的編程語言。大學(xué)網(wǎng)整理了C語言的讀書筆記,歡迎大家閱讀。
c語言讀書筆記
《C 語言深度解剖》這本書是一本“解開程序員面試筆試的秘密”的好書。作者陳正沖老師提出“以含金量勇敢挑戰(zhàn)國內(nèi)外同類書籍”,確實(shí),這本書中的知識(shí)點(diǎn)都是一些在面試中常見的考點(diǎn),并且很多都是我們平常不注意的點(diǎn),對(duì)于我們深入理解C語言確實(shí)很有幫助。
第1章關(guān)鍵字
1.register
雖然寄存器的速度非?,但是使用register修飾符也有些限制的:register變量必須是能被CPU寄存器所接受的類型。
意味著register變量必須是一個(gè)單個(gè)的值,并且其長度應(yīng)小于或等于整型的長度。而且register變量可能不存放在內(nèi)存中,
所以不能用取址運(yùn)算符“&”來獲取register變量的地址。
2.static修飾符
(1)修飾變量
靜態(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è)值。
(2)修飾函數(shù)
第二個(gè)作用:修飾函數(shù)。函數(shù)前加static使得函數(shù)成為靜態(tài)函數(shù)。但此處“static”的含義不是指存儲(chǔ)方式,而是指對(duì)函數(shù)的作用域僅局限于本文件(所以又稱內(nèi)部函數(shù))。使用內(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)鍵字來表示這第二種含義。
3.if語句使用注意
先處理正常情況,再處理異常情況。
在編寫代碼是,要使得正常情況的執(zhí)行代碼清晰,確認(rèn)那些不常發(fā)生的異常情況處理代碼不會(huì)遮掩正常的執(zhí)行路徑。這樣對(duì)于代碼的可讀性和性能都很重要。因?yàn)?if
語句總是需要做判斷,而正常情況一般比異常情況發(fā)生的概率更大(否則就應(yīng)該把異常正常調(diào)過來了),如果把執(zhí)行概率更大的代碼放到后面,也就意味著if語句將進(jìn)行多次無謂的比較。
另外,非常重要的一點(diǎn)是,把正常情況的處理放在if后面,而不要放在else后面。當(dāng)然這也符合把正常情況的處理放在前面的要求。
4.千萬小心又小心使用void指針類型。
按照ANSI(AmericanNationalStandardsInstitute)標(biāo)準(zhǔn),不能對(duì)void指針進(jìn)行算法操作,即下列操作都是不合法的:
void*pvoid;
pvoid++;//ANSI:錯(cuò)誤
pvoid+=1;//ANSI:錯(cuò)誤
ANSI標(biāo)準(zhǔn)之所以這樣認(rèn)定,是因?yàn)樗鼒?jiān)持:進(jìn)行算法操作的指針必須是確定知道其指向數(shù)據(jù)類型大小的。也就是說必須知道內(nèi)存目的地址的確切值。
例如:
int*pint;
pint++;//ANSI:正確
但是大名鼎鼎的GNU(GNU'sNotUnix的遞歸縮寫)則不這么認(rèn)定,它指定void*的算法操作與char*一致。因此下列語句在GNU編譯器中皆正確:
pvoid++;//GNU:正確
pvoid+=1;//GNU:正確
在實(shí)際的程序設(shè)計(jì)中,為符合ANSI標(biāo)準(zhǔn),并提高程序的可移植性,我們可以這樣編寫實(shí)現(xiàn)同樣功能的代碼:
void*pvoid;
(char*)pvoid++;//ANSI:正確;GNU:正確
(char*)pvoid+=1;//ANSI:錯(cuò)誤;GNU:正確
GNU和ANSI還有一些區(qū)別,總體而言,GNU較ANSI更“開放”,提供了對(duì)更多語法的支持。但是我們?cè)谡鎸?shí)設(shè)計(jì)時(shí),還是應(yīng)該盡可能地符合ANSI標(biāo)準(zhǔn)。
5.const與宏
節(jié)省空間,避免不必要的內(nèi)存分配,同時(shí)提高效率
編譯器通常不為普通const只讀變量分配存儲(chǔ)空間,而是將它們保存在符號(hào)表中,這使得它成為一個(gè)編譯期間的值,沒有了存儲(chǔ)與讀內(nèi)存的操作,使得它的效率也很高。
例如:
#define M 3//宏常量
const int N=5;//此時(shí)并未將N放入內(nèi)存中
......
inti=N;//此時(shí)為N分配內(nèi)存,以后不再分配!
intI=M;//預(yù)編譯期間進(jìn)行宏替換,分配內(nèi)存
intj=N;//沒有內(nèi)存分配
intJ=M;//再進(jìn)行宏替換,又一次分配內(nèi)存!
const定義的只讀變量從匯編的角度來看,只是給出了對(duì)應(yīng)的內(nèi)存地址,而不是象#define一樣給出的是立即數(shù),所以,const定義的只讀變量在程序運(yùn)行過程中只有一份拷貝(因?yàn)樗侨值闹蛔x變量,存放在靜態(tài)區(qū)),而#define定義的宏常量在內(nèi)存中有若干個(gè)拷貝。#define宏是在預(yù)編譯階段進(jìn)行替換,而const修飾的只讀變量是在編譯的時(shí)候確定其值。
#define宏沒有類型,而const修飾的只讀變量具有特定的`類型。
6.最易變的關(guān)鍵字----volatile
volatile是易變的、不穩(wěn)定的意思。很多人根本就沒見過這個(gè)關(guān)鍵字,不知道它的存在。也有很多程序員知道它的存在,但從來沒用過它。我對(duì)它有種“楊家有女初長成,養(yǎng)在深閨人未識(shí)”的感覺。volatile關(guān)鍵字和const一樣是一種類型修飾符,用它修飾的變量表示可以被某些編譯器未知的因素更改,比如操作系統(tǒng)、硬件或者其它線程等。遇到這個(gè)關(guān)鍵字聲明的變量,編譯器對(duì)訪問該變量的代碼就不再進(jìn)行優(yōu)化,從而可以提供對(duì)特殊地址的穩(wěn)定訪問。
先看看下面的例子:
int i=10;
int j=i;//(1)語句
int k=i;//(2)語句
這時(shí)候編譯器對(duì)代碼進(jìn)行優(yōu)化,因?yàn)樵?1)(2)兩條語句中,i沒有被用作左值。這時(shí)候編譯器認(rèn)為i的值沒有發(fā)生改變,所以在(1)語句時(shí)從內(nèi)存中取出i的值賦給j
之后,這個(gè)值并沒有被丟掉,而是在(2)語句時(shí)繼續(xù)用這個(gè)值給k賦值。編譯器不會(huì)生成出匯編代碼重新從內(nèi)存里取i的值,這樣提高了效率。但要注意:(1)(2)語句之間i沒有被用作左值才行。
再看另一個(gè)例子:
volatile int i=10;
int j=i;//(3)語句
int k=i;//(4)語句
volatile關(guān)鍵字告訴編譯器i是隨時(shí)可能發(fā)生變化的,每次使用它的時(shí)候必須從內(nèi)存中取出i的值,因而編譯器生成的匯編代碼會(huì)重新從i的地址處讀取數(shù)據(jù)放在k中。
這樣看來,如果i是一個(gè)寄存器變量或者表示一個(gè)端口數(shù)據(jù)或者是多個(gè)線程的共享數(shù)據(jù),就容易出錯(cuò),所以說volatile可以保證對(duì)特殊地址的穩(wěn)定訪問。
但是注意:在VC++6.0中,一般Debug模式?jīng)]有進(jìn)行代碼優(yōu)化,所以這個(gè)關(guān)鍵字的作用有可能看不出來。你可以同時(shí)生成Debug版和Release版的程序做個(gè)測試。
留一個(gè)問題:const volatile int i=10;這行代碼有沒有問題?如果沒有,那i到底是什么屬性?
這個(gè)可以同時(shí)使用。
7.空結(jié)構(gòu)體是有大小的
structstudent
{
}stu;
sizeof(stu)的值是多少呢?在VisualC++6.0上測試一下。
很遺憾,不是0,而是1。為什么呢?你想想,如果我們把structstudent看成一個(gè)模子的話,你能造出一個(gè)沒有任何容積的模子嗎?顯然不行。編譯器也是如此認(rèn)為。編譯器認(rèn)為任何一種數(shù)據(jù)類型都有其大小,用它來定義一個(gè)變量能夠分配確定大小的空間。既然如此,編譯器就理所當(dāng)然的認(rèn)為任何一個(gè)結(jié)構(gòu)體都是有大小的,哪怕這個(gè)結(jié)構(gòu)體為空。那萬一結(jié)構(gòu)體真的為空,它的大小為什么值比較合適呢?假設(shè)結(jié)構(gòu)體內(nèi)只有一個(gè)char型的數(shù)據(jù)成員,那其大小為1byte(這里先不考慮內(nèi)存對(duì)齊的情況).也就是說非空結(jié)構(gòu)體類型數(shù)據(jù)最少需要占一個(gè)字節(jié)的空間,而空結(jié)構(gòu)體類型數(shù)據(jù)總不能比最小的非空結(jié)構(gòu)體類型數(shù)據(jù)所占的空間大吧。這就麻煩了,空結(jié)構(gòu)體的大小既不能為0,也不能大于1,怎么辦?定義為0.5個(gè)byte?但是內(nèi)存地址的最小單位是1個(gè)byte,0.5個(gè)byte怎么處理?解決這個(gè)問題的最好辦法就是折中,編譯器理所當(dāng)然的認(rèn)為你構(gòu)造一個(gè)結(jié)構(gòu)體數(shù)據(jù)類型是用來打包一些數(shù)據(jù)成員的,而最小的數(shù)據(jù)成員需要1個(gè)byte,編譯器為每個(gè)結(jié)構(gòu)體類型數(shù)據(jù)至少預(yù)留1個(gè)byte的空間。所以,空結(jié)構(gòu)體的大小就定位1個(gè)byte。
8. 大端與小端
在x86 系統(tǒng)下,輸出的值為多少?
#include
int main()
{
int a[5]={1,2,3,4,5};
int *ptr1=(int *)(&a+1);
int *ptr2=(int *)((int)a+1);
printf("%x,%x",ptr1[-1],*ptr2);
return 0;
}
5和0x02000000
由于x86是小端方式,所以低位內(nèi)容存放到了低位地址。圖中每一種顏色代筆一個(gè)int型的內(nèi)存分布。&a可以獲得數(shù)組a的地址,也就是這兒的0xbfd46624, 所以&a+1的結(jié)果應(yīng)該是0xbfd46638(即圖中最下面紅色部分)。對(duì)于代碼中的ptr1由于其為int型指針,所以ptr[-1]的意思應(yīng)該是取0xbfd46638地址之前的一個(gè)整型,即為a數(shù)組中的最后一個(gè)值5。而在計(jì)算ptr2的時(shí)候,(int)a是將整型地址a轉(zhuǎn)換成了一個(gè)整型數(shù),這樣(int)a+1的結(jié)果就是0xbfd46625,然后再將其轉(zhuǎn)化為int型指針,這樣利用ptr2獲得的數(shù)值就是從0xbfd46625開始的一個(gè)整型,即為0x02000000
10. 花括號(hào)
花括號(hào)每個(gè)人都見過,很簡單吧。但曾經(jīng)有一個(gè)學(xué)生問過我如下問題:
char a[10] = {“abcde”};
他不理解為什么這個(gè)表達(dá)式正確。我讓他繼續(xù)改一下這個(gè)例子:
char a[10] { = “abcde”};
問他這樣行不行。那讀者以為呢?為什么?
花括號(hào)的作用是什么呢?我們平時(shí)寫函數(shù),if、while、for、switch 語句等都用到了它,但有時(shí)又省略掉了它。簡單來說花括號(hào)的作用就是打包。你想想以前用花括號(hào)是不是為了把一些語句或代碼打個(gè)包包起來,使之形成一個(gè)整體,并與外界絕緣。這樣理解的話,上面的問題就不是問題了。
11.再論 a 和&a 之間的區(qū)別
int main()
{
char a[5]={'A','B','C','D'};
char (*p3)[5] = &a;
char (*p4)[5] = a;
return 0;
}
int main()
{
char a[5]={'A','B','C','D'};
char (*p3)[3] = &a;
char (*p4)[3] = a;
return 0;
}
int main()
{
char a[5]={'A','B','C','D'};
char (*p3)[10] = &a;
char (*p4)[10] = a;
return 0;
}
int a[5][5];
int (*p)[4];
p = a;
問&p[4][2] - &a[4][2]的值為多少?
12. 用 malloc 函數(shù)申請(qǐng) 0 字節(jié)內(nèi)存
另外還有一個(gè)問題:用 malloc 函數(shù)申請(qǐng) 0 字節(jié)內(nèi)存會(huì)返回 NULL 指針嗎?
可以測試一下,也可以去查找關(guān)于 malloc 函數(shù)的說明文檔。申請(qǐng) 0 字節(jié)內(nèi)存,函數(shù)并不返回 NULL,而是返回一個(gè)正常的內(nèi)存地址。但是你卻無法使用這塊大小為 0
的內(nèi)存。這好尺子上的某個(gè)刻度,刻度本身并沒有長度,只有某兩個(gè)刻度一起才能量出長度。對(duì)于這一點(diǎn)一定要小心,因?yàn)檫@時(shí)候 if(NULL != p)語句校驗(yàn)將不起作用。
13. 不使用任何變量編寫 strlen 函數(shù)
看到這里,也許有人會(huì)說,strlen 函數(shù)這么簡單,有什么好討論的。是的,我相信你能 熟練應(yīng)用這個(gè)函數(shù),也相信你能輕易的寫出這個(gè)函數(shù)。但是如果我把要求提高一些呢:
不允許調(diào)用庫函數(shù),也不允許使用任何全局或局部變量編寫 int my_strlen (char *strDest); 似乎問題就沒有那么簡單了吧?這個(gè)問題曾經(jīng)在網(wǎng)絡(luò)上討論的比較熱烈,我?guī)缀跏侨獭坝^戰(zhàn)” ,差點(diǎn)也忍不住手癢了。不過因?yàn)槲业慕鉀Q辦法在我看到帖子時(shí)已經(jīng)有人提出了, 所以作罷。
解決這個(gè)問題的辦法由好幾種,比如嵌套有編語言。因?yàn)榍短讌R編一般只在嵌入式底 層開發(fā)中用到,所以本書就不打算討論 C 語言嵌套匯編的知識(shí)了。 有興趣的讀者,可以查找相關(guān)資料。 也許有的讀者想到了用遞歸函數(shù)來解決這個(gè)問題。是的,你應(yīng)該想得到,因?yàn)槲野堰@ 個(gè)問題放在講解函數(shù)遞歸的時(shí)候討論。
既然已經(jīng)有了思路, 這個(gè)問題就很簡單了。
代碼如下:
int my_strlen( const char* strDest )
{
assert(NULL != strDest);
if ('' == *strDest)
{
return 0;
}
else
{
return (1 + my_strlen(++strDest));
}
}
第一步:用 assert 宏做入口校驗(yàn)。
第二步:確定參數(shù)傳遞過來的地址上的內(nèi)存存儲(chǔ)的是否為''。如果是,表明這是一個(gè) 空字符串,或者是字符串的結(jié)束標(biāo)志。
第三步:如果參數(shù)傳遞過來的地址上的內(nèi)存不為'',則說明這個(gè)地址上的內(nèi)存上存儲(chǔ) 的是一個(gè)字符。既然這個(gè)地址上存儲(chǔ)了一個(gè)字符,那就計(jì)數(shù)為 1,然后將地址加 1 個(gè) char類型元素的大小,然后再調(diào)用函數(shù)本身。如此循環(huán),當(dāng)?shù)刂芳拥阶址慕Y(jié)束標(biāo)志符''時(shí), 遞歸停止。
當(dāng)然,同樣是利用遞歸,還有人寫出了更加簡潔的代碼:
int my_strlen( const char* strDest )
{
return *strDest?1+strlen(strDest+1):0;
}
這里很巧妙的利用了問號(hào)表達(dá)式, 但是沒有做參數(shù)入口校驗(yàn), 同時(shí)用*strDest 來代替('' == *strDest)也不是很好。所以,這種寫法雖然很簡潔,但不符合我們前面所講的編碼規(guī)范。
可以改寫一下:
int my_strlen( const char* strDest )
{
assert(NULL != strDest);
return ('' != *strDest)?(1+my_strlen(strDest+1)):0;
}
上面的問題利用函數(shù)遞歸的特性就輕易的搞定了, 也就是說每調(diào)用一遍 my_strlen 函數(shù), 其實(shí)只判斷了一個(gè)字節(jié)上的內(nèi)容。但是,如果傳入的字符串很長的話,就需要連續(xù)多次函數(shù)調(diào)用,而函數(shù)調(diào)用的開銷比循環(huán)來說要大得多,所以,遞歸的效率很低,遞歸的深度太大甚 至可能出現(xiàn)錯(cuò)誤(比如棧溢出) 。所以,平時(shí)寫代碼,不到萬不得已,盡量不要用遞歸。即便是要用遞歸,也要注意遞歸的層次不要太深,防止出現(xiàn)棧溢出的錯(cuò)誤;同時(shí)遞歸的停止條 件一定要正確,否則,遞歸可能沒完沒了。
c語言讀書筆記
我有一本c語言程序設(shè)計(jì)書,已經(jīng)靜靜的躺著好長時(shí)間了,前幾天朋友說,你這本書有些發(fā)黃了,看來是好長時(shí)間沒有翻過了。
其實(shí)這本書是我初學(xué)電腦時(shí)朋友給的,但只看了幾頁就放在那兒了,那時(shí)沒有自己的電腦,看起來很吃力。在朋友的提醒下,現(xiàn)在可以找一點(diǎn)時(shí)間去翻一翻,雖然沒有什么價(jià)值,但學(xué)習(xí)也是一種樂趣......
記錄第二天:
昨天詳細(xì)讀了一下第一章,感覺寫的很詳細(xì),但我不知道書上的知識(shí)點(diǎn)是否全正確。
一、數(shù)據(jù)類型的基本概念
(1)數(shù)據(jù)類型規(guī)定了一個(gè)以值為其元素的集合。
(2)數(shù)據(jù)類型定義了一個(gè)運(yùn)算集
(3)數(shù)據(jù)類型定義了數(shù)據(jù)在計(jì)算機(jī)內(nèi)的存儲(chǔ)及書寫中的表示方式。
二、c語言的數(shù)據(jù)類型
數(shù)據(jù)包含常量和變量,他們都屬于某個(gè)數(shù)據(jù)類型。
三、常量
常量是程序中其值不發(fā)生變化的量,常量有數(shù)、字符和字符串。在c中常量不需要類型說明就可以直接使用,除此之后c中還有一種表示常量的形式,稱為符號(hào)常量。
(一)數(shù)
1、c中數(shù)有整數(shù)和小數(shù)
(1)整數(shù)
整數(shù)有十進(jìn)制,八進(jìn)制,十六進(jìn)制,八進(jìn)制以數(shù)字0開頭,十六進(jìn)制以0x開頭,十進(jìn)制以1-9中的一個(gè)開頭。
整數(shù)有正負(fù)之分,分別在前面加上+,-符號(hào),正數(shù)的符號(hào)+可以省略。
整數(shù)有短整數(shù),整數(shù),長整數(shù)之分,一般短整數(shù)16位,在我的機(jī)器上是short(16),int(32),long(32),對(duì)于整數(shù)的取值范圍有符號(hào)的(-2的n位次方至2的n位次方減1),無符號(hào)的0到2的n位次方-1
長型數(shù)的書寫方法:在數(shù)后面加一個(gè)L,如:0xffL
(2)實(shí)數(shù)
又叫浮點(diǎn)數(shù),只有十進(jìn)制的,實(shí)數(shù)有單精度和雙精度之分,實(shí)數(shù)有兩種表示形式,一種是小數(shù),一種是指數(shù)。
小數(shù):由整數(shù)部分,小數(shù)點(diǎn),小數(shù)部分。
指數(shù):由尾數(shù)(必須有),e/E,指數(shù)(必須是整數(shù))
(二)字符常量
字符常量是用一對(duì)''括起來的單一字符,一個(gè)字符常量在計(jì)算機(jī)中占一個(gè)字節(jié)(8位),字符常量的值就是這個(gè)字符在所屬字符集中的編碼(如:ASCII碼)。
字符常量中的單引號(hào)用作定界符,所以對(duì)于單引號(hào)的表示方法就得用另外一種方法表示:''' 用一個(gè)斜杠加一個(gè)'來轉(zhuǎn)義一個(gè)單引號(hào),對(duì)于斜框用來轉(zhuǎn)義。
字符常量在計(jì)算機(jī)中是以編碼的方式存放,所以說他實(shí)際是一個(gè)字節(jié)的整數(shù),可以參與各種運(yùn)算,如+,-,*,/,比較等。
(三)字符串常量
字符串常量是用雙引號(hào)護(hù)起來的一串字符,字符的個(gè)數(shù)稱其長度,字符串常量簡稱為字符串。
長度為n的字符串在計(jì)算機(jī)的存儲(chǔ)中占用n+1個(gè)字節(jié),最后多出來的那個(gè)存放一個(gè)NULL字符,ASCII編碼是0,我們可以用''來表示這個(gè)字符。
任何一個(gè)字符串在機(jī)器內(nèi)都是以結(jié)尾。如:abc,其實(shí)是'a','b','c',''的存儲(chǔ)格式。
對(duì)于"這個(gè)雙引號(hào),由于用作定界符了,所以只能轉(zhuǎn)義表示:"。
注意: 'A' , "A"這是兩個(gè)不同的存儲(chǔ)方式,一個(gè)是65,一個(gè)是65,0
(四)
一般的字符可以直接寫出,但對(duì)于NULL,回車,新行,退格等字符如何書寫?
對(duì)于這些字符我們可以用其它的方式表示出來,常用的有:
新行
回車
水平制表
v 垂直制表
退格
f 換頁
a 響鈴
" 雙引號(hào)
' 單引號(hào)
NULL
ddd 1到3位八進(jìn)制數(shù)表示一個(gè)字符
xdd 1到2位十六進(jìn)制數(shù)表示一個(gè)字符
其實(shí)ddd,xdd就是字符的編碼。
(五)符號(hào)常量
在c語言中可以對(duì)常量進(jìn)行命名,即用符號(hào)代替常數(shù)值,該符號(hào)叫符號(hào)常量,符號(hào)常量一般用大寫字母表示。
定義格式:
#define 符號(hào)常量名 常量
如:
#define NULL 0
#define EOF -1
#define PI 3.1415926
這里#define是預(yù)編譯命令,每一個(gè)#define只能定義一個(gè)符號(hào)常量,且用一行書寫,不用分號(hào)結(jié)尾。
例:
#include
#define PI 3.1415926
int main(void)
{
float area,r;
printf("請(qǐng)輸入圓的半徑:");
scanf("%f",&r);
area = PI*r*r;
printf("這個(gè)圓的面積是:%f ", area);
return 0;
}
使用符號(hào)常量的好處:
(1)增強(qiáng)程序的可讀性。
如用PI,代表數(shù)學(xué)中的PI,用EOF代表文件尾,很直觀。
(2)增強(qiáng)程序的可維護(hù)性
如果多處用到同一個(gè)常量,可以定義符號(hào)常量,維護(hù)時(shí)只修改一處即可。對(duì)于擴(kuò)充和可移植一個(gè)程序時(shí)大有好處。
四、變量
變量是他的值可以發(fā)生變化的一種量,每一個(gè)變量都對(duì)應(yīng)計(jì)算機(jī)中相應(yīng)長度的存儲(chǔ)單元,以存放變量所取的值。
如:
#include
int main(void)
{
int x = 0; //x的初值為0
x = 5; //x的值發(fā)生了變化
x = 7*5;
x = x+1;
printf("%d ",x);
return 0;
}
每一個(gè)變量都用一個(gè)名字(叫變量名)來表示,變量的名字實(shí)際上是內(nèi)存單元的命名,變量的地址就是該內(nèi)存單元的開始地址。變量的命名規(guī)則同用戶自定義標(biāo)識(shí)符。
任何一個(gè)變量都屬于某一數(shù)據(jù)類型,如果他是整型量,則只能取整數(shù)值。
(一)基本數(shù)據(jù)類型
(1)、從長度上分有8位、16位、32位和64們珠。
(2)、從數(shù)據(jù)的符號(hào)來分,有無符號(hào)的,和有符號(hào)的。
(3)、按照數(shù)學(xué)性質(zhì)來分,分為整型和實(shí)型。
c語言的基本數(shù)據(jù)類型表:
對(duì)于數(shù)的值域范圍的算法:
有符號(hào):[-2(位長度-1)次方到 2(位長度-1)次方-1]
無符號(hào):[0到 2位長度次方]
-----------------------------------------------------------------
類型標(biāo)識(shí)符 名字 長度 范圍
char 字符型 8 ASCII字符代碼
unsigned char 無符號(hào)字符型 8 0-255
signed char 有符號(hào)字符型 8 -127:127
int 整型 16(和環(huán)境有關(guān)) 范圍算法
unsigned int 無符號(hào)整型 同上 同上
signed int 有符號(hào)整數(shù) 同上 同上
short int 短整型 16(和環(huán)境有關(guān)) 同上
unsigned short int 無符號(hào)短整型 同上 同上
signed short int 有符號(hào)短整型 同上 同上
long int 長整型 32位(和環(huán)境有關(guān)) 同上
unsigned long int 無符號(hào)長整型 同上 同上
signed long int 有符號(hào)長整型 同上 同上
float 單精度浮點(diǎn)型 32
double 雙精度浮點(diǎn)型 64
void 空類型
-------------------------------------------------------------------
注:
(1)void類型有兩種用法,一是指定函數(shù)的'返回值的類型,一是用來設(shè)置類屬指針。
(2)對(duì)于不同的環(huán)境,數(shù)據(jù)表示的范圍不同,可以用sizeof(類型)來測試。
(二)變量的定義
變量的定義就是按照特定的方式為其指定標(biāo)識(shí),類型和長度等。程序中所用的每一個(gè)變量都必須先定義后引用,沒有定義的變量是不能引用的。定義的目的是為編譯程序提供所需的信息,以保證完成以下工作。
1、在編譯時(shí)根據(jù)類型信息來檢查程序中有無非法的數(shù)據(jù)結(jié)構(gòu)。
2、根據(jù)類型信息來檢查對(duì)變量施加的運(yùn)算是否合理。如對(duì)兩個(gè)浮點(diǎn)數(shù)不可以進(jìn)行%運(yùn)算。
3、編譯時(shí)根據(jù)類型和長度信息對(duì)變量分配內(nèi)存,確定數(shù)據(jù)在內(nèi)存中的表示方式。
定義:
數(shù)據(jù)類型 變量或變量表;
如:
int year,date;
int x;
(三)變量的初始化
int x; 對(duì)于這樣的變量只是指定了名字和數(shù)據(jù)類型,并沒有給他初始值,但這并不表示變量沒有值,他的值是當(dāng)前內(nèi)存單元中的數(shù)據(jù),這個(gè)數(shù)據(jù)是沒有意義的,引用時(shí)會(huì)產(chǎn)生莫名其妙的結(jié)果。
初始化:在定義時(shí)直接賦值,則稱為初始化。
int x = 5;
double y = 3.4;
變量的初始化并不都是在編譯階段完成的,只有靜態(tài)變量和外部變量是在編譯階段完成,而局部變量是在運(yùn)行時(shí)初始化的。局部變量的初始化就是一個(gè)賦值語句。
int abc()
{
int a =3;
int b =4; //這是在運(yùn)行時(shí)才初始化,而非編譯時(shí)。
}
//補(bǔ)充
數(shù)據(jù)類型的轉(zhuǎn)換
在c語言的表達(dá)式中,準(zhǔn)許對(duì)不同類型的數(shù)值型數(shù)據(jù)進(jìn)行某一操作,當(dāng)不同類型的數(shù)據(jù)進(jìn)行操作時(shí),先將其轉(zhuǎn)換成相同的數(shù)據(jù)類型,然后再進(jìn)行操作。
有兩種轉(zhuǎn)換方式:隱式轉(zhuǎn)換,顯示轉(zhuǎn)換。
一、隱式類型轉(zhuǎn)換
隱式轉(zhuǎn)換就是在編譯時(shí)由編譯程序按照一定規(guī)則自動(dòng)完成。c語言規(guī)定的轉(zhuǎn)換規(guī)則是由低級(jí)向高級(jí)轉(zhuǎn)換,如果一個(gè)操作符帶有兩個(gè)不同類型的操作數(shù),那么在操作之前先將較低的類型向高級(jí)轉(zhuǎn)換,再進(jìn)行運(yùn)算。
注意:
1、所有的float類型都轉(zhuǎn)換成double類型,提高運(yùn)算精度。
2、在賦值語句中,如果=號(hào)左右兩邊的數(shù)據(jù)類型不同,則將賦值號(hào)右邊的值轉(zhuǎn)換為賦值號(hào)左邊的數(shù)據(jù)類型。
3、在函數(shù)參數(shù)傳遞時(shí),也發(fā)生數(shù)據(jù)類型轉(zhuǎn)換。
4、char short自動(dòng)轉(zhuǎn)換成int再參與運(yùn)算。
規(guī)則:
1、char short自動(dòng)轉(zhuǎn)換成int
2、float轉(zhuǎn)換成double
3、低級(jí)到高級(jí)-> char short ->int ->unsigned-> long ->(float ->double)double
二、顯式轉(zhuǎn)換
顯式轉(zhuǎn)換又叫強(qiáng)制型轉(zhuǎn)換,他不換默認(rèn)規(guī)則,由程序員指定。
如:
int i;
i = i+3.124; //默認(rèn)是i轉(zhuǎn)成double,再運(yùn)算,之后double轉(zhuǎn)成int賦給i
顯示轉(zhuǎn)換: i = i+(int)3.124 //先把3.124轉(zhuǎn)成int,再參與運(yùn)算。
顯示類型轉(zhuǎn)換方法:(數(shù)據(jù)類型)表達(dá)式
如:(int) 3.14159; //把double -> int
[c語言讀書筆記]
【c語言讀書筆記】相關(guān)文章:
c++課程設(shè)計(jì)實(shí)踐報(bào)告08-10
讀書筆記摘抄03-23
《初雪 》讀書筆記08-16
草葉集讀書筆記06-18
汽車構(gòu)造讀書筆記08-22
愛心與教育讀書筆記06-18
讀書筆記的寫法指點(diǎn)04-14
護(hù)理札記的讀書筆記06-19
英語 讀書筆記(精選16篇)10-24