计算指针与数组在sizeof、strlen中的大小

这节我们通过习题来深刻理解sizeof,strlen的区别,以及指针与数组在sizeof,strlen中的大小。

 第一题(一维数组)

//首先我们应该知道数组名两个特殊表示不为首元素地址:1.在sizeof(数组名)这里表示整个数组的大小 2.&数组名 这里表示整个数组地址
//当然我知道指针的大小是4还是8取决的计算机的是32位还是64位,这里我们统一在32位
int main()
{
	int a[] = { 1, 2, 3, 4 };
	printf("%d\n", sizeof(a));//16			整个数组的大小
	printf("%d\n", sizeof(a + 0));//4		首元素的地址 (a+0)-->a[0];
	printf("%d\n", sizeof(*a));//4			对首元素解引用
	printf("%d\n", sizeof(a + 1));//4		第二个元素的大小 (a+1)-->a[1];
	printf("%d\n", sizeof(a[1]));//4        第二个元素的大小
	printf("%d\n", sizeof(&a));//4			取整个数组的地址,但是地址都是为4
	printf("%d\n", sizeof(*&a));//16		对整个数组地址解引用,其实相当于没有操作 *&a-->a
	printf("%d\n", sizeof(&a + 1));//4		取的整个数组的地址,再对整个地址+1,这里相当于int*()[4],还是地址
	printf("%d\n", sizeof(&a[0]));//4		第一个元素的地址
	printf("%d\n", sizeof(&a[0] + 1));//4	第个元素的地址

	


	return 0;
}

第二题(一维数组)

//	//strlen是求字符串长度的,关注的是字符串中的\0,计算的是\0之前出现的字符的个数
//	//strlen是库函数,只针对字符串
//	//sizeof只关注占用内存空间的大小,不在乎内存中放的是什么
//	//sizeof是操作符

int main()
{
	char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };

	printf("%d\n", sizeof(arr));//6			整数组的大小
	printf("%d\n", sizeof(arr + 0));//4		首元素地址的大小-->&a[0]
	printf("%d\n", sizeof(*arr));//1		对首元素地址解引用,就是首元素的大小
	printf("%d\n", sizeof(arr[1]));//1		第二个元素的大小
	printf("%d\n", sizeof(&arr));//4		数组的地址
	printf("%d\n", sizeof(&arr + 1));//4	数组后的地址 位置相当于在arr[7]
	printf("%d\n", sizeof(&arr[0] + 1));//4	第二个元素的地址

	printf("%d\n", strlen(arr));//随机值			因为不是字符串,无法确定'\0'的位置		
	printf("%d\n", strlen(arr + 0));//随机值		
	printf("%d\n", strlen(*arr));//野指针			--> strlen('a');-->strlen(97);无法解析到未定义数组外的地址
	printf("%d\n", strlen(arr[1]));//野指针			-->strlen('b')-->strlen(98);
	printf("%d\n", strlen(&arr));//随机值			首元素地址
	printf("%d\n", strlen(&arr + 1));//随机值-6		整个数组的地址
	printf("%d\n", strlen(&arr[0] + 1));//随机值-1	第二个元素的地址

	return 0;
}

第三题(字符串)

int main()
{
	char arr[] = "abcdef";
	printf("%d\n", sizeof(arr));//7			整个字符串的大小,这里有'\0',1(字节)*7(元素)
	printf("%d\n", sizeof(arr + 0));//4		首元素的地址		
	printf("%d\n", sizeof(*arr));//1		首元素的大小
	printf("%d\n", sizeof(arr[1]));//1		第二个元素的大小	
	printf("%d\n", sizeof(&arr));//4		地址都为4
	printf("%d\n", sizeof(&arr + 1));//4
	printf("%d\n", sizeof(&arr[0] + 1));//4

	printf("%d\n", strlen(arr));//6				计算所以字符串的长度,到'\0'结束
	printf("%d\n", strlen(arr + 0));//6		
	printf("%d\n", strlen(*arr));//error		strlen(地址)
	printf("%d\n", strlen(arr[1]));//error
	printf("%d\n", strlen(&arr));//6			整个字符串地址,但是最开始还是在首元素地址开始的
	printf("%d\n", strlen(&arr + 1));//随机值   相当于第二行的地址开头的地址,这里没有定义,所以为随机值	 
	printf("%d\n", strlen(&arr[0] + 1));//5		从第二元素地址开始计算


	return 0;
}

第四题(指针)

//这里我们需要明白 "abcdef"是放在常量区,char *p的地址是开辟在栈区,他们实在不同的区域内
int main()
{
	char *p = "abcdef";

	printf("%d\n", sizeof(p));//4			整个字符串地址,但是位置开始还是在首元素地址
	printf("%d\n", sizeof(p + 1));//4		整个字符串地址+1,最开始在位置在首元素地址,
//+1之后在第二个元素地址
	printf("%d\n", sizeof(*p));//1			对于首元素地址解引用
	printf("%d\n", sizeof(p[0]));//1		首元素的大小
	printf("%d\n", sizeof(&p));//4			位置 栈空间:【*            】
	//这里相当于一个二级指针,这块开辟的地址与字符串没有任何联系,
//但是sizeof只是计算这块开辟空间的大小

	printf("%d\n", sizeof(&p + 1));//4		该栈空间地址的最后一个 位置:【              *】
	printf("%d\n", sizeof(&p[0] + 1));//4	对元素a的地址+1 就是b的地址

	printf("%d\n", strlen(p));//6			整个字符串地址的首地址开始计算
	printf("%d\n", strlen(p + 1));//5		首地址+1开始计算	
	printf("%d\n", strlen(*p));//error		确定值
	printf("%d\n", strlen(p[0]));//error
	printf("%d\n", strlen(&p));//随机值		栈空间开辟的首地址开始计算,下一个地址存的是该元素的地址,所以不知道何时能遇到'\0'
	printf("%d\n", strlen(&p + 1));//随机值	栈空间 位置【 *            】
	printf("%d\n", strlen(&p[0] + 1));//5   相当于(p + 1)


	return 0;
}

第五题(二维数组)

int main()
{
	int a[3][4] = { 0 };
	//0 0 0 0
	//0 0 0 0
	//0 0 0 0

	printf("%d\n", sizeof(a));//48				整个数组的大小3*4*4=48
	printf("%d\n", sizeof(a[0][0]));//4			第一个元素的大小
	printf("%d\n", sizeof(a[0]));//16			整个第一行的大小
	// a[0]是第一行这个一维数组的数组名,单独放在sizeof内部,a[0]表示第一个整个这个一维数组
	//sizeof(a[0])计算的就是第一行的大小

	printf("%d\n", sizeof(a[0] + 1));//4
	//a[0]并没有单独放在sizeof内部,也没取地址,a[0]就表示首元素的地址
	//就是第一行这个一维数组的第一个元素的地址,a[0] + 1就是第一行第二个元素的地址

	printf("%d\n", sizeof(*(a[0] + 1)));//4
	//a[0] + 1就是第一行第二个元素的地址
	//*(a[0] + 1))就是第一行第二个元素

	printf("%d\n", sizeof(a + 1));//4  &a[1]
	//a虽然是二维数组的地址,但是并没有单独放在sizeof内部,也没取地址
	//a表示首元素的地址,二维数组的首元素是它的第一行,a就是第一行的地址
	//a+1就是跳过第一行,表示第二行的地址

	printf("%d\n", sizeof(*(a + 1)));//16  第二行 0 0 0 0所以值的的大小
	//*(a + 1)是对第二行地址的解引用,拿到的是第二行
	//*(a+1)-->a[1]

	printf("%d\n", sizeof(&a[0] + 1));//4
	//&a[0] - 对第一行的数组名取地址,拿出的是第一行的地址
	//&a[0]+1 - 得到的是第二行的地址

	printf("%d\n", sizeof(*(&a[0] + 1)));//16
	printf("%d\n", sizeof(*a));//16
	//a表示首元素的地址,就是第一行的地址
	//*a就是对第一行地址的解引用,拿到的就是第一行

	printf("%d\n", sizeof(a[3]));//16  计算第四行的值的大小 虽然没有,但是它只是计算,相当于计算的4*(int)
	

	return 0;
} 

感谢大家支持!!!!!!!

猜你喜欢

转载自blog.csdn.net/includeevey/article/details/125578128