C_and_CPP 板


LINE

我们先来看一下你定义出来的 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://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1655461848.A.2E7.html ※ 编辑: closer76 (223.137.47.224 台湾), 06/17/2022 18:38:20
1F:推 OnlyRD: 通常这种太特殊的写法,如果没有特殊目的,基本上 06/17 21:32
2F:→ OnlyRD: 都属於设计有问 06/17 21:32
3F:→ OnlyRD: 题的程式,不仅维护困难,容易造成问题,语意也不 06/17 21:32
4F:→ OnlyRD: 清楚。有些程式 06/17 21:32
5F:→ OnlyRD: 为了效能问题,会采用特殊的手法,但是这段程式看 06/17 21:32
6F:→ OnlyRD: 起来效能更差, 06/17 21:32
7F:→ OnlyRD: 记忆体也没省。 06/17 21:32
8F:推 CoNsTaR: 楼上,说实话这真的还好,它当然不是什麽设计多好的程式 06/17 22:32
9F:→ CoNsTaR: ,但真的还算是清楚易懂,很多比这惨十倍以上的程式你还 06/17 22:32
10F:→ CoNsTaR: 不是要捏着小鸟去处理 orz 06/17 22:32
11F:推 OnlyRD: 也是,但我现在做的事情几乎都是from scratch,架 06/19 03:20
12F:→ OnlyRD: 构跟基底我打的 06/19 03:20
13F:→ OnlyRD: ,当然不想折磨别人。 06/19 03:20
14F:推 wulouise: 猜先有MSG_OBJ後有*_USE 然後有地方没改*_USE洞被乱补 06/19 08:27







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:Gossiping站内搜寻

TOP