通过调用另一个函数将指针移动到某个地址

时间:2017-07-25 09:09:43

标签: c pointers function-calls

为什么在此代码中指针转移到另一个位置:

#include <stdio.h>

void f(int *p)
{
        int j=2;
        p=&j;
        printf("%d\n%p\n%d\n",*p,&j,p);
}

int main(void)
{
        int *q;
        int m=98;
        q=&m;
        f(q);
        printf("%p ",q);
        return 0;
}

输出:

  

2
  0x7ffff5bf1bcc
  0x7ffff5bf1bcc
  0x7ffff5bf1bc8

据我所知,当函数f()完成打印值j地址 j时,内存占用{ {1}}返回堆栈,但IMO j应该继续指向该位置,即使在功能结束后也是如此。它也应该在主要中打印相同的地址。这有什么问题?

4 个答案:

答案 0 :(得分:6)

在实际代码中考虑您的意思是printf("%p ", (void *)q);

不,C中的函数参数是按值传递的。它不会将对参数所做的更改反映到所使用的实际参数中(在函数调用中)。

换句话说,函数参数是函数(调用)作用域的本地参数,对它们所做的任何更改都不会反映到实际的参数中。

因此,如果您需要更改指针,则需要将指针传递给需要更改的指针。

考虑一个相当轻松但现实的场景。

void f (int x) { x = 10; }

int main(void) { f(5); printf ("%d", 5); return 0;}

现在,您希望它打印10吗?

那说,一个建议。始终将参数转换为%p转换说明符(void *)(如果尚未加入)。 printf()是一个可变函数,对于指针,不会发生默认参数提升,因此提供的参数类型需要显式匹配预期的类型。否则,从技术上讲,它是undefined behavior

答案 1 :(得分:2)

了解指针和指针与指针之间的区别 - 传递 p 的指针无疑可以改变它所指向的变量的值( m ),但是要更改它指向的内存位置 - 你需要一个指向指针的指针。

答案 2 :(得分:1)

扩展@SouravGhosh所说的内容,当你传入指向int的指针时,你正在制作指针的副本。如果你想更改指针,你需要双重间接,并传入一个指向int的指针。复制第一个指针,您可以直接影响第二个指针。

void f(int ** p)
{
    int j = 2;
    *p = &j;
    printf("%d\n%p\n%p\n",*p,&j,p); 
}

int main(void)
{
    int ** q = (int **)malloc( izeof(int *));
    int m = 98;
    *q = &m;
    f(q);
    printf("%p ",q);
    free(q);
    return 0;
}

输出

  

2   0xffffcbcc   0xffffcbcc   0xffffcbcc

答案 3 :(得分:0)

如果你这样做,你会发现它永远不会改变:

#include <iostream>
#include "Header2.h"
#include "header1.h"

#include <stdio.h>
void f(int *p)
{
    int j = 2;
    p = &j;
    printf("%d\n%p\n%p\n", *p, &j, p);
}

int main(void)
{
    int *q;
    int m = 98;
    q = &m;
    printf("Value of pointer q before calling f() =%p ", q);
    f(q);
    printf("Value of pointer q after calling f() =%p ", q);
    return 0;
}