C語言數組和指針的剖析

              數組和指針的剖析   
   
 
    指針到底是什麼呢。指針其實可以比作相當於一個寄存器,我們暫且可以這樣理解。因爲一個寄存器中一般存放的都是一個4字節的內存地址。所以我們的指針同樣也是存放的一個內存地址。我們其實在訪問指針就是間接的訪問內存地址。 轉爲彙編中相當於 dowrd  ptr [指針] 。這樣訪問的就是指針地址中存儲的數據。   
   
  很多人說指針和數組時相同的,因爲他們認爲 例如。   
   
  char *string = "hello world";   
   
    他們通過string [0] 就可以訪問到字符’h’。其實這時存在一個間接的作用。這裏我們假設string的內存地址時 00405128。例如這裏我們通printf("%c", string[0])。 那麼此時程序則會將 dword ptr [string+1]  壓入堆棧。 不過因爲堆棧一般是通過寄存器操作的所以 mov eax ,dword ptr [string+1] 。因爲一般我們彙編中要進行訪問內存中的數據的時候,數據地址需要加上 []。 例如 mov eax, 3 和 mov eax, [3] 。顯然不同,前者是將立即數3傳遞到eax寄存器中。後者是將地址3中開始的32位值 傳遞給eax寄存器。因爲一般我們寫彙編程序時候用的是[]。其實彙編代碼默認爲 dword ptr []。   
 
  上面說了這麼多,我想你應該明白指針的作用了吧。訪問指針實質是訪問指針地址中存放的32位數值的地址中的數據。   
 
所以大家這裏千萬不要認爲,既然我們平常可以用初始化一個字符串指針。例如   
  char *string = "hello world";   
  那麼就可以通過strcpy等函數操作。   
  例如strcpy(string, ’"test")。   
  這裏是錯誤的。爲何? 因爲我們之前的hello world是存在於數據段的。載入內存後此片區域是不可寫的。只有只讀的權限。所以此時操作就會報錯。   
   
  數組就不同了。數組本身就是代表的一個地址。   
  例如char string [] = {"hello world"};   
  string 本身就是代表的一個地址。 那麼此時訪問的就是string的內存地址。而不像指針,還需要取得指針中存放的32位地址值。   
  例如 通過printf("%c",string[1]); 那麼此時訪問的就是直接將 string + 1壓入堆棧 。當然這裏我只是簡單的一個表達,實際上因爲我們的函數都是通過堆棧分配內存空間的,這裏會取得我們string 在堆棧中的值從而進行對他訪問。   
  char string[] = {"hello world"};   
  Strcpy(string, "test");   
  爲何可以訪問?   
因爲我們在聲明string數組後是通過堆棧分配內存的。String 此時就存在於堆棧中。因爲我們都知道數組是以連續的內存空間。所以string地址中存放的就是hello world 。因爲我們是存在於代碼區,所以擁有可寫權限,從而可以進行寫操作。   
 
  這裏在舉一些很要緊的例子。例如   
  char *string;   
  Scanf("%s", string); //錯誤,因爲我們的string指針在堆棧中分配內存,因爲此時string地址中存放的是堆棧隨即分配的ASCII數值,所以此時在進行scanf從緩衝區取得輸入字符串並保存到相應的內存地址就會錯誤。因爲這個string 指針中的內存地址是堆棧隨即分配ASCII數值的。根本就定位不到內存空間。所以就會報錯。   

                                                                                                                  
 希望此篇文章能給大家帶來一些幫助,有什麼不對的也請多多指正。謝謝。   
                                                                  
 
                                                                   作者:xyblack      
                                                                   郵箱:[email protected] 


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章