admin管理员组

文章数量:1487745

七道指针运算笔试面试题

开篇备忘录: 引用马斯克名言, 人生是场马拉松, 而不是速度的比拼.

正文开始

开篇介绍

指针,作为一种重要的数据类型,在计算机编程中扮演着至关重要的角色。它可以存储内存地址,使我们能够更直接地访问和操作数据。在解决特定问题时,使用指针可以使我们的程序更高效和灵活。

在笔试运算题中,指针的应用尤为重要。我们常常需要通过指针来跟踪和操作数据的位置,从而实现对数据的更精确和快速的处理。了解如何正确地使用指针运算符和指针算术是解决这些问题的关键。

本篇文章将带您深入了解指针的运算,包括指针的声明与初始化、指针的运算规则和常见的指针问题。我们将通过实际的例子和详细的解析,帮助您理解指针运算的原理和应用。

无论您是初学者还是有一定经验的开发者,掌握指针运算对于提升编程能力和解决实际问题都是至关重要的。在接下来的文章中,我们将带您一步步了解指针运算的一些常见问题和技巧,希望能够为您在笔试中的表现提供帮助。

数组名代表数组首元素的地址, 只有&数组名和sizeof数组名才代表整个数组的地址

题目一

代码语言:javascript代码运行次数:0运行复制
#include<stdio.h>
int main()
{
	int a[5] = { 1, 2, 3, 4, 5 };
	int* ptr = (int*)(&a + 1);
	printf("%d,%d", *(a + 1), *(ptr - 1));
	return 0;
}
//程序的结果是什么?

试题解析: &a取出整个数组的地址, 固&a+1 指向的位置如下, 强制转化成int* 赋值给ptr指针, 此时ptr-1 只能向前移动一个int四个字节大小, 解引用即5, 而a表示数组首元素地址, 即指向1的地址 , +1表示向后移动一个int元素, 即指向2的地址, 解引用表示2

程序结果:

题目二

代码语言:javascript代码运行次数:0运行复制
//在X86环境下
//假设结构体的⼤⼩是20个字节
//程序输出的结果是啥?
struct Test
{
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p = (struct Test*)0x100000;

int main()
{
	printf("%p\n", p + 0x1);
	printf("%p\n", (unsigned long)p + 0x1);
	printf("%p\n", (unsigned int*)p + 0x1);
	return 0;
}

题目解析:

代码语言:javascript代码运行次数:0运行复制
struct Test
{
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p = (struct Test*)0x100000; //把十六进制数强制转换成结构体类型地址

int main()
{
	printf("%p\n", p + 0x1); //p+1跨过一个结构体类型大小(20个字节) 
	//用%p打印默认16进制打印地址,不足八位用0补充,固结果为00100014
	printf("%p\n", (unsigned long)p + 0x1);
	//把p强制类型转换成无符号长整形变量, +1 即0x100001, 用%p打印结果为
	//00100001
	printf("%p\n", (unsigned int*)p + 0x1);
	//把p强制类型转换成int类型指针,p+1跨过四个字节,即00100004
	return 0;
}

程序结果:

题目三

代码语言:javascript代码运行次数:0运行复制
#include <stdio.h>
int main()
{
	int a[3][2] = { (0, 1), (2, 3), (4, 5) };
	int* p;
	p = a[0];
	printf("%d", p[0]);
	return 0;
}
//程序执行的结果是啥?

试题解析:

代码语言:javascript代码运行次数:0运行复制
#include <stdio.h>
int main()
{
	int a[3][2] = { (0, 1), (2, 3), (4, 5) };
	//            {    {1},    {3} ,   {5}}
	//使用了逗号表达式运算符,其内容如下调试窗口
	int* p;
	p = a[0];//a[0]存放第一个元素地址,即第一个一维数组首元素的地址,相当于*(a+0)
	printf("%d", p[0]);//相当于*(p+0),即*p,即第一个元素1
	return 0;
}

程序结果:

题目四

代码语言:javascript代码运行次数:0运行复制
//假设环境是x86环境,程序输出的结果是啥?
#include <stdio.h>
int main()
{
	int a[5][5];
	int(*p)[4];
	p = a;
	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
	return 0;
}

试题解析:

代码语言:javascript代码运行次数:0运行复制
#include <stdio.h>
int main()
{
	int a[5][5];
	int(*p)[4];//数组指针,指向存放4个int型元素数组
	p = a;
	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
	//p[4][2],等价于*(*(p+4)+2),先求*(p+4),p指向了有4个int类型元素的数组,+1跨
	//过一个数组,+4所指向的位置如下图图二所示,解引用表示首元素地址,再+2表示向后移动两
	//个元素,即图二位置所示. 然后取出该位置地址
	//a[4][2],等价于*(*(a+4)+2),而a是二维数组的名字,指向的首元素为一维数组,每个
	//一维数组的大小为5个int类型元素, +1跨过一个数组大小为5个int,如下图所示, 解引用表示
	//一维数组首元素地址, 再+2表示向后移动两个元素,如图一所示, 然后取出该位置地址.
	//两指针相减结果为,指针之间相差的元素个数, 用%d打印即-4 , 而用%p打印则不转换
	//直接打印内存所存放的补码, 那么-4在内存中怎么存放的呢 -4的原码表示为
	//10000000 00000000 00000000 00000100 反码为:
	//11111111 11111111 11111111 11111011 补码为:
	//11111111 11111111 11111111 11111100 
	//用16进制打印出来即FFFFFFFC
	return 0;
}

画图:

图一:

图二:

程序结果:

题目五

代码语言:javascript代码运行次数:0运行复制
#include <stdio.h>
int main()
{
	int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int* ptr1 = (int*)(&aa + 1);
	int* ptr2 = (int*)(*(aa + 1));
	printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
	return 0;
}
//程序执行的结果是啥?

试题解析:

代码语言:javascript代码运行次数:0运行复制
#include <stdio.h>
int main()
{
	int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int* ptr1 = (int*)(&aa + 1);
	//&aa表示取出整个数组的大小,即指向二维数组, +1跨过一个二维数组, 其指向的位置如下图所示
	int* ptr2 = (int*)(*(aa + 1));
	//aa表示数组首元素的地址,首元素为一维数组,即指向一维数组,+1跨过一个一维数组, 解引用表示一维数组首元素地址,+1向后跨过一个元素,指向的位置如下图所示
	printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
	return 0;
}

画图:

程序结果:

题目六

代码语言:javascript代码运行次数:0运行复制
#include <stdio.h>
int main()
{
	char* a[] = { "work","at","alibaba" };
	char** pa = a;
	pa++;
	printf("%s\n", *pa);
	return 0;
}
//程序执行的结果是啥?

试题解析:

代码语言:javascript代码运行次数:0运行复制
#include <stdio.h>
int main()
{
	char* a[] = { "work","at","alibaba" };
	//如下图所示, 字符指针数组所指向的内容
	char** pa = a;
	//a表示数组首元素的地址, 是char*类型,要保存char*指针类型,需要二级指针来保存
	pa++;//pa++即指向下一个元素,解引用为at
	printf("%s\n", *pa);
	return 0;
}

画图:

程序结果:

题目七

代码语言:javascript代码运行次数:0运行复制
#include <stdio.h>
int main()
{
	char* c[] = { "ENTER","NEW","POINT","FIRST" };
	char** cp[] = { c + 3,c + 2,c + 1,c };
	char*** cpp = cp;
	printf("%s\n", **++cpp);
	printf("%s\n", *-- * ++cpp + 3);
	printf("%s\n", *cpp[-2] + 3);
	printf("%s\n", cpp[-1][-1] + 1);
	return 0;
}
//程序打印的结果是啥?

画图:

试题解析:

代码语言:javascript代码运行次数:0运行复制
#include <stdio.h>
int main()
{
	char* c[] = { "ENTER","NEW","POINT","FIRST" };
	char** cp[] = { c + 3,c + 2,c + 1,c };
	char*** cpp = cp;
	printf("%s\n", **++cpp);
//如图所示,首先++cpp保存了cp中第二个元素的地址,解引用表示第二个元素,即c+2,再解引用,表示c+2所指向的内容,即POINT
	printf("%s\n", * -- * ++cpp + 3);
	//如图所示,先++cpp,即在向下保存了cp中第三个元素的地址,解引用表示c+1,而--即
	//对里面的内容c+1 -- 即为c,在解引用表示c所指向的内容,再+3即ER
	printf("%s\n", *cpp[-2] + 3);
	//即为先对*(cpp-2)解引用,即c+3,在求*c+3表示c里面第4个元素指向了FIRST,再+3即为ST
	printf("%s\n", cpp[-1][-1] + 1);
	//即(*(*cpp-1)-1),首先求得c+2,再-1解引用为c+1所指向元素内容,+1即为EW
	return 0;
}

程序结果:

总结

指针运算是一个比较复杂但又非常重要的概念,在面试中经常会涉及到相关问题。面试者需要对指针运算有深入的理解,并能够灵活运用指针来解决问题。如果上述内容对您有帮助的话, 还请点赞收藏, 如果发现错误 ,恳请给予指正, 感谢 !

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2024-07-14,如有侵权请联系 cloudcommunity@tencent 删除数组指针int程序数据

本文标签: 七道指针运算笔试面试题