数组名及数组传参问题

数组名

#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;
}

数组传参
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值