我对新C感到陌生,我无法找到与此相关的任何内容(也许是因为我不确定我在寻找什么)。
我试图创建一个没有大小的int和float数组(可能是0或者在用户使用该程序时可能会增加)。
我试图做以下事情:
int bills[];
float totalAmount[];
我无法分配最大尺寸,因为我用for循环打印每个数组(如果我指定的尺寸为99 I'将打印99行,我不会想要那个)。
我很确定这是可能的,但我不知道如何。
谢谢!
答案 0 :(得分:5)
C不支持具有动态数量元素的数组。必须在编译时确定数组的元素数,或者可以在创建时在运行时计算C99。创建阵列后,其大小是固定的,无法更改。在少数情况下,[]
之间未在数组定义或数组声明中明确指定大小。
如果您提供初始化程序,则可以定义数组,而不包含最左侧维度的显式大小。编译器将从初始化程序推断出大小:
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";
注意编译器如何在字符串大小写中添加隐式空终止符。
在多个案例中,你可以声明一个没有最左边维度的大小说明符的数组:
extern
类存储的全局变量(数组在别处定义),int main(int argc, char *argv[])
。在这种情况下,无论如何都会忽略为最左边的维度指定的大小。struct
的最后一个成员。这是一个名为灵活数组的C99扩展。编译器没有关于这些数组的实际大小的信息。程序员使用一些其他信息来确定长度,可以是单独的变量,也可以是数组内容。
对于函数参数,数组作为指针传递,即使指定了元素数,sizeof(argv)
也会计算指针的大小。
答案 1 :(得分:2)
您可以使用malloc()
(或calloc()
),realloc()
和free()
的组合来实现此目标。
可以将内存分配为固定大小的块,而不是为每个要存储的号码重新分配内存。
如果您愿意,我们定义一个宏(或const
)BLOCK_SIZE
。
#define BLOCK_SIZE 10
首先声明一个适当类型的指针并分配第一个块。
请注意,malloc()
以及realloc()
如果由于内存不足等原因而发生错误,则会返回NULL
。
int *ptr=malloc(sizeof(int)*BLOCK_SIZE);
if(ptr==NULL)
{
perror("some error");
return 1;
}
现在声明一个变量,以根据当前分配的内存存储最大可能索引(以避免非法内存访问)。
int max_index = BLOCK_SIZE-1;
现在使用循环。
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]);
}
在每次迭代中,我们会检查i
是否大于max_index
。如果是,则在读取值之前使用realloc()
分配另一个块。
完成使用后,不要忘记取消分配内存。
free(ptr);
此外,正如this帖子中所述,malloc()
与realloc()
实际上与后者的第一个参数NULL
相同。
在你发布的代码中,没有必要显式地转换calloc()
的返回值,因为返回的是void
指针,它会被隐式转换为目标指针类型。
答案 2 :(得分:1)
您没有声明没有大小的数组,而是声明指向多个记录的指针。
所以,如果你想做
int bills[];
在C中执行此操作的正确方法是
int* bills;
你必须在某个时间点分配大小并初始化数组。
bills = (int*)malloc(sizeof(int)*items);
其他数据类型的数组也是如此。如果您在运行时之前不知道数组的大小,则应该使用指向运行时分配给正确大小的内存的指针。