栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言指针相关——经典面试题

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言指针相关——经典面试题

目录

1. 指针类型决定指针+ -的步长

2. 注意逗号表达式()与 { } 之间区别

3. 二维数组与指针

4. 字符指针


1. 指针类型决定指针+ -的步长

强制类型转换:类型转换,但是值不会改变;

	int a[5] = { 1, 2, 3, 4, 5 };
	int *ptr = (int *)(&a + 1);//强制类型转换:类型转换,但是值不会改变;
	printf( "%d,%d", *(a + 1), *(ptr - 1));
	//答案:2 5
	//已知,结构体Test类型的变量大小是20个字节
	p = (struct Test*)0x100000;//p就是结构体类型的指针
	printf("%pn", p + 0x1);//这里指针类型是20(0x14)字节
	printf("%pn", (unsigned long)p + 0x1);
    //这里把p转换成整数类型,整型+-1就是直接+-1,所以直接加 0x1

	printf("%pn", (unsigned int*)p + 0x1);//这里指针类型是4(0x4)字节
    //答案:00100014/00100001/00100004
	int a[4] = { 1, 2, 3, 4 };
	int *ptr1 = (int *)(&a + 1);
	int *ptr2 = (int *)((int)a + 1);//***注意***:此时a为整型,那么a+1的值就是a+1
	printf( "%x,%x", ptr1[-1], *ptr2);// %x是以16进制输出整数;
	//注意:ptr1[-1]就是 *(ptr1 - 1)
	//下面给出a数组在内存中的存储(每个字节)
	//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00
	//a本来是地址指向01,+1之后(字节+1)指向01后面的00了
	//ptr2指向整个序列的第二个字节,且ptr2是整型指针类型,解引用后访问4个字节:00 00 00 02 (小端实际要反过来)= 0x2000000
	//答案: 4 2000000

2. 注意逗号表达式()与 { } 之间区别
	int a[3][2] = { (0, 1), (2, 3), (4, 5) };
	//注意,里面若是{}括号,那么就是正常解答
	//(,)是逗号表达式,实际上a[3][2]  = {1,3,5}
	int *p;
	p = a[0];//表示第一行首元素的地址
	printf( "%dn", p[0]);//p[0] == *(p+0),p[0]表示a[0][0],第一行第一个元素
	//答案是1

3. 二维数组与指针
	int a[5][5] = {0};
	int(*p)[4];
	p = (int(*)[4])a;
	printf("%dn",&p[4][2] - &a[4][2]);//-4  ***重要***:两个地址相减得到是中间元素的个数
	printf("%pn",&p[4][2] - &a[4][2]);//fffffffc -4以%p的形式打印时,直接将补码以地址的形式读取;
	//以上a[4][2]容易获得
	//p[4][2]的获取,画出a[5][5]在内存中的存储
	//00000 00000 00000 00000 00000
	//p是int(*)[4]型指针,指向a[5][5]第一行第一个元素的地址;
	//p[4]相当于*(p+4),p向后指向了4*4个元素,也就是a[3][1]的位置
	//p[4][2] == (*(p+4))[2] == *((*(p+4))+2)
	//(p+4)是地址,*(p+4)解引用是数组名,且p解引用后*p应该是4个元素的数组,(p+4)也一样
	//所以(*(p+4))[2]向后指2个元素,也就是a[3][3]
	//a[3][3]和a[4][2]中间有4个元素;
	int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int *ptr1 = (int *)(&aa + 1);
	int *ptr2 = (int *)(*(aa + 1));//第二个int*其实可以不用
	//(aa+1)表示第二行(是一个一维数组)的地址,解引用*(aa+1)表示第二行的数组名,也表示第二行的首元素的地址
	//int *ptr2 = (*(aa + 1));
	//int *ptr2 = (int *)((aa + 1));
	printf( "%d,%dn", *(ptr1 - 1), *(ptr2 - 1));
	//答案: 10 5

4. 字符指针
	char *a[] = {"work","at","alibaba"};//字符串数组
	char** pa = a;//a是数组名,pa指向首元素(字符指针)的地址
	pa++;//(pa+1) 指针向后移了一项;
	printf("%sn", *pa);
	//at
	char *c[] = {"ENTER","NEW","POINT","FIRST"};
	char**cp[] = {c+3,c+2,c+1,c};
	char***cpp = cp;
	printf("%sn", **++cpp);      //point
	printf("%sn", *--*++cpp+3);  //er
	printf("%sn", *cpp[-2]+3);   //st
	printf("%sn", cpp[-1][-1]+1);//ew
	//讲解见笔记:画一下数组的内存分布再做题;
	//注意:++cpp会对cpp重新赋值,相当于cpp = (cpp+1)
	//而cpp[-2]等价于 *(cpp-2),不会cpp重新赋值

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/982844.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号