在 C 中——我可以从一个函数中初始化一个数组(并设置大小)吗?

In C - Can I initialize an array (and set the size) from within a function?

我正在尝试传递一个指向函数的指针,并在该函数中创建一个数组,并将传递的指针设置为该数组。

我想做的是在函数内部创建一个数组,然后在函数外部使用该数组。

void createArray(int *myPointer)
{
    int intArray[20];

    *myPointer = &intArray[0]; // This line gets error:
                               // assignment makes integer from pointer without a cast [-Wint-conversion]

    for (int i = 0; i < 20; i++)
    {
        intArray[i] = i + 10;
    }
}

int main(void)

{
    int *intPointer;
    createArray(&intPointer);
    for (int i = 0; i < 20; i++)
    {
        printf("%d : %d \n", i, intPointer[i]);
    }
    return 0;
}

你打算使用

void createArray(int **myPointer)

这将解决两个类型的错误。

但这将使main的指针指向一个在createArrayreturns之后不再存在的变量。那很糟。这就是为什么您必须使用 malloc 而不是自动存储的原因。

void createArray( int **myPointer ) {
    int *intArray = malloc( 20 * sizeof(int) );

    *myPointer = intArray;  // Same as `&intArray[0]`
    if ( !intArray )
       return;

    for ( int i = 0; i < 20; i++ )
        intArray[i] = i + 10;
}

int main(void) {
    int *intPointer;
    createArray(&intPointer);
    if ( intPointer ) {
       perror( NULL );
       exit( 1 );
    }

    for (int i = 0; i < 20; i++)
        printf( "%d: %d\n", i, intPointer[i] );

    return 0;
}

编译器错误的原因是 *myPointer 取消引用,它为您提供了指针指向的 int 类型的内容。编译器说你不能将指针 &intArray[0] 分配给普通的 int.

除了是无效的C,它不会改变指针指向的地方。为此,您必须执行 myPointer = &intArray[0];。但是,在这种情况下,您也不能这样做,因为 myPointer 只是函数内部的一个本地指针变量——您传递的指针的本地副本。您需要一种方法来更新 main().

中的指针

此外,我们永远无法 return 指向本地数据(具有“自动存储持续时间”的数据)的指针,因为一旦我们离开函数,该数据就不再有效。

正常的解决方案是创建动态分配的内存,因为这样的内存在整个程序执行过程中一直存在(或直到您明确释放它)。有两种不同的方法可以为此编写函数:

#include <stdlib.h> // for malloc

int* createArray (void)
{
    int* result = malloc(20 * sizeof(*result));
    if(result == NULL)
        return NULL; // some error handling will be required here

    for (int i = 0; i < 20; i++)
    {
        result[i] = i + 10;
    }
  
    return result;
}

...
int *intPointer = createArray();
...
free(intPointer);

或者,您可以按值传递指针本身,这样通过执行 *myPointer = ...; 赋值,您可以引用 int** 指向的位置:

#include <stdlib.h> // for malloc

void createArray (int** myPointer)
{
    int* result;
    result = malloc(20 * sizeof(*result));
    if(result == NULL)
    { 
        /* some error handling will be required here */ 
    }

    for (int i = 0; i < 20; i++)
    {
        result[i] = i + 10;
    }
  
    *myPointer = result;
}

...
int *intPointer;
createArray(&intPointer);
...
free(intPointer);

这两个都可以,使用哪个主要是设计问题。指针 returned 的语法更简单,但通常函数的 return 是为某些错误代码保留的。