c語言 語句塊內 變量
a指向b所對應的內存地址,這個地址總是存在的,所以出了代碼塊后,還能用*a的方法來得到這個地址里面所存的數值,但是這樣作是不正確的,因為當出了代碼塊后,b所對應的那塊內存地址就無效了,這塊內存可能被其他代碼所使用,你的a就變成傳說中的野指針了,*a的值就變得不可預測了,在實際的程序中,你這樣的代碼就有可能造成程序崩潰等嚴重問題。
為了說明這一點,看一下我下面的例子:
#include <stdio.h>
int main()
{
int *a;
{
int b[100] = {8, 0};
a = b;
}
printf("%d\n", *a);
{
int c[100] = {100, 99,0};
}
printf("%d\n", *a);
return 0;
}
你會發現*a的值在變,就是由于我前面說的"野指針"所導致的。
c語言 語句塊內 變量
a指向b所對應的內存地址,這個地址總是存在的,所以出了代碼塊后,還能用*a的方法來得到這個地址里面所存的數值,但是這樣作是不正確的,因為當出了代碼塊后,b所對應的那塊內存地址就無效了,這塊內存可能被其他代碼所使用,你的a就變成傳說中的野指針了,*a的值就變得不可預測了,在實際的程序中,你這樣的代碼就有可能造成程序崩潰等嚴重問題。
為了說明這一點,看一下我下面的例子:#include
C語言 語句塊外部的變量默認存儲類型 語句塊外部那一行 那如果這樣
register 是寄存器變量。從硬件的角度來說,就是說用的是CPU的內部寄存器,而不是內存。呃~~是這樣的,變量存在的地方從物理的角度上有2兩個。從使用角度上來說有4個。物理上就是CPU的內部寄存器和內存,從CPU的硬件來說,比如說加法器。只能使用自己的內部寄存器。所以,比如i++這條指令。如果你使用的是寄存器變量,在編譯后 就會變成 大概 :
ADD R4, 1, R4 //R4= R4 +1 自增 R4就是i變量
這樣一條~
然而如果是在內存里就要
LDR R4, =i_ADDRESS //從內存地址中載入數值進寄存器
ADD R4, 1, R4 //R4 = R4 + 1 自增
STR R4, =i_ADDRESS //將R4中的數據再寫回原來的地址里
這就是差別,如果你循環個幾千幾百次 差距就出來了。
然后,是從編程的意義上來說,變量的地方:寄存器變量,代碼區,堆,和棧~
函數的參數,一定會是寄存器變量。當然太多了寄存器不夠了那就只能是內存變量了。通常就是R0 R1 R2 R3對應函數的前四個參數。然后就是你顯式聲明的,就是那個關鍵字。然后就是靠編譯器優化。所以你聲明多了也沒啥用,寄存器數量有限~
代碼區,就是說在編譯期就確定要存在的!就是全局變量和static 靜態變量,不管你有沒有賦初始化值,這些內存和代碼一起在編譯時就已經確定了。然后是堆棧,通常來說堆和棧是兩個東西。一句話說,你的局部變量會在調用函數時在堆上生成!就是說,你在調用第一函數時會在堆棧上為這個函數中的變量分配內存,如果你在第一函數里調用第二函數,那么就會在堆上緊接著的內存繼續分配內存,這個時候,稱第一函數的變量內存被壓棧~當退出第二函數時,這些內存被釋放~說白了就是堆指針移動回原來的地方了。
棧是操作系統按一定格式化格式后的內存,malloc()函數申請的匿名內存都是從這來的~我見過有的實時操作系統用的是鏈表~申請內存的過程就是從鏈表中移出節點。釋放內存的過程就是向鏈表中插入節點~呃,具體的不說了,太多了~~~