![](/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.