为什么在此代码中指针转移到另一个位置:
#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
应该继续指向该位置,即使在功能结束后也是如此。它也应该在主要中打印相同的地址。这有什么问题?
答案 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;
}