[問題] char* = " "字串宣告的問題

看板C_and_CPP (C/C++)作者 (popokaka)時間12年前 (2013/12/22 00:39), 編輯推噓5(5032)
留言37則, 7人參與, 最新討論串1/1
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) GCC 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) no 問題(Question): 今天看到前幾篇有關於char* test = "ABCD"的問題 剛好跟朋友討論到字串 我一直以為char* test = "ABCDEFGHIJK"; 是宣告一個指像字串的指標test 然後test內容存放一個位置 該位置指向某個記憶體位置 然後那個位置後面依序放著"ABCD..." 不過寫code下去看結果好像不是如此 感覺code推出的結果比較像是char* 這格放了"ABCDE"這個內容 更可怕的是int*一樣也能放字串 在用%s印出來(雖然不會有人這樣寫 最後就是我原本對C語言指標的理解整個崩壞了.. 以下附上我實驗的code能不能請板友解釋char* test = "ABCD"這行指令 compiler到底會對他做什麼事情0.0? 程式碼(Code):(請善用置底文網頁, 記得排版) http://ideone.com/ADbsbD 補充說明(Supplement): 大一還修了一整年的C語言 現在真是各種羞愧... -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.43.154.14

12/22 00:41, , 1F
等號是把右邊的東西丟給左邊
12/22 00:41, 1F

12/22 00:42, , 2F
就我自己的解讀:系統找一塊唯讀的記憶體區段,然後把
12/22 00:42, 2F

12/22 00:43, , 3F
"ABCD"放進去,然後再將'A'那個byte的記憶體位置指派給
12/22 00:43, 3F

12/22 00:43, , 4F
test
12/22 00:43, 4F
我原本也是這樣理解的所以一開始還寫printf("%s\n",*test); 結果會core dumped 改成printf("%s\n",test);反而能正常輸出ABCD ※ 編輯: krauserq 來自: 114.43.154.14 (12/22 00:46)

12/22 00:47, , 5F
char指標一次吃1byte int指標一次吃4byte
12/22 00:47, 5F

12/22 00:49, , 6F
*test 是char啊,對於%s是不正確的型態啊
12/22 00:49, 6F

12/22 00:49, , 7F
我現在比較好奇int *test = "ABCD"的 *test的數值到底@@
12/22 00:49, 7F
先謝謝t大 printf的部分是我犯蠢了 不過int*那部份我也是無法接受 ※ 編輯: krauserq 來自: 114.43.154.14 (12/22 00:51)

12/22 00:57, , 8F
正在問其他大神有甚麼書寫到這些XD
12/22 00:57, 8F

12/22 01:02, , 9F
據說是因為little endian order 理解中
12/22 01:02, 9F

12/22 01:45, , 10F
重點是位址阿 幾乎可以說int*或char*只是寫給你看的
12/22 01:45, 10F

12/22 01:45, , 11F
讓你知道你指到的是什麼東西
12/22 01:45, 11F

12/22 01:46, , 12F
今天你高興你當然可以用int*去接一個字串的位置
12/22 01:46, 12F

12/22 01:47, , 13F
只是編譯器會給你警告而已
12/22 01:47, 13F

12/22 01:49, , 14F
endianness是指超過1byte東西在記憶體裡擺放的順序
12/22 01:49, 14F

12/22 01:54, , 15F
如果有一個int a = 0x1234ABCD
12/22 01:54, 15F

12/22 01:55, , 16F
big endian會先放前面的位數
12/22 01:55, 16F

12/22 01:56, , 17F
在記憶體裡面照位址順序是 0x12, 0x34, 0xAB, 0xCD
12/22 01:56, 17F

12/22 01:56, , 18F
little endian反過來 先放小的 0xCD, 0xAB, 0x34, 0x12
12/22 01:56, 18F

12/22 01:57, , 19F
如果int *test = "ABCD" 對test指向位址當作int取值的話
12/22 01:57, 19F

12/22 01:58, , 20F
big endian會得到 ('A'<<24)|('B'<<16)|('C'<<8)|('D')
12/22 01:58, 20F

12/22 01:59, , 21F
little endian會得到 ('D'<<24)|('C'<<16)|('B'<<8)|('A')
12/22 01:59, 21F

12/22 01:59, , 22F
簡單來講是這樣
12/22 01:59, 22F

12/22 11:43, , 23F
..你的問題跟endian沒有關係
12/22 11:43, 23F

12/22 11:45, , 24F
指標只是指示一個位置 要如何操作* 要看這個*是什麼型態
12/22 11:45, 24F

12/22 11:46, , 25F
宣告同時初使化的常數 資料是放在連續的記憶體空間上
12/22 11:46, 25F

12/22 11:48, , 26F
stdout要怎麼去顯示要看 pfintf中的設定得格式為何 以及
12/22 11:48, 26F

12/22 11:49, , 27F
他從記憶體上 從哪個位置為首 抓了多長的資料出來
12/22 11:49, 27F

12/22 11:49, , 28F
最後就是你看到的東西
12/22 11:49, 28F

12/22 12:18, , 29F
就存到initialized data segment 的唯讀區而已
12/22 12:18, 29F

12/22 12:21, , 30F
基本上對指標來講,就是4byte的空間,不管你用什麼型態
12/22 12:21, 30F

12/22 12:21, , 31F
宣告都一樣。所以不同型態都能承接這個位置
12/22 12:21, 31F

12/22 12:22, , 32F
只是最後要使用的時候,就要轉成對的型態讓他能解出來
12/22 12:22, 32F

12/22 14:21, , 33F
@clarkman: 這麼說不全然正確. 很久以前這裡已經戰過了..
12/22 14:21, 33F

12/22 14:21, , 34F
不同型態的指標沒有這麼單純
12/22 14:21, 34F

12/22 14:22, , 35F
這裡的問題在於對 printf 作用的認知錯誤
12/22 14:22, 35F

12/22 14:49, , 36F
指標轉型當時大戰了超久XD
12/22 14:49, 36F

12/22 18:02, , 37F
那我去觀摩一樣~~增長見識了
12/22 18:02, 37F
文章代碼(AID): #1IjSGq4D (C_and_CPP)
文章代碼(AID): #1IjSGq4D (C_and_CPP)