C语言中ptr = my_array和ptr =&my_array [0] [0]有什么区别?

sma*_*erd 1 c pointers reference multidimensional-array dereference

我是C的新手.对于以下代码:

int *ptr;
int my_array[5][5] = {{1,2},{3,4,5},{6},{7}};
Run Code Online (Sandbox Code Playgroud)

我注意到我的编译器发出警告:

ptr = my_array;
Run Code Online (Sandbox Code Playgroud)

但工作得很好:

ptr = &my_array[0][0];
Run Code Online (Sandbox Code Playgroud)

这是为什么?

Vla*_*cow 6

在具有罕见异常的表达式中使用的数组将转换为指向其第一个元素的指针.

如果你有这样的数组

int my_array[5][5];
Run Code Online (Sandbox Code Playgroud)

那么它是一个数组数组,它​​是数组元素的类型int[5].例如,表达式my_array[0]具有类型int[5].因此,表达式中使用的数组将转换为指向int ( * )[5]其第一个元素(指向其第一个"行")的类型的指针.

类型int *和类型int ( * )[5]不同,没有从一种类型到另一种类型的隐式转换.

表达式&my_array[0][0]具有类型int *.

因此,如果要将数组重新解释为一维数组,则需要使用隐式转换

ptr = ( int * )my_array;
Run Code Online (Sandbox Code Playgroud)

调查这个示范程序

#include <stdio.h>

int main( void )
{
    int my_array[5][5] = 
    { 
        { 1, 2 },
        { 3, 4, 5 },
        { 6 },
        { 7 } 
    };

    for (int(*p)[5] = my_array; p != my_array + 5; ++p)
    {
        for (int *q = *p; q != *p + 5; ++q)
        {
            printf("%d ", *q);
        }
        putchar('\n');
    }
}
Run Code Online (Sandbox Code Playgroud)

它的输出是

1 2 0 0 0
3 4 5 0 0
6 0 0 0 0
7 0 0 0 0
0 0 0 0 0
Run Code Online (Sandbox Code Playgroud)