在标准C语言(不是C99)中,在运行时声明数组的大小



数组需要在编译时定义大小。是否有可能在运行时使用malloc或其他东西来定义数组的大小?

这是完全可能的,也是非常常见的。合适的工具是malloc()函数。这允许您在运行时动态创建任何大小的数组。一个例子是在运行时创建一个由用户指定大小的数组。

int main(int argc, const char **argv) 
{
    printf("How long should the dynamic array be?");
    int length;
    scanf("%d", &length);
    // dynamically create the array with malloc
    int *array = malloc(sizeof(*array) * length);
    return 0;
}

这个数组(指向int的指针)可以像任何其他数组一样使用,通过[]操作符访问其值。

int fifthValue = array[4]; // assumes array was malloc()'d with at least 5 mem slots.

当你用完这个动态创建的数组后,使用free()函数把它的内存还给程序。

free(arr);

malloc()的第二个替代方案是calloc()函数。因为malloc()返回的内存块并不总是初始化的,所以它可能包含垃圾数据。如果不希望这样,可以使用calloc()函数。calloc()将为您初始化返回到0的内存中的所有元素。对calloc()的调用与对malloc()的调用略有不同。

int main(int argc, const char **argv) 
{
    printf("How long should the dynamic array be?");
    int length;
    scanf("%d", &length);
    // dynamically create the array with calloc and initialize it to 0
    int *array = calloc(length, sizeof(*array));
    return 0;
}

综上所述,malloc()free()函数非常适合在C中创建动态数组。请记住,在malloc()(或calloc())保留的内存中始终调用free()

要定义在编译时数组的大小,您可以使用预处理器宏,例如,创建一个可以在一个位置更新的常量表达式:

#define ARR_LEN 50
char array_one[ARR_LEN];
char array_two[ARR_LEN];

如果您想在运行时确定实际长度,那么您必须使用动态内存分配:

int arr_len = <user-input>;
char *array_one = (char*)malloc(sizeof(char) * arr_len);
// use the array
free(array_one);

VLA是c99的一个特性。并且在ANSI C/C89/C90中不可用,不管你怎么称呼它

但是VLA引入了我不喜欢的复杂性,所以在std C中,通常会这样做:(创建一个连续的内存块,就像堆上的C数组一样,然后通过解引用指针来访问它,或者直接使用数组语法,两者都是等效的,ok)

typedef struct
{
    int a;
    int b;
}MyStruct;
int main(int argc, const char * argv[])
{
    size_t numberOfElements = 5;
     //this will create a buffer numberOfElements * sizeof(MyStruct) in size and init each byte to 0;
    MyStruct * myAlmostArray = calloc(sizeof(MyStruct),numberOfElements);
    //do Stuff
    int i;
    for(i=0;i<numberOfElements;i++)
    {
        //gets the array (not needed in this example)
        MyStruct s = myAlmostArray[i];
        s.a = 3;
        s.b = i;
        //write the stack array back to the heap allocated psuedo array
        myAlmostArray[i] = s;
        //or slightly different example where you mutate the heap memory directly
        myAlmostArray[i].a = 3;
        myAlmostArray[i].b = i;
        //or the same thing written differently
        MyStruct * m = myAlmostArray + i;
        m->a = 3;
        m->b = i;
    }
    // free the memory
    free(myAlmostArray);
}

正如其他答案所指定的那样,您可以使用malloc函数来创建mxn矩阵1 int s

int **matrix = malloc(m * sizeof(int *));
for(int i = 0; i < n; i++)
    matrix[i] = malloc(n * sizeof(int));  

另一种方法是,虽然它不是动态的,也不是有效的,但却给人一种动态的印象:

#define m 100
#define n 100
//...
int main()
{
    int arr[m][n], row, col;
    scanf("%d %d", row, col);
    arr[row][col];
    //...
}  

1注意,虽然看起来你是在创建一个数组,但数组和指针是两种不同的类型。数组不是指针,指针也不是数组

您可以根据您的需求使用calloc , malloc or realloc

malloc函数分配n个字节的内存,适合于任何类型的存储。这个指针适合传递给free(释放它)或realloc(改变它的大小(并可能将它移动到不同的位置)。与malloc一样,Calloc分配nmemb*size字节,并将它们设置为所有位为0。
应该注意的是,所有位的0不一定是有效的空指针或浮点0,因此不能依赖callloc来正确初始化所有数据类型。

下面是一些代码示例

#include<stdlib.h>
/* 
    some code
*/
n = some_calculation() ; // array size generated at runtime
// data_type is the type of the array eg. int or struct
//using calloc ,it will set allocated values to zero or NULL as per their data_type
data_type *array = calloc(n,sizeof(data_type)) ;
// using malloc , it will only allocate adresses, they may contain garbage values
data_type *array = (data_type *)malloc(n);
// using realloc
array = (data_type *) realloc(array, new_n);
// after you have used your array , you can free the memory allocated
free(array);    

可以使用alloca实现动态大小数组的等效实现。这个函数在当前函数的堆栈帧中的系统堆栈上分配空间,就好像它是一个局部变量一样。例如:

void fun(int i) {
   int a[i];
   ...
}

将被实现为:

void fun(int i) {
   int *a = alloca(i * sizeof(int));
   ...
}

分配的空间在函数返回时被"释放"。然而,alloca不符合POSIX。

相关内容

  • 没有找到相关文章

最新更新