在下面的示例中,是否可以使用这样的签名声明test(),以便打印6
?我希望这可以用于样式和可读性目的,因此很清楚该函数采用了正好6个字符的数组,并且它实际上可以使用sizeof
获取此信息。
#include <stdio.h>
void test( char foo[ 6 ] )
{
printf( "%zu\n", sizeof( foo ) ); // Prints 8 as it's a pointer now, but I want 6 as in an array
}
int main()
{
char foo[ 6 ];
printf( "%zu\n", sizeof( foo ) ); // Prints 6, which is what I want
test( foo );
return 0;
}
到目前为止,我能想到的最好的是:
typedef char Foo[ 6 ];
void test( Foo foo )
{
printf( "%zu\n", sizeof( Foo ) ); // Works, but it doesn't even use foo, and I want to get the size information from foo! What if I change the signature of the function later? I would have to update this line too, which is something I'd like to avoid
}
答案 0 :(得分:4)
是的,有可能:
#include <stdio.h>
void test(char (*foo)[6]) // "declare foo as pointer to array 6 of char"
{
printf("%zu\n", sizeof(*foo)); // mind the asterisk
}
int main(void)
{
char foo[6];
test(&foo); // mind the ampersand
return 0;
}
比较cdecl.org(“C gibberish↔English”)
char (*foo)[6]
:“声明foo为指向char”数组6的指针char foo[6]
:“将foo声明为char的数组6”char *foo[6]
:“将foo声明为指向char的数组6”另一个选择是包装数组。但是如果你不喜欢引用/解除引用,那么这个带有附加成员访问权限的解决方案可能不是你想要的:
#include <stdio.h>
typedef struct
{
char data[6];
} char_6_array_t;
void test(char_6_array_t foo)
{
// prints "6: abcdef"
printf("%zu: %.*s\n", sizeof(foo.data), (int) sizeof(foo.data), foo.data);
}
int main(void)
{
char_6_array_t foo = { {"abcdef"} };
// Depending on the ABI, this prints 6, 8, or possibly 16:
printf("%zu\n", sizeof(foo));
test(foo);
return 0;
}
答案 1 :(得分:2)
不是没有一些杂技。
有很多方法可以让它发挥作用,无论是你问题中的全局变量,还是凯提出的解决方案。但是C语言不会通过值将整个数组作为函数参数传递。您的test
函数只接收指向char
的指针,编译器不会告诉您指针指向的数组大小。
其他一些语言,比如C ++,会为你处理这类事情。但是在C中,你只需要自己跟踪尺寸,无论如何。一种常见的方法是在函数中添加另一个参数,传递数组的大小。
在你给出的函数原型中:
void test( char foo[ 6 ] )
我认为不幸的是编译器忽略了6
,尽管你可能会认为这并没有多大意义。对于多维数组,编译器确实注意你给出的大小,除了第一个,所以foo[][6]
有效,并且必须告诉编译器每行的每一行你的阵列结束了。 (见this question。)
另一种解决方法是使用这样的结构:
struct array {
char *a; // pointer to your real array
size_t s; // how many elements your array has
};
您可以将其中一个结构传递给您的函数,然后从中读取大小。