線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:3154
推到 Plurk!
推到 Facebook!

int & char 問題

尚未結案
syao
初階會員


發表:66
回覆:63
積分:25
註冊:2005-02-02

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-11-21 14:01:11 IP:59.104.xxx.xxx 未訂閱
#include 
#include     int main(int argc, char *argv[])
{        int i[10];        scanf("%s",i);
    printf("%s\n",i);
    
    
    
    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]);        system("PAUSE");
    return 0;    }    
char 是整數 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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-11-21 15:05:56 IP:61.228.xxx.xxx 未訂閱
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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-11-21 21:58:58 IP:211.22.xxx.xxx 未訂閱
引言:
  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的關係.
derrenbol1兄對基本型態,記憶體配置以及memory dump觀念清晰!棒! -----------------------
syao
初階會員


發表:66
回覆:63
積分:25
註冊:2005-02-02

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-11-21 23:09:30 IP:59.104.xxx.xxx 未訂閱
to derrenbol1 謝謝 printf("0xx\n",i[0]); 0xx怎麼解釋沒看過這種格式 printf("%c\n",i[0]&0xff); i[0]&0xff這種格式我也沒看過 &是指位址 方便解釋一下上面兩種格式嗎?? Little Endian Big Endian 記憶體高低位問題嗎??是跟編譯器而有所不同嗎? 謝謝
derrenbol1
中階會員


發表:5
回覆:113
積分:93
註冊:2004-12-09

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-11-22 01:35:37 IP:61.228.xxx.xxx 未訂閱
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)因素.
系統時間:2024-05-11 17:30:37
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!