# APCS 題目講解 106/03/04 第20題
- 全域變數
- 區域變數
- 自訂函數
---
## code
```cpp=
int g1 = 30, g2 = 20;
int f1(int v) {
int g1 = 10;
return g1+v;
}
int f2(int v) {
int c = g2;
v = v+c+g1;
g1 = 10;
c = 40;
return v;
}
int main() {
g2 = 0;
g2 = f1(g2);
printf("%d", f2(f2(g2)));
return 0;
}
```
---
## 初始變數狀態:
1. 在全域時宣告$g1=30,g2=20$
2. 程式會先跑$main()$主函式,在$main()$主函式中會將$g2$設成$0$,因為g2是全域變數,因此$g2$會被改成$0$。
:::warning
此時在$main()$函式中更改的是g2的全域變數。
:::
3. 接著程式會呼叫函式,而呼叫函式之後會將此函式的回傳值賦值給$g2$
```cpp
g2 = f1(g2);
```
因此這邊會將$g2$的值傳進$f1()$
---
## $f1()$ $function$ 變數狀態
```cpp
int f1(int v) {
int g1 = 10;
return g1+v;
}
```
1. 首先傳進來的值會是$g2$的$0$,因此這邊的區域變數v將會是$0$。
2. 這邊會在$f1()$中宣告一個區域變數$g1$
:::warning
注意:這邊的$g1$是屬於$f1()$的區域變數,不會動到全域變數的$g1$因此全域變數的$g1$仍然是$30$,如果怕會混淆的話可以將區域變數中的$g1$想成$g1^{\prime}$。
:::
3. 最後程式會回傳$g1+v$,相當於回傳$10$。
---
## 1.回到$main()$函式
1. 還記得剛剛在$main()$函式呼叫的狀況吧
```cpp
g2 = f1(g2);
```
因此這邊的$g2$會接到$f1(g2)$的回傳值$10$
:::warning
這邊更改的$g2$是全域變數的$g2$,因此全域變數的$g2$會是$10$
:::
----
## 2.回到$main()$函式
2. 接著我們要將結果$print$出來,但在$printf()$中會再次呼叫函式$f2(f2(g2))$,這邊會將$g2$丟進去$f2()$裡,也就是傳$10$進入$f2()$,而$f2(g2)$的回傳值會再次傳給$f2()$,最後其回傳值會交給$printf()$函式進行$print$。
---
## 1. $f2()$ $function$ 變數狀態
1. 我們將$g2$傳進來,並將此值賦值給$v$,此時$v$就是$10$
2. 接著下一行程式會將$g2$賦值給$c$,此時$c$就是$10$
3. 這一行code會做一段運算
```cpp
v = v+c+g1;
```
相等於,
```
v = 10+10+30;
```
因為目前都沒改到$g1$,所以$g1$還是$30$,因此此時$v$會變成$50$
----
## 2. $f2()$ $function$ 變數狀態
4. 而下一行code就真的會動到全域變數的$g1$,因此全域變數的$g1$就會變成$10$,但在$c = 40$只會改到區域變數的$c$,因此沒有大礙。
5. 最後我們回傳$v$,就完成此次函式呼叫。
----
## 3. $f2()$ $function$ 變數狀態
1. 記得嗎?我們的code還會再次呼叫$f2()$
```cpp
f2(f2(g2))
```
動作和前幾張投影片一樣,只是變數有改而已
2. 我們將剛剛的回傳值$50$傳進來,並將此值賦值給$v$,此時$v$就是$50$
3. 接著下一行程式會將$g2$賦值給$c$,此時$c$就是$10$
----
## 4. $f2()$ $function$ 變數狀態
5. 這一行code會做一段運算
```cpp
v = v+c+g1;
```
:::warning
我們在上一次函式呼叫更改過了$g1$的全域變數,因此這邊的$g1$是$10$,要特別注意!
:::
所以這邊的運算會是
```
v = 50+10+10;
```
所以$v$就會是$70$
----
## 5. $f2()$ $function$ 變數狀態
最後會更改$g1$和$c$但我們之後不會再用到了,所以不管它,最後我們$return$ $70$再$print$出來就完成這一題了!
---
## 回顧
這題運用到全域變數和區域變數的概念,還有函式的應用,整體說起來不會太難,仔細讀題應該就可以答對了。
##### by 中和高中 吳振榮
{"metaMigratedAt":"2023-06-17T01:29:16.237Z","metaMigratedFrom":"YAML","title":"APCS 題目講解 106/03/04 第20題","breaks":true,"contributors":"[{\"id\":\"616555cd-54b9-4bba-98c9-ddf2c0a6bbc6\",\"add\":2488,\"del\":309}]"}