如何在C语言中动态声明数组的大小?

13

我基本上想要C语言中等价于这个的代码(只需要数组部分,不需要类和字符串解析等):

public class Example
{
    static int[] foo;
    public static void main(String[] args)
    {
        int size = Integer.parseInt(args[0]);
        foo = new int[size]; // This part
    }
}

请原谅我的 C 语言无知。我已经被 Java 腐蚀了 ;)


看起来你也被C++给腐蚀了 ;) - gbarry
6个回答

11
/* We include the following to get the prototypes for:
 * malloc -- allocates memory on the freestore
 * free   -- releases memory allocated via above
 * atoi   -- convert a C-style string to an integer
 * strtoul -- is strongly suggested though as a replacement
*/
#include <stdlib.h>
static int *foo;
int main(int argc, char *argv[]) {
    size_t size = atoi(argv[ 1 ]); /*argv[ 0 ] is the executable's name */
    foo = malloc(size * sizeof *foo); /* create an array of size `size` */
    if (foo) {  /* allocation succeeded */
      /* do something with foo */
      free(foo); /* release the memory */
    }
    return 0;
}

注意:此为即兴写作,没有进行任何错误检查。


1
你应该提到 "if (foo) free(foo);" 是"垃圾回收"。 - Joel
1
C语言中没有垃圾回收机制。我开玩笑的;-) 但是我确实加了一些注释。 - dirkgently
我认为不应该将foo声明为静态变量,因为这在Java中的含义是不同的。在这里,我们只想要一个全局变量。 - Ben
静态变量有什么问题吗?它是全局的(文件范围),具有内部链接,对于原始帖子的理解比我编写更智能的版本要容易得多(没有全局变量)。此外,这是一个即兴版本,还有很多需要改进的地方。 - dirkgently
@dirkgently 你的回答很好。我只是想说将foo声明为int *就足够了。在Java中,静态关键字用于声明仅实例化一次的变量,而不是每个新对象都实例化一次。 - Ben
显示剩余2条评论

5

在C语言中,如果你忽略错误检查,你可以使用以下方法实现:

#include <stdlib.h>
static int *foo;

int main(int argc, char **argv)
{
     int size = atoi(argv[1]);
     foo = malloc(size * sizeof(*foo));
     ...
}

如果您不想使用全局变量并且您在使用C99,您可以这样做:
int main(int argc, char **argv)
{
    int size = atoi(argv[1]);
    int foo[size];
    ...
}

这里使用了VLA - 变长数组。

4
很不幸,这个问题的许多答案,包括被接受的答案,是正确的,但与OP的代码片段不等价。请记住,operator new[]会为每个数组元素调用默认构造函数。对于像int这样没有构造函数的POD类型,它们将默认初始化(即:零初始化,请参见C++标准的§8.5 ¶5-7)。

我刚刚将malloc(分配未初始化的内存)替换为calloc(分配清零的内存),因此给定C++代码片段的等效代码是:

#include <stdlib.h>  /* atoi, calloc, free */

int main(int argc, char *argv[]) {
    size_t size = atoi(argv[1]);
    int *foo;

    /* allocate zeroed(!) memory for our array */
    foo = calloc(sizeof(*foo), size);
    if (foo) {
        /* do something with foo */

        free(foo); /* release the memory */
    }

    return 0;
}

非常抱歉重新激活这个老问题,但离开时没有留下评论(我没有足够的声望)感觉不太好;-)


2
如果你需要初始化数据,可以使用calloc:
int* arr = calloc (nb_elems, sizeof(int));
/* Do something with your array, then don't forget to release the memory */
free (arr);

这样,分配的内存将被初始化为零,这可能很有用。请注意,您可以使用任何数据类型来替代int。


1

当在运行时实现排序算法时,在函数中声明数组时,你需要 int *a=calloc(n,sizeof(int));。这在 Turbo C++ 中有效。这里是我在归并排序中应用它。


你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

0
int count = getHowManyINeed();
int *foo = malloc(count * sizeof(int));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接