当前位置:   article > 正文

C语言--数组&指针笔试题解析(指针:你看我几分像从前)_c语言指针数组经典题目详解

c语言指针数组经典题目详解

尊贵的各位大厂码农你们好,是的,没错,我又来找你们来帮我指正文章了,今天的主题是数组和指针的笔试题专栏,大家给掌掌眼,有问题的话还请帮忙斧正哦!

 

目录

前言:

一,数组笔试题

一,一维数组

二,字符数组

2.1,直接赋值型的字符数组

2.2,字符串赋值给字符数组

 2.3,字符串赋值给字符指针

三,二维数组

二,指针笔试题 

试题1:

试题2: 

 试题3:

试题4:

试题5: 

 试题6:

 试题7:

试题8(重点理解掌握): 

前言:

首先,在开始笔试题之前,首先得了解一下几个问题:

1,sizeof()的作用是求对象所占空间的大小,单位是字节。

2,数组名的几种不同用法所代表的含义,一般情况下数组名代表的是首元素地址,但有两种例外情况,首先sizeof(数组名),这里的数组名代表整个数组。其次取地址数组名,代表的是整个数组的地址。

一,数组笔试题

一,一维数组

对于倒数第三个题有一点要强调一下,就是它跳过了整个数组,但是数组后面的地址空间是未知的,是不是我们这里再求作所占空间大小就是有问题的,答案是并不是,后面的地址只能说我们没访问权限。但是这块地址空间是一定存在的,所以就是单纯的求这块地址空间的大小。

还有*&a,如果是放在sizeof内部,他其实就是相当于sizeof(a),求整个数组的大小,但是如果是放在外面用的话,就是相当于拿到整个数组,也就是数组名,等价于首元素地址。这里二者处在不同位置,含义是不一样的

二,字符数组

2.1,直接赋值型的字符数组

对于第三个第四个这种情况,因为你拿到的是字符,比如字符a,对应ascii码就是97,那站在strlen(),你把97传给我,我就把它当成一个地址,但是首先97这个地址编号存不存在,用户能否访问都是一个问题,所以可能就会出现非法访问的问题。

 

2.2,字符串赋值给字符数组

 

到这里可以给sizeof() 与 strlen() 做一个总结:

sizeof()是一个操作符,返回值类型为size_t的无符号类型,他的作用就是计算对象所占内存空间的大小,不在乎内存中放的什么。

strlen()是一个函数,是用来计算字符串长度的,从给定的地址向后访问 ,直至到\0停止。

 

 2.3,字符串赋值给字符指针

 

 

三,二维数组

对于二维数组,这里重点需要注意几个点:

1,注意区分二维数组数组名与第一行的数组名,也就是上面的a 与 a[0],前者表示的是二维数组的首元素的地址,是第一行的地址,而后者表示的是第一行的第一个元素的地址。二者数值一样,但是意义不一样。

2,对于sizeof而言,他只是求对象所占内存空间的大小,他的求值依据是对象的类型,而不是真正的会去访问这块内存空间。所以在最后的sizeof(a[3])里面,看似好像越界访问数组了,因为数组只有三行,但是实际上我们并没有真正的访问这块空间,只是说假如有这么一块空间是int [4]类型,然后让你求这块空间所占内存空间的大小。

 

二,指针笔试题 

试题1:

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

大家觉得结果是什么? 没错,就是2,5,至于为什么是这样,解析如下:

 

试题2: 

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

首先,定义的p是一个结构体指针,已知他的地址是0x100000。这个题的主要考查点就是不同指针类型,加上整数,移动的步长不同。

解析:

注意%p是让我们用地址的形式打印数据,并不是去找这个地址,所以对于第二个结果而言,他只是用地址的形式打印输出。至于为什么前面会补0,是因为这是在32位系统下,你输出展示得有四个字节,所以前面你得补上两个0,如果打印完全,以第一个为例应该是00000000000000000000000000100014,一共满32位。 

 

 试题3:

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

 解析:

 

%x表示以十六进制不带前缀的格式输出结果,所以最后的输出是4,2000000。这里我们小总结一下,%p是以地址形式输出,结果前面会补0,%x是以十六进制不带前缀的格式输出,前面不进行任何补充,如果是%#x,输出结果前面加0x. 

试题4:

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

这个题的结果是什么先不说,只能说这个题有个大坑可能等着你掉进去呢!

仔细看这个数组,长得倒是有模有样的,但是内部不纯,里面放的是逗号表达式,所以结果可不是简简单单的0,那么让我们解析解析:

 

试题5: 

  1. int main()
  2. {
  3.    int a[5][5];
  4.    int(*p)[4];
  5.    p = a;
  6.    printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
  7.    return 0;
  8. }

 解析:

 

 试题6:

  1. int main()
  2. {
  3.    int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
  4.    int *ptr1 = (int *)(&aa + 1);
  5.    int *ptr2 = (int *)(*(aa + 1));
  6.    printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));
  7.    return 0;
  8. }

 解析:

 

 试题7:

  1. int main()
  2. {
  3. char *a[] = {"work","at","alibaba"};
  4. char**pa = a;
  5. pa++;
  6. printf("%s\n", *pa);
  7. return 0;
  8. }

 这个题考察的一个点就是将字符串赋值给一个字符数组的时候,本质上不是将一整个字符串存进数组中,存放的只是字符串首元素地址。

 

试题8(重点理解掌握): 

  1. int main()
  2. {
  3. char *c[] = {"ENTER","NEW","POINT","FIRST"};
  4. char**cp[] = {c+3,c+2,c+1,c};
  5. char***cpp = cp;
  6. printf("%s\n", **++cpp);
  7. printf("%s\n", *--*++cpp+3);
  8. printf("%s\n", *cpp[-2]+3);
  9. printf("%s\n", cpp[-1][-1]+1);
  10. return 0;
  11. }

 解析:

 

 

今天的文章就到这了,如果大家觉得还可以的话,还请帮忙三连三连哦,十分感谢!

 

 

 

 

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/164667
推荐阅读
相关标签
  

闽ICP备14008679号