顯示廣告
隱藏 ✕
看板 Programming
作者 Knuckles(阿德)
標題 [轉錄][C++] Call by Value
時間 2010年03月08日 Mon. AM 12:56:45


※ 本文轉錄自 Knuckles_note 看板

看板 Knuckles_note
作者 Knuckles(阿德)
標題 [C++] Call by Value
時間 2010年03月06日 Sat. PM 06:36:44


來試試利用投影片功能來講解這個東西

本文主要在講: 副程式的用法、傳值、傳址、傳參考

誰適合閱讀: 剛開始接觸C語言的新手、
            疑似學過C語言,可是一直搞不懂指標的人

^L 前言

一開始學C語言時,大家最害怕的就是指標(pointer)
其實指標的定義也沒什麼難懂的,不容易搞懂的應該是他的用法
也就是function的傳值(Call by Value)傳址(Call by Address)傳參考(Call by Reference)

不過其實在國外根本沒有 Call by Address 這個說法
是台灣的某本教學書自創的,然後就一堆人沿用下來
正確的說法應該是"傳指標的值" Call by Value of Pointer
至於為什麼,下一篇就會講到了

這一篇先從 Call by Value 開始講起

^L Call by Value

先來了解一下 Call by Value 是什麼,以及他有什麼不好的

先舉個簡單的程式當例子...

^L Call by Value

#include <iostream>
using namespace std;



int main()
{
	
int a=3,b=4,c;
	
c = max(a,b); // 這邊我想用一個自訂的副程式 max 來計算 a 與 b 的最大值,並存進 c
	
cout << c << endl; // 顯示出 c 的值

	
return 0;
}


^L Call by Value

#include <iostream>
using namespace std;

int max(int,int); // 副程式使用前要先宣告,我要傳入兩個整數,傳出一個整數

int main()
{
	
int a=3,b=4,c;
	
c = max(a,b);
	
cout << c << endl;

	
return 0;
}

^L Call by Value

#include <iostream>
using namespace std;

int max(int,int);

int main()
{
	
int a=3,b=4,c;
	
c = max(a,b);
	
cout << c << endl;

	
return 0;
}

int max(int a, int b) // 開始定義這個副程式
{
	
int c;
	
if(a > b) c = a; // 如果 a 比較大,將 a 的值存進 c
	
else      c = b  // 不然的話,     將 b 的值存進 c
	
return c; // 傳出 c 的值
}


^L Call by Value

#include <iostream>
using namespace std;

int max(int,int);

int main()
	
	
	
	
在這個程式中
{
	
int a=3,b=4,c;
	
	
	
我們會發現主程式 main() 中有 a b c 三個變數
	
c = max(a,b);
	
cout << c << endl;

	
return 0;
}

int max(int a, int b)
	
	
	
副程式 max() 中也有 a b c 三個變數
{
	
int c;
	
if(a > b) c = a;
	
else      c = b 
	
return c;
}

^L Call by Value

#include <iostream>
using namespace std;

int max(int,int);
	
	
	
這邊要注意的就是

int main()
	
	
	
	
main()的a,b,c 與 max()的a,b,c 是不一樣的東西!!
{
	
int a=3,b=4,c;
	
c = max(a,b);
	
cout << c << endl;

	
return 0;
}

int max(int a, int b)
{
	
int c;
	
if(a > b) c = a;
	
else      c = b  
	
return c;
}

^L Call by Value

#include <iostream>
using namespace std;

int max(int,int);
	
	
	
用記憶體的示意圖來說,當程式還未執行前,記憶體長這樣:
	
	
	
	
	

int main()
	
	
	
	
main()的變數:
{
	
int a=3,b=4,c;
	
	
	
a  3
	
c = max(a,b);
	
	
	
b  4
	
cout << c << endl;
	
	
c       (←空著代表不知道是多少)

	
return 0;
}

int max(int a, int b)
	
	
	
max()的變數:
{
	
int c;
	
	
	
	
a    
	
if(a > b) c = a;
	
	
b    
	
else      c = b  
	
	
c    
	
return c;
}

^L Call by Value

#include <iostream>
using namespace std;

int max(int,int);
	
	
	
當執行到 c = max(a,b); 這行時,記憶體長這樣:
	
	
	
	
	

int main()
	
	
	
	
main()的變數:
{
	
int a=3,b=4,c;
	
	
	
a  3  ─────┐傳出 3
	
c = max(a,b);
	
	
	
b  4  ─────┼───┐傳出 4
	
cout << c << endl;
	
	
c               │
	

	
	
	
	
	
	
	
	

	
return 0;
	
	
	
	
	
	

}
	
	
	
	
	
	
	
	

	
     
	
	
	
	
	
	
	

int max(int a, int b)
	
	
	
max()的變數:
	
	

{
	
	
	
	
	
	
	
	

	
int c;
	
	
	
	
a  3  ←────┘
	

	
if(a > b) c = a;
	
	
b  4  ←────────┘
	
else      c = b  
	
	
c    
	
return c;
}

^L Call by Value

#include <iostream>
using namespace std;

int max(int,int);
	
	
	
當執行到 c = max(a,b); 這行時,記憶體長這樣:
	
	
	
	
	

int main()
	
	
	
	
main()的變數:
{
	
int a=3,b=4,c;
	
	
	
a  3  ─────┐傳出 3
	
c = max(a,b);
	
	
	
b  4  ─────┼───┐傳出 4
	
cout << c << endl;
	
	
c               │
	

	
	
	
	
	
	
	
	
	
因為呼叫副程式時
	
return 0;
	
	
	
	
	
	
	
只有把變數的傳過去而已
}
	
	
	
	
	
	
	
	
	
所以叫 Call by Value
	
     
	
	
	
	
	
	
	

int max(int a, int b)
	
	
	
max()的變數:
	
	

{
	
	
	
	
	
	
	
	

	
int c;
	
	
	
	
a  3  ←────┘
	

	
if(a > b) c = a;
	
	
b  4  ←────────┘
	
else      c = b  
	
	
c    
	
return c;
}

^L Call by Value

#include <iostream>
using namespace std;

int max(int,int);
	
	
	

	
	
	
	
	

int main()
	
	
	
	
main()的變數:
{
	
int a=3,b=4,c;
	
	
	
a  3  
	
c = max(a,b);
	
	
	
b  4  
	
cout << c << endl;
	
	
c     
	
	
	
	
	
	
	

	
return 0;
	
	
	
	
	

}
	
	
3     4
	

	
     
	
    ↙
	
這裡可以看成是 int a = 3; int b = 4;

int max(int a, int b)
	
	
	
max()的變數:
	

{
	
	
	
	
	
	
	

	
int c;
	
	
	
	
a  3  
	
if(a > b) c = a;
	
	
b  4  
	
else      c = b  
	
	
c    
	
return c;
}

^L Call by Value

#include <iostream>
using namespace std;

int max(int,int);
	
	
	
接著跳進副程式,執行到 return c; 時,記憶體長這樣:
	
	
	
	
	

int main()
	
	
	
	
main()的變數:
{
	
int a=3,b=4,c;
	
	
	
a  3  
	
c = max(a,b); 
	
	
	
b  4  
	
cout << c << endl;
	
	
c  4  ←────┐
	
	
	
	
	
	
	

	
return 0;
	
	
	
	
	

}
	
	
	
	
	
	
	

	
     
	
	
	
	
	
	

int max(int a, int b)
	
	
	
max()的變數:
	

{
	
	
	
	
	
	
	

	
int c;
	
	
	
	
a  3  
	
	

	
if(a > b) c = a;
	
	
b  4  
	
	

	
else      c = b  
	
	
c  4  ─────┘傳出 4
	
return c; 
}

^L Call by Value

#include <iostream>
using namespace std;

int max(int,int);
	
	
	
最後將 c 顯示出來,我們就會得到 4 這個值
	
	
	
	
	

int main()
	
	
	
	
main()的變數:
{
	
int a=3,b=4,c;
	
	
	
a  3  
	
c = max(a,b);
	
	
	
b  4  
	
cout << c << endl;
	
	
c  4  
	
	
	
	
	
	
	

	
return 0;
	
	
	
	
	

}
	
	
	
	
	
	
	

	
     
	
	
	
	
	
	

int max(int a, int b)
	
	
	
max()的變數:
	

{
	
	
	
	
	
	
	

	
int c;
	
	
	
	
a     ↖
	
if(a > b) c = a;
	
	
b     ← 副程式結束後,變數就消滅了
	
else      c = b  
	
	
c     ↙
	
return c;
}

^L Call by Value

#include <iostream>
using namespace std;

int max(int,int);
	
	
	
由於main()的a,b,c 與 max()的a,b,c 是不一樣的東西

int main()
	
	
	
	
所以如果怕混淆,在 max()中的 a,b,c 也可以換個名字
{
	
int a=3,b=4,c;
	
c = max(a,b);
	
cout << c << endl;

	
return 0;
}

int max(int a, int b)
{
	
int c;
	
if(a > b) c = a;
	
else      c = b  
	
return c;
}

^L Call by Value

#include <iostream>
using namespace std;

int max(int,int);
	
	
	
由於main()的a,b,c 與 max()的a,b,c 是不一樣的東西

int main()
	
	
	
	
所以如果怕混淆,在 max()中的 a,b,c 也可以換個名字
{
	
int a=3,b=4,c;
	
c = max(a,b);
	
cout << c << endl;

	
return 0;
}

int max(int x, int y)
	
	
	
像這樣,把 a,b,c 改成 x,y,z 執行結果是一模一樣的
{
	
int z;
	
if(x > y) z = x;
	
else      z = y 
	
return z;
}

^L Call by Value

Call by Value 聽起來很簡單,為什麼不用這個就好了呢?

我們再來看下個例子:

^L Call by Value

#include <iostream>
using namespace std;

void swap(int,int);
	
	
	


int main()
	
	
	
	
這邊寫了一個副程式 swap();
{
	
int a=3,b=4;
	
	
	
希望執行後可以將 a 與 b 的值互換
	
swap(a,b);
	
cout << "a=" << a
	
     << ",b=" << b << endl;
	
可是執行的結果是: a=3,b=4

	
return 0;
	
	
	
a,b 的值並沒有互換,為什麼呢?
}

void swap(int a, int b)
{
	
int c = a;
	
a = b;
	
b = c;
}

^L Call by Value

#include <iostream>
using namespace std;

void swap(int,int);
	
	
	
開始 Debug,當執行到 swap(a,b); 時

int main()
	
	
	
	
main()的變數:
{
	
int a=3,b=4;
	
	
	
a  3  ─────┐傳出 3
	
swap(a,b);
	
	
	
b  4  ─────┼───┐傳出 4
	
cout << "a=" << a
	
	
	
        │
	

	
     << ",b=" << b << endl;
	
	
	
	

	
	
	
	
	
	
	
	

	
return 0;
	
	
	
	
	
	

}
	
	
	
	
	
	
	
	

	
     
	
	
	
	
	
	
	

void swap(int a, int b)
	
	
	
swap()的變數:
	
	

{
	
	
	
	
	
	
	
	

	
int c = a;
	
	
	
a  3  ←────┘
	

	
a = b;
	
	
 
	
	
b  4  ←────────┘
	
b = c;  
	
	
	
c    
}

^L Call by Value

#include <iostream>
using namespace std;

void swap(int,int);
	
	
	
進入副程式 swap() 執行完 b = c; 時:

int main()
	
	
	
	
main()的變數:
{
	
int a=3,b=4;
	
	
	
a  3  
	
swap(a,b);
	
	
	
b  4  
	
cout << "a=" << a
	
	

	
     << ",b=" << b << endl;
	
	
	

	
	
	
	
	
	
	

	
return 0;
	
	
	
	
	

}
	
	
	
	
	
	
	

	
     
	
	
	
	
	
	

void swap(int a, int b)
	
	
	
swap()的變數:
	

{
	
	
	
	
	
	
	

	
int c = a;
	
	
	
a  4  ←┐a和b的確是交換了呀
	
a = b;
	
	
 
	
	
b  3  ←┘
	
b = c; 
	
	
	
c  3
}

^L Call by Value

#include <iostream>
using namespace std;

void swap(int,int);
	
	
	
回到 main() 將 a 和 b 的值顯示出來:

int main()
	
	
	
	
main()的變數:
{
	
int a=3,b=4;
	
	
	
a  3  
	
swap(a,b);
	
	
	
b  4  
	
cout << "a=" << a 
	
	

	
     << ",b=" << b << endl;
	
顯示結果為: a=3,b=4
	
	

	
	
	
	
	
	
	

	
return 0;
	
	
	
	
	

}
	
	
	
	
	
	
	

	
     
	
	
	
	
	
	

void swap(int a, int b)
	
	
	
swap()的變數:
	

{
	
	
	
	
	
	
	

	
int c = a;
	
	
	
a     ↖
	
a = b;
	
	
 
	
	
b     ← 副程式結束後,變數就消滅了
	
b = c;  
	
	
	
c     ↙
}

^L Call by Value

#include <iostream>
using namespace std;

void swap(int,int);
	
	
	
所以我們現在知道了

int main()
	
	
	
	
因為 swap() 執行完沒有回傳結果
{
	
int a=3,b=4;
	
	
	
所以 swap() 中的 a, b 交換後的值,就隨著 swap() 的結束而消失了
	
swap(a,b);
	
	
	

	
cout << "a=" << a
	
	
而在 main() 中的 a, b 還是原本沒有交換過的值
	
     << ",b=" << b << endl;
	
	

	
	
	
	
	
	
	

	
return 0;
	
	
	
	
	

}
	
	
	
	
	
	
	

	
     
	
	
	
	
	
	

void swap(int a, int b)
	
	
	

{
	
	
	
	
	
	
	

	
int c = a;
	
	
	

	
a = b;
	
	
 
	
	

	
b = c;  
	
	
	

}

^L Call by Value

#include <iostream>
using namespace std;

void swap(int,int);
	
	
	
那就在 swap() 中將結果回傳啊?

int main()
	
	
	
	
可是C語言的function就只能回傳一個值,要怎麼傳咧?
{
	
int a=3,b=4;
	
	
	

	
swap(a,b);
	
	
	

	
cout << "a=" << a
	
	

	
     << ",b=" << b << endl;
	
	

	
	
	
	
	
	
	

	
return 0;
	
	
	
	
	

}
	
	
	
	
	
	
	

	
     
	
	
	
	
	
	

void swap(int a, int b)
	
	
	

{
	
	
	
	
	
	
	

	
int c = a;
	
	
	

	
a = b;
	
	
 
	
	

	
b = c;  
	
	
	

}

^L Call by Value

#include <iostream>
using namespace std;

void swap(int,int);
	
	
	
要是可以在 swap() 中修改 main()裡 a,b 的值就好了

int main()
	
	
	
	
沒錯!的確是可以,這就是為什麼要有指標的原因
{
	
int a=3,b=4;
	
	
	
請繼續看下一篇 Call by Address (Call by Pointer)
	
swap(a,b);
	
	
	

	
cout << "a=" << a
	
     << ",b=" << b << endl;
	
	

	
	
	
	
	
	
	

	
return 0;
	
	
	
	
	

}
	
	
	
	
	
	
	

	
     
	
	
	
	
	
	

void swap(int a, int b)
	
	
	

{
	
	
	
	
	
	
	

	
int c = a;
	
	
	

	
a = b;
	
	
 
	
	

	
b = c;  
	
	
	

}


--
※ 來源: DISP BBS (http://disp.twbbs.org)
※ 作者: Knuckles  來自: 114.45.56.117  時間: 2010-03-06 18:36:44
※ 編輯: Knuckles  來自: 114.45.56.117  時間: 2010-03-06 18:57:41
※ 編輯: Knuckles  來自: 114.45.56.117  時間: 2010-03-06 19:43:40
※ 編輯: Knuckles  來自: 118.168.102.236  時間: 2010-03-07 15:35:58推 abc1231qa:未看先推 "疑似學過C語言,可是一直搞不懂指標的人">>134.208.3.175 03-06 20:46
abc1231qa:順帶一提 我從以前聽到的都是 Call by Pointer耶.....雖然Call by Address也差不多阿>>134.208.3.175 03-06 20:50
sakuku:未看先推教學文>>59.121.42.223 03-06 21:46

--
※ 來源: DISP BBS (http://disp.twbbs.org)
※ 作者: Knuckles  來自: 118.168.102.236  時間: 2010-03-08 00:56:45
※ 看板: Programming 文章推薦值: 8 目前人氣: 0 累積人氣: 1201 
分享網址: 複製 已複製
( ̄︶ ̄)b iloveyouever, ATI, unshing, ken888686 說讚!
1樓 時間: 2010-03-12 04:27:07 (台灣)
  03-12 04:27 TW
 借轉  想學學 這個 power  point 該怎麼做
ott 轉錄至看板 ott 時間:2010-03-12 04:27:29
uefangsmith 轉錄至看板 uefacool 時間:2010-03-26 00:44:51
2樓 時間: 2010-08-01 13:57:47 (台灣)
  08-01 13:57 TW
編輯好多次!推用心良苦
3樓 時間: 2010-08-01 14:10:32 (台灣)
  08-01 14:10 TW
對阿 我居然都忘記要M起來了
iloveyouever 轉錄至看板 my_time_my_heart 時間:2010-08-01 19:46:31
4樓 時間: 2010-08-29 23:59:29 (台灣)
  08-29 23:59 TW
請問有辦法把這文章複製到WORD裡嗎?想要印出來看,寫得很好呀!
5樓 時間: 2010-08-30 00:44:05 (台灣)
  08-30 00:44 TW
我個人只想到了土砲的方法 1.利用回覆文章取得原始文字檔 然後自己編輯
                         2.一頁一頁printscreen 然後印出來
                         3.丟站長水球
6樓 時間: 2010-08-30 00:47:54 (台灣)
  08-30 00:47 TW
有試過直接複製,可是沒顏色,而且有些排版會跑掉。一頁一頁的話,背景都黑的,印的效果不知道好不好。
7樓 時間: 2010-08-30 00:49:57 (台灣)
  08-30 00:49 TW
這幾篇的呈現方式是個重點,也因為如此,所以很容易理解。
8樓 時間: 2010-08-30 00:50:04 (台灣)
  08-30 00:50 TW
果然還是丟站長水球最快XD
9樓 時間: 2010-08-30 00:50:46 (台灣)
  08-30 00:50 TW
市面上的書,如果有像這樣解說的,我一定買呀。
10樓 時間: 2010-08-30 00:51:43 (台灣)
  08-30 00:51 TW
如果有rss輸出的話,不知道效果好不好..。
11樓 時間: 2010-08-30 00:55:32 (台灣)
  08-30 00:55 TW
以前可是被call by value、reference、pointer、address、name..搞混,
看了好久,才搞懂這些名詞。有些根本就莫名其妙...。
12樓 時間: 2010-08-30 00:56:57 (台灣)
  08-30 00:56 TW
做成power point好像比較原汁原味,看來只能試試丟水球了。
13樓 時間: 2010-08-30 10:35:41 (台灣)
  08-30 10:35 TW
用最土炮的方法了,用F11全螢幕,再用截圖軟體一頁頁剪下來。
14樓 時間: 2010-08-30 10:38:56 (台灣)
  08-30 10:38 TW
建議用Fx,IE的話(我用PCMAN)示意圖排版會跑掉。接下來試試看反白的效果怎麼樣,
印全黑的感覺很耗墨。剪圖的話,缺點就是不能編輯文字了...。
15樓 時間: 2010-08-30 18:26:02 (台灣)
  08-30 18:26 TW
對吼 用貼圖的 在用小畫家反白就好啦
r)回覆 e)編輯 d)刪除 M)收藏 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇