当前位置: 首页 > wzjs >正文

网站备案 拉黑百度站长官网

网站备案 拉黑,百度站长官网,做发帖的网站代码,免费做网站表白C语言学习 指针基础 友情链接:C语言专栏 文章目录C语言学习前言:指针笔试题笔试题1笔试题2笔试题3笔试题4笔试题5笔试题6笔试题7笔试题8总结:附录上文链接专栏前言: 继上文【C语言】指针笔试题1,此篇文章是指针学习的…

C语言学习

指针基础
友情链接:C语言专栏


文章目录

  • C语言学习
  • 前言:
  • 指针笔试题
    • 笔试题1
    • 笔试题2
    • 笔试题3
    • 笔试题4
    • 笔试题5
    • 笔试题6
    • 笔试题7
    • 笔试题8
  • 总结:
  • 附录
    • 上文链接
    • 专栏


前言:

继上文【C语言】指针笔试题1,此篇文章是指针学习的最终章,笔试题详解。建议对指针有了深入理解再来食用。


指针笔试题

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

输出在这里插入图片描述
解析:

int main()
{int a[5] = { 1, 2, 3, 4, 5 };int* ptr = (int*)(&a + 1);   //&a为数组指针,&a + 1则跳过整个数组,//即此时指向数组最后一个元素(5)的后面//(int*)(&a + 1)又将它强制类型转化为int*的指针printf("%d,%d", *(a + 1), *(ptr - 1));//a数组名首元素地址,a + 1则为的第二个元素地址,// *(a + 1)解引用则为2;//ptr为int*的指针,指向数组最后一个元素(5)的后面,//ptr - 1则指针向后退4个字节(因为指针为int*),指向数组最后一个元素,//*解引用则为5;return 0;
}

笔试题2

代码:

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

输出(都为16进制):
在这里插入图片描述
解释:

int main()
{printf("%p\n", p + 0x1);//p + 0x1,跳过一个结构体大小,故为0x14(16进制);printf("%p\n", (unsigned long)p + 0x1);//(unsigned long)p,将p强制类型转化为无符号长整形,//(unsigned long)p + 0x1则为0x1;printf("%p\n", (unsigned int*)p + 0x1);//(unsigned int*)p将结构体指针强制类型转换为无符号整型指针,//且unsigned int为4个字节,整数运算://所以(unsigned int*)p + 0x1则跳过四个字节,故为0x4return 0;
}

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

输出:
在这里插入图片描述

解释:

int main()
{int a[4] = { 1, 2, 3, 4 };int* ptr1 = (int*)(&a + 1);    //&a数组地址,//&a + 1数组指针跳过整个数组,即指向数组最后一个元素的后面//(int*)(&a + 1)强制类型转换,将数组指针转化为(int*)类型的指针;//即ptr1为指向数组最后一个元素后面int*指针int* ptr2 = (int*)((int)a + 1);//下面画图解释printf("%x\n", ptr1[-1]);printf("%x\n", *ptr2);  //下面画图解释//ptr1[-1]可以转换为*(ptr-1),//ptr - 1,ptr为int*指针,-1则为向后退4个字节,指向数组最后一个元素;//故输出为4;return 0;
}

咱们主要来分析一下这两行代码(干货哦!!!):

	int* ptr2 = (int*)((int)a + 1);printf("%x\n", *ptr2); 

在此之前,咱们要对大小端字节序了解,可以看我关于【数据的存储】(由于数据的存储是在此篇博客后面的,所以未附上链接)的介绍。
假设咱们是小端字节序,则数组中元素存储是这样的:
在这里插入图片描述
了解了这个,来分析一下代码:
(int)a:a是数组首元素地址,(int)a是将a强制类型转化为int型的数据;
((int)a + 1):假设a是0x1000,(int)a + 1此时为整数运算则为0x1001,
(int*)((int)a + 1):又将(int)a + 1强制类型转化为int型的指针,那它此时指向哪里呢,看图
a指针指向示意图:
在这里插入图片描述
(int
)((int)a + 1)指针指向示意图:
在这里插入图片描述
那对于*ptr2怎么理解呢?

因为ptr2是int型的指针,所以解引用访问四个字节,有因为咱们是小端字节序,所以它是从从ptr2指针指向的位置起(0x1001)向后访问4个字节(int)内容,即为*ptr2

图示:
在这里插入图片描述
16进制则为0x02000000;
当然,咱们也可以试试大端字节序的情况下是什么样的。

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

输出:
在这里插入图片描述
解释:

#include <stdio.h>
int main()
{int a[3][2] = { (0, 1), (2, 3), (4, 5) };//重点在这://(0, 1)逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。//即数组可写为int a[3][2] = { 1, 3, 5 };后面默认为0;int* p;p = a[0];//a[0]为第一行的数组名//数组名为首元素地址//即p=&a[0][0]printf("%d", p[0]);//p[0]可以这样看*(p+0);//故为1;return 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;
}

输出:
在这里插入图片描述

解释:

int main()
{int a[5][5];int(*p)[4];//一维数组指针p = a;//首先,咱们先对p与a的类型进行分析:// p是int(*)[4];a是int(*p)[5];这个是要明白的,然后分析代码;// 对于a与p他俩的区别是什么呢://a + 1 会跳过 5 * sizeof(int) 字节(通常 20 字节)//p + 1 会跳过 4 * sizeof(int) 字节(通常 16 字节)printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);return 0;
}

首先,先来看数组a的示意图:在这里插入图片描述
咱们先来看a[4][2]所在的位置,很简单:
在这里插入图片描述
那来看看p[4][2]
在这里插入图片描述
将两者放一起:
在这里插入图片描述
那么对于&p[4][2] - &a[4][2],即指针相减,得到的是两个指针之间的元素,为-4;
对于%d形式的输出,就为-4;
但对于%p形式的输出呢?
解释:

  • %p 用于打印指针(内存地址),而内存地址本质上是无符号整数。
  • -4 的二进制补码:0xFFFFFFFC(即 11111111 11111111 11111111 11111100)。
  • 当 -4 被当作指针(无符号数)时,它会被解释为 0xFFFFFFFC。也可以说,%p不管内存中存储的是什么,它只会原样输出存储的二进制(因为无符号数“补码”的概念)。

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

输出:
在这里插入图片描述

解释:

int main()
{int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };int* ptr1 = (int*)(&aa + 1);//&aa取出整个数组的地址//&aa+1跳过整个数组,指向数组最后一个元素的后面//(int*)(&aa + 1)将数组指针强制类型转化为int*类型的//即ptr1是一个int*的指针,且指向数组最后一个元素的后面int* ptr2 = (int*)(*(aa + 1));//aa二维数组的数组名是第一行的地址,类型为int(*)[5]//aa + 1第二行地址,类型为int(*)[5]//*(aa + 1),可以这样写aa[1]//即数组第二行元素,为一维数组//一维数组数组名是首元素地址//首元素地址类型为int*//(int*)(),多余//即ptr2指向数组第二行第一个元素printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));//*(ptr1 - 1)数组最后一个元素10;//*(ptr2 - 1)数组第一行最后一个元素5return 0;
}

笔试题7

看代码:

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

输出:
在这里插入图片描述

解释:

#include <stdio.h>
int main()
{char* a[] = { "work","at","alibaba" };//对字符指针数组进行解释://它是将三个字符串的首元素地址存储在数组中char** pa = a;//a 是数组名,在大多数表达式中会退化为指向首元素的指针,即 pa 为 &a[0](类型是 char**)。//pa 存储的是 a[0] 的地址(即 &a[0])pa++;//pa 原本指向 a[0],pa++ 后指向 a[1](即 &a[1])printf("%s\n", *pa);//*pa 得到 a[1],即 'at' 的首地址,printf 打印这个字符串";return 0;
}

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

输出:
在这里插入图片描述

解释:

int main()
{char* c[] = { "ENTER","NEW","POINT","FIRST" };//数组 c 的每个元素(c[0]、c[1] 等)存储的是指向对应字符串常量的指针://c[0] → 指向 "ENTER" 的首地址(即字符 'E' 的地址)。//c[1] → 指向 "NEW" 的首地址。//c[2] → 指向 "POINT" 的首地址。//c[3] → 指向 "FIRST" 的首地址。char** cp[] = { c + 3,c + 2,c + 1,c };//c数组名为首元素地址,即&c[0];//c + 3 → 指向c[3]     cp[0]//c + 2 → 指向c[2]     cp[1]//c + 1 → 指向c[1]     cp[2]//c  → 指向c[0]        cp[3]char*** cpp = cp;//cp数组名为首元素地址,即&cp[0];//cpp → 指向cp[0]//搞清楚上面这部分,就很简单了//注意:++cpp会产生副作用,会使得cpp改变printf("%s\n", **++cpp);//++cpp → 指向cp[1];//*++cpp 为cp[1]是c + 2 → 指向c[2];//**++cpp 为c[2];//则输出为"POINT"printf("%s\n", *-- * ++cpp + 3);//注意操作符优先级//++cpp → 指向cp[2];//* ++cpp为cp[2] → 指向c[1]//-- * ++cpp  → 指向c[0]//*-- * ++cpp 为c[0] → 指向 "ENTER" 的首地址//*-- * ++cpp + 3 → 指向 "ENTER" 的'E'的地址//则输出为"ER"printf("%s\n", *cpp[-2] + 3);//由于此时cpp → 指向cp[2]//cpp[-2]等效为*(cpp-2)//cpp-2 → 指向cp[0]//*(cpp-2)即为cp[0];//*(cp[0])即为c[3] → 指向 "FIRST" 的首地址。//+ 3 → 指向 "FIRST" 的'S'的地址//则输出为"ST"printf("%s\n", cpp[-1][-1] + 1);//cpp[-1][-1]+1等效为*(*(cpp-1)-1)+1;//先看cpp-1 → 指向cp[1];//*(cpp-1)则为cp[1] → 指向c[2];//*(cpp-1)-1 → 指向c[1];//*(*(cpp-1)-1)则为c[1] → 指向 "NEW" 的首地址。//+1 → 指向 "NEW" 的'E'的地址;//则输出为"EW"return 0;
}

总结:

指针到这就结束了,但我们的学习尚未结束,希望大家对指针都有各自的理解。
谢谢学习至此!!!

请添加图片描述

附录

上文链接

【C语言】指针基础:为什么说指针是C语言的灵魂?
【C语言】指针进阶1:数组与指针
【C语言】指针进阶2:数组、指针、函数

【C语言】指针笔试题1

专栏

C语言专栏

http://www.dtcms.com/wzjs/9586.html

相关文章:

  • 家电维修 做网站还是搞公众号宁波网站制作优化服务公司
  • 私域流量scrm系统刷seo关键词排名软件
  • 西安品牌网站建设网站客服
  • 网站开发教学黑帽seo教程
  • 兰州一键建站企业短期职业技能培训班
  • 后台建设电商网站北京债务优化公司
  • 江浙沪做网站的公司宁波seo网络推广多少钱
  • 如何在自己电脑上做网站哈尔滨怎样关键词优化
  • 在国外社交网站做产品推广成人短期技能培训学校
  • 关于网站开发的创业计划书怎样做网络推广营销
  • 哪些网站做的最好搜索引擎优化怎么做
  • 网站建设需解决问题免费网站安全软件大全游戏
  • 制作网站主要包括哪些步骤搜索引擎排名查询工具
  • 山东大学青岛校区建设指挥部网站怎么被百度收录
  • wordpress建站微信联系永久免费客服系统
  • 网站建设工具最简洁的今日新闻摘抄二十条
  • 济南代做标书网站标志推广普通话宣传语100字
  • 做网站接活全流程win10优化大师
  • 传媒公司商业计划书青岛seo杭州厂商
  • 舟山做网站兰州网站优化
  • 网站建设工资一月多少seo站长助手
  • 网站建设中英文网络推广运营主要做什么
  • drupal做虚拟发货网站哪些平台可以免费发布产品
  • 网址源码在线查看兰州seo推广
  • 建设公司网站计入哪个科目百度推广登录入口官网网
  • 有哪些好的网站建设免费获客平台
  • word可以做招聘网站吗网站流量统计工具有哪些
  • 兼职做猎头的网站推广神器app
  • 做问卷调查赚钱网站好企点官网
  • 怀柔做网站的公司百度排行榜明星