【C语言】指针笔试题

news/2025/2/26 16:57:53/

前言:上期我们介绍了sizeof与strlen的辨析以及sizeof,strlen相关的一些笔试题,这期我们主要来讲指针运算相关的一些笔试题,以此来巩固我们之前所学的指针运算!

文章目录

  • 一,指针笔试题
    • 1,题目一
    • 2,题目二
    • 3,题目三
    • 4,题目四
    • 5,题目五
    • 6,题目六
    • 7,题目七

一,指针笔试题

我们直接上题目:

1,题目一

下面程序运行的结果是什么?

#include <stdio.h> 
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&a
a为数组首元素的地址; &a为整个元素的地址;&a+1跳过整个数组指向最后一个元素的末尾。
上面程序int *ptr = (int *)(&a + 1); 就是将数组最后一个地址强转为(int *)类型 赋给ptr
所以当我们打印*(a + 1)打印的就是第二个元素 2!
打印*(ptr - 1)时,由于ptr存放的是最后一个元素末尾的地址再-1就找到了最后一个元素的地址 解引用拿到最后一个元素 5!

答案如下:
在这里插入图片描述

2,题目二

下面程序运行的结果是什么?

//在X86环境下 
//假设结构体的⼤⼩是20个字节 
//程序输出的结果是啥? 
struct Test { int Num; char *pcName; short sDate; char cha[2]; short sBa[4]; 
}*p = (struct Test*)0x100000; 
int main() 
{ printf("%p\n", p + 0x1); printf("%p\n", (unsigned long)p + 0x1); printf("%p\n", (unsigned int*)p + 0x1); return 0; 
} 

分析如下:

一, 首先看 0x100000 被强转成了结构体指针类型 p ,而且题目也告诉我们在X86环境下假设结构体的大小是20个字节。

  1. p+0x1 就相当于偏移了一个结构体的大小即20字节 二20字节转为16进制是 0x14 所以 p+0x1==0x100014

二,第二个打印的内容是将p强制类型转换为 unsigned long类型 我们知道在X86环境下long类型的数据是占4个字节的。

  1. 所以 unsigned long)p + 0x1就相当于p偏移一个unsigned long类型的大小 所以 unsigned long)p + 0x1 结果为0x100004吗?

注意这里有坑 :(unsigned long)p是将p转换成了整数啊!p此时已经不是指针了,所以不是指针加一而是整数加1! 而整数加1就是直接加一 所以结果为 0x100001

三,第三个打印的内容是将p强转为unsigned int*的类型,这时的p就是指针了,指针加一跳过一个unsigned int*类型该类型的大小为4个字节 所以结果为 0x100004

注意%p是C语言中用来格式化和打印指针变量的格式化符号。当你想打印一个指针变量的地址时,可以使用%p来输出该变量的地址值。

通过以上的分析我们首先要明白指针加一到底跳过多少字节?这取决于指针的类型,其实就是指针指向了什么类型的数据。
答案如下:
在这里插入图片描述

3,题目三

下面程序运行的结果是什么?

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

分析如下:

这道题也有陷阱,题目考察的知识点就是对数组名的理解。但是如果我们没有认真看题而是直接去看p[0]打印的结果,这时我们就会认为结果是0,因为p[0]==a[0]为第一行第一个元素所以是0。但结果是错的为什么呢?

  1. 我们看到数组初始化用的是()小圆括号。
  2. 圆括号里边有逗号所以考的是逗号表达式
    所以数组其实是这样的:
    在这里插入图片描述
    回到题目我们就可以从数组直接看出答案为1

答案如下:
在这里插入图片描述

4,题目四

下面程序运行的结果是什么?

//假设环境是x86环境,程序输出的结果是啥? 
#include <stdio.h> 
int main() 
{ int a[5][5]; //需要完整对应就需要一个int(*)[5]的数组指针int(*p)[4]; p = a; printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]); return 0; 
}

分析如下:

这里是引用
由上图我们需要知道2个点:

  1. 指针-指针的前提是两个指针指向同一个空间
  2. 指针-指针得到的结果的绝对值是两个指针之间的元素个数 并且小地址-大地址会得到负数
    我们知道&p[4][2]-&a[]4[2]==-4那么问题来了 -4以%p%d的形式打印的结果分别是什么呢?
  3. 以%d形式打印 结果就为 -4
  4. 以%p的形式打印就要注意了 前面说过%p是用来打印地址的 打印-4时会直接将内存中的值当作地址打印 而地址中存放的是16进制数 而-4的16进制数为0xFFFFFFFC

如果对于进制转换还不是很了解的话可以去看我之前写的进制转换这篇文章;传送门:进制转换

答案如下:
在这里插入图片描述

5,题目五

#include <stdio.h> 
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,aa为二维数组首元素的地址而二维数组首元素为第一行的地址+1会跳过一行指向的第一行最后一个元素的末尾;&aa拿到的是整个二维数组的地址 +1会跳过一个二维数组 指向的是二维数组最后一个元素的末尾。
通过上面的分析我们不难得出答案是10和5

答案如下:
在这里插入图片描述

6,题目六

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

分析如下:

这一题是一个关于二级指针的题,首先a是一个指针数组,*pa=a拿到了a数组的首地址"work",这其实相当于一个指针数组存放了三个类型为char*的字符串常量我们画图演示:
在这里插入图片描述
pa++就跳过了一个元素指向了"at"这个常量字符串 所以打印的结果就是"at"。

答案如下:
在这里插入图片描述

7,题目七

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

分析如下:
要解决这道题首先要把图给画好:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
好了这就是一些有关指针运算相关的练习了,如果有问题欢迎指出与我讨论。
感谢能够看到这里的读者,如果我的文章能够帮到你那我甚是荣幸,文章有任何问题都欢迎指出!制作不易还望给一个免费的三连,你们的支持就是我最大的动力!
在这里插入图片描述


http://www.ppmy.cn/news/1575052.html

相关文章

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_atoi 函数

ngx_atoi 声明在 src/core/ngx_string.h ngx_int_t ngx_atoi(u_char *line, size_t n); 定义在 src/core/ngx_string.c ngx_int_t ngx_atoi(u_char *line, size_t n) {ngx_int_t value, cutoff, cutlim;if (n 0) {return NGX_ERROR;}cutoff NGX_MAX_INT_T_VALUE / 10;cutlim…

matlab ylabel怎么让y轴显示的标签是正的

这是90度的&#xff0c;即默认形式 在 MATLAB 中&#xff0c;若想让ylabel设置的 y 轴标签是正的&#xff08;即文字正常显示而非默认的垂直排列&#xff09;&#xff0c;可以通过设置Rotation属性来实现 在使用ylabel函数添加 y 轴标签时&#xff0c;通过Rotation,0将标签文…

20250223C语言指针与应用

20250223C语言指针与应用 01指针位数.cpp #include<stdio.h> int main() {char a 0x22; // char *p;char *p&a; //指针变量就是存放地址&#xff0c;为了可以存下计算机内存中任何地址&#xff0c;16位系统指针变量大小为2字节&#xff0c;32-4字节&#xff08;4x…

GO 快速升级Go版本

由于底层依赖升级了&#xff0c;那我们也要跟着升&#xff0c;go老版本已经不足满足需求了&#xff0c;必须要将版本升级到1.22.0以上 查看当前Go版本 命令查看go版本 go version [rootlocalhost local]# go version go version go1.21.4 linux/amd64 [rootlocalhost local]# …

5分钟使用Docker部署Paint Board快速打造专属在线画板应用

文章目录 前言1.关于Paint Board2.本地部署paint-board3.使用Paint Board4.cpolar内网穿透工具安装5.创建远程连接公网地址6.固定Paint Board公网地址 &#x1f4a1; 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住…

Ubuntu部署ktransformers

准备工作 一台服务器 CPU&#xff1a;500G GPU&#xff1a;48G&#xff08;NVIDIA4090&#xff09; 系统&#xff1a;Ubuntu20.04&#xff08;github的文档好像用的是22.04&#xff09; 第一步&#xff1a;下载权重文件 1.下载hfd wget https://hf-mirror.com/hfd/hfd.s…

DeepSeek掘金——VSCode 接入DeepSeek V3大模型,附使用说明

VSCode 接入DeepSeek V3大模型,附使用说明 由于近期 DeepSeek 使用人数激增,服务器压力较大,官网已 暂停充值入口 ,且接口响应也开始不稳定,建议使用第三方部署的 DeepSeek,如 硅基流动 或者使用其他模型/插件,如 豆包免费AI插件 MarsCode、阿里免费AI插件 TONGYI Lin…

快手弹幕 websocket 分析

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 逆向分析 import timeimport requests…