Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从C中的函数返回数组?_C_Arrays_Pointers - Fatal编程技术网

如何从C中的函数返回数组?

如何从C中的函数返回数组?,c,arrays,pointers,C,Arrays,Pointers,大多数网站都这样说: C编程不允许将整个数组作为参数返回 对一个函数进行修改。但是,您可以通过以下方式返回指向数组的指针: 指定不带索引的数组名称 我刚开始讲指针,据我所知,指针变量是一个存储内存地址的变量。当我们使用*解除对它的引用时,我们到达那个内存地址并保存存储在那里的值。此外,对于数组,指针必须指向第一个元素 现在,如果我们的函数返回指向数组第一个元素的指针,如本例所示: int * myFunction() { . . . } 我们将如何去引用它 “函数返回指针”是

大多数网站都这样说:

C编程不允许将整个数组作为参数返回 对一个函数进行修改。但是,您可以通过以下方式返回指向数组的指针: 指定不带索引的数组名称

我刚开始讲指针,据我所知,指针变量是一个存储内存地址的变量。当我们使用*解除对它的引用时,我们到达那个内存地址并保存存储在那里的值。此外,对于数组,指针必须指向第一个元素

现在,如果我们的函数返回指向数组第一个元素的指针,如本例所示:

int * myFunction() {
   .
   .
   .
}
  • 我们将如何去引用它
  • “函数返回指针”是否意味着它返回指针指向的内存地址
  • 那么,

    第二点要记住的是C不主张返回 将局部变量的地址设置为函数外部,以便 必须将局部变量定义为静态变量

  • 什么是静态变量?[我浏览了足够多的网页,但没有发现任何令人满意的东西]。维基百科定义:
  • 在计算机编程中,静态变量是一个已被修改的变量 静态分配,以便其生存期或“范围”扩展到 整个程序的运行

    另一个网站说,

    静态存储类指示编译器保持本地 在程序生命周期内存在的变量,而不是 每次它进出时都会创建和销毁它 范围

    有人请给我一个清晰和基本的解释什么是静态变量,以及它在这个上下文中是如何相关的(从函数返回数组)

    我真的很困惑

    我们将如何去引用它

    函数返回的指针变量

    通过使用适当的运算符
    *
    ,例如:

    int z = 5;
    int* pointer_to_z = &z; // get memory address of z and store that in pointer_to_z
    int can_i_have_my_z_back_please = *z; // check what value is at that memory address and store it, a copy is made here.
    
    “函数返回指针”是否意味着它正在返回 指针指向的内存地址

    它返回一个指针变量,这个变量保存值的内存地址。基本上,“指向”值与“拥有它的地址”相同

    什么是静态变量?我冲浪够多了,但没找到 任何令人满意的东西

    关于静态变量已经是什么,有很多很好的答案。总而言之(仅限于变量的生存期,而非其链接),静态变量在初始化后对程序的其余部分有效,这意味着它的生存期不像局部变量那样受范围限制:

    void hello()
    {
      int x = 5;
    } // x destroyed here..
    
    void hello_static()
    {
      static int x = 5;
    } // x will only be destroyed at the "end" of the program
    
    这反过来意味着返回本地静态变量的指针(内存地址)是完全安全的,因为静态变量仍然可以访问:

    int* return_my_static()
    {
      static int a = 5;
      return &a;
    }
    
    int main()
    {
      int* pointer_to_static = return_my_static(); // get the memory address of the static
      printf("%i", *pointer_to_static); // print out the value by dereferencing
    }
    
    但是,对局部非静态变量执行此操作将导致未定义的行为,因为指向的变量(其内存地址)已被销毁,因此不再有效:

    int* return_local()
    {
      int a = 5;
      return &a;
    } // a is destroyed here.. oopsies
    
    int main()
    {
         int* pointer_to_local = return_local(); // get the memory address of the local.
         //local variable has been destroyed now and 'pointer_to_static' now points to garbage memory!
          printf("%i", *pointer_to_local); // Try to print out the value by dereferencing, this is undefined behaviour, anything can happen.
    }
    
    请注意,上面的代码可能会运行并输出预期结果,但这纯粹是运气,这是未定义的行为,应该不惜一切代价避免,因为此时可能发生任何事情。

    问题3:

    int a;
    
    void foo() {
       int b
       static int c;
    }
    
    int main() {
        foo();
    }
    
    当程序启动时,a和c的内存被分配并保持分配状态,直到程序退出。所以在任何给定的时间,a和c上都有。每次有人(此处为main)调用foo时,都会在堆栈上分配b,直到该函数返回为止

    关于问题3前面的引述:

    int a;
    
    void foo() {
       int b
       static int c;
    }
    
    int main() {
        foo();
    }
    
    返回a和c的地址没有问题,因为只要程序运行,它们就存在,但将地址返回到b是一个错误,因为调用方一拿到指针,指针就指向无效内存

    问题1:

    在指针前面放一个星号可以解除对它的引用。没关系,指针指向的是什么。如果它是一个数组,您可以增加或减少指针以获得您试图达到的索引,就像在一个简单的加法中:*(p+4)将访问第五个元素(因为*(p+0)是第一个元素,所以*(p+1)是第二个元素,依此类推)

    除了写*(p+4),你还可以写p[4]

    假设函数如下所示:

    int * myFunction() {
        static int array[8];
        return array;
    }
    
    然后return语句将返回数组的地址,该地址与数组的第一个元素的地址完全相同

    因此,具有int*p=myFunction();然后,您可以使用直观的语法p[0]=42;访问数组。。。;p[7]=23

    问题2:

    返回指针的函数就是返回指针的函数。指针是指向内存中某个点的东西。通常这称为内存地址,但C语言并不关心。因此,在实践中,“函数返回指针”意味着它返回指针指向的内存地址,是的。

    返回到前面:

    什么是静态变量

    当程序首次启动时,具有
    静态
    存储持续时间的对象已为其分配了存储空间,并且该存储空间一直保持到程序退出。在以下情况下,对象具有
    静态
    存储持续时间:

    • 其标识符在文件范围内声明(在任何函数体之外);或
    • 它的标识符是用
      static
      关键字声明的
    例如:

    #include <stdio.h>
    
    int g_var;                      // static storage duration
    
    void foo( void )
    {
      static int s_var = 10;        // static storage duration
      int l_var = 10;               // auto storage duration
    
      printf( "g_var = %d, s_var = %d, l_var = %d\n", g_var++, s_var++, l_var );
    }
    
    l_var
    具有
    auto
    存储持续时间-其生存期仅限于
    foo
    函数的生存期。每次调用
    foo
    时,在函数进入时分配和初始化
    l_var
    的新实例的存储,并在函数退出时释放。这很重要-
    l_var
    在退出
    foo
    时停止存在,因此当
    foo
    返回1时,指向它的任何指针都将无效

    这就是为什么你不能做这样的事情

    int * bar( void )
    {
      int array[N];
      ...
      return array;
    }
    
    因为
    数组int * bar( void )
    {
      static int array[N];
      ...
      return array;
    }
    
    void foo( int *array, size_t arraySize )
    {
      ...
      array[i] = some_value;
      ...
    }
    
    int * bar( void )
    {
      int *array = malloc( sizeof *array * N );
      if ( array )
      {
        // initialize array contents
      }
      return array;
    }
    
    int *p = bar();
    
    printf( "p[0] = %d\n", *p );
    printf( "p[0] = %d\n", *(p + 0) );
    printf( "p[0] = %d\n", p[0] );