繁体   English   中英

C中的二维arrays及子数组的长度

[英]Two-Dimensional arrays in C and the length of sub-array

在此示例中,如何检查子数组 (*last) 的长度?

int
main()
{
    int *arr[3];
    arr[0] = (int[]){1, 2, 9, 4, 5};
    arr[1] = (int[]){10, 2, 8};
    arr[2] = (int[]){20, 2, 7, 0, 10};
    
    
    int *last = arr[2];
    return 0;
}

不使用 sizeof(因为指针)并且不使用

while (*last) { ... }

因为数组中为零?

如果你有一个长度只能在运行时知道的数组,你必须以某种方式存储足够的信息来恢复该长度。 这可能是通过简单地存储长度,作为数组的一部分或在一些并行结构中,或者在数组的末尾放置一个标记值(如果有一个可能的标记值永远不会作为实际数据出现),或者以其他方式,取决于您的创造力。

如果可以在编译时计算长度,则可以使用某种宏 hack 将长度存储在数据中。 但是您需要注意复合文字的生命周期:

  1. 复合文字的值是由初始化列表初始化的未命名的 object 的值。 如果复合文字出现在 function 的主体之外,则 object 的存储持续时间为 static; 否则,它具有与封闭块关联的自动存储持续时间。

因此,存储指向在顶层声明的复合文字的指针是安全的,并且最安全的(但不一定是好的风格,请参见注释 1)存储指向在main()的外部块中声明的复合文字的指针,它在程序终止之前不会退出。 但是,如果您存储程序中其他任何地方声明的复合文字的地址,则需要确保您存储指针的 object 不会超过复合文字 object 的寿命。特别是,从function 是灾难的根源。

因此,在您的示例的特定情况下,您可以使用以下“X-macro”hack(但确实不可取):

int main(void) {
    #define ARR              \
        X(1, 2, 9, 4, 5),    \
        X(10, 2, 8),         \
        X(20, 2, 7, 0, 10)

    #define X(...) (int[]){__VA_ARGS__}
    int *arr[] = { ARR };
    #undef X

    #define X(...) (sizeof((int[]){__VA_ARGS__})/sizeof(int))
    int arr_len[] = { ARR };
    #undef X

    #undef ARR

    printf("The last element of arr[2] is %d\n", arr[2][arr_len[2] - 1]);
}

笔记

  1. 将指针存储到在main()的外部块中声明的复合文字是一种糟糕的风格,因为赋值稍后可能会移动到子块或不同的 function 中,从而创建一个悬空指针。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM