要僅更改結構的成員,您不需要那樣。但要將實際指針更改爲,您需要模擬的結構通過使用指向結構的指針的參考傳遞。
例如,只改變一員,這是不夠
void initializeFields(struct someStruct* foo)
{
foo->field1 = 1;
foo->field2 = 2;
}
int main(void)
{
struct someStruct bar;
initializeFields(&bar);
printf("field1 = %d\n", bar.field1);
printf("field2 = %d\n", bar.field2);
return 0;
}
但是,如果你比如要動態分配結構中的功能,你需要通過參考效仿通:
void initializeFields(struct someStruct** foo)
{
// The difference is this assignment
*foo = malloc(sizeof(struct someStruct));
(*foo)->field1 = 1;
(*foo)->field2 = 2;
}
int main(void)
{
struct someStruct* bar;
initializeFields(&bar);
printf("field1 = %d\n", bar->field1);
printf("field2 = %d\n", bar->field2);
return 0;
}
另外兩個示例顯示按值傳遞和仿真通過引用之間的區別。
考慮下面的程序:
#include <stdio.h>
void foo(int y)
{
y = 5;
}
int main(void)
{
int x = 1;
printf("1: x = %d\n", x);
foo(x);
printf("2: x = %d\n", x);
return 0;
}
上述程序將打印
1: x = 1
2: x = 1
這是因爲複製x
價值被傳遞給函數foo
。在foo
中修改本地副本不會修改main
中的原始變量x
。
現在參照效仿通:
#include <stdio.h>
void foo(int *y)
{
*y = 5;
}
int main(void)
{
int x = 1;
printf("1: x = %d\n", x);
foo(&x);
printf("2: x = %d\n", x);
return 0;
}
該程序將打印出
1: x = 1
2: x = 5
這是因爲我們不改變功能foo
裏面的指針變量y
,但我們改變它指向的值的位置,這恰好是main
函數中的變量x
。
我明白了,但爲什麼在第二種情況下,我們需要指向返回malloc'd內存的指針?爲什麼我們不能只傳遞一個指向foo的指針? – Bionix1441
這是一個很好的做法嗎?我的意思是,返回一個分配在initializeFields中的結構指針聽起來比分配一個指針的指針更好,並且不返回任何內容,甚至在malloc失敗的情況下也不會返回錯誤代碼。 – PanzerKadaver
@ Bionix1441因爲C只具有所謂的*按值傳遞*,這意味着爲傳遞的參數創建了一個副本。修改副本當然不會修改原始內容。如果你有一個接受'int'參數的函數,並且在你修改參數的函數中,你會期望你傳遞給調用函數的值被修改嗎? –