繁体   English   中英

main / function 中的指针有区别吗

[英]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函数*ptrptrptr别名——它们指定相同的对象,因此通过更改*ptrptr您也可以更改ptr

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

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

您的问题是您在mainout2pointer有两个不同的变量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是您传递给out2pointerptr的副本,这就是为什么它不受*ptrptr=*ptrptr+1;影响的原因*ptrptr=*ptrptr+1;

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

原因是你必须通过引用而不是通过传递ptr

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

因此,当你增加ptrptr ,它不会影响ptr变量out2pointer(char*, char**)因为ptrptrout2pointer(char*, char**)是指向ptrmain功能,而不是ptrout2pointer(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**)).

每次当你增量ptrptrout2pointer(char*, char**)内存位置,你递增变量0x1111 ,但是变量ptrout2pointer(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)

方法二:

另一种方法是将重新分配ptrptrout2pointer(char*, char**)到& ptr

通过,这样做ptrptr将指向局部变量ptr (局部于out2pointer(char*, char**) ),而不是main函数中的ptr

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

感谢你的提问

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM