回覆列表
  • 1 # 使用者79390703623

    修改:原來有“p=name[i]其實和p = name + i沒有任何區別”一句,是不對的,name[i]是陣列,其中name可以作為只讀指標來看待,那麼應該是*p = *(name + i)。name[i]相當於對指標這問題提的真好,理解這個問題了以後,對C語言指標的概念也就掌握了,而C語言最重要的就是指標。題主這重點抓的真到位,可謂綱舉目張,擒賊擒王。p是一個變數,那麼想怎麼給它賦值,就可以怎麼給它賦值,但是C語言是強型別語言,如果賦值型別不匹配就會報錯,如果賦值型別雖然不匹配但是可以預設轉換,那麼編譯可以透過但是會給警告。比如可以這樣做:p = 0;p = 1;都沒問題,因為p是一個指標,數字型別可以賦值給指標,但是給它賦值是什麼含義?含義不對,即使編譯透過,執行也會報錯的。在第一個檔案裡存在一個錯誤是i沒有初始化,必須初始化為0或者1或者什麼數字,不然一定會出錯,下面的討論假設初始化為1:在第一個檔案裡面,p是一個變數,這個變數的型別是指標,這個指標所指向的是“字串指標”。那麼既然是變數,就可以讀和寫,所以可以賦值;由於是強型別,所以只要是指標型別或者能轉換成指標型別的就可以賦值;由於它是一個指向”字串指標“的指標,所以給它賦值的時候,如果所賦值物件型別不是指向”字串指標“,一般編譯器都會提示一下的。name也是一個變數,這個變數的型別也是指標,這個指標所指向的是”字串陣列“。在C語言裡面,陣列其實就是指標,但是是常量,不能寫,只能讀,所以name這個變數可以讀可以寫,但是它指向的記憶體因為是常量陣列所以只能讀不能寫,除此以外name和p沒有任何區別。因此,name + i是指標加法,name + i還是一個指標,指向字串陣列,只不過所指內容和name不一樣,是name的”下一個“,所以p = name +i 屬於兩個同類型指標賦值,沒有任何問題;p=name[i]和p = name + i是不一樣的,name定義為一個數組,name[i]是取陣列的第i個元素,相當於*(name + i)。(感謝 @單車戀人 指正)但是這個賦值還是會成功的,因為p是指向字元指標的指標,本質還是一個指標,name是一個字元指標的陣列,取出的第i個元素是一個字元指標,賦值可以成功,但是型別不一樣(字元指標的指標和字元指標)。p=*name+i 性質就變了,就是把name所指向的內容加1,然後賦值給p,name作為一個指標指向的是 字串陣列,還好字串陣列也是指標(指標與陣列在C語言裡面都按照指標處理),所以賦值可以成功,但是會給出編譯警告,因為畢竟他們不是相同型別,p是指向指標的指標,賦值內容是陣列,相當於指標。*p=name+i 在這裡name + i和前面的分析一樣,它和p是相同型別,是指標的指標;而*p是一個指標了,這時候要把它賦給*p還是指標之間的賦值,編譯可以透過,但是指標型別不同,也會給出編譯警告。這裡要注意,p是一個變數沒問題,但是*p能不能賦值取決於p指向的空間,如果p指向一塊可讀不可寫的記憶體,程式執行到這裡會執行時退出;如果p指向一塊可寫的記憶體而且有足夠的空間,那麼就沒問題。抱歉第二個檔案就不這樣詳細分析了,沒想到這麼長太累了,不過思路是類似的。寫了段程式碼供參考,用的是64位Linnux下Gcc編譯器,所以列印指標的時候轉換成long型別,如果是32位轉換成int型別,這裡p指向的是一塊不可寫記憶體,所以在*p = name + i那裡會執行時報錯:

  • 中秋節和大豐收的關聯?
  • 石榴不用農藥真長不成嗎?