指標陣列加總 題解
指標陣列加總 題解
簡潔題意
實作 void sum(int *arr[]);。arr 的每一格存著一個 int 的位置,最後一格是 NULL 表示資料結束。請把所有被指到的整數加起來並輸出總和。這一題要自己 cout,不是回傳。
int *arr[] 是什麼
前兩題的參數都是「一個 int 的位置」。這一題的 arr 多了一層:它是一個陣列,每一格存的都是一個 int 的位置(11.2 的延伸知識段落)。
所以要分清楚兩件事:
arr[i]:第 \(i\) 格存的門牌號碼。*arr[i]:照那個號碼走過去,取出住在那裡的數字。
要加總的是後者。
走到哪裡才停
題目沒有給你 n,而是在最後一格放了 NULL——「不指向任何東西」的空指標。這種用一個特殊值標記結尾的做法叫哨兵,迴圈條件就寫成「還沒碰到哨兵就繼續」:
for (int i = 0; arr[i] != NULL; i++)
arr[i] 是位置,拿它跟 NULL 比是在問「這格還有資料嗎」;千萬不要拿 *arr[i] 去比 0,那是在問「這格的數字是不是 \(0\)」,完全是另一件事。
累加要用 long long
題目保證的是最後的總和放得進 int,中途的累加值沒有保證。每次呼叫最多 \(10^4\) 個數字、每個絕對值最多 \(10^6\),中途完全可能先衝到 \(10^{10}\) 再被負數拉回來——那已經超過 int 的範圍(上冊 2.9)。用 long long 累加就沒這個問題。
若這次呼叫有 \(n\) 個非空指標,時間複雜度 \(O(n)\)。
參考程式碼
#include <iostream>
using namespace std;
void sum(int *arr[]) {
long long total = 0;
for (int i = 0; arr[i] != NULL; i++) { // 走到空指標就停
total += *arr[i]; // arr[i] 是位置,*arr[i] 才是數字
}
cout << total;
}
常犯錯誤
- 把
arr[i]加進總和:那是位置不是數字,型態就不合,編譯直接失敗:invalid conversion from ‘int*’ to ‘long long int’。 - 數指標個數:迴圈走法是對的,但加的是
1不是*arr[i]。範例 1 印出5,正解是15。 - 條件寫成
*arr[i] != 0:資料裡真的可以出現 \(0\),一遇到就提早停。範例 2 第一筆是-3 0 7 -2,會印出-3,正解是2。 - 條件寫成
arr[i + 1] != NULL:這樣最後一個有效資料永遠加不到。範例 1 印出12,剛好少了最後的3。
接下來
前三題的指標都只是站在原地。指標反轉陣列 會讓兩個指標各站一端往中間走——那裡會用到指標的最後一個動作:互相比大小。