关于二维数组初始化后的整体赋值(语言-c语言)

main()
{
int a[2][2]={0},z[1]={2};
// a[0]=z;
scanf("%d",&a[0]);
// a[0]=1;
printf("%d",a[0][0]);
char *s[2];
s[0]="abc";

}

定义一个数组后,不能再整体赋值,把另外一个数组直接传递给这个数组,在编译器的ERROR看到提示是数据类型不同,我猜测是因为z被视作了一个指针,而a[0]是一个整型,编译器又不能转换,所以行不通,在这个推测下,我又尝试了直接给a[0]赋值一个整数,但是依旧无法通过编译,可能是因为a[2][2]为一个二维数组,但是神奇的是,我们用scanf函数,却又可以给a[0],我不知道其中原理,同时char *s[2]; s[0]="abc";这样的数组为什么也能通过编译,s[1]不应该也是一个指针吗,这其中是否进行了类型转换?

a[0]不是int,而是int指针,a[0]和&a[0][0]是一样的, z也是int指针。虽然a[0]和z都是int指针,但是a[0]不能被赋值,a[0]=z;和a[0]=1;都是会报ERROR的,我测试的编译器是GCC 5.4.0。

a, a[0], &a[0][0], &a[0]四个指针的值都是相同的,就是指向同一个地址,可以通过printf("%p,%p,%p,%p\n",a,a[0],&a[0][0],&a[0]);来验证。区别是在指针值+1的时候,也就是printf("%p,%p,%p,%p\n",a+1,a[0]+1,&a[0][0]+1,&a[0]+1);,此时a+1和&a[0]+1是原地址值+8,a[0]+1和&a[0][0]+1是原地址值+4。

这里scanf语句是有问题的,给a[0][0]赋值的话,“%d”需要一个int *,也就是scanf("%d",&a[0][0]),和scanf("%d",a[0]);是等价的,至于&a[0]可以的话我猜是因为地址值是和&a[0][0]一样的,应该是编译器做了类型转换。

char *s[2]; s[0]="abc"; 是可以的,没有类型转换。s是char指针的数组,所以s[0]和s[1]存放的是char指针,s[0]="abc";是将字符串“abc”的首地址赋值给s[0],而s[1]没有被赋值。

因为scanf的输入和对数组赋值不同,scanf的参数需要的是数组元素的地址,
int a[2][2]二维数组可以分解成二个一维数组,即 a[0]、a[1]
a[0]返回的值就是这个一维数组0元素的地址,就是说a[0]等于&a[0][0]
但a[0]不是指针,虽然返回0元素的地址,但是不能被赋值.
而scanf只是把输入的数据写入传参的地址中,并不进行类型检测,数据类型不同也可以正确写入.

再说char *s[2]; s[0]是一个指针需要赋值的是一个地址,而"abc"返回的就是这个字符串的首地址,这没什么问题

如有帮助,请点击我的回答下方的【采纳该答案】按钮帮忙采纳下,谢谢!

img