java 变量作用域 c语言_C语言深入理解 - 常量与变量
++++++++++++++++++++++++++++++++++++++++++
《C語言深入理解系列?- 常量與變量》
查看其它博文請關(guān)注原創(chuàng)作者。
本文系本站原創(chuàng),歡迎轉(zhuǎn)載! 轉(zhuǎn)載請注明出處:
++++++++++++++++++++++++++++++++++++++++++
常量與變量
正所謂靜中有動,動中有靜,常量與變量亦是如此,它們之前相互依賴,相互影響。關(guān)于常量與變量,很多朋友可能覺得沒有什么好介紹的,它實(shí)在是太簡單了,單從字面上看就知道什么意思?我想說的不是關(guān)于常量與變量的概念,而是其深入的實(shí)質(zhì)。
其實(shí)很多朋友在學(xué)到后面指針的時候經(jīng)常會出現(xiàn),段錯誤,暈指針(我對那些指針恐懼者的癥狀叫法),野指針等問題,都是因為對常量和變量的理解不夠深入,基礎(chǔ)理解不夠踏實(shí)。
常量:其值不會發(fā)生改變的量,稱為常量。它們可以和數(shù)據(jù)類型接合起來分類。比如:整形常量,浮點(diǎn)型常量,字符常量等等,常量是可以不經(jīng)過定義和初始化,而直接引用的。
常量分類:常量又分為:直接常量和符號常量。
直接常量又叫做:字面常量。如12,0,4.6,’a’,”abcd”
符號常量:如宏定義的:#define PI 3.14
特點(diǎn):常量的值在其作用域內(nèi)不會發(fā)生改變,也不能再被賦值。其在出現(xiàn)時就被當(dāng)作一個立即數(shù)來使用。也就是說,只能被訪問,被讀,而不能被寫,被賦值。
其實(shí),你一旦聲明了一個常量,那么常量所在的內(nèi)存空間就被加上了只讀的屬性,它有點(diǎn)類似于const關(guān)鍵字。
變量:其值在其作用域內(nèi)可以改變的量稱為變量。一個變量應(yīng)該有一個名字,在內(nèi)存中占據(jù)一定的存儲空間。變量在使用前必須要定義。每個變量都有自己的地址。
變量分類:變量依據(jù)其定義的類型,分為不同類型,如:整型變量,字符型變量,浮點(diǎn)型變量,指針型變量等等。
特點(diǎn):變量其值可以發(fā)生改變,意味著它可以被覆蓋,被寫入,被賦值。每個變量必須要有一個名字和它所在內(nèi)存空間綁定,如圖xxx所示。
圖xxx 變量內(nèi)存空間示意圖
代碼中聲明整型變量a,它的類型已經(jīng)決定,那么它的大小也就是4個字節(jié)(32位機(jī)上),那么在內(nèi)存中就有連續(xù)的四個字節(jié)與之對應(yīng),a變量名就代表了這四個字節(jié)的空間,a變量的地址就是連續(xù)四個字節(jié)的開始的地址0x000。就好像是飯店里每個房間都有一個地址,如201室代表二樓每一個房間,叫201不太雅觀,我們起個名字叫:牡丹廳。那么,我們?nèi)藶榈膶ⅰ澳档d”這個名字和201房間綁定在了一起。當(dāng)我們說到牡丹廳,就知道是201房間,同樣當(dāng)我們說201房間我們也知道是牡丹廳。
同樣的道理,當(dāng)我們說a變量,就知道是從0x000這個地址開始的4個字節(jié),當(dāng)我們說0x000地址就知道這是a變量的空間。那么既然a是變量也就是說它所代表的空間里的數(shù)據(jù)是可以修改的,同樣0x000地址處的數(shù)據(jù)也是可以修改的。
變量名和變量的值:
變量名是在變量的聲明的時候,該名字就和內(nèi)存中一塊地址綁定在一起了??梢酝ㄟ^變量名直接找到對應(yīng)的內(nèi)存區(qū)域,也可以通過地址找到其內(nèi)存區(qū)域。
變量的值是變量所對應(yīng)的內(nèi)存區(qū)域內(nèi)存放的二進(jìn)制序列。變量的值不會因為變量的類型發(fā)生了改變而改變,當(dāng)變量被轉(zhuǎn)換為對應(yīng)類型時,內(nèi)存區(qū)域的二進(jìn)制序列以該類型的形式翻譯出來。這也是強(qiáng)制類型轉(zhuǎn)換能夠成立的原因。
例如:
int a = 97;
char ch1 = ‘a(chǎn)’;
char ch2 = (char)a;
char *p = (char*)a;
第一行代碼:整型變量a在內(nèi)存中是以97的二進(jìn)制形式存放的,當(dāng)使用它時,會被以十進(jìn)制形式表現(xiàn)出來。
第二行代碼:字符變量ch1的ASCII 碼是97,也是以97的二進(jìn)制存放的,使用時,會被以字符’a’的形式表現(xiàn)出來。
第三行代碼:將整型變量a強(qiáng)制類型轉(zhuǎn)換成字符型,a變量里的值沒有變,變的是它的類型,它里面的值還是97的二進(jìn)制,它類型變成了char,97的二進(jìn)制變成char型,表現(xiàn)出來就是字符’a’。
第四行代碼:聲明一個字符型指針變量p,p是個變量,它里面的值可變,它的值是整型變量a的值強(qiáng)制類型轉(zhuǎn)換成了字符指針類型。這個時候p里的值還是97的二進(jìn)制,只不過這個97的意義已經(jīng)代表了一個字符型指針,也就是一個指向字符的地址了。
由此可見:變量在內(nèi)存中存放和它的值沒有關(guān)系,而是和它的類型相關(guān)的。同樣我們也可以得出:一個二進(jìn)制序列對于計算機(jī)本身而言沒有任何意義,計算機(jī)根本不知道這個二進(jìn)制數(shù)據(jù)是干什么的,只有具體到它的類型時或出現(xiàn)在合適的場合時,才能代表具體的意義。如果一串二進(jìn)制數(shù)據(jù)出現(xiàn)在地址總線上,它代表是一個地址,如果該相同數(shù)據(jù)出現(xiàn)在數(shù)據(jù)總線上,它代表是一個數(shù)據(jù)。所以,當(dāng)我們看到一個數(shù)據(jù)時,比如:3.1415926,不能把它戴上定向思維的帽子認(rèn)為它就是PI,而是要看清它的本質(zhì),它就是一堆二進(jìn)制代碼。
我們來看下下面的例子:
1.
char ch = ‘a(chǎn)’;
int a = (int)ch;
printf(“%d %c\n”, a, ch);
ch是什么?ch里裝的是什么?a是什么?a里面裝的是什么?打印什么?
2.
int add = 0x12345678;
int *p = (int*)add;
add是什么?add里裝的是什么?p是什么?p里裝的是什么?*p又是什么?&p又是什么?
3.
#define PI 3.14
int a = PI;
printf(“%d\n”, a);
上面的代碼有沒有問題?
4.
#define PI 3.14
printf(“%d\n”, PI);
代碼有沒有問題?
5.
#define PI 3.14
int a = PI;
PI = 3.1415926;
int b = PI;
printf(“%d %d\n”, a, b);
代碼有沒有問題?
6.
char *str = “hello world”;
printf(“%s\n”, str);
*str = “goodbye world”;
printf(“%s\n”, str);
代碼有沒有問題?
答案:
1.?????? 測試對變量類型的理解和類型轉(zhuǎn)換。ch是字符型變量,ch里是字符’a’的二進(jìn)制數(shù),a是整型變量,a里面是字符’a’的二進(jìn)制數(shù)的整型表示方式,以十進(jìn)制數(shù)表示出來97。打印結(jié)果為97 和 a。
2.?????? 測試對整型和地址類型轉(zhuǎn)換。add是一個整數(shù)變量,add里是0x12345678的二進(jìn)制數(shù),以十進(jìn)制表現(xiàn)出來,p是一個整型指針變量名,p里面是0x12345678的二進(jìn)制數(shù),以地址的方式表現(xiàn)出來,代表地址0x12345678。*p是通過*去訪問地址0x12345678這個地址處的數(shù)據(jù)(如果你試圖去打印它,會出錯,因為這個地址你不一定有權(quán)限去訪問)。&p是取出整型指針變量p的地址,因為p是一個變量,它也有自己的地址,所以可以取出它的地址來(見上面變量的定義)。
3.?????? 宏定義一個常量PI,PI這個符號代表了3.14,在代碼執(zhí)行前的預(yù)處理階段第二行int a = PI,已經(jīng)被替換為了int a = 3.14,將3.14賦值給整型,會舍棄掉小數(shù)點(diǎn)后面部分結(jié)果,僅保留整數(shù)部分,打印結(jié)果為3。
4.?????? 和上面3一樣,在預(yù)處理階段被替換成了printf(“%d\n”, 3.14),結(jié)果為1374389535,這是因為將浮點(diǎn)型的3.14在內(nèi)存中的數(shù)據(jù),以整型來表現(xiàn)的。
5.?????? 第三行PI = 3.1415926會出錯,PI是個常量其被替換成了3.14 = 3.1415926,3.14是個字面常量,不能被賦值。錯誤信息為“向無效左值賦值出錯”(關(guān)于常見錯誤信息,見C語言常見錯誤詳解章節(jié))。
6.?????? 第三行*str = “goodbye world”出錯,第一行中將字符串常量“hello world”的首地址給了字符指針變量str,第三行試圖將“goodbye world”的首地址,通過*str的訪問方式覆蓋str指向的字符串常量“hello world”。這句話理解起來都比較費(fèi)勁,因為這里有兩個錯誤:
試圖向常量里寫數(shù)據(jù)。
“hello world” 是字符串常量,那么這個字符串空間里的內(nèi)容不能改變。
指針變量里應(yīng)該放地址,字符串都是以首地址為地址。
向一個地址里寫入字符串應(yīng)該使用strcpy。*str只是代表了str指向的字符串中的第一個字符,將字符串地址寫入到一個字符里肯定不行。
關(guān)于上面說的,可能現(xiàn)在還不太好理解,請讀者通讀完C語言指針和數(shù)組之后再來細(xì)品,定會有不同程度的深入理解。
++++++++++++++++++++++++++++++++++++++++++
《C語言深入理解系列?- 常量與變量》
查看其它博文請關(guān)注原創(chuàng)作者。
本文系本站原創(chuàng),歡迎轉(zhuǎn)載! 轉(zhuǎn)載請注明出處:
++++++++++++++++++++++++++++++++++++++++++
總結(jié)
以上是生活随笔為你收集整理的java 变量作用域 c语言_C语言深入理解 - 常量与变量的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 局域网主机扫描_pytho
- 下一篇: 长春学校计算机科学技术学院,长春大学计算