指针进阶-->笔试题详解(数组笔试题)

 

"痛苦难以避免,而磨难可以选择。"-->村上春树

作者:Mylvzi 

 文章主要内容:数据在内存中的存储 

核心知识点: 

核心:

1.对于数组名的理解:数组名是数组首元素的地址(二维数组的数组名就是第一行的地址),但有两个例外,一是单独出现在sizeof内部,表示整个数组的大小,二是&数组名,代表存放整个数组的地址;

2.理解sizeof只关注()的数组类型,是地址,大小就为4/8;关注()的数据类型(数组的数据类型就是去掉数组名)

3.理解指针变量存储字符串的本质-->存储字符串首元素的地址

4.理解二维数组的元素构成,即二维数组是一维数组的数组;

5.理解数组与指针之间的的等价关系;arr[1]-->*(arr+1)  *arr-->*(arr+0)-->arr[0]

6.理解strlen函数的本质即参数类型,本质是计算\0之前的字符个数,参数是const char*,是一个地址,也就是说strlen是从你传的地址作为首地址,一直向后读取字符个数,直到遇到\0;当()是元素时,会从其对应的ascii码值所在的地址访问,造成非法访问,报错

相关代码代码如下: 

int main()
{
	/*一维数组*/
	//数组名代表数组首元素地址,但有两个例外
	//1.sizeof数组名,计算的是整个数组的大小(数组名单独放在sizeof内部)
	//2.&数组名,代表整个数组的地址
	//sizeof 只关注类型,要分清代表的是元素还是地址
	//对于指针,我们要关注他的指向,也就是存放的地址;其大小是固定的

	int a[] = { 1,2,3,4 };
	printf("%d\n", sizeof(a));//16 ->int [4]
	printf("%d\n", sizeof(a + 0));//这里的a是数组首元素的地址,+0还是数组首元素的地址,大小为4/8byte
	printf("%d\n", sizeof(*a));//数组首元素,是元素,4(int类型)
	printf("%d\n", sizeof(a + 1));//第二个元素的地址,是地址,大小为4/8byte
	printf("%d\n", sizeof(a[1]));//第二个元素,是元素,大小为4
	printf("%d\n", sizeof(&a));//&a也是地址,是地址,4/8byte
	printf("%d\n", sizeof(*&a));//16  等价于sizeof(a)
	//&a 是数组的地址,是一个数组指针变量,类型为int(*)[4],解引用就是访问4个int类型的元素
	printf("%d\n", sizeof(&a + 1));//地址,大小为4/8byte
	printf("%d\n", sizeof(&a[0]));//地址,大小为4/8byte
	printf("%d\n", sizeof(&a[0] + 1));//地址,大小为4/8byte

	
	/*字符数组*/
	/*char arr[] = { 'a','b','c','d','e','f' };*/
	printf("%d\n", sizeof(arr));//数组名在sizeof内部,计算整个数组的大小,6
	printf("%d\n", sizeof(arr + 0));//是地址,大小为4/8
	printf("%d\n", sizeof(*arr));//代表字符a,大小为1
	printf("%d\n", sizeof(arr[1]));//代表字符b,大小为1
	printf("%d\n", sizeof(&arr));//是地址,大小为4/8
	printf("%d\n", sizeof(&arr + 1)); //是地址,大小为4 / 8
	printf("%d\n", sizeof(&arr[0] + 1));//是地址,大小为4/8

	//strlen的参数是const char* ,计算的是\0之前的字符个数
	printf("%d\n", strlen(arr));//随机值
	printf("%d\n", strlen(arr + 0));//随机值
	printf("%d\n", strlen(*arr));//err strlen的参数是一个指针,是地址,*arr,相当于将a的地址传了过去,以97为起始地址,属于非法访问内存
	printf("%d\n", strlen(arr[1]));//err 同上
	printf("%d\n", strlen(&arr));//随机值  &arr的值和arr的值是一样的,都指向数组首元素地址
	printf("%d\n", strlen(&arr + 1));//随机值  数组最后一个元素的下一位的地址
	printf("%d\n", strlen(&arr[0] + 1));//随机值 从数组第二个元素开始打印字符串

	//sizeof只关注类型,传arr是数组,数组的类型是去掉数组名
	// 对于sizeof来说,只需注意他是地址还是普通元素
	char arr[] = "abcdef"; //a b c d e f \0 
	printf("%d\n", sizeof(arr));//数组类型:char [7]; -->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  本质是一个地址
	printf("%d\n", sizeof(&arr + 1));//4  地址
	printf("%d\n", sizeof(&arr[0] + 1));//4  地址

	printf("%d\n", strlen(arr));//6
	printf("%d\n", strlen(arr + 0));//6
	printf("%d\n", strlen(*arr));//非法访问内存
	printf("%d\n", strlen(arr[1]));//同上
	printf("%d\n", strlen(&arr));//6
	printf("%d\n", strlen(&arr + 1));//随机值
	printf("%d\n", strlen(&arr[0] + 1));//5

	
	//利用字符指针存储字符串-->指针内存储的是字符串首字符的地址
	const char* p = "abcdef";
	printf("%d\n", sizeof(p));//4  地址
	printf("%d\n", sizeof(p + 1));//4  地址
	printf("%d\n", sizeof(*p));//1  元素
	printf("%d\n", sizeof(p[0]));//p[0]->*(p+0)->*p  1
	printf("%d\n", sizeof(&p));//&p->char**  4
	printf("%d\n", sizeof(&p + 1));//&p,char**,+1,注意此处的指针变量与数组无关
	//存储的是P本身的地址  4
	printf("%d\n", sizeof(&p[0] + 1));//4 -->b的地址


	printf("%d\n", strlen(p));//6
	printf("%d\n", strlen(p + 1));//5
	printf("%d\n", strlen(*p));//err
	printf("%d\n", strlen(p[0]));//err
	printf("%d\n", strlen(&p));//随机值
	printf("%d\n", strlen(&p + 1));//随机值
	printf("%d\n", strlen(&p[0] + 1));//5



	/*二维数组*/
	//学会数组中的等价关系
	// 给定arr是数组名(一维,二维皆可)
	//arr[1]-->*(arr+1) 
	int a[3][4] = { 0 };
	printf("%d\n", sizeof(a));//计算整个数组的大小,3*4*4  48
	printf("%d\n", sizeof(a[0][0]));//4
	printf("%d\n", sizeof(a[0]));//4*4=16  a[0]是一个一维数组的地址,类型为int(*)[4]
	//a[0]是第一行一维数组的数组名,单独出现在sizeof内部,计算整个一维数组的大小
	printf("%d\n", sizeof(a[0] + 1));//4  a[0]是第一行一维数组的数组名,没有单独出现在sizeof内部
	//所以代表第一行一维数组的首元素的地址-->a[0][0]
	//a[0][0]+1 就是a[0][1]的地址,是一个指针变量;一定要注意指针指向
	printf("%d\n", sizeof(*(a[0] + 1)));//4  计算的就是第一行第二个元素的大小
	printf("%d\n", sizeof(a + 1));//4  
	//a是二维数组名,是第一行的地址,存的时候是通过数组指针存放的int(*)[4]
	//a+1是第二行的地址,是一个指针变量
	printf("%d\n", sizeof(*(a + 1)));//16   
	//*(a+1)-->a[1]  sizeof(*(a+1))-->sizeof(a[1]) int[4]
	printf("%d\n", sizeof(&a[0] + 1));//4 是第二行一维数组的地址,本质是一个地址
	//&a[0]是第一行的地址
	printf("%d\n", sizeof(*(&a[0] + 1)));//16  是对第二行整个一维数组解引用
	//计算第二行整个一维数组的大小
	printf("%d\n", sizeof(*a));//16  a是二维数组数组名,代表二维数组第一行的地址
	//*a就是对第一行解引用,计算第一行整个一维数组的大小
	//*a-->*(a+0)-->a[0]-->sizeof(a[0])
	printf("%d\n", sizeof(a[3]));//16-->a[3]是一个一维数组,数组类型为int[4]


	//sizeof只关注()内的数据类型,只关注类型属性
	//表达式有两个属性
	//1.值属性:即表达式最后的计算结果
	//2.类型属性:即表达式计算结果的类型

	int a = 7;
	short s = 4; 
	printf("%d\n", sizeof(s = a + 2));//short 2

	printf("%d\n", s);//4

	return 0;
}

你可能感兴趣的:(算法,数据结构)