带你搞懂指针和数组方面的相关例题(1)

引言

要搞懂下面这些例题,首先你要知道关于数组名的意义以下这几点:
数组名的意义:

  1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
  2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
  3. 除此之外所有的数组名都表示首元素的地址。

一维数组

//32位平台下
//一维数组
int main()
{
	int a[] = { 1, 2, 3, 4 };
	printf("%d\n", sizeof(a));//16
	//计算的是整个数组的大小,整个数组4个元素,每个元素字节大小为4,所以结果为4 * 4 = 16
	printf("%d\n", sizeof(a + 0));//4
	//a + 0表示的是第一个元素的地址,它计算的是地址的大小,地址的大小在32位平台下为4,在64位平台下为8
	printf("%d\n", sizeof(*a));//4
	//a在这里表示为数组首元素的地址,即1的地址,对1的地址解引用。就是求数组首元素的大小。1是整型,整型大小为4
	printf("%d\n", sizeof(a + 1));//4
	//a在这里表示为首元素的地址,首元素地址加1表示跳过一个元素,a + 1指向的是第二个元素的地址。第二个元素的地址大小为4
	printf("%d\n", sizeof(a[1]));//4
	//计算数组第二个元素的大小,即结果为4

	printf("%d\n", sizeof(&a));//4
	//计算的是整个数组的地址,只要求地址的大小,就记住,32位平台下大小为4,64位平台下大小为8.这里结果是4
	printf("%d\n", sizeof(*&a));//16
	//计算的是整个数组的大小,&a表示取出的是整个数组的地址,然后对整个数组的地址进行解引用,所以计算的就是整个数组的大小。结果为16
	printf("%d\n", sizeof(&a + 1));//4
	//这里&a表示的是整个数组的地址,它加1,即是跳过整个数组,然后指向下一个位置的地址。即数组后面的空间的地址,结果为4.
	printf("%d\n", sizeof(&a[0]));//4
	//计算的是数组第一个元素的地址的大小。结果为4
	printf("%d\n", sizeof(&a[0] + 1));//4
	//计算的是数组第二个元素的地址的大小。结果为4
	return 0;
}

字符数组

//32位平台下
//字符数组 
int main()
{
	char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
	printf("%d\n", sizeof(arr));//6
	//数组名单独放在sizeof内部,计算的是整个数组的大小,因为数组有6个元素,每个元素是char类型。所以结果为6
	printf("%d\n", sizeof(arr + 0));//4
	//表示的是首元素地址,结果为4
	printf("%d\n", sizeof(*arr));//1
	//表示的是对数组首元素地址进行解引用。计算的是字符‘a’的大小,为1
	printf("%d\n", sizeof(arr[1]));//1
	//计算的是字符‘b’的大小,结果为1
	printf("%d\n", sizeof(&arr));//4
	//计算的整个数组的地址大小,结果为4
	printf("%d\n", sizeof(&arr + 1));//4
	//计算的是跳过整个数组后的位置的地址,结果为4
	printf("%d\n", sizeof(&arr[0] + 1));//4
	//计算的是第二个元素,字符‘b’的地址。结果为4


	printf("%d\n", strlen(arr));//随机值
	//这里的arr表示首元素地址,strlen是求长度,给一个地址,从前向后数,遇到‘\0’停下来。
	//这里没有‘\0',故结果是随机值。准确的说是比6大的随机值,因为数组里面已经有了6个元素。
	printf("%d\n", strlen(arr + 0));//随机值
	//这里的arr + 0表示首元素地址.故结果也是随机值
	printf("%d\n", strlen(*arr));//报错
	//首先strlen()的使用,它接收的得是一个地址;而*arr在这里表示的是字符‘a’,把字符给它传过去,故结果会报错
	printf("%d\n", strlen(arr[1]));//报错
    //同上,结果报错
	printf("%d\n", strlen(&arr));//
	//&arr在这里表示的是数组地址,把数组地址给strlen传过去,strlen接收它,
	//站在它的角度,依然是字符串的地址,依然是从字符‘a’的地址开始向后数,故结果仍是随机值
	printf("%d\n", strlen(&arr + 1));//随机值
	//在这里计算的是从跳过整个数组后的位置的地址,开始向后数直到遇到‘\0',才停止的长度。故为随机值。
	//准确来说,与上面的区别来说,结果为随机值-6.
	printf("%d\n", strlen(&arr[0] + 1));//随机值
	//从字符‘b’开始向后数,结果也为随机值。准确来说,结果为随机值 - 1.



	char arr[] = "abcdef";
	//[a b c d e f \0]
	printf("%d\n", sizeof(arr));//7
	//计算的是整个数组的大小,结果为7
	printf("%d\n", sizeof(arr + 0));//4
	//计算的是首元素地址a的大小,结果为1
	printf("%d\n", sizeof(*arr));//1
	//对数组的首元素地址进行解引用,即计算的是a的大小,结果为1
	printf("%d\n", sizeof(arr[1]));//1
	//计算的是字符b的大小,结果为1
	printf("%d\n", sizeof(&arr));//4
	//计算的是整个数组的地址,结果为4
	printf("%d\n", sizeof(&arr + 1));//4
	//计算的是跳过整个数组的后的位置的地址,结果为4
	printf("%d\n", sizeof(&arr[0] + 1));//4
	//计算的是b的地址,结果为4


	printf("%d\n", strlen(arr));//6
	//计算的是字符串的长度,从a的地址开始向后数,遇到\0停止,结果为6 
	printf("%d\n", strlen(arr + 0));//6
	//从a的地址开始向后数,遇到\0停止,结果为6 
	printf("%d\n", strlen(*arr));//报错
	//传给strlen的不是地址,故结果报错
	printf("%d\n", strlen(arr[1]));//报错
	//传给strlen的不是地址,故结果报错
	printf("%d\n", strlen(&arr));//6
	//从a的地址开始向后数,遇到\0停止,结果为6 
	printf("%d\n", strlen(&arr + 1));//随机值
	//跳过整个数组之后的位置的地址开始向后数,不知何时遇到\0,故结果为随机值
	printf("%d\n", strlen(&arr[0] + 1));//5
	//从b的地址开始向后数,遇到\0停止,结果为5


	char *p = "abcdef";
	printf("%d\n", sizeof(p));//4
	//计算的是指针变量的大小,p在这里是一个字符指针。结果为4
	printf("%d\n", sizeof(p + 1));//4
	//p本来是a的地址,p + 1 就变成了b的地址,故结果为4
	printf("%d\n", sizeof(*p));//1
	//p是a的地址,对a解引用,计算的是a的大小,结果为1
	printf("%d\n", sizeof(p[0]));//1
	//p[0]等同于*(p + 0),计算的是a的大小,结果为1
	printf("%d\n", sizeof(&p));//4
	//计算的是p的地址,结果为4
	printf("%d\n", sizeof(&p + 1));//4
	//计算的是跳过p后的位置的地址,结果为4
	printf("%d\n", sizeof(&p[0] + 1));//4
	//计算的是b的地址,结果为4

	printf("%d\n", strlen(p));//6
	//把a的地址交给p,从a的地址开始数,结果为6
	printf("%d\n", strlen(p + 1));//5
	//从b的地址开始数,结果为5
	printf("%d\n", strlen(*p));//报错
	//传给strlen的不是地址,故结果报错
	printf("%d\n", strlen(p[0]));//报错
	//传给strlen的不是地址,故结果报错
	printf("%d\n", strlen(&p));//随机值
	//p的地址不清楚,故结果为随机值
	printf("%d\n", strlen(&p + 1));//随机值
	//跳过p的后的位置的地址,结果为随机值
	printf("%d\n", strlen(&p[0] + 1));//5
	//从b的地址开始数,结果为5
	return 0}

二维数组

//二维数组
int main()
{
	int a[3][4] = { 0 };
	printf("%d\n", sizeof(a));//48
	//计算的是整个数组的大小,二维数组,三行四列,共有12个元素,每个元素是int型,故结果为48
	printf("%d\n", sizeof(a[0][0]));//4
	//计算的是第一行第一个元素的大小,结果为4
	printf("%d\n", sizeof(a[0]));//16
	//把a[0]看作一个一维数组,那么a[0]就可以看作一维数组的数组名,数组名单独放在sizeof内部,
	//所以a[0]表示整个的第一行,计算的是整个第一行的大小,第一行有4个元素,结果为16
	printf("%d\n", sizeof(a[0] + 1));//4
	//a[0]作为数组名并没有单独放在sizeof内部,也没有取地址,
	//因此在这里表示的是第一行第一个元素的地址,加1表示的是第一行第二个元素的地址,故结果为4
	printf("%d\n", sizeof(*(a[0] + 1)));//4
	//同上,对第一行第二个元素解引用得到一个整型元素,大小为4.
	printf("%d\n", sizeof(a + 1));//4
	//二维数组数组名a在这里表示首元素地址,即第一行的地址,第一行地址加1,得到的是第二行的地址,结果为4
	printf("%d\n", sizeof(*(a + 1)));//16
	//*(a + 1)等同于a[1],把a[1]看作一维数组的数组名,则计算的是第二行的大小,结果为16
	//a + 1是第二行的地址,对第二行解引用,则求的是整个第二行的大小
	printf("%d\n", sizeof(&a[0] + 1));//4 
	//对第一行的数组名取地址,得到第一行的地址,加1得到的就是第二行的地址,结果为4
	printf("%d\n", sizeof(*(&a[0] + 1)));//16
	//对第二行的地址进行解引用,计算的就是整个第二行的大小
	printf("%d\n", sizeof(*a));//16
	//a在这里表示首元素的地址,二维数组的首元素就是第一行,
	//即a表示第一行的地址,对第一行的地址解引用,得到的就是整个第一行的大小
	printf("%d\n", sizeof(a[3]));//16
	//sizeof()内部的表达式是不计算的,因此不会去访问它。
	//根据它的类型属性我们可以知道a[3]等同于a[0] a[1] a[2]。因此在这里它的结果为16.
	return 0;
}
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值