【不是惡夢的開始,而是再度的精進。陣列名稱可以視為一個位址】
陣列名稱可以視為一個位址,因此當我們要將陣列傳給函數的時候,或許會選擇使用指標的方式傳給函數,以避免陣列的內容必須一個一個複製,尤其複製大陣列是非常沒有效率的。
例:
#include <iostream>
using namespace std;
double average(double* arr, int count); // 以傳址的方式處理
int main()
{
double value[] = {1,2,3,4,5,6,7,8,9,10};
cout << "value 位址為 : " << value << "\n\n";
cout << "平均為: "
<< average(value, sizeof value / sizeof value[0])
<< "\n\n";
return 0;
}
double average(double* arr, int count)
{
cout << "arr 位址為 : " << arr << "\n\n";
double sum = 0;
for(int i = 0; i < count; i++)
sum += *arr++; //依址取值
return sum / count;
}
執行結果:
value 位址為: 0x70fdc0
arr 位址為 : 0x70fdc0
平均為: 5.5
確實把value的位址 0x70fdc0 傳給函數
也正因為陣列名稱可以視為一個位址,所以當我們將陣列當作引數傳給函數,也只是複製陣列位址並傳給呼叫的函數,並不是把整個陣列內的值複製給函數,事實上陣列不能以值傳遞,也就是說並不會把陣列內容一筆一筆複製過去。
例:
#include <iostream>
using namespace std;
double average(double arr[], int count);
int main()
{
double value[] = {1,2,3,4,5,6,7,8,9,10};
cout << "value 位址為 : " << value << "\n\n";
cout << "平均為: "
<< average(value, sizeof value / sizeof value[0]) //第一個引數並不是value[]
<< "\n\n"; // 若用value[]會編譯錯誤
return 0;
}
double average(double arr[], int count)
{
cout << "arr 位址為 : " << arr << "\n\n";
double sum = 0;
for(int i = 0; i < count; i++)
sum += arr[i];
return sum / count;
}
執行結果:
value 位址為 : 0x70fdc0
arr 位址為 : 0x70fdc0
平均為: 5.5
事實證明把value的位址 0x70fdc0 複製傳給函數
雖然並不是以指標的方式傳址,卻也同樣的把位址傳過去了,因此函數add()就可以修改main()函數內的陣列值了,並不像變數以值傳遞時無法修改到原函數main()內變數的狀態了。
例:
#include <iostream>
using namespace std;
double average(double arr[], int count);
void print(double arr[], int count);
void add(double arr[], int count);
int main()
{
double value[] = {1,2,3,4,5,6,7,8,9,10};
cout << "value 位址為 : " << value << "\n\n";
cout << "平均為: "
<< average(value, sizeof value / sizeof value[0])
<< "\n\n";
cout << "原始 value 值 : ";
print(value, sizeof value / sizeof value[0]);
cout << "\n\n";
add(value, sizeof value / sizeof value[0]);
cout << "原始 value 值已被更改 : ";
print(value, sizeof value / sizeof value[0]); // 再印一次陣列value的值
cout << "\n\n";
cout << "平均為: "
<< average(value, sizeof value / sizeof value[0])
<< "\n\n";
return 0;
}
void add(double arr[], int count)
{
cout << "增值3 : ";
for(int i = 0; i < count; i++)
{ arr[i] += 3 ;
cout << arr[i] << " ";
}
cout << "\n\n";
return;
}
void print(double arr[], int count)
{
for(int i = 0; i < count; i++)
cout << arr[i] << " ";
cout << "\n\n";
return;
}
double average(double arr[], int count)
{
cout << "arr 位址為 : " << arr << "\n\n";
double sum = 0;
for(int i = 0; i < count; i++)
sum += *arr++;
return sum / count;
}
執行結果:
value 位址為 : 0x70fdc0
arr 位址為 : 0x70fdc0
平均為: 5.5
原始 value 值 : 1 2 3 4 5 6 7 8 9 10
增值3 : 4 5 6 7 8 9 10 11 12 13
原始 value 值已被更改 : 4 5 6 7 8 9 10 11 12 13
arr 位址為 : 0x70fdc0
平均為: 8.5
對於二維陣列,第一維度的大小不是型態定義的一部份,因此我們可以省略第一維的大小。雖然函數也需要知道第一維度的大小,因此我們可採用與一維陣列相同的方法,加入第二個參數以指定(計算)陣列第一維度的大小 :
double value[][4] = {
{1,2,3,4},
{5,6,7,8},
{9,10,11,12}
};
除非你希望表示你的函數只能處理固定大小的陣列,才需要標示第一維的大小。
例:
#include <iostream>
using namespace std;
double sum(double arr[][4], int n);
int main()
{
double value[][4] = {
{1,2,3,4},
{5,6,7,8},
{9,10,11,12}
};
cout << "sizeof value = " << sizeof value << "\n";
cout << "sizeof value[0] = " << sizeof value[0] << "\n\n";
cout << "\n" << "總數等於 : " << sum(value, sizeof value / sizeof value[0])
// sizeof value / sizeof value[0] 求第一維大小
<< "\n\n";
return 0;
}
double sum(double arr[][4], int count)
{
double total = 0;
cout << "count = " << count << "\n\n";
for(int i = 0; i < count; i++)
for(int j = 0; j < 4; j++)
total += arr[i][j]; // 指標寫法 total += *(*(arr + i) + j);
return total;
}
執行結果:
sizeof value = 96
sizeof value[0] = 32
count = 3
總數等於 : 78
.