C语言刷题(20)

news2024/11/25 23:00:44

指针笔试题

笔试题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[1],第一个是2,a的类型是int [5],&a的类型就是int(*)[5],
是个数组指针。所以给int(*)[5]类型加一,相当于加了一个int [5]的长度。也就
是这个指针直接跳过了a全部的元素,直接指在了刚好越界的位置上,然后转换成了
int *后再减一,相当于从那个位置向前走了一个int,从刚好越界的位置回到了5的
址处,所以第二个是5



笔试题2

由于还没学习结构体,这里告知结构体的大小是20个字节

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

本质上考察指针加1的知识点:

p = 0x100000

p + 0x1 为跳过一个结构体指针(20字节),所以为0x100014

(unsigned long)p + 0x1  为强制类型转换为整型(1048576),整型数字加1(1048577),写成16进制就是0x100001

(unsigned int*)p + 0x1   为强制类型转换为整型指针,加的就是一个指针的大小4/8,就是0x100004/8

而在X86环境下打印,地址是4个字节

答案就是:

0010014

0010001

0010004

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

ptr1[ -1 ] == *(ptr1-1)   因为ptr1直接指在了刚好越界的位置上,然后转换成了
int *后再减一,相当于从那个位置向前走了一个int,从刚好越界的位置回到了4的
址处,所以是4

(int)a + 1  假设a的首元素地址为0x0012ff40,将它强制转换成 int 整型,整型数字加1,就是0x0012ff41,相当于往后移了一个字节,再将它强制转换成 int* 指针类型,假设是小端存储,存储形式就是  01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 ,而 *ptr2 解引用就是往后读取4个字节(因为是int *)大小(00 00 00 02)0x02000000,又因为是以%x形式打印,所以就是16进制。答案是2000000


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

答案是1

注意:(0, 1), (2, 3), (4, 5)是逗号表达式,不是每一行数组的内容,因为二维数组每一行也是一个数组,所以也要用{ },所以{ (0, 1), (2, 3), (4, 5) }表示的其实是{1,3,5},因为a[0] 是第一行的数组名,就是数组第一行的首元素地址(即a[0][0]),p[0] == *(p+0) == *p ,所以就是a[0][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表示二维数组首元素地址,也就是数组第一行的地址,p = a 相当于将int(*)[ 5 ]类型的指针赋给 int(*)[ 4 ]类型的指针,而p+1 == &p[ 1 ]跨过的是四个整型大小,a+1跨过的是5个整型大小,所以算出&p[4][2] - &a[4][2]为-4(相差4个整型大小),而前面是用%p打印,相当于把-4当作地址,-4在内存中是以补码的形式存储的,就是11111111 11111111 11111111 11111100,16进制就是0xff ff ff fc

所以答案是:0xff ff ff fc,-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 + 1 是整个二维数组的地址+1,就是刚好越界的位置,再强制转换成int *,所以*(ptr1 - 1)就是往前移一个int大小,就是指向9,再解引用

*(aa + 1) == aa[ 1 ] 中aa是二维数组首元素的地址,就是第一行的地址,再加1就是第二行的地址,解引用就变成第二行第一个元素的地址,再强制转换成int *,所以*(ptr2 - 1)就是往前移一个int大小,就是指向5,再解引用


笔试题7

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

    char *a[] = {"work","at","alibaba"}是将"work","at","alibaba"三个字符串的首元素(w , a , a)的地址放入a数组里

   char**pa = a;就是pa指针的地址指向a数组首元素的地址(w)

    pa++;就是pa指针的地址指向a数组第二个元素的地址(a)

最后以%s打印,就是从a的地址开始打印字符串,结果就是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;
}

需要画图来看(画指向关系)

    char *c[] = {"ENTER","NEW","POINT","FIRST"};是将"ENTER","NEW","POINT","FIRST"四个字符串的首元素(E , N , P , F)的地址放入c数组里
    char**cp[] = {c+3,c+2,c+1,c};cp数组每个元素是char**,那么就是四个指针分别指向c的首元素地址+3(c的首元素地址+3又指向F地址),c的首元素地址+2(P),c的首元素地址+1(N),c的首元素地址(E)
    char***cpp = cp;cpp就是三级指针,指向cp的首元素地址
    printf("%s\n", **++cpp);cpp变成指向cp第二个元素地址的地址(发生变化了),解引用一次就是cp第二个元素(指向P的地址的地址),再解引用一次就是P的地址,最后以%s打印,就是从P的地址开始打印字符串,结果就是POINT
    printf("%s\n", *--*++cpp+3);++cpp使cpp变成指向cp第三个元素地址的地址(发生变化了),再解引用得到cp第三个元素(指向N的地址的地址),再进行--,就是cp第三个元素变成指向E的地址的地址(发生变化了),就是存储的从c+1变成c,再解引用得到E的地址,再+3得到第二个E的地址,最后以%s打印,就是从第二个E的地址开始打印字符串,结果就是ER
    printf("%s\n", *cpp[-2]+3); *cpp[-2]+3  == **(cpp-2)+3,cpp现在是指向cp第三个元素地址的地址,-2变成指向cp首元素地址的地址,解引用得到c+3,再解引用得到F的地址,再+3得到S的地址,最后以%s打印,就是从S的地址开始打印字符串,结果就是ST
    printf("%s\n", cpp[-1][-1]+1);cpp[-1][-1] == *(*(cpp-1)-1),cpp现在是指向cp第三个元素地址的地址,-1变成指向cp第二个元素地址的地址,再解引用得到c+2,再-1得到c+1,再解引用得到N地址,再+1变成E的地址,最后以%s打印,就是从E的地址开始打印字符串,结果就是EW

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1554515.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SQL映射文件

一、SQL映射的xml文件 1.1 mapper元素 二、select 三、别名与Java映射 四、resultMap 啊

类模板成员函数的类外实现

能够掌握类模板中的成员函数的类外实现&#xff1a; #include <iostream> #include <Windows.h> #include <string>using namespace std;template<typename T1, typename T2> class Person { public:T1 m_Name;T2 m_Age;Person(T1 name, T2 age);void…

动态规划——简单多状态专题

一、按摩师&#xff08;打家劫舍 | &#xff09; 1.链接 面试题 17.16. 按摩师 - 力扣&#xff08;LeetCode&#xff09; 2.描述 3.思路 4.参考代码 class Solution { public:int massage(vector<int>& nums) {int n nums.size();if(n 0){return 0;}vector<…

整理git上的模板框架

vite-vue3.0-ts-pinia-uni-app 技术栈的app框架 功能&#xff1a;基于 uni-app&#xff0c;一端发布多端通用&#xff0c;目前已经适配 H5、微信小程序、QQ小程序、Ios App、Android App。 taro3vue3tsnutuipinia taro3 框架小程序跨端平台 vue3.0-element-vite-qiankun 后台…

vue3+threejs新手从零开发卡牌游戏(十四):调整卡组位置,添加玩家生命值HP和法力值Mana信息

由于之前的卡组位置占了玩家信息的位置&#xff0c;所以这里将它调整到site区域&#xff1a; 修改game/site/p1.vue&#xff0c;在site右下角添加一个卡组区域&#xff1a; // 初始化己方战域 const init () > {let sitePlane scene.getObjectByName("己方战域Plan…

【干货分享】OpenHarmony轻量系统适配方案

1. 简介 本文在不改变原有系统基础框架的基础上&#xff0c; 介绍了一种OpenAtom OpenHarmony&#xff08;以下简称“OpenHarmony”&#xff09;轻量系统适配方案。 本方案使用的是 OpenHarmony v3.2 Release版本源码。 2. 方案设计 本文使用的硬件模块的主要特性及功能如…

基于最小二乘支持向量机(LSSVM)的数据时序预测(单输入输出)

作品描述付费内容发布设置 宋体 黑体 微软雅黑 monospace cursive Sans Serif Inconsolata Roboto Mirza Arial 代码原理 基于最小二乘支持向量机&#xff08;LSSVM&#xff09;的数据时序预测&#xff08;单输入输出&#xff09;是指利用LSSVM模型来预测未来时序数据的单个…

Flutter环境搭建及版本管理

前言 Flutter已成为移动应用开发的主流选择&#xff0c;其跨平台优势日益凸显&#xff0c;使学习Flutter成为现代开发者的必备技能。越来越多的公司和团队选择Flutter构建应用&#xff0c;这为开发者提供了更广阔的就业机会和职业发展空间。Flutter的热度源自其强大的特性和生…

某红队面试经验

背景 据小道消息说今年的国护疑似提前到了五月份&#xff0c;所以最近也是HW面试的一个高峰期啊&#xff0c;这里分享一下上次的红队面试问题 面试问答 问&#xff1a;Java 反序列化的原理&#xff1f; 答&#xff1a;如果Java应用对用户输入&#xff0c;即不可信数据做了反…

Docker命令及部署Java项目

文章目录 简介Docker镜像镜像列表查找镜像拉取镜像删除镜像镜像标签 Docker容器容器启动容器查看容器停止和重启后台模式和进入强制停止容器清理停止的容器容器错误日志容器别名及操作 Docker部署Java项目 简介 Docker是一种容器化技术&#xff0c;可以帮助开发者轻松打包应用…

大话设计模式之代理模式

代理模式&#xff08;Proxy Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许通过代理对象控制对另一个对象的访问。代理对象充当客户端和实际对象之间的中介&#xff0c;客户端通过代理对象间接访问实际对象&#xff0c;从而可以在访问控制、缓存、延迟加载等方面提…

yolo系列热力图,即插即用。

原地址&#xff1a;https://github.com/z1069614715/objectdetection_script/tree/master/yolo-gradcam

反应式编程(二)什么是粘包、拆包?如何解决?

目录 一、粘包、拆包介绍1.1 什么是 TCP 协议&#xff1f;1.2 什么是粘包、拆包&#xff1f;1.3 粘包、拆包的四种情况1.4 粘包、拆包的原因1&#xff09;TCP协议中的滑动窗口机制2&#xff09;传输层的 MSS 与链路层的 MTU3&#xff09;TCP协议中的 Nagle 算法4&#xff09;应…

git配置SSH 密钥

git配置SSH 密钥 1.window配置ssh1.安装ssh2.安装 Git&#xff08;安装教程参见安装Git&#xff09;并保证版本大于 1.9![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/e59f4e16b83c45649f1d9d7bd6bf92c0.png)3.SSH 尽量保持最新&#xff0c;6.5之前的版本由于使用…

【文献分享】PyPlume程序:快速海洋表面传输评估的工具包

PyPlume: A toolkit for rapid ocean surface transport assessments PyPlume&#xff1a;快速海洋表面传输评估的工具包 PyPlume 是一个 Python 工具箱和管道&#xff0c;用于统一从模型和观测加载二维洋流矢量场、模拟轨迹模型以及分析和可视化粒子轨迹的过程。提供了 Ju…

python 如何安装redis

一、redis介绍 redis是一个非关系型的缓存数据库&#xff0c;因为是缓存所以redis的速度会非常快。redis主要是依靠键值对进行存储&#xff0c;类似于java的map、python的字典。redis支持许多的语言&#xff0c;如java、C、C、C#、PHP、JavaScript、Perl、python等。 二、pyt…

基于SSM的高校普法系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的高校普法系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring Spri…

redis 的设计与实现(三)——对象

1. 前言&#xff1a; 在第一章节我们了解到了&#xff0c;redis底层所涉及的数据结构&#xff0c;但是这并非是离我们最近的一层&#xff0c;在此之上&#xff0c;redis实现了一层对象与我们交互。我们在本篇内容中将了解到&#xff1a; 对象对应的实现redis一些常用特性的实现…

物联网实战--入门篇之(三)嵌入式STM32

目录 一、Keil简介 二、工程结构 三、文件目录 四、STM32简介 五、编码风格 六、总结 一、Keil简介 Keil是一款常用的单片机开发工具&#xff0c;主要包含了编译、仿真、调试和开发界面(IDE)&#xff0c;后被ARM公司收购&#xff0c;与其MDK-ARM合并为MDK-ARM Keil软件包…

宝塔面板操作一个服务器域名部署多个网站

此处记录IP一样&#xff0c;端口不一样的操作方式&#xff1a; 宝塔面板操作&#xff1a; 1、创建第一个网站&#xff1a; 网站名用IP地址&#xff0c;默认80端口。 创建好后&#xff0c;直接IP访问就可以了。看到自带的默认首页 2、接下来部署第二个网站&#xff1a; 仍然是…