指针笔试题~走近大厂

前言

作者小蜗牛向前冲

名言我可以接收失败,但我不能接收放弃

指针笔试题~走近大厂_第1张图片

 如果觉的博主的文章还不错的话,还请点赞,收藏,关注支持博主。如果发现有问题的地方欢迎❀大家在评论区指正。


目录

笔试题1:

笔试题2

 笔试题3

 笔试题4

 笔试题5

笔试题6 

 笔试题7

笔试题 8

 总结

 下面我将为大家分享几道指针的笔试题,希望大家能有所收获。

笔试题1:

#include

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数组元素的分布图


指针笔试题~走近大厂_第2张图片

 从图中我们可以看出指针ptr指向的是数组a之外的元素

a是数组名-->首元素的地址。

那么我们(a+1)不就是从首地址跳过一个元素,指向下个元素的地址,*(a+1)就找到了元素2。

那么(ptr-1)左移动一个整形的大小,指向5这个元素,*(ptr-1)便找到这个元素。

所以我们的结果为2,5.

指针笔试题~走近大厂_第3张图片

笔试题2

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

首先我们要明白p是什么,p是一个结构体指针,%p值的是打印出指针的地址,我们可以假设p的地址为0x000000,那么p+0x1又表示什么呢?其实就是将p+20-->0x000014

其中(unsigned long)p,将指针p强制类型转化为整形,所以(unsigned long)p+0x1-->0x000001。

其次(unsigned int*)p,这影响的是指针+-跳过的字节数,其中ungsing int*的大小为4字节,所以 (unsigned long)p + 0x1-->0x000004。

 笔试题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数组的内存分布图


指针笔试题~走近大厂_第4张图片

这里我们先理解清楚,ptr1和ptr2都是int *类型的指针。

(&a + 1)表示跳过整个数组,指向数组后面的元素。

(int)a将a转化为整形,(int )a+1表示a的值加1,就指针跳过1个字节(如图的位置)。

%x指以十六进制打印。

好了我们理解清楚这些变量名的意义了,就开始解题吧。

ptr1[-1]- ->*((&a+1)-1),也就是说解引用指向数组最后位置的指针,就找到了元素0x4.

*ptr2,就是找到ptr2指针指向的元素,根据内存的存取规则,要倒这取出来-->02 00 00 00 ,所以屏幕中最终打印的值为2 00 00 00。

 笔试题4

#include 
int main()
{
    int a[3][2] = { (0, 1), (2, 3), (4, 5) };
    int *p;
    p = a[0];
    printf( "%d", p[0]);
 return 0;
}

 


a数组元素的分布图


指针笔试题~走近大厂_第5张图片

 这道题目其实是有个坑,大家误认为初始化为

0 1

2 3

4 5

这种形式,其实()是个,号表达式,输出的值右括号最后的值。所以根据上面的数组元素分布图,我们的出p[0]-->*(p+0)的值为。

 笔试题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;
}

a数组的元素分布图 


指针笔试题~走近大厂_第6张图片

这里我们理解a是什么?p又是什么?&p[4][2]和&a[4][2]表示什么?

其中a为二维数组,a的类型为int(*)[4],p为数组指针,p的类型为int(*)[4]。

&a[4][2],图中黄色方块为a[4][2]指向的元素。

p[4][2]-->&*(*(p+4)+2),首先P+4指向图中的位置,为什么呢?可能会人有有疑问,因为p认为自己指向的是4个int类型,所以每次+1都会跳过4个整形元素。其次,在(*(p+4)+2),*(p+4)就会访问4个整形的数组,数组名+就会跳过2个元素,指向第3个元素,在*(*(p+4)+2)就会找到第3个元素(图中绿色方块)。

所以, &p[4][2] - &a[4][2](指针-指针)=指针于指针之间的元素个数4,因为是第地址的指针-高地址的指针结果为-4.

-4

原码:10000000 00000000 00000000 00000100

反码:11111111 11111111 11111111 11111011

补码:1111 1111 1111 1111 1111 1111 1111 1100

十六进制:F   F     F        F     F      F      F       C

%p打印FFFFFFFC。

%d打印-4。

笔试题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数组的元素分布图


指针笔试题~走近大厂_第7张图片

 这道题和笔试题1及其相似的,把图画出来后就很好解题了。

ptr1-1-->指向aa[1][4],*(prt1-1)找到10。

ptr2-1-->指向aa[0][4],*(ptr2-1)z找到5。

 笔试题7

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

 a与pa的内存分布


指针笔试题~走近大厂_第8张图片 

 这里我们同样画好图,pa是个二级指针,a是个常量字符串,其中a的变量名表示首元素的地址,开始pa-->w,后来pa++-->a,所以&s打印出''at''。

下面正式进入我们的压轴大题,小伙伴们准备好接收挑战了吗? 

笔试题 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;
}

最初的内存布局


指针笔试题~走近大厂_第9张图片

 我们画出最初的内存布局后,就开始解题。

1**ccp,从图中我们可以很明显的看出指向的是字符串FIRST(cpp-->c+2).

2*--*++cpp+3(注意++--都是改变量的值),这里我们靠近变量的操作符先进行运算,++cpp,这使得cpp指向c+1,*(c+1)找到c+1,在--*++cpp指的是c+1-->c,*--*++cpp便找到字符串ENTER的首地址,然后,*--*++cpp+3,找到E的地址,打印ER。(cpp-->c+1,c+1-->c)。

3*cpp[-2]+3-->*(cpp-2)+3,这里cpp-2使得cpp指向c+3,*(c+3)找到FIRST的首地址,*(cpp-2)+3找到S的首地址,打印ST。(cpp-->c+3)

4cpp[-1][-1]+1-->*(*(cpp-1)-1)+1,cpp-1指向c+2,*(cp-1)-1-->(指向)c+1,*(*(cpp-1)-1)找到NEW的首地址,*(*(cpp-1)-1)+1找到E的地址,打印EW。

 总结

1在做指针类型的题目的时会画图分析很重要。

2p[1]可以等价于*(p+1),p[1][1]也可以等价于*(*(p+1)+1).

3要牢记数组名就是首元素的地址(二种特殊情况就不多说了)。

4指针-指针意义是表示二指针间的元素个数。


大家喜欢的话就点个赞支持博主吧!

指针笔试题~走近大厂_第10张图片

 

你可能感兴趣的:(初识C语言,c#,学习,算法)