数组名
#include<stdio.h>
int main()
{
#if 0
int a[5] = {1,2,3,4,5};
printf("%d\n", sizeof(a));//20,a代表整个数组
printf("%d\n", sizeof(&a));//4,&a只是个(指向整个一维数组的)指针常量,在32位操作系统下,占4字节
printf("%d\n", sizeof(&a[0]+1));//4,指针常量
printf("%d\n", a);//10352456,a代表数组首元素的地址
printf("%d\n", a+1);//10352456+4
printf("%d\n", *(a+1));//2
printf("%d\n", &a[0]);//10352456,*(a+i) == a[i]
printf("%d\n", &a);//10352456
printf("%d\n", &a[0]+1);//10352456+4
printf("%d\n", &a+1);//10352456+5*4
//在一维数组中
//数组名代表整个数组的时候只有两种情况:
//1、sizeof(数组名);2、&数组名
//其余情况下,数组名代表的是数组首元素的地址
#endif
#if 0
以int a[3][4] = {{1,3,5,7}, {9,11,13,15}, {17,19,21,23}};为例
1、a是二维数组名。
a数组包含3个元素,即3个行元素:a[0]、a[1]、a[2]。
而每一个行元素又是一个一维数组,它包含4个元素,即4个列元素。
可以认为二维数组是“数组的数组”,即二维数组a是由3个一维数组组成的。
2、从二维数组的角度来看,a也是代表二维数组首元素的地址。
不过现在的首元素可不是一个简单的基本整型元素,而是由4个基本整型元素组成的一维数组。
因此,a代表的是首行(即序号为0的行)的首地址。a+i代表序号为i的行的首地址。
如果二维数组的首行的首地址为2000,则a+1的值为2000+4*4=2016,a+1指向a[1],【a[0]与*(a+0)等价】
&a[1][0]的值也为2016,但&a[1][0]+1==a[1]+1的值却是2020。而(a+1)+1=2032。
3、a数组的0行1列元素的地址怎么表示?
(1)&a[0][1]
(2)a[0]是一维数组名,所以a[0]+1。就像一维数组那样。
又因为a[0]与*(a+0)等价,所以还有
(3) *(a+0)+1这不就是*a+1嘛,也就是说“*a”就是a[0][0]的地址,可不再是首行的首地址。请务必记住 *(a+i)和a[i]是等价的。
4、a数组的0行1列元素的值怎么表示?
(1)a[0][1]
(2)*(a[0]+1)
(3)*(*(a+0) + 1)或者*(*a + 1) 请务必记住*a[i]表示i行0列元素的值。
5、再次强调:
二维数组名a是指向行的。因此,a+1中的“1”代表一行中全部元素所占的字节数。
一维数组名a[0]是指向列的。因此,a[0]+1中的“1”代表仅仅一个元素所占的字节数。
在指向行的指针前面加上“*”就转向为指向列的指针。这个列只能是第 i 行第0列,因为你是从行转过来的。
而在指向列的指针前面加上“&”就转向为指向行的指针。
//&a[i] == a+i[&(*(a+i)) == a+i,而且&(*(a+1)+0) != a+1,“&”要求左值],
//&a[i][0] == a[i]
//&(&a[0][0]) != a+0,其中,&(&a[0][0])的“&”要求左值
6、注意:
不要把&a[i]简单地理解为a[i]的地址,因为并不存在a[i]这样一个实际的存储数据的内存单元。
它只是一种地址的计算方法,能得到第 i 行的首地址,&a[i]和a[i]的值是一样的,但它们的含义是不同的。
&a[i]或a+i指向行,而a[i]或*(a+i)或&a[i][0]指向列。
当列下标 j 为0时,&a[i]和a[i](即a[i]+j)值相等,即它们代表同一地址,
但应注意它们所指向的对象是不同的,即指针的基类型是不同的。
*(a+i)只是a[i]的另一种表示形式,不要简单地认为*(a+i)是“a+i所指单元中的内容”。
在一维数组中,a+i指的是一个数组元素的内存单元,在该单元中有具体值,上述说法是正确的。
而对二维数组来讲,a+i不是指向具体的内存单元,而是指向行。
#endif
//在二维数组中
//数组名代表整个二维数组的时候只有2种情况:
//1、sizeof(数组名);
//2、&数组名;
//其余情况下,数组名代表的是二维数组首元素(首元素是一个整个的一维数组)的地址
//a/a+0指向的是a[0],而a[0]指向的是a[0][0]。
//a+i指向的是a[i],而a[i]指向的是a[i][0]。
//&a[i] == a+i[&(*(a+i)) == a+i,而且&(*(a+1)+0) != a+1,“&”要求左值],
//&a[i][0] == a[i]
//&(&a[0][0]) != a+0,其中,&(&a[0][0])的“&”要求左值
//*a == *(a+0),但是&a != &(a+0)
//而sizeof(*(数组名+i))/sizeof(数组名[i]) 和 &(*(数组名+i))/&数组名[i]代表第i个的整个一维数组
//其余情况下,代表的是一维数组首元素的地址
printf("%d\n", sizeof(&(a+1)));//不能编译过,error C2102: “&”要求左值
printf("%d\n", sizeof(&(a+0)));//不能编译过,error C2102: “&”要求左值
//printf("%d\n", sizeof(&a));//4,指针常量,指向整个二维数组的指针常量
printf("%d\n", sizeof(&(&a[0])));//不能编译过,error C2102: “&”要求左值
//也就是说&不能接表达式,也不能&(&)。
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
//printf("%d\n", sizeof(a));//48,a代表整个二维数组
//printf("%d\n", sizeof(*a));//16,*a == *(a+0)等价于a[0],sizeof(a[i])中的a[i]代表第i个的整个一维数组
//printf("%d\n", sizeof(&a));//4,指针常量,但它是指向整个二维数组的指针常量
printf("%d\n", a);//19922092
printf("%d\n", *a);//19922092,*a == *(a+0)等价于a[0]
printf("%d\n", *a+1);//19922096 = 19922092+4,*a == *(a+0)等价于a[0],a[0]+1,相当于一维数组名+1。
printf("%d\n", &a);//19922092
printf("%d\n", &a+1);//19922140 = 199221092+12*4
printf("%d\n", *a[0]);//1
//printf("%d\n", sizeof(a+1));//4,指针常量,a+1是指向a[1]的,类似于一维数组的sizeof(&a)
//printf("%d\n", sizeof(*(a+1)));//16,*(a+1)等价于a[1],a[i]在sizeof中单独使用代表第i行的一维数组
printf("%d\n", sizeof(&(a+1)));//不能编译过,error C2102: “&”要求左值
printf("%d\n", a+1);//19922108 = 19922092+4*4,a就是指向二维数组首元素的地址,只不过这个首元素是一个整个的一维数组
printf("%d\n", &a[0]+1);//19922108 = 19922092+4*4
printf("%d\n", &a[0][0]+1);//19922092+4,相当于一维数组名+1。
printf("%d\n", &a[0][1]+1);//19922092+4+4
printf("%d\n", &a[1][0]+1);//19922092+5*4
printf("%d\n", *(a+1));//19922108 = 19922092+4*4,*(a+1)等价于a[1]
printf("%d\n", *(a+1)+1);//19922092+5*4
printf("%d\n", *a+1);//19922096 = 19922092+4,*a == *(a+0)等价于a[0],a[0]+1,相当于一维数组名+1
printf("%d\n", &(*(a))+1);//19922092+4*4
printf("%d\n", &(*(a+1))+1);//19922092+4*4+4*4
//printf("%d\n", sizeof(a+0));//4,指针常量,a+0是指向a[0]的,类似于一维数组的sizeof(&a)
//printf("%d\n", sizeof(*(a+0)));//16,*(a+0)等价于a[0],a[i]在sizeof中单独使用代表第i行的一维数组
printf("%d\n", sizeof(&(a+0)));//不能编译过,error C2102: “&”要求左值
printf("%d\n", a+0);//19922092,a+0是指向a[0]的
printf("%d\n", *(a+0));//19922092,*(a+0)等价于a[0]
//printf("%d\n", sizeof(&a+1));//4,指针常量,是下一个二维数组的首地址
//printf("%d\n", sizeof(a[1]));//16,a[1]代表第1行的一维数组
//printf("%d\n", sizeof(&a[1]));//4,指针常量,&a[1]等价于a+1
//printf("%d\n", sizeof(&a[1]+1));//4,&a[1]+1 == a+1 +1 == a+2
printf("%d\n", &a+1);//19922140 = 199221092+12*4
printf("%d\n", a[1]);//19922108 = 199221092+4*4
printf("%d\n", &a[1]);//19922108 = 199221092+4*4
printf("%d\n", &a[1]+1);//19922124 = 199221092+4*4+4*4
//printf("%d\n", sizeof(&a+0));//4,指针常量,当前二维数组的首地址
//printf("%d\n", sizeof(a[0]));//16,a[0]代表第0行的一维数组
//printf("%d\n", sizeof(&a[0]));//4,指针常量,&a[0]等价于a+0
//printf("%d\n", sizeof(&a[0]+1));//4,&a[0]+1 == a+1
printf("%d\n", sizeof(&(&a[0])));//不能编译过,error C2102: “&”要求左值
printf("%d\n", &a+0);//19922092
printf("%d\n", a[0]);//19922092
printf("%d\n", &a[0]);//19922092
printf("%d\n", &a[0]+1);//19922108 = 199221092+4*4
//printf("%d\n", sizeof(a[1]+1));//4,a[1][1]的地址
//printf("%d\n", sizeof(*(a[1]+1)));//4,a[1][1]
printf("%d\n", a[1]+1);//19922112 = 199221092+5*4
printf("%d\n", *(a[1]+1));//6
//printf("%d\n", sizeof(a[0]+1));//4,a[0][1]的地址
//printf("%d\n", sizeof(*(a[0]+1)));//4,a[0][1]
printf("%d\n", a[0]+1);//19922196 = 19922092+4
printf("%d\n", *(a[0]+1));//2
return 0;
}
数组传参