【问题标题】:How to get the information from a pointer [duplicate]如何从指针中获取信息[重复]
【发布时间】:2013-12-22 16:38:21
【问题描述】:

这是我的代码:

int *myFunction()
{
    int A[3] = {1,2,3};
    return A;             //this will return the pointer to the first element in the array A
}

int main (void)
{
    int A[3];

    A = myfunction();     //A gets the return value of myFunction

    for(int j=0; j==2; j++)
    {
        B[j] = 2* A[j];   //doubles each value in the array
    }
    printf("%d",B);
    return 0;      
}

但这不起作用,因为返回的 A 不是实际的向量。如何在主函数中获取实际的向量 {1,2,3}?

【问题讨论】:

  • 您不能这样做,因为AmyFunction 的本地对象,当myFunction 结束时它将超出范围,从而使main 具有无效的指针。 (另外你没有在main 中声明A。)
  • 尝试返回A的地址&A,然后在方法外使用。
  • 还要注意你的for 循环永远不会运行,因为j == 2 在第一次迭代时是假的。您的意思可能是j != 2,尽管j < 3 会更好(也更常见)。

标签: c arrays function pointers return


【解决方案1】:
#include <stdio.h>

int (*myFunction(void))[3]
{
    static int A[3] = {1,2,3};
    return &A;
}

int main (void){
    int (*A)[3], B[3];

    A = myFunction();

    for(int j=0; j<=2; j++)
    {
        B[j] = 2 * (*A)[j];
    }
    for(int j=0; j<3;++j)
        printf("%d ", B[j]);
    return 0;
}

【讨论】:

    【解决方案2】:

    将要填充的数组及其大小作为参数传递给 initisliser 函数:

    size_t myFunction(int * A, size_t s)
    {
      int A_tmp[3] = {1,2,3};
    
      size_t i = 0;
      for (; i < s && i < sizeof(A_tmp)/sizeof(A_tmp[0]); ++i)
      {
        A[i] = A_tmp[i];
      }
    
      return i;
    }
    

    然后这样称呼它:

    int main()
    {
      int myA[3];
      size_t s = sizeof(myA)/sizeof(myA[0]);
      size_t n = myFunction(myA, s);
      if (n < s)
        fprintf(stderr, "Caution: Only the first %zu of %zu elements of A were initialised.\n", n, s);
    
      // and continue to print array...
    }
    

    【讨论】:

      【解决方案3】:

      函数myFunction分配A,但这种分配只存在于函数的scope内。当函数返回时,持有A 的内存被销毁。这意味着该函数正在返回一个指向尚未分配的内存的指针。

      问题是变量A 不会在函数之外持续存在。您可以使用全局变量或将指向缓冲区的指针传递给myFunction

      全局变量法:

      static int A[3];
      
      int* myFunction()
      {
          A[0] = 1; A[1] = 2; //etc
          return A;
      }
      

      在这个例子中,因为A 是一个全局的,A 指向的内存会在你的程序的整个生命周期中持续存在。因此返回一个指向它的指针是安全的......

      顺便说一句,全局变量可能不应该以这种方式使用......它有点笨拙。使用static 关键字意味着A 将无法在此模块(C 文件)之外访问。

      指针方法:

      void myFunction(a[3])
      {
          a[0] = 1; a[1] = 2; //etc
      }
      
      int main()
      {
          myA[3];
          myFunction(myA);
          // and continue to print array...
      }
      

      在本例中,main() 函数分配了myA。该变量在函数执行时存在(它是automatic variable)。指向数组的指针被传递给函数,该函数填充数组。因此main()函数可以从myFunction()获取信息。

      使变量myA 持久化的另一种方法是在堆上分配它。要做到这一点,你会做类似int *myA = malloc(sizeof(int) * NUMBER_OF_INTS_IN_ARRAY 的事情。然后,此内存将持续存在,直到您使用 free() 专门销毁它或您的程序结束。

      【讨论】:

      • “范围”是错误的术语;函数内部使用的标识符的范围不是问题。对象的生命周期是问题所在。您可以在其标识符范围之外使用对象,就像将其地址传递给完全不同的例程一样。您不能在其生命周期结束后使用对象。范围是标识符的编译时属性。 Lifetime 是对象的运行时属性。例如,句子“问题在于变量A 不会在函数之外持续存在。”应该是“问题是对象A在函数执行后没有持久化。”
      【解决方案4】:

      照原样,您的代码无论如何都无法正常工作...您的for 循环已损坏,main 中有未定义的变量,您的函数名称不匹配,并且您的打印无法执行反正你想要什么...

      最大的问题是你有未定义的行为,你不能在本地定义的函数之外访问A[]。纠正这个问题的最简单方法是使用动态内存,malloc() 一些内存用于A 中的myFunction,然后在完成后使用mainfree() 内存中的值。

      这是解决其他语法问题的示例:

      int *myFunction()
      {
          int *A;
          A = malloc(3 * sizeof(int));
          A[0] = 1;
          A[1] = 2;
          A[2] = 3;
          return A;
      }
      
      int main (void)
      {
          int *A = myFunction();     //A gets the return value of myFunction
          int B[3] = {0, 0, 0};
          int j;
          for(j=0; j<3; j++)
          {
              B[j] = 2* A[j];   //doubles each value in the array
          }
          free(A);
          printf("%d",B[0]);
          return 0;      
      }
      

      【讨论】:

        【解决方案5】:

        int A[3] = {1,2,3}; 正在堆栈上创建,也就是说,它是一个本地数组,它的内存可以在myFunction 执行后再次使用。您必须要么在 myFunction 内创建 int A[3] static,要么将其置于所有函数之外。另一种选择是在main 中创建int A[3],并将A 的地址传递给myFunction,这样myFunction 就可以直接修改A 的内容。

        【讨论】:

          猜你喜欢
          • 2012-02-26
          • 2020-12-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-09
          • 2017-03-28
          • 2017-04-05
          • 1970-01-01
          相关资源
          最近更新 更多