[問題] 指標問題

看板C_and_CPP (C/C++)作者 (我愛阿蓉)時間14年前 (2010/01/29 22:20), 編輯推噓13(13045)
留言58則, 4人參與, 最新討論串5/13 (看更多)
以下是我做的小小測試 不過我故意不寫成繼承 class AA{ public: AA():x(0),a(0){} int x; int a; void FOO(){cout<<"A"<<endl;} }; class BB{ public: BB():y(0.0),b(0.0){} double y; double b; int z; void FOO(){cout<<"B"<<endl;} }; int main() { BB *pb=new BB; AA* p=(AA*)pb; p->x=5; //cout<<int((int)pb->y>>4); char *ptr=(char*)&pb->y; ptr-=4; cout<<(int)*ptr; return 0; } 如果ptr不-4 印的出5 可是我不懂為啥可以印 1. 我覺得要-4阿 小印第安不是 低位元擺在低位址嗎? 另外就是 2. p->FOO()為啥可以正常印出A~~~ 這我觀念比較不好 有辦法解釋為啥這樣可以正確呼叫嗎? 3. 如果我想印出5 而不透過 一個ptr 有辦法直接將pb->y做一些手腳嗎?? 謝謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.24.92.44

01/29 22:51, , 1F
2. FOO() 被轉成 FOO(AA* this) 了吧 所以還是可以call
01/29 22:51, 1F

01/29 23:01, , 2F
ptr-=4; // ptr是指標捏...
01/29 23:01, 2F

01/29 23:02, , 3F
恩對阿 我是想要他移動4byte
01/29 23:02, 3F

01/29 23:06, , 4F
指標 -4 不是移動 4 bytes 哦!去複習指標算數運算吧
01/29 23:06, 4F

01/29 23:10, , 5F
3.cout << (int) *(int*)&(pb->y) ; 滿亂來的...
01/29 23:10, 5F

01/29 23:11, , 6F
他轉成char*剛好4 bytes
01/29 23:11, 6F

01/29 23:16, , 7F
1. 因為pb,p,ptr 這三個的位置是一樣的...
01/29 23:16, 7F

01/29 23:17, , 8F
為啥不是4byte.. char難道不是1b嗎...
01/29 23:17, 8F

01/29 23:17, , 9F
(int)*ptr 的意思就是叫電腦把 *ptr 當 int 看
01/29 23:17, 9F

01/29 23:18, , 10F
所以不管他是big還是little都一樣...
01/29 23:18, 10F

01/29 23:20, , 11F
剛測試過&p->x 跟 &pb->y 是一樣的所以ptr不用移
01/29 23:20, 11F

01/29 23:21, , 12F
差別只有型態
01/29 23:21, 12F

01/29 23:35, , 13F
d大問一下 你3. 為啥不能單純用(int)轉就好?
01/29 23:35, 13F

01/29 23:37, , 14F
而且就算我shift 4 byte 應該可以印出五吧?
01/29 23:37, 14F

01/29 23:38, , 15F
你是想問 為什麼不能用 (int) pb->y 嗎?
01/29 23:38, 15F

01/29 23:39, , 16F
對~
01/29 23:39, 16F

01/29 23:40, , 17F
FOO(AA* this) 不太懂意思耶 call FOO只是看指標型別嗎?
01/29 23:40, 17F

01/29 23:42, , 18F
(int) pb->y 只是把 pb->y 的值(double) 轉成int
01/29 23:42, 18F

01/29 23:43, , 19F
而不是把那塊記憶體當成 int 來讀
01/29 23:43, 19F

01/29 23:44, , 20F
轉不太過來= = 這樣和你先用int*指過去 再取值 再轉型 印出
01/29 23:44, 20F

01/29 23:44, , 21F
有什麼不同 如果你的方法最後(int)不寫 會不能印嗎@@
01/29 23:44, 21F

01/29 23:46, , 22F
哈哈 最左邊的(int) 可以不用寫XD
01/29 23:46, 22F

01/29 23:48, , 23F
觀念我好像有點bug 不過我想問 stack不是 大->小嗎
01/29 23:48, 23F

01/29 23:49, , 24F
=5 這動作 為啥不是在 最後4byte 賦值
01/29 23:49, 24F

01/29 23:49, , 25F
我畫的圖 左邊是小 右邊是大 :)
01/29 23:49, 25F

01/29 23:49, , 26F
我以我才會想-4
01/29 23:49, 26F

01/29 23:50, , 27F
以指標所指的位置為準 指哪就丟哪囉
01/29 23:50, 27F

01/30 00:01, , 28F
....我困惑了 cout<<&pb->y<<endl<<&pb->b<<endl; 為啥是
01/30 00:01, 28F

01/30 00:01, , 29F
小,大 我以為是因為在heap 把pb改成物件 也是印出 小,大
01/30 00:01, 29F

01/30 00:02, , 30F
為啥它配置的 記憶體是小->大呢 不是應該大->小嗎
01/30 00:02, 30F

01/30 00:03, , 31F
物件或是陣列之類的放在stack或heap併不會換順序呀
01/30 00:03, 31F

01/30 00:04, , 32F
會換的話...那 *(ptr+5) 在兩邊的意思不就不同了XD
01/30 00:04, 32F

01/30 00:04, , 33F
我隨便宣告個 int a再int b 印 =>大,小 呀
01/30 00:04, 33F

01/30 00:05, , 34F
區域變數是存在stack裡, 所以才是大到小
01/30 00:05, 34F

01/30 00:05, , 35F
heap是從小配置到大
01/30 00:05, 35F

01/30 00:05, , 36F
那這不算區域嗎~
01/30 00:05, 36F

01/30 00:07, , 37F
不過物件本身的layout會從小到大就是了
01/30 00:07, 37F

01/30 00:08, , 38F
這關係到要從某位置offset取資料成員, 跟d大講的一樣
01/30 00:08, 38F

01/30 00:18, , 39F
那可以呼叫到foo是因為指標是AA型態嗎
01/30 00:18, 39F

01/30 00:23, , 40F
你可以把 void AA::FOO() 想成是 void FOO(AA* this)
01/30 00:23, 40F

01/30 00:24, , 41F
而 p->FOO() 被轉成 FOO(p)
01/30 00:24, 41F

01/30 00:26, , 42F
D大這種 想法是有書上這樣說的嗎 我都沒有這種觀念耶
01/30 00:26, 42F

01/30 00:27, , 43F
我現在正在想您3. 的說法 到底單純用(int) 有什麼不一樣...
01/30 00:27, 43F

01/30 00:27, , 44F
有點轉不過來
01/30 00:27, 44F

01/30 00:28, , 45F
為啥我這樣印出來是0....
01/30 00:28, 45F

01/30 00:30, , 46F
*(int*)&(pb->y) /* 抓前四個byte當 int */
01/30 00:30, 46F

01/30 00:30, , 47F
可以想成 pb->y 以double來看可能是0.幾 我把他的值用int 看
01/30 00:30, 47F

01/30 00:30, , 48F
就變0了?
01/30 00:30, 48F

01/30 00:31, , 49F
Yeah!
01/30 00:31, 49F

01/30 00:32, , 50F
那您說的function這種看法 是有什麼根據嗎!!? 以前沒想那麼多
01/30 00:32, 50F

01/30 00:32, , 51F
應該說是被round掉了吧 忘記是四捨五入還是 floor了...
01/30 00:32, 51F

01/30 00:35, , 52F
好像是以前上課聽到的...?
01/30 00:35, 52F

01/30 00:36, , 53F
忘記好像是compiler是這樣將C++轉成C 然後當成C處理
01/30 00:36, 53F

01/30 00:40, , 54F
不過遇到 virtual function 會比較複雜
01/30 00:40, 54F

01/30 00:41, , 55F
每個class都會存一個成員函數表, 裡面是每個函數的起
01/30 00:41, 55F

01/30 00:42, , 56F
始位置, 當呼叫函數時編譯器就去查表, 這應該書上的
01/30 00:42, 56F

01/30 00:43, , 57F
多型章節會講到, 因為你的指標是AA*, 所以找class AA
01/30 00:43, 57F

01/30 00:44, , 58F
的表
01/30 00:44, 58F
文章代碼(AID): #1BOkwQaE (C_and_CPP)
討論串 (同標題文章)
以下文章回應了本文
完整討論串 (本文為第 5 之 13 篇):
1
1
4
13
5
21
13
58
5
39
1
28
1
9
文章代碼(AID): #1BOkwQaE (C_and_CPP)