目录

需要用到语法

笔试题1:

解析:

笔试题2:

解析:

总结:

笔试题3:

解析:

笔试题4:

解析:

笔试题5:

解析:

笔试题6:

解析:

笔试题7:

解析:

笔试题8:

解析:

总结:


C语言只有一维数组,而且数组的大小必须在编译期就作为一个常数确定下来。然而,C语言中数组的元素可以是任意类型的对象,当然也可以是另一个数组。这样,要“仿真”出一个多维数组就不是一件难事。

对于一个数组,我们只能做两件事:确定数组的大小,获得指向该数组下标为0的指针。

其它有关数组的操作,都是通过指针进行的。换句话说,任何一个数组下标的运算都等同于一个对应指针的运算,因此我们完全可以依据指针行为定义数组下标的行为。——《C缺陷与陷阱》


需要用到语法

  1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
  2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
  3. 除此之外所有的数组名都表示首元素的地址。

笔试题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;
}
//程序的结果是什么?

解析:

首先我们看(&a+1)

其中,a是数组名,那我们就知道,在数组名前加取地址符,表示整个数组的地址。

而&a+1表示的地址,则是跨过整个数组的第一个地址。(如果不明白,请看下方例题说明图)

此时我们可以知道&a+1表示的地址的位置。

此时&a+1的类型为int (*)[5]:

a为数组首元素,类型为int [5],取地址后,为数组指针类型int (*)[5]。

将&a+1强制类型转换为和指针变量ptr相同的类型,在赋给它。

*(a+1):a是数组名,表示首元素地址,加1表示增加一个整型的空间,指向下标为1的数组的,解引用后值为2。

*(ptr-1):由图可知,指针变量ptr此时指向a[5](此时数组以越界,方便引用所以如此写,这种写法是错误的),ptr-1表示减去一个整型的地址,指向下标为4的数组,解引用后为5.

笔试题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的地址为00100000,此结构体的大小为20个字节。

p+0x1:表示p+1,指针加减整数,看指针的类型的大小加减地址,此结构体类型的大小为20,所以增加20,而地址的表示方法是16进制,增加20即增加14,最终结果为00100014。

(unsigned long)p+0x1:将结构体指针类型强制类型转换为unsigned long类型,不是指针,加减正常,结果为00100001。

(unsigned int*)p+0x1:由上可知,此次需要增加一个整型的大小,即+4,结果为00100004。

总结:

  • 指针增减整数时,增减对应类型的大小

笔试题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在内存中的存储图

我们可以将它简化为:

&a+1:增加一个数组a的大小

(int*)(&a+1):将其转化为int*类型在赋给指针变量ptr。

(int)a+1:将首元素的地址转化为int类型,因为此时不是指针,直接加1即可,即假设a的地址为00000001,直接加1为00000002,因为数组的地址是相连的,此时这个值,实际表示下表为0的数组所占四个字节中的第二个字节。强制类型转化后,ptr2指向此位置。

如图所示:

ptr1[-1]:即ptr1指向位置的前一个整型的地址,a[3],结果为4

*ptr2:解引用后,为整型,占四个字节,(该实验基于VS编译器,VS编译器为小端),即从左向右的四个字节(图中红框以标出),依次从小到大。它的十六进制表示为0x02000000。

题中要求打印十六进制数:

  • %x:是16进制的格式打印,并消出高位多余0.

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

解析:

二维数组内,(0,1),(2,3),(4,5)为逗号表达式,取逗号右边的,即1,3.,5,

所以此二维数组为:

int a[3][2] = { 1,3,5 };

则p[0]为1.

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

解析:

p为数组指针变量,p = a即为 int (*p)[4] = a;

*(p+0) = a[0];      (*(p+0))[0]  =  a[0][0];      (*(p+0))[3]  =  a[0][3];

*(p+1) = a[1];         (*(p+1))[0]  =  a[1][0];      (*(p+1))[3]  =  a[1][3];

....

*(p+4) = a[4];         (*(p+4))[0]  =  a[4][0];      (*(p+4))[3]  =  a[4][3];

因为此数组指针的含义为存储4个整型的大小的一维数组,

而数组a由5个存储大小为5的一位数组的二维数组组成。

所以可以得到如图表示:

  • 指针减指针为:在一块连续的空间内,两个指针之间的距离(用数组元素的个数来衡量)

故&p[4][2] - &a[4][2]中间相差4个元素,而&p[4][2]为低地址处所以为-4。

第一个输出的形式为%p,十六进制,-4转化为2进制为

10000000000000000000000000000100   //原码

111111111111111111111111111111111100   //补码

转化为十六进制为:FFFFFFFC

第二个输出整型,-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表示数组内含有两个元素,分别是两个一位数组,

而这两个一维数组又分别包含五个元素。

&aa+1:此时aa表示整个数组的地址,加1为增加整个数组所占的空间的大小。

*(aa+1):aa为数组首元素的地址,加1后aa+1为数组第2个元素的地址,也就是第二个一维数组的地址。

ptr1和ptr2都为指针,指针减整型,减去存储内存的元素的类型。

ptr1-1:减去一个整型的空间,指向aa[1][4]

ptr2-1:同上,指向aa[0][4]

最终结果为10,5

笔试题7:

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

解析:

char* a[]为指针数组,是数组用来存放指针,该数组有三个元素,分别是三个字符串的地址。

pa = a;是将数组a的首元素的地址放入二级指针变量pa中。

pa++:即为a++,从数组首元素的地址变为第二个元素的地址。

*pa:此时pa为a[1],也就是第二个元素表示字符串的首地址,以%s的形式输出,依次打印字符串。

笔试题8:

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

解析:

数组c中共有4个元素,分别为四个字符串的地址。

数组cp中共有4个元素,分别是存储数组c中4个字符串地址的4个地址

指针cpp存储数组cp中首元素的地址。

我们可以得到如图的结构

  • **++cpp:

  • *-- * ++cpp + 3:
  • ++操作,解引用操作,--操作,按优先级依次进行,最后进行+操作

  • *cpp[-2] + 3

  • cpp[-1][-1] + 1

总结:

  • 指针的题需要掌握,指针加减整数和指针减指针的知识
  • 清楚数组名前是否有取地址符&,有和无,所表示的意义不同,加1后的结果不同
  • 明确数组与指针紧密相连,数组可以用指针表示,十分灵活
  • 每个数组都是一维数组,只是存储的元素不同,可能是另一个一维数组。

【C语言】八道经典指针笔试题(详解)相关推荐

  1. 这八道经典指针笔试题你都会做嘛?

    本文详细介绍了八大指针经典笔试题,内涵盖指针大部分的用法, 全部了解掌握其原理之后对指针的学习大有帮助!!! 对指针掌握 也就掌握了内存,C语言也就没有什么更绕的了 详解八道经典指针笔试题 一.八道经 ...

  2. 图解八道经典指针笔试题

    题目目录 第一题 第二题 第三题 第四题 第五题 第六题 第七题 第八题 第一题 int main() {int a[5] = { 1, 2, 3, 4, 5 };int *ptr = (int *) ...

  3. 【Vue面试专题】50+道经典Vue面试题详解!

    目录 前言 相关学习资源 01-Vue组件之间通信方式有哪些 02-v-if和v-for哪个优先级更高? 03-能说一说双向绑定使用和原理吗? 04-Vue中如何扩展一个组件 05-子组件可以直接改变 ...

  4. 4道经典指针笔试题讲解 ~

  5. 八道简单入门编程题详解+拓展(水花仙,二进制序列……)

    目录 1.求二进制1的个数 2.计算分数的值 3. 水花仙数 4. 打印X图形 5.输出乘法口诀表 6.输出一个整数的每一位 7.模拟登陆 8.二进制序列 1.求二进制1的个数 求一个整数,在内存当中 ...

  6. 【JavaScript面试专题】经典JS面试题详解!

    目录 数据类型 判断数据类型方法 原型.原型链 var.let.const 闭包 继承 浅拷贝.深拷贝 call.apply.bind == 和 === 区别 防抖和节流 宏任务和微任务 localS ...

  7. 【C语言】大厂指针笔试题(1码+1图)详解——程序结果判断题

    C指针相关系列 1.一篇就够了(建议收藏)--超详解sizeof与strlen的用法 2.C语言之深入指针进阶(建议收藏以备不时之需) 3.回炉重造的C之指针+结构体 [C语言]大厂指针笔试题详解(1 ...

  8. 历时一个月!50+Vue经典面试题详解,值得收藏!

    大家好,我是若川.持续组织了8个月源码共读活动,感兴趣的可以 点此加我微信ruochuan12 参与,每周大家一起学习200行左右的源码,共同进步.同时极力推荐订阅我写的<学习源码整体架构系列& ...

  9. C语言-八道笔试题由浅入深玩转指针

    前言:本文章将带你刷8道比较有意思的指针笔试题,笔者将由深入浅出解析这些题目!必要的题目,作者已经加上内存布局图!希望本文对你有所帮助! 目录 一.笔试题1 -指针与一维数组的关系-值 二.笔试题2- ...

最新文章

  1. Kali Linux打开多个终端窗口
  2. Informatica PowerCenter使用介绍-转载
  3. CodeForces - 609E Minimum spanning tree for each edge(最小生成树+树链剖分+线段树/树上倍增)
  4. git:如何让不同开发者提交在同一条直线上
  5. file_operations结构体分析 (设备文件的操作)
  6. 【codevs2822】爱在心中 tarjan 缩点+理解
  7. 性能计数器驱动_【Nature Sustainability】机械力驱动的摩擦电高效空气负离子发生器...
  8. 智能小车二十《摄像头和路由器装上小车》
  9. 十八般武艺玩转GaussDB(DWS)性能调优:总体调优策略
  10. 【OpenCV入门教程之六】 创建Trackbar 图像对比度、亮度值调整(转)
  11. Log4Net使用手册 ---转载
  12. 真北敏捷会员0002陈旭:身心俱疲的暗黑Scrum
  13. 外星人aw768键盘设置快捷键
  14. 那年的夏天——致毕业
  15. 黑马程序员就业班第一天的总结以及自己的看法
  16. Arduino框架下对ESP32 NVS非易失性存储解读以及应用示例
  17. Aspose.Cells使用教程:使用 .NET 在 Linux 上创建或编辑 Excel 文件
  18. 我用过的最好脑图工具——Xmind(含安装包)
  19. 【韩松】Deep Gradient Comression
  20. 数据代码如何“产地直销”,做到持续集成持续发布?

热门文章

  1. 马斯克最新访谈全文,信息量极大,远见令人震撼
  2. mac下安装nvm以及node
  3. APS系统在企业生产中的场景应用
  4. 微波射频学习笔记10-------T型结功率分配器
  5. linux学习笔记,简单的粗暴使用教学
  6. Intel历史上最强的竞争对手:但并不是AMD
  7. 大智慧新一代公式编写教程
  8. word文件如何设置编辑限制?如何删除编辑限制?
  9. uniapp打包后地图不能使用,如何使用地图
  10. amd锐龙笔记本cpu怎么样_AMD发布两款锐龙笔记本CPU