iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 11
0

call by value(傳值),大家很常用。原理就是把值給指定的function使用
但大家有沒有想過這個做法會佔用較多的記憶體位址
我們馬上來看看程式

int fun(int D, int E, int F){
   printf("fun:%d\n",&D);
   printf("fun:%d\n",&E);
   printf("fun:%d\n",&F);
}

int main(){
   int A=0;
   int B=0;
   int C=0;
   printf("main:%d\n",&A);
   printf("main:%d\n",&B);
   printf("main:%d\n",&C);
   fun(A, B, C);
return 0; 
} 

1)主程式先宣告A,B,C三個變數,並輸出其位址(10進位)
2)再把A,B,C三個變數的值,傳給fun中的D,E,F三個變數,再輸出其位址(10進位)
https://ithelp.ithome.com.tw/upload/images/20171226/20107818SuXpotMEtO.png

我們可以看到:主程式中三個變數的位址,互相相差4位元
但在fun中的三個變數,其位址卻相差8位元
也許這現象只是發生在function中,所以我們也來實驗一下

=====================分格線=====================

這一次用call by reference

int fun(int &D, int &E, int &F){
   printf("fun:%d\n",&D);
   printf("fun:%d\n",&E);
   printf("fun:%d\n",&F);
}

int main(){
   int A;
   int B;
   int C;
   printf("main:%d\n",&A);
   printf("main:%d\n",&B);
   printf("main:%d\n",&C);
   fun(A, B, C); 
} 

https://ithelp.ithome.com.tw/upload/images/20171226/20107818JsIeVn8SzV.png
這一次,不論是在main 或是 function中輸出位址,均相差4
理論與結果看似合理
但大家不要忘記,call by reference就是傳參考,所以不論是main變數的位址或是值,都會跟function變數的位址或是值是一樣
所以這個測試方式不準確。
簡單說:D,E,F是A,B,C的複製人,兩者所儲存的位址均一樣
=====================分格線=====================

那我們只好分別獨自宣告

int fun(){
   int D;
   int E;
   int F;
   printf("fun:%d\n",&D);
   printf("fun:%d\n",&E);
   printf("fun:%d\n",&F);
}

int main(){
   int A;
   int B;
   int C;
   printf("main:%d\n",&A);
   printf("main:%d\n",&B);
   printf("main:%d\n",&C);
   fun(); 
} 

https://ithelp.ithome.com.tw/upload/images/20171226/20107818JWKOuCWb0k.png
這function中獨自宣告,再輸出位址
我們看到三個function中變數的位址,均相差4位元
所以,我們可以推論function宣告變數,其實並不會增加記憶體佔用位置。

=====================分格線=====================

兩種call by,也用了,最後一個call by address

int fun(int *D, int *E, int *F){
   printf("fun:%d\n",&D);
   printf("fun:%d\n",&E);
   printf("fun:%d\n",&F);
}

int main(){
   int A;
   int B;
   int C;
   printf("main:%d\n",&A);
   printf("main:%d\n",&B);
   printf("main:%d\n",&C);
   fun(&A, &B, &C); 
} 

https://ithelp.ithome.com.tw/upload/images/20171226/20107818KeO9VNzsdN.png
1)分別把A,B,C變數的位址,傳給D,E,F變數儲存
2)再分別印出各變數
因為D,E,F所佔用的位址是自己原來的位址,只是儲存的值是A,B,C的位址
所以我們可以看到call by address的方式,在function中變數的位址也是相差8位元

=====================推論=====================

我猜測call by addresscall by value這兩種傳資料的方式,除了需要佔用自己的位址外,還需要佔用目標的位址,因此需要佔用8位元。
而在function中宣告call by reference,前者只需要佔用自己的位址,後者則直接把值與地址傅去使用,因為不需要記載目標的位址,所以只需要用基本的4位元即可。

=====================心得=====================
我是沒想到連call by三兄弟對於記憶體的容量也有差異
所以我們日後再節省記憶體空間,除了可以修改資料型態外,可以盡量減少使用call by addresscall by value


上一篇
[影像處理系列] 排序統計濾波器[2]
下一篇
輕談:struct結構是多此一項嗎?[1]入門
系列文
提神?看程式比喝咖啡更有效。30

尚未有邦友留言

立即登入留言