Re: [問題] 請教指標操作方式

看板C_and_CPP (C/C++)作者 (克樓瑟)時間1年前 (2022/06/17 18:30), 1年前編輯推噓4(4010)
留言14則, 3人參與, 1年前最新討論串2/2 (看更多)
我們先來看一下你定義出來的 struct,在記憶體中長什麼樣。 (假設你的 int 長度也是 16-bit,系統為 little-endian) : typdef struct{ typedef struct{ : int A; int B; : char *data; char userData[8]; : } MSG_OBJ } MSG_OBJ_USE MSG_OBJ MSG_OBJ_USE Address +------------+ +-------------+ x | | | | x+1 | A | | B | +------------+ +-------------+ x+2 | | | userData[0] | x+3 | data | | userData[1] | +------------+ x+4 | userData[2] | x+5 | userData[3] | x+6 | userData[4] | x+7 | userData[5] | x+8 | userData[6] | x+9 | userData[7] | +-------------+ 宣告指標、和宣告陣列,記憶體長得就會不一樣。 然後,我們假設 compiler(實際上是 linker)把你的 globalData[8] 放在 0x9518 這個位置: : char globalData[8] = {0}; Address +---------------+ 0x9518 | globalData[0] | 0x9519 | globalData[1] | : 0x951F | globalData[7] | +---------------+ 然後你的 obj 放在 0x9520: : MSG_OBJ_USE obj; 由於你宣告在 global scope,我們假設整段空間的內容預設都是 0。 : void getDataFun(MSG_OBJ* b) : { : b->data = globalData; : } 接下來這行有些 tricky.... getDataFun() 要接收的是 MSG_OBJ* 但你傳進的去的是 MSG_OBJ_USE* : getDataFun(&obj); 現在大部份的 compiler 會因為 type 不合而發生 error(最少也是 warning), 但如果 compiler 讓你過的話,等於是 「把 0x9520 開始的記憶體空間,當成是 MSG_OBJ 來處理」。 因此,這行執行完後,你的 obj 的內容會變成: MSG_OBJ_USE Address +-------------+ 0x9520 | 0x00 | 0x9521 | 0x00 | +-------------+ 0x9522 | 0x18 | 0x9523 | 0x95 | 0x9524 | 0x00 | 0x9525 | 0x00 | 0x9526 | 0x00 | 0x9527 | 0x00 | 0x9528 | 0x00 | 0x9529 | 0x00 | +-------------+ Why? 因為 getDataFun() 把 0x9520 當成 MSG_OBJ 來處理, 所以就把 globalData 的位址(也就是 0x9518) 填到原本 MSG_OBJ::data 該在的位置(也就是 0x9520+2 & 0x9520+3)。 : char* ptr = (char*)(*(uint16_t*)obj.useData); //平台指標為16 bits 一步一步看: Type Value obj.useData ==> char* 0x9522 (uint16_t*)obj.useData ==> uint16_t* 0x9522 *(uint16_t*)obj.useData ==> uint16_t 0x9518(obj.useData的內容) (char*)*(uint16_t*)obj.useData ==> char* 0x9518 因此 ptr 的內容就是 0x9518,也就是 globalData 的位址。 : //Step.2 : for(int i=0;i<8;i++); : { : obj.useData[i] = ptr[i]; : } 從前面的分析來看,這個 loop 就是把 globalData 的值複製到 obj.userData... 如此而已。 : //問題: : Step1.的動作意思是useData array上面放的值是指標, 所以才可以取值(*)給ptr : 然後用step2把copy資料. : 我的疑問是b->data = globalData應該是把&globalData[0] 指定給b->data而已. 其實我看不懂你的問題。 XD 不過希望前面的分析能幫到你的忙。 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 223.137.47.224 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1655461848.A.2E7.html ※ 編輯: closer76 (223.137.47.224 臺灣), 06/17/2022 18:38:20

06/17 21:32, 1年前 , 1F
通常這種太特殊的寫法,如果沒有特殊目的,基本上
06/17 21:32, 1F

06/17 21:32, 1年前 , 2F
都屬於設計有問
06/17 21:32, 2F

06/17 21:32, 1年前 , 3F
題的程式,不僅維護困難,容易造成問題,語意也不
06/17 21:32, 3F

06/17 21:32, 1年前 , 4F
清楚。有些程式
06/17 21:32, 4F

06/17 21:32, 1年前 , 5F
為了效能問題,會採用特殊的手法,但是這段程式看
06/17 21:32, 5F

06/17 21:32, 1年前 , 6F
起來效能更差,
06/17 21:32, 6F

06/17 21:32, 1年前 , 7F
記憶體也沒省。
06/17 21:32, 7F

06/17 22:32, 1年前 , 8F
樓上,說實話這真的還好,它當然不是什麼設計多好的程式
06/17 22:32, 8F

06/17 22:32, 1年前 , 9F
,但真的還算是清楚易懂,很多比這慘十倍以上的程式你還
06/17 22:32, 9F

06/17 22:32, 1年前 , 10F
不是要捏著小鳥去處理 orz
06/17 22:32, 10F

06/19 03:20, 1年前 , 11F
也是,但我現在做的事情幾乎都是from scratch,架
06/19 03:20, 11F

06/19 03:20, 1年前 , 12F
構跟基底我打的
06/19 03:20, 12F

06/19 03:20, 1年前 , 13F
,當然不想折磨別人。
06/19 03:20, 13F

06/19 08:27, 1年前 , 14F
猜先有MSG_OBJ後有*_USE 然後有地方沒改*_USE洞被亂補
06/19 08:27, 14F
文章代碼(AID): #1Yh5VOBd (C_and_CPP)
文章代碼(AID): #1Yh5VOBd (C_and_CPP)