在C中,向数组传递指针的正确方法是什么?

在C中,向数组传递指针的正确方法是什么?,c,c99,clang-static-analyzer,C,C99,Clang Static Analyzer,以这段代码为例: #include <stdio.h> void print_array(size_t size, unsigned (*myarray)[]) { printf("Array size: %lu\n", size); for (size_t i = 0; i < size; ++i) printf("%u ", (*myarray)[i]); printf("\n"); } int main() { un

以这段代码为例:

#include <stdio.h>
void print_array(size_t size, unsigned (*myarray)[])
{
    printf("Array size: %lu\n", size);
    for (size_t i = 0; i < size; ++i)
            printf("%u ", (*myarray)[i]);
    printf("\n");
}
int main() {
    unsigned myarray[] = { 9, 8, 7, 6, 5 };
    print_array(sizeof(myarray) / sizeof(unsigned), &myarray);
    return 0;
}
输出为:

Array size: 5
9 8 7 6 5 

这段代码中的错误是什么?在C中向数组传递指针的正确方法是什么?

您只需传递一个指针,并使用数组变量表示其第一个元素开始的地址这一事实。 它似乎在使用pedantic和clang时,对函数参数可能指向的对象做了很多假设,所以它抱怨

void print_array(size_t size, const unsigned *myarray)
{
    printf("Array size: %lu\n", size);
    for (size_t i = 0; i < size; ++i)
            printf("%u ", myarray[i]);
    printf("\n");
}

int main() {
    unsigned myarray[] = { 9, 8, 7, 6, 5 };
    print_array(sizeof(myarray) / sizeof(unsigned), myarray);
    return 0;
}
void print\u数组(size\t size,const unsigned*myarray)
{
printf(“数组大小:%lu\n”,大小);
对于(大小i=0;i
这似乎是误报。代码没有问题-尽管样式有点异国情调,但都是有效的C

如果注释是关于实际缺少初始化,则可能与工具未检查调用方有关。但是,即使分析器只考虑本地转换单元,它也不能假设传递的变量在默认情况下是未初始化的。这将是一个非常奇怪的假设

可能分析人员被吓到了,您实际上正在将一个
无符号(*myarray)[5]
传递给一个函数,该函数需要一个
无符号(*myarray)[
(指向不完整类型的指针,一个大小未指定的数组)。您可以尝试将参数更改为
unsigned(*myarray)[size])
,看看它是否能让工具更快乐

编辑:不过数组指针类型是兼容的,所以工具也不应该因此而抱怨。根据C17 6.7.6.2/6,一种或两种数组类型可以省略大小说明符,并且仍然兼容:

对于要兼容的两种数组类型,两者都应具有兼容的元素类型,如果两个大小说明符都存在,并且都是整数常量表达式,则两个大小说明符应具有相同的常量值


你能给出编译的命令吗?看起来像C++一样编译,而不是CcCon分析器只检查当前函数,但不调用它。当前函数中没有对unsigned(*myarray)[]进行初始化,因此analyzer会向指向组成它们的元素的指针抛出warinigArrays衰减。所以
void print\u array(size\t size,unsigned*myarray)
就可以了。您可以使用`print_array(sizeof(myarray)/sizeof(unsigned),myarray)调用它<代码>。(在print_array`实现中也需要相应地进行一些修改)我用来编译它的命令是/usr/bin/./lib/clang/ccc analyzer-Wall-Wpedantic-Wextra src/main.c-o test在c语言中,数组在传递给函数时衰减为指向其第一个元素的指针。是的,这段代码更容易阅读,但这并不能解释工具警告。(还应该使用const correction。)顺便说一句,问题是“在C中向数组传递指针的正确方式是什么?”严格来说,这段代码并没有这样做——它是向第一个元素传递指针。在这个版本中,当将unsigned*ptr=NULL作为myarray传递时,没有警告,在我介绍的版本中,会有一个警告。此答案不回答所问的问题,不应进行表决。向数组类型传递完整指针确实会使警告静音。@AleksanderBobiński!我真的不知道不完整类型的数组指针是否与固定大小的数组指针兼容。我想不是,但C标准很模糊。它提到了一些关于如何处理函数声明中不完整数组类型的内容,但这里是函数定义。指针类型与C 2018 6.7.6.2 6兼容。请注意,没有大小的数组类型是不完整的类型;它不是一个不完整类型的数组。@EricPostIschil Ok,因此一个或两个数组类型可以省略数组大小,并且它们将是兼容的。没有解释为什么静态分析仪仍然发出警告。我将添加一个关于阵列兼容性的注释。
void print_array(size_t size, const unsigned *myarray)
{
    printf("Array size: %lu\n", size);
    for (size_t i = 0; i < size; ++i)
            printf("%u ", myarray[i]);
    printf("\n");
}

int main() {
    unsigned myarray[] = { 9, 8, 7, 6, 5 };
    print_array(sizeof(myarray) / sizeof(unsigned), myarray);
    return 0;
}