int a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};
a是一个二维数组名。a数组包含3行,即3个行元素:a[0],a[1],a[2]。而每一个行元素又是一个一维数组,它包含4个元素,即4个列元素。如a[0]里面包含a[0][0]...a[0][3].
从二维数组角度看,a代表二维数组首元素(a[0])的起始地址,现在的首元素不是一个简单的整形元素,而是由四个整型元素组成的一维数组,因此a代表的是首行的起始地址。a+1代表序号为1的行的起始地址(不能因为a代表a[0]的起始地址,即a为&a[0][0],就认为a+1代表&a[0][1])。a代表首行的起始地址重点在首行上,而不是起始地址,所以a+1就是第二行的起始地址。
理解上方红字这里也就容易理解了:a+1是二维数组中序号为1行的起始地址(序号从0开始算),a+1指向序号为1的行。而*(a+1)并不是a+1单元的内容,因为a+1并不是一个数组元素(a[1][0])的地址(它是a[1])的起始地址(不过二维数组中序号为1行的起始地址和a[1][0]的地址确实一样)所以*(a+1)就是a[1]。
一个是行的地址,一个是元素的地址,只不过那个行的地址是起始地址。行的初始地址前加*号不能理解为对&a[1][0]取值。行的初始地址前加*号得到的还是地址,是一维数组名a[1]的地址,指向的是a[1][0]。1行的起始地址正好也是是1行1列元素的地址。
问:2行3列的地址:*(a+2)+3 ; &a[2][3] ; a[2]+3
同理,可得i行j列的地址。
a[0],a[1]既然是一维数组名,从前面已知,数组名代表数组首元素地址,因此a[0]代表一维数组a[0]中第0列元素的地址,即&a[0][0]。
a[0]是一维数组名,该一维数组中序号为1的元素的地址显然应该用a[0]+1来表示,此时a[0]+1中的1代表一列元素的字节数,即4个字节。所以a数组第0行1列元素的地址为&a[0][1]或者a[0]+1。
a+1: 1行数组的首地址,指向序号为1的行
*(a+1)=a[1],指向a[1][0]
两者地址虽然相同,但是数据类型不同。