看板 Programming
作者 標題 [轉錄][C++] Call by Value
時間 2010年03月08日 Mon. AM 12:56:45
※ 本文轉錄自 Knuckles_note 看板
看板 Knuckles_note
作者 標題 [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
推 :順帶一提 我從以前聽到的都是 Call by Pointer耶.....雖然Call by Address也差不多阿>>134.208.3.175 03-06 20:50
推 :未看先推教學文>>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 累積人氣: 1206
( ̄︶ ̄)b iloveyouever, ATI, unshing, ken888686 說讚!
※
ott
轉錄至看板 ott 時間:2010-03-12 04:27:29
※
uefangsmith
轉錄至看板 uefacool 時間:2010-03-26 00:44:51
※
iloveyouever
轉錄至看板 my_time_my_heart 時間:2010-08-01 19:46:31
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
有試過直接複製,可是沒顏色,而且有些排版會跑掉。一頁一頁的話,背景都黑的,印的效果不知道好不好。
11樓 時間: 2010-08-30 00:55:32 (台灣)
→
08-30 00:55 TW
以前可是被call by value、reference、pointer、address、name..搞混, 看了好久,才搞懂這些名詞。有些根本就莫名其妙...。
14樓 時間: 2010-08-30 10:38:56 (台灣)
→
08-30 10:38 TW
建議用Fx,IE的話(我用PCMAN)示意圖排版會跑掉。接下來試試看反白的效果怎麼樣, 印全黑的感覺很耗墨。剪圖的話,缺點就是不能編輯文字了...。
回列表(←)
分享