【问题标题】:Is there a way to use zero-length arrays with 2d arrays?有没有办法将零长度数组与二维数组一起使用?
【发布时间】:2021-07-19 01:53:44
【问题描述】:

我刚刚发现了零长度数组,我想将它用于二维数组,这些数组的优点是避免了结构内部的指针,因此我们可以释放结构而不是释放它的数据,所以它可以更好地在容器结构中使用,例如链表,而不必传递析构函数,但问题是我不知道如何将它用于二维数组。我的结构看起来像这样:

struct  s_arg
{
    int     argc;
    char    argv[0][0];
};

但问题是:如何在没有另一个包含大小的数组的情况下跟踪每个成员的大小?这是否可以在没有 malloc 的结构成员的情况下做到这一点?

【问题讨论】:

    标签: arrays c


    【解决方案1】:

    没有。

    可以使用不知道大小的数组的唯一原因是您无需知道大小即可访问元素。给定一个数组a,a[0] 位于数组的开头,a[1] 是其后的一个元素,依此类推。任何元素a[i] 的位置都可以在不知道数组大小的情况下计算出来。

    自然,要存在一个数组,就必须有人为其分配内存,因此他们必须知道其大小。所以数组的创建者必须知道它的大小,而用户不需要。

    GCC 允许零长度数组作为扩展,因此结构可以在其末尾有一个数组,其中内存由结构的创建者分配,谁知道它的大小。除了支持旧软件外,一旦 C 标准支持未知大小的数组(声明为无大小,[],称为灵活数组成员),此扩展就变得不必要了。

    对于二维数组,在不知道数组大小的情况下使用数组的能力不适用。给定一个名为a 的二维数组char,a[i][j] 位于a[i] 开始之后的j 元素。这些元素中的每一个都是char,因此计算j char 超出a[i] 很容易。而a[i] 在a 的开始之后开始i 元素。但是a 的元素是char 的数组。要知道i元素有多大,你必须知道元素的大小;你必须知道char数组的大小。

    因此,除非知道第二维的大小,否则不能使用二维数组。

    有一些方法可以使用在运行时知道其第二维大小的二维数组,包括:

    • 使用一维数组并手动计算索引,就像a[i*size + j]一样。
    • 使用一维数组并转换其地址。例如,从具有成员m 的某些结构s 中,(char (*)[size]) s.m,然后可以用作((char (*)[size]) s.m)[i][j]。 (有关将一维数组视为二维数组的语言律师问题,请参阅其他 Stack Overflow 问题和答案。)

    此外,您的成员名称argv 表明您可能希望此结构存储作为main 参数传递的命令行参数。如果是这样,您应该注意main 的第二个参数argv 是指向指针的指针,而不是指向数组的指针。这些字符串中的数据一般不会在内存中排列,用作char 的二维数组。您可以将字符串复制到二维数组中,但这通常会很浪费。

    【讨论】:

    • 感谢您的详细解释。关于argv 的部分,我在互联网上看到有人像int main(int argc, char *argv[]) 这样对他们的主要功能进行原型设计,那么这种说法是假的吗?
    • @Fayeure:这是声明main 的正确方式。 argv 参数是一个指针数组。 char *argv[]本质上是char *(argv[])——argv首先是一个数组,然后它的元素是指针。所以字符串可以在内存中的任何地方——数组的每个元素都是一个指针,一个指针可以指向任何地方。它们不一定被组织成一个数组。 char (*foo)[] 是指向char 数组的指针。 (用这个声明main 是不合适的。)如果知道大小,比如char (*foo)[1024],那么地址上可能有多个char 数组。
    猜你喜欢
    • 1970-01-01
    • 2021-07-04
    • 2019-10-29
    • 2019-10-18
    • 2019-12-31
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多