指针笔试题详解(1)

前言:在学习完指针的知识后,我们要即使查漏补缺,不断练习这样才能真正学会一个知识,所以在前两篇指针干货学习的基础上,我为大家带来一些十分经典的指针笔试题,内容篇幅不长,讲解清晰,请放心食用

1.必备知识点:(务必理解后面会反复使用)

数组名

1.数组名就是首元素的地址

2.当数组名为下面两种情况时有特殊含义:(1) sizeof(数组名),这里的数组名代表的是整个数组,计算的是整个数组的大小。(2) &数组名,这里表示整个数组的地址,类型为一个数组指针类型,注意除了以上两种情况的是他表达形式,数组名都表示数组首元素的地址。

3.二维数组名:二维数组名代表首行元素的地址

例如  

#include<stdio.h>
int main()
{
    int arr[5][4]={0};
    //则arr为第一行数组的地址类型为int(*)[4]
    //arr[0],arr[1],arr[2],arr[3],arr[4]分别为第1,2,3,4,5行数组的数组名
    //例arr[4]=*(arr+4)

}

OK.你已经get到了下面这一种指针面试题题型的精髓,对于你对指针的深入理解大有收获,那我们开始吧!

1,关键字sizeof()与指针的相关题型

突破点1《整形数组名题型》

int main() 
{
	int a[] = { 1,2,3,4 };
	printf("%d\n", sizeof(a));//数组名a单独放在sizeof内部,计算的整个数组的大小,单位是字节,4*4 = 16字节
	printf("%d\n", sizeof(a + 0));//a表示的首元素的地址,a+0还是数组首元素的地址,是地址大小4/8字节
	printf("%d\n", sizeof(*a));//a表示的首元素的地址,*a就是对首元素的地址的解引用,就是首元素,大小是4个字节
	printf("%d\n", sizeof(a + 1));//a表示的首元素的地址,a+1是第二个元素的地址,是地址,大小就4/8个字节
	printf("%d\n", sizeof(a[1]));//a[1]是数组的第二个元素,大小是4个字节
	printf("%d\n", sizeof(&a)); //&a 表示是数组的地址,数组的地址也是地址,地址大小就是4/8字节
	printf("%d\n", sizeof(*&a));//可以理解为*和&抵消效果,*&a相当于a,sizeof(a)是16
	//&a -> int(*)[4]
	//&a是数组的地址,它的类型是int(*)[4]数组指针,如果解引用,访问的就是4个int的数组,大小是16个字节
	printf("%d\n", sizeof(&a + 1));//&a是数组的地址,&a+1 跳过整个数组后的地址,是地址就是4/8
	printf("%d\n", sizeof(&a[0]));//&a[0]取出数组第一个元素的地址,是地址就是4/8
	printf("%d\n", sizeof(&a[0] + 1));//&a[0]+1就是第二个元素的地址,是地址大小就是4/8个字节

	//&a[0] - int*
	//
	return 0;
}

核心思想其实还是要注意sizeof()里面放的是否为那两种特殊情况(详情见上方必备知识点)。 

突破点2《字符数组名题型》

int main() 
{
	char arr[] = { 'a','b','c','d',e','f' };
	printf("%d\n", sizeof(arr));//数组名a单独放在sizeof内部,计算的整个数组的大小,单位是字节,6*1 = 6字节
	printf("%d\n", sizeof(a + 0));//arr表示的首元素的地址,a+0还是数组首元素的地址,是地址大小4/8字节
	printf("%d\n", sizeof(*arr));//arr表示的首元素的地址,*arr就是对首元素的地址的解引用,就是首元素,大小是1个字节
	printf("%d\n", sizeof(arr[1]));//arr[1]表示的数组第二个元素元素,计算的是第二个元素的大小,单位是字节,1字节,也可以理解为arr[1]-->*(arr+1)此时arr代表首元素地址+1,为数组第二个元素地址,然后再解引用,为第二个元素,为1字节
	printf("%d\n", sizeof(&arr));//&arr为特殊情况所以代表整个数组的地址,类型为一个数组指针类型,大小是个4/8字节
	printf("%d\n", sizeof(&arr+1)); //&arr 表示是整个数组的地址,所以&arr+1为跳过该数组的第一个地址,但还是一个数组地址,数组的地址也是地址,地址大小就是4/8字节
	printf("%d\n", sizeof(&arr[0] + 1));//&a[0]+1就是第二个元素的地址,是地址大小就是4/8个字节
	return 0;
}

突破点3 《字符串数组名题型》

int main()
{
	char arr[] = "abcdef";

	printf("%d\n", sizeof(arr));此时为特殊情况,arr代表整个数组,计算整个数组的大小,单位为字节,大小为7*1字节
	printf("%d\n", sizeof(arr + 0));arr代表首元素地址,arr+0还是首元素地址,所以大小为4/8字节
	printf("%d\n", sizeof(*arr));这里arr代表首元素地址,*arr即对首元素地址解引用,大小为1字节
	printf("%d\n", sizeof(arr[1]));与上一道题等价。
	printf("%d\n", sizeof(&arr));&arr为整个数组地址,所以大小为4/8
	printf("%d\n", sizeof(&arr + 1));在上一道题的基础上,跳过一整个数组,指向下一个数组地址,大小为4/8字节
	printf("%d\n", sizeof(&arr[0] + 1));显然就是首元素地址+1,为第二个元素地址,大小为4/8.

	return 0;
}

突破点《指针变量指向字符串题型》

int main()
{
	char* p = "abcdef";

	printf("%d\n", sizeof(p)); //p是一个指针变量,sizeof(p)计算的就是指针变量的大小,4 / 8个字节
	printf("%d\n", sizeof(p + 1));//p是指针变量,是存放地址的,p+1也是地址,地址大小就是4/8字节
	printf("%d\n", sizeof(*p));//*p访问的是1个字节
	printf("%d\n", sizeof(p[0]));//p[0]--> *(p+0) -> *p   1个字节

	printf("%d\n", sizeof(&p));//&p也是地址,是地址就是4/8字节,&p是二级指针
	printf("%d\n", sizeof(&p + 1)); //&p是地址, + 1后还是地址,是地址就是4 / 8字节
	&p + 1,是p的地址+1,在内存中跳过p变量后的地址

	printf("%d\n", sizeof(&p[0] + 1));//p[0]就是a,&p[0]就是a的地址,&p[0]+1就是b的地址,是地址就是4/8字节

	return 0;
}

 突破点4《二维数组名题型》

int main()
{
	//二维数组
	int a[3][4] = { 0 };	
	//printf("%d\n", sizeof(a));//数组名单独放在sizeof内部(又是特殊情况),计算的是整个数组的大小,单位为字节,大小为3*4*4=48字节
	//printf("%d\n", sizeof(a[0][0]));//a[0][0]代表第一个元素,大小为4字节
	//printf("%d\n", sizeof(a[0]));//a[0]表示第一行的数组名,a[0]作为数组名单独放在sizeof内部,计算的是第一行的大小。大小为字节16
	//printf("%d\n", sizeof(a[0] + 1));//注意这里的a[0]遇上一道题的a[0]不同,这里a[0]并不是单独放在括号内的,也可以理解为*(a+0)+1,二维数组名代表首行元素地址int(*)[3],对首行数组地址解引用得到首行数组的数组名a[0]也就是第一个元素的地址,所以代表首元素地址,a[0]+1代表第二个元素地址,大小为4/8字节
	//printf("%d\n", sizeof(*(a[0] + 1)));//据上一道题,这里代表第二个元素,大小为4
	//printf("%d\n", sizeof(a + 1));//a代表首行数组的地址,a+1就代表第二行数组的地址,大小为4/8字节
	//printf("%d\n", sizeof(*(a + 1)));//据上题可知,对第二行数组地址解引用,得到第二行数组名a[1]单独放在sizeof中计算的是第二行数组大小,大小为16字节
	//printf("%d\n", sizeof(&a[0] + 1));//&a[0]->&(*(a+0))+1,就等价于a+1表示第二行数组地址,大小为4/8字节
	//printf("%d\n", sizeof(*(&a[0] + 1)));//据上一题,则对第二行数组地址解引用,得到第二行数组名,大小为16字节
	//printf("%d\n", sizeof(*a));//对首行数组地址解引用,计算的是第一行元素的大小,大小为4*4=16(*a=a[0])
	//printf("%d\n", sizeof(a[3]));//因为sizeof只认类型,并不会真正去调用,所以与sizeof(a[0])相同,大小为4/8字节

	return 0;
}

 是不是很有趣呢,小小指针,何当英雄路,如果你感觉对你有帮助的话,那请期待指针笔试题(2)的详解

 

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值