2010年2月19日 星期五

找問題~

昨天的問題似乎讓我感到很有興趣


早上來的時候,觀察看看有什麼不同之處,以方便找出問題


 


利用指標結構進副程式,指標結構出副程式,可以看到在執行副程式時,roll和pitch的address已經有問題了,不知道為何address不正確!


*_att 是0x8BA


*_att->roll._ 的address 竟然是0x000?


*_att->pitch._ 的address 竟然是0x004?



在宣告struct ATTITUDE *_btt;


似乎出了問題*_btt的address竟然是0x000,也難怪送進副程式的address會有問題@@


難道在主程式內不能這樣宣告嗎?還是我什麼沒有注意到?



利用結構進副程式,指標結構出副程式,可以看到在執行副程式時,roll和pitch的address是正確的,因為是float的關系,所以相差4的address。


*_att 是0x8BA


*_att->roll._ 的address 是0x89C


*_att->pitch._ 的address 是0x8A0



因為_dtt .roll._的address 在0x89c


因為_dtt .pitch._的address 在0x8a0


所以是合理的



找到問題了,但是我還是不知道為什麼會這樣@@


還需要再研究看看!
怎麼開始覺得熱血了,是因為天氣變暖了嗎?


5 則留言:

  1. 宣告指標只有門牌,你沒有給實體。所以指標內容不會給值,必須設定才會有。
    之前是宣告結構,所以會給結構的實體。
    不過將結構當參數傳,會將整個資料複製進函式內,堆疊用掉一堆。
    傳出也會產生資料複製,對執行效率確實不好。
    不過您已傳入結構指標,就可以直接修改它,也不必傳回了。

    [版主回覆02/21/2010 06:36:56]講到堆罍,怎麼觀看堆疊?
    因為用得很習慣,是軟體做好了
    我一直對堆疊很疑惑
    要如何觀察?
    另外可的話,是否可以講堆積?
    謝謝

    回覆刪除
  2. 這樣改就可以用了
    int main(void){
    struct ATTITUDE data,*_btt;
    float k;
    _bbt = & data;

    get_attitude_from_accel( _btt,1,2,3);
    k=_btt->pitch._;
    k=_btt->roll._;
    return 0;
    }


    [版主回覆02/21/2010 06:39:34]原來如此
    那我又有問題了
    既然結構就可以傳值進副程式,為何還要宣告一個結構指標?
    還是因為這樣只是為了後續的程式的可讀性?
    謝謝

    回覆刪除
  3. 使用指標
    對於結構來說,大型結構要工作,若不是使用指標的話。就需要複製整個結構資料給函式,運算完成再將結果整個複製回原來位址。
    這個程序常常沒有效率,因為只是修改其中一小部分,卻要整個搬來搬去。
    使用指標,只是拿個門牌,然後函式是到人家家裏去工作,所以不用搬來搬去。
    就是因為指標是門牌,所以宣告出來要使用前一定要先指定位址,才會知道去那裡工作。
    這是指標方便,但又危險的地方,因為給錯位址,跑錯地方也是照做,會破壞其它資料。所以更高階的語言都不使用指標,改用參考(Reference)來做。
    要了解指標,我想到一本入門書"指標的藝術"。我的部落格有它的照片及資料。
    指標的藝術,讀後感

    回覆刪除
  4. C語言使用堆疊。主要是在節省記憶體並使用在區域變數(函式內部宣告)上。
    看過組合語言,可以知道call指令會產生一個返回位址在堆疊(stack)上,並跳到新的函式去工作。而ret指令則是從堆疊取回返回位址跳回來。
    C語言也做一樣的動作,但它進入新函式第一件事是取得區域變數(local variable)的記憶體。為了確定可以在返回時一併回收區域變數記憶體,所以它使用堆疊(stack)做為區域變數。
    在X86上區域變數記憶體和返回位址是靠在一起的,只要返回前將CPU中的stack pointer調回呼叫的樣子,再執行ret,那前一個函式根本不會發現動到記憶體。
    所以C語言多層呼叫後,可以看到堆疊上面除了各函式返回位址外,每個返回位址中間都夾著各函式所用的區域變數。
    另外C語言的呼叫參數也是利用堆疊傳送,因為它在返回時也是要丟棄。它也可以當區域變數用。可以試試這個函式,它可以工作。
    int Increase(int x)
    {
        x++; return x;
    }
    不過,回傳值通常不利用堆疊傳送,會使用暫存器。除非回傳的資料很多,例如使用結構時,才會使用堆疊回傳。

    回覆刪除
  5. 發現您還真是早起啊!
    [版主回覆02/21/2010 16:10:26]不一定ㄟ,其實我的起床時間是和前一晚睡覺有關系
    愈早睡就愈早起
    這陣子可能沒什麼事吧
    所以也比較早休息
    早上起床做事頭腦比較清楚
    到了下午就開始效率變很差了

    回覆刪除