Java教程

孩子又吃不下饭?再来做几组指针和数组笔试题下下饭嘞~

本文主要是介绍孩子又吃不下饭?再来做几组指针和数组笔试题下下饭嘞~,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

目录

Group 1

Group 2

Group 3

Group 4 

Group 5

Group 6

Group 7 

Group 8


听说有孩子为了下饭已经把之前的题目看得烂熟于心惹,所以这里再给出几组指针和数组笔试题,保证有新鲜的题目下饭~

废话不多说,上菜

Group 1

int main()
{
    int a[5] = { 1, 2, 3, 4, 5 };
    int *ptr = (int *)(&a + 1);
    printf( "%d,%d", *(a + 1), *(ptr - 1));
    return 0; 
}

窝萌再来重复之前讲过的一个很重要的知识点:

数组名表示数组首元素的地址,但是有两个例外:

1.&数组名取出的是整个数组的地址

2.数组名单独放在sizeof内部时数组名表示的是整个数组

现在开始手撕

首先,&a取出的是整个数组的地址,+1后就跳过了整个数组,由于又强制转换成了int*,所以以后每次+-1都只能跳过一个int*类型的变量,所以在最后ptr-1时就指向了元素5,解引用后就得到了元素5,而a表示数组首元素的地址,+1后得到数组第二个元素的地址,解引用后就得到了数组第二个元素,因此输出的结果就是2,5

现在看一下编译器跑出的结果:

Group 2

struct Test
{
 int Num;
 char *pcName;
 short sDate;
 char cha[2];
 short sBa[4];
}*p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
int main()
{
 p = (struct Test*)0x100000;
 printf("%p\n", p + 0x1);
 printf("%p\n", (unsigned long)p + 0x1);
 printf("%p\n", (unsigned int*)p + 0x1);
 return 0; }

p是个结构体指针,p的地址是0x00100000,由于该结构体占20个字节,+1后就跳过20个字节,由于地址是用十六进制表示的,所以最后用十六进制表示的结果就是0x00100014

接下来p被强制类型转换成了无符号整形,因此+1就是加了整数1,所以最后结果就是0x00100001

然后p又被强制类型转换成了无符号int *类型的变量,所以+1就跳过4个字节,因此最后结果就是0x00100004

(ps:当用%p打印时是不会出现的0x滴)

让我们来看一下编译器输出的结果吧:

Group 3

int main()
{
    int a[4] = { 1, 2, 3, 4 };
    int *ptr1 = (int *)(&a + 1);
    int *ptr2 = (int *)((int)a + 1);
    printf( "%x,%x", ptr1[-1], *ptr2);
    return 0; }

首先,&a取出的是整个数组的地址,+1后就跳过了整个数组,再强制类型转换后,以后加减就是跳过一个整形类型,把a强制类型转换为int类型后地址就是个数值,+1就是大一个数值的整形,再强制类型转换后又指向了一个大一号的地址,由于在vs2019中数据在内存中是小端字节序存储,并且按照十六进制的形式,所以+1后就跳到了图中红色箭头指向的位置,因此ptr[-1] == *(ptr1)所以就得到了元素4,因此第一个输出的就是4,第二个解引用后就得到02000000,也就是2000000

我们最后来看一下编译器输出的结果:

 

Group 4 

#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; 
}

这里有个小坑嘞,现在我们把它填上

首先,题目中二维数组的初始化是有问题的,正确的初始化应该用{},而用()就是逗号表达式咯,所以最后的二维数组的初始化结果如图所示

a[0]表示该二维数组第一行首元素的地址,这里创建了指针变量p指向了第一行首元素, p[0] == *(p+0),也就是第一行的首元素1,所以最后的输出结果就是1

看编译器输出的结果:

Group 5

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;
}

首先这里创建了一个五行y五列的二维数组,由于p是一个有4个整形元素的数组指针类型,这里直接就给p数组第一行首元素的地址(也许程序会报错),p[4][2] ==  *(*(p+4)+2),由于p是个数组指针,p[4]就表示以p视角第四行元素的地址(等价于数组的地址),所以p[4][2]就表示取出在p视角下第四行的第二个元素,&p[4][2]就表示p视角下第四行第二个元素的地址,&a[4][2]是二维数组中第五行第三个元素的地址,由于指针-指针算出的是两个指针之间元素的个数,所以就是-4,由于第一个结果是用%p打印,-4在计算机中存储的二进制补码是11111111111111111111111111111100,地址是用16进制表示的,1111是一个f,所以最后的结果就是fffffffc,第二个结果用%d打印,%d打印的是有符号数,所以输出的结果就是-4

 我们来看一下编译器跑出的结果:

Group 6

 

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;
}

这道题和之前的某道题目类似,这里创建了一个两行五列的二维数组,首先&aa取出的是整个二维数组的地址,+1就跳过了整个二维数组,然后强制类型转换为int *,此后+-1就只能跳过一个整形,*(aa+1) == aa[1],也就是第二行元素的地址,强制转换为int *后,ptr2就指向了第二行第一个元素,因此第一个输出的结果就是10,第二个输出的结果就是5

看一下程序运行的结果:

Group 7 

int main()
{
	char* a[] = { "work","at","alibaba" };
	char** pa = a;
	pa++;
	printf("%s\n", *pa);
	return 0;
}

当各个字符串作为表达式时,得到的是字符串首元素的地址,因此这里创建了指针数组a存储各个地址,此后又创建了二级指针pa指向了数组a首元素的地址,pa+1就跳过一个char *类型的变量,pa++后此时pa就指向了a数组第二个元素,解引用后就得到第二个字符串“at”首元素的地址,只要给出地址%s就可以顺着打印,因此最后输出的结果就是“at”

康康程序运行的结果:

Group 8

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;
}

当“ENTER ”作为表达式时得到的是第一个E的地址,同理,后边的字符串得到的都是第一个元素的地址,这里用一个指针数组c进行存储,然后创建了二级指针数组cpp,依次指向了c中第四个元素,第三个元素,第二个元素,第一个元素,接着又创建了三级指针变量cpp,由于此时cp表示数组首元素的地址,所以这里的cpp存的就是cp里首元素的地址

首先,++cpp后cpp就指向了cp中第二个元素,再两次解引用就得到了P元素的地址,所以第一个打印的结果就是“POINT”

根据操作符的优先级,++cpp后cpp就指向了cp中第三个元素,解引用后就得到c+1的地址,--之后就变成了c的地址,再解引用就得到了“ENTER”中第一个E的地址,+3后跳过三个char类型的变量,就得到了“ENTER中”T的地址,因此第二个打印的结果就是“TER”

第三个,cpp[-2]后又指向了cp中第一个元素,解引用后就得到c+3的地址,也就是“FIRST”中F的地址,再+3跳过三个char类型,就得到“FIRST”中S的地址,因此这里的输出结果就是“ST”

最后一个,cpp[-1][-1] == *(*(cpp-1)-1)首先cpp-1就得到cp中第二个元素的地址,解引用后就得到c+2,-1后就得到c+1,再解引用就得到“NEW”中N的地址,+1后得到“NEW”中E的地址,所以这里打印出的就是“EW”

我们康康结果是不是这样的嘞:

OK,本次下饭试题就先到这里啦

觉得不戳请点赞关注一下嘞,喜上加喜可是再好不过啦~ 

这篇关于孩子又吃不下饭?再来做几组指针和数组笔试题下下饭嘞~的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!