【问题标题】:Pointers for dummies假人指针
【发布时间】:2014-10-24 13:03:10
【问题描述】:

我刚学了指针,我写了一个非常简单的程序来检查我理解的是否正确;我的想法是创建一个简单的函数,将整数值作为输入并返回其地址。

尽管这应该是世界上最简单的事情,但编译后我收到一条警告消息,但我不知道为什么....

#include <stdio.h>
#include <stdlib.h>

// returnType functionName(type arg1, type arg2)
int* return_me(int);

int main(){
    int  x = 1;
    int *p;

    p = &x;
    printf("p: %p\n", p);

    p = return_me(x);
    printf("p: %p\n", p);

    return 0;
}

int* return_me(int num){
     return &num;
}

我应该得到相同的结果,但我没有......我在哪里搞砸了?

这是警告:

pointers.c: In function ‘return_me’:
pointers.c:21:2: warning: function returns address of local variable [-Wreturn-local-addr]
return &num;

【问题讨论】:

  • 向好问题迈出的第一步:除了说您收到警告消息外,还要发布警告消息
  • 局部变量num与变量x不在同一内存位置

标签: c function pointers


【解决方案1】:

线

p = return_me(x);

x的值赋给函数中的变量num,类似这样:

int num = x ;
p = &num ;

num 是不同的变量,具有不同的地址。

另请注意,当您从函数返回其地址时,局部变量 num 不再存在,打印其地址并没有真正定义。


像这样的:

int* return_me( int* pnum )
{
     printf("%d" , *pnum ) ;
     return pnum ;
}

【讨论】:

  • 这是否意味着没有办法创建一个函数来做我想做的事情?
  • @FedericoGentile 您应该首先传递地址。函数中的取消引用将为您提供价值。
  • mmm...如果我先传递地址,那么 return_me 函数将变得无用,因为它基本上什么都不做...我的目标是创建一个函数,将随机整数作为输入并将其地址作为输出...我现在明白 num 和 x 地址混合了,但我就是不知道如何解决这个问题
  • @FedericoGentile 我认为这是可能的,你真的应该问一个新问题,因为这是一个不同的问题。
  • @FedericoGentile:没有什么好的方法可以定义一个你想要的函数;形式参数将始终是与实际参数不同的内存对象。您可以定义像#define RETURN_ME(x) &amp;(x) 这样的宏,尽管它不是很有用,并且它假定x 将始终有一个地址(如果x 是数字文字或不是左值的表达式,则情况并非如此)。
【解决方案2】:

问题是 c 中的参数总是按值复制。 因此,您只能实例化一个新的 int 并将值复制到它num

int x = 1;       // x is an int
int* p = &x;    // p is a pointer to an int

return_me(x)     // here you pass the integers value as "copy by value"

内部return_me()

int* return_me(int num){    // here you instantiate a new int "num" and copy the value from "x" to it.
     return &num;           // therefore you have a new Int and a new a new address which is different from "i" outside this func
}

【讨论】:

    【解决方案3】:

    我在这里重写了你的代码。有一点修改。

    #include <stdio.h>
    #include <stdlib.h>
    
    // returnType functionName(type arg1, type arg2)
    int* return_me(int*);
    
    int main(){
    int  x = 1;
    int *p;
    
    p = &x;
    printf("p: %p\n", p);
    
    p = return_me(&x);
    printf("p: %p\n", p);
    
    return 0;
    }
    
    int *return_me(int *num){
     return num;
    }
    

    在我的系统上,当我执行上述代码时,我得到以下输出

    p: 0x7fff4e0305ec
    p: 0x7fff4e0305ec
    

    有图表示

      X         P        num
    +----+    +----+    +----+
    | 1  |    |1000|    |1000|
    +----+    +----+    +----+
     1000      2000      3000
    Fig: 1a,1b,1c respectively.
    

    代码

    int x=1;
    

    参考图 1a。

    代码

    p=&x;
    

    参考图 1b。

    代码

    int *return_me(int *num){
    

    其中 num 保存的值如图 1c 所示。

    同样的值也返回给主函数。

    您的代码的问题是,您使用的是变量 x 的副本(即按值调用),而不是变量 x 的实际地址(使用按引用调用完成)。 当您发送 x 的副本时,变量的生命周期将在声明它的函数中。在你的情况下,当控制离开函数(即 main() )时,变量的生命被认为是死的。

    【讨论】:

      【解决方案4】:

      当您将整数作为 x 传递给函数时,该函数不会获取 x 所在的地址。相反,它只是获得了它的价值。编译器通常通过将其值分配给某个寄存器或将其压入堆栈来传递此类值。无论哪种方式,被调用的函数都不能对其位置做出任何假设。相反,它只能使用它的VALUE。如果一个函数需要知道某个变量的地址,通常是因为它是一个 OUT 参数,这意味着被调用的函数应该操作该值,并将其投影回调用函数,在这种情况下,调用函数应该改为传递指向该变量的指针,而不是它的值。

      【讨论】:

        【解决方案5】:

        如果不使用“&”运算符,您将无法在 C 中找到任意随机整数的地址。 您尝试实现的功能由 '&' 运算符本身实现。 所以你应该阅读 & 运算符以及它是如何在 C 中实现的。

        【讨论】:

          猜你喜欢
          • 2017-09-05
          • 2012-12-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-10
          • 2015-12-28
          • 1970-01-01
          相关资源
          最近更新 更多