如何声明未定义或没有初始大小的数组?

ars*_*sus 33 c

我知道可以使用malloc完成,但我还不知道如何使用它.

例如,我希望用户使用带有哨兵的无限循环来输入几个数字以阻止它(即-1),但由于我不知道他/她将输入多少,我必须声明一个没有初始大小的数组,但我也知道它不会像这样的int arr []; 在编译时,因为它必须有一定数量的元素.

用夸张的大小来声明它如int arr [1000]; 会工作,但感觉愚蠢(并浪费内存,因为它会将1000个整数字节分配到内存中),我想知道更优雅的方式来做到这一点.

gnu*_*nud 36

这可以通过使用指针,并使用在堆上分配内存来完成malloc.请注意,以后无法询问内存块有多大.您必须自己跟踪阵列大小.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char** argv)
{
  /* declare a pointer do an integer */
  int *data; 
  /* we also have to keep track of how big our array is - I use 50 as an example*/
  const int datacount = 50;
  data = malloc(sizeof(int) * datacount); /* allocate memory for 50 int's */
  if (!data) { /* If data == 0 after the call to malloc, allocation failed for some reason */
    perror("Error allocating memory");
    abort();
  }
  /* at this point, we know that data points to a valid block of memory.
     Remember, however, that this memory is not initialized in any way -- it contains garbage.
     Let's start by clearing it. */
  memset(data, 0, sizeof(int)*datacount);
  /* now our array contains all zeroes. */
  data[0] = 1;
  data[2] = 15;
  data[49] = 66; /* the last element in our array, since we start counting from 0 */
  /* Loop through the array, printing out the values (mostly zeroes, but even so) */
  for(int i = 0; i < datacount; ++i) {
    printf("Element %d: %d\n", i, data[i]);
  }
}
Run Code Online (Sandbox Code Playgroud)

而已.接下来是一个更为复杂的解释为什么这个工作:)

我不知道你对C指针的了解程度如何,但C中的数组访问(如array[2])实际上是通过指针访问内存的简写.要访问指向的内存data,请编写*data.这称为解除引用指针.因为data是类型int *,所以*data是类型int.现在来看一个重要的信息:(data + 2)意味着"将2个字节的字节大小添加到指向的地址data".

C中的数组只是相邻内存中的一系列值.array[1]就在旁边array[0].因此,当我们分配一大块内存并希望将其用作数组时,我们需要一种简单的方法来获取内部每个元素的直接地址.幸运的是,C允许我们在指针上使用数组表示法.data[0]意思相同*(data+0),即"访问指向的内存data".data[2]表示*(data+2)并访问int内存块中的第三个.

  • 谢谢。这是我需要的全面解释,谢谢您的额外努力,先生,我现在可以根据您的解释编写代码来尝试一些事情。最后一个问题是,假设我想将其扩展到超过 50 个元素,我将如何增加数组大小? (2认同)

NPE*_*NPE 13

它经常做的方式如下:

  • 分配一些初始(相当小)的数组;
  • 读入这个数组,跟踪你读过多少元素;
  • 一旦数组已满,重新分配它,将大小加倍并保留(即复制)内容;
  • 重复直到完成.

我发现这种模式经常出现.

这个方法的有趣之处在于它允许N人们在O(N)不需要N事先知道的情况下在分摊的时间内逐个地将元素插入到空数组中.


Jen*_*edt 5

Modern C,又名C99,具有可变长度阵列,VLA.不幸的是,并非所有编译器都支持这一点,但如果你的确支持这一点,那么这将是另