1樓:「已登出」
列印不出來是因為這條語句將嘗試訪問非法(程式不該訪問)的記憶體。
printf
("%s",*
pt);
//嘗試訪問超出劃定範圍的記憶體空間,被作業系統攔下
答主重現了一下,那麼從下圖可以看出,p和pt的位址是0x00affb6c,"abc"的首位址是0x00de6b30
那麼解引用pt得到的是0x00de6b30,對不對?
*pt即是對0036fba0的解除引用,取其中的值就是00125858,為什麼列印不出 abc啊!
這句話看似沒有問題,然而忽略了:pt的型別是char*,那麼請大聲告訴我解引用pt得到的型別是什麼~
回音:char!!!
實際上解引用後,題主以為值應該是0x00de6b30,實際上只有處於低位的0x30被採用,剩下的高位部分全部被忽略,這是因為char的大小只有乙個位元組。
那麼,在會炸的語句中,位址並不是0x00de6b30,而是0x00000030
那麼此時作業系統認為題主的程式在試圖檢視位址0x00000030的內容(對其解引用),這個位址不在作業系統允許的範圍內,結果就是Visual Studio丟擲異常。
要正常列印也可以,把pt的型別強制轉換成char**即可。或者按照 @朱涵俊的答案進行一次強制轉換。
話說為什麼題主說**pt可以,在MSVC和Clang下都編譯不過去……
2樓:邵飛
換成**pt,就可列印出來abc 假設p的位址為1 內容就是為abc的首位址
pt的位址為2,*pt=p 就是*pt為1pt的內容為1*pt=1 只能得到p的位址得不到p的內容,也就是abc的首位址因為*p=abc的首位址,*pt=p
所以*(*pt)=abc的首位址
也就是說*pt找到的是p的記憶體位址
沒能找到p的內容,p的內容才是abc的首位址
3樓:楊詩偉
我來回答!!!
指標是C語言最強大的特性,沒有之一,它可以帶你去任何地方。
當然,如何使用不慎,也會走火入魔。
題主的程式等效於以下:
char* s1 = "abc";
char* s2 = "def";
char* s3 = "ghi";
char* p[3] = ;
char* pt = p;
(雖然規範寫法是*和變數在一起,但是我更喜歡把它和型別在一起,這樣讓我看起來更舒服)
char* pt = p;這一句,等效於char* pt = &s1;
當陣列變數名用作指標值時,它等於陣列的首位址,也即第乙個元素的位址。
*pt,實際上等於*&s1 = s1,也即"abc"的位址。
回答完畢。
4樓:朱涵俊
指標的指標不等於指標陣列。
pt是字串指標,*pt是字元,你把字元當做字串來列印,當然會異常。
printf(」%s」,*(char**)p2),這樣就可以正常列印了,如果直接*p2,是個字元,即乙個位元組大小,這樣只會傳入p位址的低8位。
printf(「%s」,*(long*)p2);這樣也可以列印,有的編譯器會警告。題主就差乙個型別轉換。
5樓:BinaryTree
其實很簡單,你忘記了陣列變數名其實也是乙個指標。
在你的程式裡
char *p[3]=;//這裡的p其實相當於 char **pchar *pt = p;//你將二重指標的賦給了乙個一重指標現在*pt解除引用,其實他的值是p[0]的位址。所以你用%s輸出就「炸了」//我也不知道你說的炸了什麼意思。
至於你說的另外
char *p1="yes";//這是乙個一重指標char *p2=&p1;//你將一重指標的位址賦給了乙個一重指標,這個p2實際上是乙個二重指標
所以*p2又「炸了」
所以記住,字串不是乙個型別,是乙個字元陣列,訪問到'\0'結束。
在C語言中,二級指標有什麼用處?
比較明顯的乙個作用,就是減少函式傳參,不然還需要傳乙個 index,來指示函式呼叫後的記憶體偏移量,傳 進去,函式呼叫後,你的指標就自動指向偏移後的位址了。 Belleve 指標的陣列,尤其是指向 struct 的指標的陣列,比如 typedef struct Record typedef stru...
C語言指標最多有多少級?
03c84f62d 只要你的記憶體足夠,指標可以無限套娃。具體操作 省略main函式 size t MAX COUNT 1024 int num 1 void point for size t i 0 i MAX COUNT i point void point 指標級數多到一定地步的時候就已經不再...
C語言指標 二維陣列,為啥會這樣?
沒明白你不理解的點在哪,我猜是單純糾結於為什麼要寫成0 COLS 0而不直接寫0。答案是直接寫0也可以,其實是為了統一下格式,就是乘號,結果上和直接寫0沒區別。int a 0 COLS 0 int a 1 COLS 2 int a 3 COLS 2 統一成這種格式而已。沒啥講究的,還是 指標 破數字...