[英]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 将长度存储在数据中。 但是您需要注意复合文字的生命周期:
- 复合文字的值是由初始化列表初始化的未命名的 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]);
}
main()
的外部块中声明的复合文字是一种糟糕的风格,因为赋值稍后可能会移动到子块或不同的 function 中,从而创建一个悬空指针。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.