顯示廣告
隱藏 ✕
看板 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
※ 編輯: Knuckles  來自: 118.166.112.30  時間: 2010-04-28 13:10:22
※ 編輯: Knuckles  來自: 118.166.112.30  時間: 2010-04-28 13:15:07
※ 編輯: Knuckles 時間: 2015-10-19 07:14:59
※ 看板: KnucklesNote 文章推薦值: 5 目前人氣: 0 累積人氣: 16300 
※ 文章分類: 程式設計 C/C++
分享網址: 複製 已複製
( ̄︶ ̄)b mailtea, tails 說讚!
1樓 時間: 2010-03-06 20:46:22 (台灣)
  03-06 20:46 TW
未看先推 "疑似學過C語言,可是一直搞不懂指標的人"
2樓 時間: 2010-03-06 20:50:34 (台灣)
  03-06 20:50 TW
順帶一提 我從以前聽到的都是 Call by Pointer耶.....雖然Call by Address也差不多阿
3樓 時間: 2010-03-06 21:46:38 (台灣)
  03-06 21:46 TW
未看先推教學文
Knuckles 轉錄至看板 programming 時間:2010-03-08 00:56:45
4樓 時間: 2010-05-04 00:06:08 來自: 118.160.67.172 (台灣)
  05-04 00:06 TW
123
5樓 時間: 2010-05-06 13:00:15 來自: 163.14.2.17 (台灣)
  05-06 13:00 TW
淺顯易懂 太酷了!!!
terrykyo 轉錄至看板 terrykyo 時間:2011-04-04 01:58:22
6樓 時間: 2011-12-04 12:05:26 (台灣)
  12-04 12:05 TW
寫得好讚
TL 轉錄至看板 TL (使用複製) 時間:2012-12-08 19:45:16
r)回覆 e)編輯 d)刪除 M)收藏 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇