为什么在分配指向2D数组的指针时需要指定行?

3 c pointers multidimensional-array implicit-conversion

当没有提到2D数组的行时,编译器声明"从不兼容的指针类型赋值",我一直认为没有括号的数组意味着第一个元素的地址,在这种情况下是元素的地址twodstring [0] [0]

当提到行时,编译器没有说出错误,我想知道为什么会这样?

#include<stdio.h>

int main()
{

  char onedstring[]={"1D Array"};
  char twodstring[][5]={"2D","Array"};
  char *p1,*p2;

  p1=onedstring;
  p2=twodstring;
  p2=twodstring[1];

}
Run Code Online (Sandbox Code Playgroud)

Vla*_*cow 5

二维数组

char a[M][N];
Run Code Online (Sandbox Code Playgroud)

可以使用typedef以下列方式声明

typedef char T[N];

T a[M];
Run Code Online (Sandbox Code Playgroud)

因此,a可以声明指向数组的第一个元素的指针

T *p = a;
Run Code Online (Sandbox Code Playgroud)

where T是该类型的别名char[N].现在我们可以编写反向替换

char ( *p )[N] = a;
Run Code Online (Sandbox Code Playgroud)

那是二维数组的元素是一维数组.

这个宣言

char ( *p )[N] = a;
Run Code Online (Sandbox Code Playgroud)

相当于

char ( *p )[N] = &a[0];
Run Code Online (Sandbox Code Playgroud)

哪里a[0]有类型char[N].所以指针指向数组的第一个"行".

取消引用指针,您将获得该类型的对象char[N].

注意可以声明二维数组

char ( a[M] )[N];
Run Code Online (Sandbox Code Playgroud)

所以用一维数组声明符替换a[M]你得到的指针

char ( a[M] )[N];
char (  *p  )[N] = a;
Run Code Online (Sandbox Code Playgroud)

如果你要声明这样的指针

char *p1;
Run Code Online (Sandbox Code Playgroud)

那么你可以写一些例子

p1 = a[1];
Run Code Online (Sandbox Code Playgroud)

在这个表达式中a[1]是一个类型的一维数组char[N].使用表达式作为初始化程序,数组将转换为指向其第一个具有该类型的元素的指针char *.

所以这个表达式声明

p1 = a[1];
Run Code Online (Sandbox Code Playgroud)

相当于

p1 = &a[1][0];
Run Code Online (Sandbox Code Playgroud)

取消引用此指针,您将获得该类型的对象char.