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