D(程式語言)/d2/指標、傳引用和靜態陣列
外觀
< D(程式語言)
(從 D(程式語言)/d2/第 7 課 重定向)本章,你將學習如何在 D 中使用指標和靜態陣列。你還會學習如何在不使用指標的情況下傳引用。課文不會解釋指標和陣列背後的概念,它假設你從 C 或 C++ 中瞭解這些知識。D 還有動態陣列和陣列切片,兩者將在以後的課文中介紹。
import std.stdio;
void add_numbers(int* a, int* b)
{
*a = *a + *b;
}
void main()
{
int a = 50;
int* b = &a;
*b = 30;
writeln(a); // 30
// int* error = &50; Error: constant 50 is not an lvalue
int c = 2;
int d = 2;
add_numbers(&c, &d);
writeln(c); // 4
}
如果你是一位 C++ 程式設計師,你讀到這裡,可能會認為這是比 C++ 引用退步的一步,那麼恭喜你:雖然 D 支援指標,但它也支援更優的解決方案來將變數作為引用傳遞給函式。
import std.stdio;
void add_numbers(ref int a, int b)
{
a += b;
}
void main()
{
int c = 2;
int d = 2;
add_numbers(c, d);
writeln(c); // 4
// add_numbers(4, 2); Error: integer literals are not lvalues and cannot be passed by reference
}
它還專門支援 *輸出引數*
import std.stdio;
void initializeNumber(out int n)
{
n = 42;
}
void main()
{
int a;
initializeNumber(a);
writeln(a); // 42
}
使用 `out`,在函式開始時,`n` 在 `initializeNumber` 中被預設初始化。
import std.stdio;
void main()
{
int[5] a;
a[0] = 1;
writeln(a); // [1, 0, 0, 0, 0]
// a[10] = 3; Error: Array index 10 is out of bounds
int* ptr_a = &a[0];
ptr_a[0] = 5;
ptr_a[4] = 3;
writeln(a); // [5, 0, 0, 0, 3]
// ptr_a[10] = 3; // Bad: This memory is not owned by 'a' as it is out of bounds
// Compiler would allow it, but the result is undefined!
int[3] b = 3;
writeln(b); // [3, 3, 3]
b[] = 2;
writeln(b); // [2, 2, 2]
}
D 中的語法與 C 和 C++ 相同。運算子 `&` 獲取物件的引用,而 `*` 解引用。
在 D 中,指向 `typeA` 的指標是
typeA*
宣告一個指標的程式碼是
typeA* identifier;
.
靜態陣列具有固定長度。你可以像這樣宣告它們:
byte[10] array_of_ten_bytes;
你也可以這樣做:
byte[2] array_of_two_bytes = [39, 0x3A];
陣列索引從第一個元素的 0 開始。編譯器會在你嘗試訪問索引大於或等於陣列長度的元素時捕獲你。你可以像這樣訪問陣列元素:
my_array[index]
你也可以用單個值填充陣列,使陣列的所有元素都等於該值:
int[7] a = 2;
writeln(a); // [2, 2, 2, 2, 2, 2, 2]
a[] = 7;
writeln(a); // [7, 7, 7, 7, 7, 7, 7]
看看這段程式碼:
import std.stdio;
void addOne(int[3] arr)
{
arr[0] += 1;
// this means arr[0] = arr[0] + 1
}
void main()
{
int[3] array1 = [1, 2, 3];
addOne(array1);
writeln(array1); // [1, 2, 3]
}
輸出是 `[1,2,3]`,而不是 `[2,2,3]`。為什麼?因為靜態陣列在作為函式引數傳遞時會被複制。`addOne` 函式中的 `arr` 只是 `array1` 的一個副本。將程式碼改寫成這樣:
import std.stdio;
void addOne(ref int[3] arr)
{
arr[0] += 1;
}
void main()
{
int[3] array1 = [1, 2, 3];
addOne(array1);
writeln(array1); // [2, 2, 3]
}