C语言 如何在不声明 C 中的大小的情况下创建数组?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/50083744/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 10:44:33  来源:igfitidea点击:

How to create an array without declaring the size in C?

carrayssize

提问by chqrlie

I'm pretty new to new C and I wasn't able to find anything related to this (maybe because I'm not really sure what I'm looking for).

我对新的 C 很陌生,我找不到与此相关的任何内容(也许是因为我不确定我在寻找什么)。

I'm trying to create a int and a float array without a size (it might be 0 or it might increment while the user use the program).

我正在尝试创建一个 int 和一个没有大小的 float 数组(它可能为 0,也可能在用户使用该程序时递增)。

I was trying to do the follow:

我试图做到以下几点:

int bills[];

float totalAmount[];

I can't assign a max size because I'm printing each array with a for loop (If I assign a size of 99 I'll print 99 lines, and I don't want that).

我无法指定最大大小,因为我使用 for 循环打印每个数组(如果我指定大小为 99,我将打印 99 行,我不想要那样)。

I'm pretty sure that this is possible but I don't know how.

我很确定这是可能的,但我不知道如何。

Thanks!

谢谢!

回答by chqrlie

C does not support arrays with a dynamic number of elements. The number of elements of an array must be determined either at compile time or since C99 can be evaluated at runtime at the point of creation. Once the array is created, its size is fixed and cannot be changed. There are a few cases where the size is not explicitly specified between the [], either in array definitions or in array declarations.

C 不支持具有动态元素数量的数组。数组的元素数量必须在编译时确定,或者因为 C99 可以在创建时在运行时进行评估。数组创建后,其大小是固定的,无法更改。在少数情况下[],无论是在数组定义还是在数组声明中,都没有在之间明确指定大小。

You can definean array without an explicit size for the leftmost dimension if you provide an initializer. The compiler will infer the size from the initializer:

您可以定义,如果你提供一个初始化数组没有明确的大小,最左边的维度。编译器将从初始化器推断大小:

int a[] = { 1, 2, 3 };              // equivalent to int a[3] = { 1, 2, 3 };
int m[][2] = {{ 1, 2 }, { 3, 4 }};  // equivalent to int m[2][2] = {{ 1, 2 }, { 3, 4 }};
char s[] = "Hello world\n";         // equivalent to char s[13] = "Hello world\n";

Note how the compiler adds the implicit null terminator in the string case.

请注意编译器如何在字符串大小写中添加隐式空终止符。

You can declarean array without a size specifier for the leftmost dimension in multiples cases:

在多个情况下,您可以为最左边的维度声明一个没有大小说明符的数组:

  • as a global variable with externclass storage (the array is defined elsewhere),
  • as a function parameter: int main(int argc, char *argv[]). In this case the size specified for the leftmost dimension is ignored anyway.
  • as the last member of a struct. This is a C99 extension called a flexible array.
  • 作为具有extern类存储的全局变量(数组在别处定义),
  • 作为函数参数:int main(int argc, char *argv[]). 在这种情况下,无论如何都会忽略为最左侧维度指定的大小。
  • 作为 a 的最后一个成员struct。这是一个称为灵活数组的 C99 扩展。

The compiler has no information on the actual size of these arrays. The programmer with use some other information to determine the length, either from a separate variable or from the array contents.

编译器没有关于这些数组实际大小的信息。程序员使用一些其他信息来确定长度,无论是从单独的变量还是从数组内容。

In the case of a function argument, the array is passed as a pointer and even if the number of elements is specified, sizeof(argv)evaluates to the size of a pointer.

在函数参数的情况下,数组作为指针传递,即使指定了元素数量,也会sizeof(argv)计算为指针的大小。

回答by J...S

You could use a combination of malloc()(or calloc()), realloc()and free()to achieve this.

您可以使用malloc()(或calloc()), realloc()and的组合free()来实现这一点。

Memory can be allocated as blocks of a fixed size rather than reallocating memory for each number to be stored.

内存可以分配为固定大小的块,而不是为每个要存储的数字重新分配内存。

Let's define a macro (or a constif you like) BLOCK_SIZE.

让我们定义一个宏(或者const如果你喜欢的话)BLOCK_SIZE

#define BLOCK_SIZE 10

First declare a pointer of appropriate type and allocate the first block.

首先声明一个适当类型的指针并分配第一个块。

Note that malloc()as well as realloc()return NULLif some error occurred due to reasons like insufficient memory.

请注意,如果由于内存不足等原因发生某些错误malloc(),也会realloc()返回NULL

int *ptr=malloc(sizeof(int)*BLOCK_SIZE);    
if(ptr==NULL)
{
    perror("some error");
    return 1;
}

Now declare a variable to store the maximum possible index as per the currently allocated memory (to avoid illegal memory access).

现在根据当前分配的内存声明一个变量来存储最大可能的索引(以避免非法内存访问)。

int max_index = BLOCK_SIZE-1;

Now use a loop.

现在使用循环。

for(int i=0; ; ++i)
{
    if(i > max_index)
    {
        ptr=realloc(ptr, (max_index+1 + BLOCK_SIZE)*sizeof(int));
        if(ptr == NULL)
        {
            perror("insufficient memory!");
            break;
        }
        printf("\nRealloced!");
        max_index += BLOCK_SIZE;
    }
    scanf("%d", &ptr[i]);
    printf("\n%d: %d", i, ptr[i]);
}

In each iteration, we check if iis greater than max_index. If it is, another block is allocated using realloc()before reading the value.

在每次迭代中,我们检查是否i大于max_index。如果是,则realloc()在读取值之前使用 using 分配另一个块。

Don't forget to deallocate the memory once you are done using it.

使用完毕后不要忘记释放内存。

free(ptr);

Also, as discussed in thispost, malloc()is effectively the same as realloc()with the latter's first argument NULL.

此外,如在讨论这个帖子,malloc()是有效的一样realloc()与后者的第一个参数NULL

And in the code you posted, there's no need to explicitly cast the return value of calloc()as what's returned is a voidpointer which would implicitly be converted to the target pointer type.

在您发布的代码中,无需显式转换返回值,calloc()因为返回的是一个void指针,该指针将隐式转换为目标指针类型。

See thisand this.

看到这个这个

回答by Edwin Buck

You don't declare an array without a size, instead you declare a pointer to a number of records.

您不会声明一个没有大小的数组,而是声明一个指向许多记录的指针。

so, if you wanted to do

所以,如果你想做

int bills[];

The proper way to do this in C is

在 C 中执行此操作的正确方法是

int* bills;

And you will have to allocate the size at some point in time and initialzie the array.

并且您必须在某个时间点分配大小并初始化数组。

bills = (int*)malloc(sizeof(int)*items);

The same goes for arrays of other data types. If you don't know the size of the array until runtime, you should use pointers to memory that is allocated to the correct size at runtime.

其他数据类型的数组也是如此。如果您直到运行时才知道数组的大小,您应该使用指向在运行时分配到正确大小的内存的指针。