C 主/函数中的指针之间是否存在差异

C 主/函数中的指针之间是否存在差异,c,function,pointers,C,Function,Pointers,我一直在试验指针: 我想用双指针输出一个数组。它起作用了,但当我尝试使用相同的函数时,它不再起作用了。不知何故,指针似乎没有连接。 有没有人知道错误可能是什么 #include <stdio.h> void out2pointer(char *ptr, char **ptrptr); int main(){ char out[3][3] = {{'a','b','c' }, {'d','e','f' },

我一直在试验指针: 我想用双指针输出一个数组。它起作用了,但当我尝试使用相同的函数时,它不再起作用了。不知何故,指针似乎没有连接。 有没有人知道错误可能是什么

#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");
    }
}
在函数out2pointer printf%c中,*ptr;不正确,您需要printf%c,**ptrpr

而且这个函数根本不需要ptr参数。ptr是传递到out2pointer的ptr的副本,这就是为什么它不受*ptrptr=*ptrptr+1的影响

在函数out2pointer printf%c中,*ptr;不正确,您需要printf%c,**ptrpr

而且这个函数根本不需要ptr参数。ptr是传递到out2pointer的ptr的副本,这就是为什么它不受*ptrptr=*ptrptr+1的影响

在main function*ptrpr中,ptr是ptr的别名-它们指定相同的对象,因此通过更改*ptrpr,您也可以更改ptr

在另一个函数中,*ptrpr指定main的ptr变量,但函数中的ptr是一个不同的变量,其值最初设置为相同的值。因此,更改*ptrpr将更改main中ptr的值,但不会影响函数中同名的不同参数

最后,根据C标准,增加int*超过内部数组的末尾,或者延迟这样的指针,都有未定义的行为。当打印数组的字母d或增加指针以使其指向e时,会发生这种情况。在主函数中,

ptrpr将ptr别名-它们指定相同的对象,因此通过更改*ptrpr,也可以更改ptr

在另一个函数中,*ptrpr指定main的ptr变量,但函数中的ptr是一个不同的变量,其值最初设置为相同的值。因此,更改*ptrpr将更改main中ptr的值,但不会影响函数中同名的不同参数


最后,根据C标准,增加int*超过内部数组的末尾,或者延迟这样的指针,都有未定义的行为。当打印数组的字母d或增加指针以使其指向e时,会发生这种情况。

您的问题是main和out2pointer中有两个不同的变量ptr

如果你主要是这样做的话

那么*ptrptr=*ptrptr+1实际上修改了ptr,即在main中可见的ptrvariable

当您将这些指针传递给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!
        }
    }
}

您的问题是main和out2pointer中有两个不同的变量ptr

如果你主要是这样做的话

那么*ptrptr=*ptrptr+1实际上修改了ptr,即在main中可见的ptrvariable

当您将这些指针传递给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!
        }
    }
}

问题是您必须将ptr的地址发送到out2pointer**char,**char。是的,out2pointer函数声明必须更改

原因是您必须通过引用而不是通过值来传递ptr

因为ptrptr指向out2pointerchar*中的一个全新指针变量ptr,char**因此,我们需要更改声明,如下所示

因此,当您递增ptrpr时,它不会影响out2pointerchar*中的ptr变量,char**。因为out2pointerchar*中的ptrpr,char**指向主函数的ptr,而不是out2pointerchar*中的ptr,char**

让我们理解为什么会发生这种情况,

在函数调用out2pointerchar*之后,在main中的char**

每次在out2pointerchar*,char**中递增ptrpr时,都是在内存位置0x1111处递增变量,但out2pointerchar*,char**的变量ptr在内存位置0x3333处,该位置不递增。因此,ptr在每个循环迭代中都指向“a”

方法1:

修改out2pointer函数声明: 作废out2pointerchar**ptr,char**ptrpr;//是的,我们需要**ptr

修改main中的outpointer2函数调用: 输出2点和ptr,prtptr;//传递ptr的地址和值

最后,在out2pointerchar**、char**的函数定义中,修改printf如下: 打印文件%c,**ptr

方法2:

另一种方法是重新分配 输出2点卡*中的ptrptr,字符**至&ptr

这样,ptrptr将指向局部变量ptrlocal to out2pointerchar*、char**,而不是主函数中的ptr

是的,与前一种方法相比,这种方法需要的更改更少


谢谢您的提问

问题是您必须将ptr的地址发送到Out2 Pointer**char,**char。是的,out2pointer函数声明必须更改

原因是您必须通过引用而不是通过值来传递ptr

因为ptrptr指向out2pointerchar*中的一个全新指针变量ptr,char**因此,我们需要更改声明,如下所示

因此,当您递增ptrpr时,它不会影响out2pointerchar*中的ptr变量,char**。因为out2pointerchar*中的ptrpr,char**指向主函数的ptr,而不是out2pointerchar*中的ptr,char**

让我们理解为什么会发生这种情况,

在函数调用out2pointerchar*之后,在main中的char**

每次在out2pointerchar*,char**中递增ptrpr时,都是在内存位置0x1111处递增变量,但out2pointerchar*,char**的变量ptr在内存位置0x3333处,该位置不递增。因此,ptr在每个循环迭代中都指向“a”

方法1:

修改out2pointer函数声明: 作废out2pointerchar**ptr,char**ptrpr;//是的,我们需要**ptr

修改main中的outpointer2函数调用: 输出2点和ptr,prtptr;//传递ptr的地址和值

最后,在out2pointerchar**、char**的函数定义中,修改printf如下: 打印文件%c,**ptr

方法2:

另一种方法是将out2pointerchar*、char**中的ptrptr重新分配给&ptr

这样,ptrptr将指向局部变量ptrlocal to out2pointerchar*、char**,而不是主函数中的ptr

是的,与前一种方法相比,这种方法需要的更改更少


谢谢您的提问

请将您的文本输出作为文本包含在问题中。不需要包含文本图片。像遍历一维数组一样遍历二维数组,有时称为展平多维数组,根据标准调用未定义的行为,但在实践中大多有效。我不建议在实际程序中使用这种技术。这里有一些很好的答案,但它可能有助于了解c通过值传递一切。将ptr传递给函数时,out2pointer将收到ptr指向的地址的副本。这篇文章解释了更多:请将您的文本输出作为文本包含在问题中。不需要包含文本图片。像遍历一维数组一样遍历二维数组,有时称为展平多维数组,根据标准调用未定义的行为,但在实践中大多有效。我不建议在实际程序中使用这种技术。这里有一些很好的答案,但它可能有助于了解c通过值传递一切。将ptr传递给函数时,out2pointer将收到ptr指向的地址的副本。本文将进一步解释:您应该描述OP的代码不正确的原因以及如何解决问题。您应该描述OP的代码不正确的原因以及如何解决问题。
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'
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**)).