![](/img/trans.png)
[英]What is the difference between **pointer and &pointer as function parameter?
[英]Is there a difference between pointer in main / function
我一直在試驗指針:我想使用雙指針輸出一個數組。 它起作用了,但是當我用一個函數嘗試同樣的方法時,它不再起作用了。 不知何故,指針似乎沒有連接。 有誰知道錯誤可能是什么。
#include <stdio.h>
void out2pointer(char *ptr, char **ptrptr);
int main(){
char out[3][3] = {{'a','b','c' },
{'d','e','f' },
{'g','h','i' }};
char *ptr = &out[0][0]; //pointer
char **ptrptr=&ptr; //pointerpointer
out2pointer(ptr,ptrptr);
ptr = &out[0][0];
ptrptr=&ptr;
printf("\nOutput in main:\n");
for(int i=0;i!=3;i++){
for(int k=0;k!=3;k++){
printf("%c",*ptr); //output in main
*ptrptr=*ptrptr+1;
}
printf("\n");
}
return 0;
}
void out2pointer(char *ptr, char **ptrptr){
printf("\nOutput in Function:\n");
for(int i=0;i!=3;i++){
for(int k=0;k!=3;k++){
printf("%c",*ptr); //output in Funktion
*ptrptr=*ptrptr+1;
}
printf("\n");
}
}
在main
函數*ptrptr
, ptr
別名——它們指定相同的對象,因此通過更改*ptrptr
您也可以更改ptr
。
在另一個函數中, *ptrptr
指定main
的ptr
變量,但函數中的ptr
是一個不同的變量,其值最初設置為相同的值。 因此,更改*ptrptr
將更改main
中ptr
值,但不會影響函數中具有相同名稱的不同參數。
最后,根據 C 標准,增加int *
超過內部數組的末尾,或延遲這樣的指針,具有未定義的行為。 當打印數組的字母d
或增加指針以使其指向e
時,就會發生這種情況。
您的問題是您在main
和out2pointer
有兩個不同的變量ptr
。
如果你在main
這樣做
ptrptr=&ptr; // ptr from main
for(int i=0;i!=3;i++){
for(int k=0;k!=3;k++){
printf("%c",*ptr); // ptr from main
*ptrptr=*ptrptr+1; // Modifies ptr from main.
}
}
然后*ptrptr = *ptrptr+1
實際上修改了ptr
,即在main
可見的ptr
變量。
當您將這些指針傳遞給out2pointer
您會引入另一個變量ptr
,該變量僅在函數中可見,並且與main
同名變量無關。
然后在你的函數中你總是打印*ptr
,它在你的嵌套循環中不會改變。 相反*ptrptr=*ptrptr+1;
仍然從main
修改ptr
變量,但不影響局部變量。
void out2pointer(char *ptr, char **ptrptr){
for(int i=0;i!=3;i++){
for(int k=0;k!=3;k++){
printf("%c",*ptr); // This is the ptr from the function.
*ptrptr=*ptrptr+1; // *ptrptr points to ptr from main!
}
}
}
在函數out2pointer
printf("%c", *ptr);
不正確,你需要printf("%c", **ptrptr);
.
並且該函數根本不需要ptr
參數。 該ptr
是您傳遞給out2pointer
的ptr
的副本,這就是為什么它不受*ptrptr=*ptrptr+1;
影響的原因*ptrptr=*ptrptr+1;
問題是你必須將ptr
的地址發送到 out2pointer(**char, **char)。 是的,out2pointer 函數聲明必須更改。
原因是你必須通過引用而不是通過值傳遞ptr
。
因為ptrptr
在out2pointer(char*, char**)
ptrptr
中指向一個全新的指針變量ptr
(因此,我們需要更改如下所示的聲明)函數。
因此,當你增加ptrptr
,它不會影響ptr
變量out2pointer(char*, char**)
因為ptrptr
在out2pointer(char*, char**)
是指向ptr
的main
功能,而不是ptr
在out2pointer(char*, char**)
。
讓我們了解為什么會發生這種情況,
In main,
assume &out[0][0] = 0x1111.*(assuming its a 16-bit machine)*
assume &ptr = 0x2222.
Hence, it can be inferred from your code that,
ptr = &out[0][0] = 0x1111.
*ptr = out[0][0] = 'a'.
ptrptr = &ptr = 0x2222.
*ptrptr = ptr = 0x1111.
**ptrptr = out[0][0] = 'a'.
After, *ptrptr = *ptrptr + 1 (in main), we have
**ptrptr = 'b', and *ptr = 'b'
而且,在函數調用out2pointer(char*, char**)
在main
,
In out2pointer(char*, char**),
assume &ptr = 0x3333.*(because its a new local variable)*
Hence, it can be inferred from your code that,
ptr = &out[0][0] = 0x1111.
*ptr = out[0][0] = 'a'.
ptrptr = 0x2222.(still pointing to 0x2222 and not 0x3333)
*ptrptr = ptr = 0x1111.
**ptrptr = out[0][0] = 'a'.
After *ptrptr = *ptrptr + 1 (in out2pointer(char*, char**)), we have,
**ptrptr = 'b' and *ptr = 'a'.(because, pointer at memory location 0x2222 was incremented, whereas pointer at 0x3333 remains unchanged, and you are printing the variable at 0x3333 in out2pointer(char*, char**)).
每次當你增量ptrptr
在out2pointer(char*, char**)
內存位置,你遞增變量0x1111
,但是變量ptr
的out2pointer(char*, char**)
是在內存中的位置0x3333
,這是不增加。 因此ptr
在每次循環迭代中都指向'a'
。
方法一:
修改out2pointer
函數聲明:
void out2pointer(char** ptr, char** ptrptr); // yes, we need **ptr
修改 main() 中的outpointer2
函數調用:
out2pointer(&ptr, prtptr); // pass the address of ptr and and the value
最后在out2pointer(char**, char**)
函數定義中,像這樣修改printf
:
printf("%c",**ptr)
方法二:
另一種方法是將重新分配ptrptr
在out2pointer(char*, char**)
到& ptr
。
通過,這樣做ptrptr
將指向局部變量ptr
(局部於out2pointer(char*, char**)
),而不是main
函數中的ptr
。
是的,與前一種方法相比,這種方法需要的更改較少。
感謝你的提問
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.