int & char 問題 |
尚未結案
|
syao
初階會員 發表:66 回覆:63 積分:25 註冊:2005-02-02 發送簡訊給我 |
#includechar 是整數 0~255 int 也是整數 int i[10]; // char i[10]; 但下面輸出字元並不是輸入字串的字元 printf("%c\n",i[0]); printf("%c\n",i[1]); printf("%c\n",i[2]); printf("%c\n",i[3]); printf("%c\n",i[4]); 謝謝 |
derrenbol1
中階會員 發表:5 回覆:113 積分:93 註冊:2004-12-09 發送簡訊給我 |
To syao: 小弟認為只要騙得過編譯器, 且Warnning Code不會影響程式
運作的話, 那你要怎麼寫都可以; 像你這樣的試法, 我想看到的
人都會指出只要將i改成字元型別的陣列, 結果就會對, 但若你
將printf該段的程式改成:
printf("%c\n",i[0]&0xff); //第一個輸入的字元 printf("%c\n",(i[0]>>8)&0xff); //第二個輸入的字元 printf("%c\n",(i[0]>>16)&0xff); printf("%c\n",(i[0]>>24)&0xff); printf("%c\n",i[1]&0xff); ... ...假設你輸入的字串為"12345"的話, 照你原本的程式應該只有印出 1及5就沒了(後面的i[2],i[3]..可能為非顯示字元); 改過的部份主 要是要告訴你, 你宣告的i, 從你的觀點會是"10個整數空間", 然而 對於scanf而言, 它卻是"10*4個位元組的連續記憶體區塊", 當scanf 處理你從Keyboard輸入的字元時, 是從你所給的記憶體區塊起始位置 一個Byte, 一個Byte地連續放到該區塊內, 直到你輸入Enter為止; 隨後你的程式中, 你輸入給printf的變數, 是以"一個整數"來提取, 而你的格式化字串卻是%c, 這造成printf對於你輸入的參數認為只有 一個Byte有效, 事實上你卻是輸入4個位元組長度的變數(假設你用的 編譯器對int型別將編譯成4個位元組); 再者你若加入一行 printf("0xx\n",i[0]);於你的程式中, 那麼輸出會是0x34333231, 剛好就是"4321", 倒過來 的原因則是因為Little Endian的關係. 請參考. |
Stallion
版主 發表:52 回覆:1600 積分:1995 註冊:2004-09-15 發送簡訊給我 |
引言:derrenbol1兄對基本型態,記憶體配置以及memory dump觀念清晰!棒! -----------------------printf("%c\n",i[0]&0xff); //第一個輸入的字元 printf("%c\n",(i[0]>>8)&0xff); //第二個輸入的字元 printf("%c\n",(i[0]>>16)&0xff); printf("%c\n",(i[0]>>24)&0xff); printf("%c\n",i[1]&0xff); ... ...假設你輸入的字串為"12345"的話, 照你原本的程式應該只有印出 1及5就沒了(後面的i[2],i[3]..可能為非顯示字元); 改過的部份主 要是要告訴你, 你宣告的i, 從你的觀點會是"10個整數空間", 然而 對於scanf而言, 它卻是"10*4個位元組的連續記憶體區塊", 當scanf 處理你從Keyboard輸入的字元時, 是從你所給的記憶體區塊起始位置 一個Byte, 一個Byte地連續放到該區塊內, 直到你輸入Enter為止; 隨後你的程式中, 你輸入給printf的變數, 是以"一個整數"來提取, 而你的格式化字串卻是%c, 這造成printf對於你輸入的參數認為只有 一個Byte有效, 事實上你卻是輸入4個位元組長度的變數(假設你用的 編譯器對int型別將編譯成4個位元組); 再者你若加入一行printf("0xx\n",i[0]);於你的程式中, 那麼輸出會是0x34333231, 剛好就是"4321", 倒過來 的原因則是因為Little Endian的關係. |
syao
初階會員 發表:66 回覆:63 積分:25 註冊:2005-02-02 發送簡訊給我 |
|
derrenbol1
中階會員 發表:5 回覆:113 積分:93 註冊:2004-12-09 發送簡訊給我 |
To Stallion:
謝謝您的誇獎. 小弟本業是做Soc的, 三不五時都會呈
現在無OS下進行程式開發, 所以記憶體規劃都得自己來. class="code">
printf("%x\n",'1'); // 這樣會印出"31"
// 字元1的HEX CODE = 0x31
printf("%8x\n",'1'); // 這樣印出"31"
printf("x\n",'1'); // 這樣印出"00000031"
// 跟上一行的比較則是會自動以'0'字元
// 並補齊8個字元
// 另外還可以加負號
printf("%-8x\n", '1'); // 這樣印出" 31", 往右對齊
百分比的表示式在一般的C語言書籍中皆有說明. 2. &符號只有在變數前面才是位置運算子, 其餘的地方, 它會被當成
"Logic AND"運算; 這個被拿來做"遮罩(Mask)"用, 設計者希望的
是從某個變數中"保留"某些位元, 例如:
int i = 20, j, k; // i = 20 = 0x14 j = i & 0x2; // j = (0x14 AND 0x2) = 0 k = i & 0x4; // k = (0x14 AND 0x4) = 4若依我所寫的修改程式中, 其實i[0]做不做Mask是無關的, 因為 printf函數的程式碼, 以你輸入的格式化字串為準, 但位移是一 定要的而已. 3. Big Endian與Little Endian是硬體平台(CPU)存取實體記憶體時 , 資料該怎麼"擺". 假設一筆在實體記憶體內部的資料如下: Address(Byte) 00H 01H 02H 03H Value 01H 22H 33H 44H倘若你的CPU是Big Endian, 且你以int型別指標從00H讀取的話, 你的變數讀到的值為0x01223344, 而Little Endian的CPU則是 0x44332201. 用字元型別對連續記憶體區塊作存取時, 是不須要 考慮Byte Sex(即Big Endian與Little Endian)因素. |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |