c - sizeof 运算符与可变长度数组一起作为函数参数

标签 c arrays gcc sizeof variable-length-array

根据 GNU 关于 Arrays of Variable Length 的文档,可以使用 sizeof 运算符来确定传递给函数的可变长度数组的大小:

You can also use variable-length arrays as arguments to functions:

struct entry
tester (int len, char data[len][len])
{
  /* … */
}

The length of an array is computed once when the storage is allocated and is remembered for the scope of the array in case you access it with sizeof.

但是,当使用下面的完整代码示例尝试此示例时,sizeof 运算符返回指针的大小,不是分配的 vla 的大小,因为预期基于上面的 GNU 片段。

我知道在 C 中传递数组类似于传递指向数组第一个元素的指针,但是由于我们在这种情况下在函数签名中指定了大小,所以我希望行为能够模仿使用 sizeof 在声明数组的范围内。

我还意识到我可以使用 len 参数来计算大小;但为了方便和理解 GNU 实现,我仍然认为这是一个有趣的(如果不重要的话)问题。

提前感谢任何可以对此提供见解的人!

// file: vla.c
#include <stdio.h>

void foo(int len, char data[len][len]) {
  printf("sizeof \"foo\" data: %lu\n", sizeof(data));
}

int main(int argc, char * argv[]) {
  char data[argc][argc];
  printf("sizeof \"main\" data: %lu\n", sizeof(data));
  foo(argc, data);
}

编译使用:

gcc vla.c -o vla -std=c11

调用使用:

./vla 2 3 4 5

输出:

sizeof "main" data: 25
sizeof "foo" data: 8

分析:

main data 的大小是有意义的; argc 是 5,因此它是一个 (5 * 5 = 25) 字节的二维数组。

foo data 的大小预计也是 25,但实际上是指针的大小。看起来编译器没有使用它知道 foodata 的大小这一事实,因为它是函数签名的一部分。

最佳答案

声明为 char data[len][len] 的参数实际上是 char (*data)[len],一个指向 VLA 的指针。没有真正的数组参数这样的东西,声明中的第一个 len 是没有意义的。如果您使用 sizeof *data,您将返回 len,因为指向的类型被可变地修改。

如果您希望两个 len 都有意义,您可以传递一个指向整个数组的指针类型而不是一个指向第一个元素的指针,声明参数 char (*数据)[长度][长度]。现在 sizeof *datalen*len。但是您需要使用 (*data)[i][j] 来访问它。调用该函数时,您还需要使用 & 运算符:

int l = 42;
char array[l][l];
foo(l, &array);

关于c - sizeof 运算符与可变长度数组一起作为函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51665460/

相关文章:

GCC 可以忽略函数的静态声明吗?

c - 如何使用 malloc 从 C 中的函数创建和返回二维矩阵?

c - 在 C 中的 scanf() 中使用 "\n"

c - 如何在 Makefile 中正确引用 GNU Readline 库?

java - 将字节数组显示为位图以在 Android 中获取图像的问题

gcc - ld : file not found: elf_i386 error on Mac Terminal

c - 解析用户输入的两个值

php - JSON数据集结构

python - 在 2D numpy 数组的子矩阵上高效运行

gcc - 链接共享库绝对与相对路径