C语言指针笔试题讲解

2023-09-19 08:27:37

大家好,我们来学习一些C语言的指针笔试题。对于C语言指针的模块想必大家都非常的头疼吧,那么我们就来就来看看一些关于C语言指针的笔试题。

在这里插入图片描述

首先让我们看到我们今天的第一题。

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

在这里插入图片描述
看到这个程序运行的结果,我们就好好地来分析下这个题。

在这里插入图片描述

我们看到图片,我们printf语句中的a指的是数组首元素的地址指向的就是图中1位置,a+1就代表数组中第二个元素的地址,所以我们 *(a+1)得到就是第二个元素,我们的指针指向的是图中2位置,因为&a取的是数组的地址,所以&a+1指向的就是图中2位置,ptr-1指向的就是图中3位置,所以我们 *(ptr-1)得到就是第五个元素。

我们看到下一题

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

在这里插入图片描述

我们看到在x86环境下打印的结果,因为我们的地址在内存中的存储是16进制,所以我们的结构体大小为20个字节,指针结构体加1,跳过一个结构体的大小,我们这里第一个打印就是16进制的20,第二个我们是无符号数的长整型所以加1就是普通加1,所以打印的结果就是00000001,最后一个我们的p是int*类型的指针,所以我们这里就是加4,所以结果就是00000004。

我们继续–>:

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);
	int* ptr2 = (int*)((int)a + 1);
	printf("%x,%x\n", ptr1[-1], *ptr2);
	return 0;
}

在这里插入图片描述

我们这里依旧是ptr1指向下一组数据,也就是与数组最后一个元素相邻的数据,而打印ptr1[-1]就是ptr1向前挪一个整型也就是4个字节,所以ptr1指向的就是数组的最后一个数据,所以结果就是4。第二个它先是把数组名a强制转换成整型变量,然后再加1,然后再强制转换成整型指针!就是让ptr2指向a[0]的第二个字节,看到下图:
在这里插入图片描述
在这里插入图片描述

ptr2指向了a[0]的第二个字节由于x86平台是小端序的,小端序的存取时最低位对应低地址 ,因此将会打印出2000000。

#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=a[0]指的是取的二维数组第一行第一个元素的地址,我们要注意括号里的是逗号表达式,逗号表达式的结果就是表达式中最后一个表达式的结果,所以原来数组中存放的值就是{1,3,5}。所以我们这里的p[0]就相当于*(p+0),也就是*p,所以打印的结果为1。

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[4][2]取的是第五行第三个元素的地址,而我们定义的*p数组指针,p=a我们就知道这单纯的把数组a的元素被p分为以四个元素为一行,所以我们的&p[4][2]就是我们刚得到的数组的第五行第三个元素的地址,所以两个相减得到-4,然而我们前面还得打印这个数的地址,那么我们首先就得知道地址是以16进制的形式存储的,我们首先得到的是-4的补码,因为负数里存储的是补码,我们给它取反加一得到原码,但我们这个时候是二进制,所以我们要给它转换成16进制,1111代表二进制的15,转换成16进制就是f,而1100代表的是二进制序列的12,所以转换成16进制就是c,所以地址就是fffffffc。

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

在这里插入图片描述
在这里插入图片描述

看了前几个题相信大家对ptr1已经有了更加深刻的理解,我们的ptr1指向的就是下个数据,ptr-1指向就是这个数组最后一个元素,得到的结果就是10,我们这里的aa+1就相当于aa[1],也就是&aa[1][0],所以指向的就是二维数组第二行第一个元素,那我们的ptr2-1指向的就是第一行最后一个元素的地址,所以得到的就是5。

在今天的学习中大家一定都会有些许收货吧,我们下次见,谢谢大家。

更多推荐

安卓机型固件系统分区的基础组成 手机启动规律初步常识 各分区的基本含义与说明

此贴为基本常识。感兴趣的友友可以了解手机的启动顺序和各模式的基本操作与意义。另外了解手机系统分区各文件夹的含义分区说明对应贴:安卓机型固件中分区对应说明手机开机基本启动顺序当我们按下手机开机键的时候。基本的启动顺序为注意:该结构图并不反映手机的实际分区顺序和位置,只是一个逻辑结构图。当按下电源键手机上电启动后,首先从b

【Purple Pi OH RK3566鸿蒙开发板】OpenHarmony音频播放应用,真实体验感爆棚!

本文转载于PurplePiOH开发爱好者,作者ITMING。原文链接:https://bbs.elecfans.com/jishu_2376383_1_1.html01注意事项DevEcoStudio4.0Beta2(BuildVersion:4.0.0.400)OpenHarmonySDKAPI9创建工程类型选择Ap

ARM 汇编指令集——汇编中三种符号(汇编指令、伪指令、伪操作)、汇编基本格式、数据操作指令、跳转指令、特殊功能寄存器操作指令、内存操作指令、混合编程

目录一、汇编中三种符号(汇编指令、伪指令、伪操作)二、汇编基本格式三、数据操作指令3.1数据搬移指令mov/mvn①示例②立即数3.2移位操作指令lsl/lsr/asr/ror示例3.3位运算操作指令and/orr/eor/bic①示例1②示例23.4算数运算操作指令add/adc/sub/sbc/mul①实现两个64

数字化管理平台建设实践

在勘察设计行业,各企业加速推进数字化转型。通过管理要素数字化,不断优化内部组织运营效率;通过生产手段数字化、技术产品数字化,提升服务质量,改善客户体验;通过数字化营销,精准对接市场需求,挖掘发展蓝海。本文基于勘察设计企业数字化管理系统普遍存在的问题,结合湖北省交通规划设计院股份有限公司(以下简称“湖北交规院”)的数字化

vue的组件化编程的详细讲解加代码演示

😀前言本片文章是vue系列第5篇整理了vue的组件化编程的详细讲解加代码演示🏠个人主页:尘觉主页🧑个人简介:大家好,我是尘觉,希望我的文章可以帮助到大家,您的满意是我的动力😉😉在csdn获奖荣誉:🏆csdn城市之星2名⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣💓Java全栈群星计划t

Mysql002:(库和表)操作SQL语句

目录:》SQL通用规则说明SQL分类:》DDL(数据定义:用于操作数据库、表、字段)》DML(数据编辑:用于对表中的数据进行增删改)》DQL(数据查询:用于对表中的数据进行查询)》DCL(用户权限:用于创建用户、修改数据库访问权限等)SQL通用规则说明:1.SQL语句可以单行编写,也可以多行编写,以英文分号结束2.SQ

基于Java+vue前后端分离高校社团管理系统设计实现(源码+lw+部署文档+讲解等)

博主介绍:✌全网粉丝30W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌🍅文末获取源码联系🍅👇🏻精彩专栏推荐订阅👇🏻不然下次找不到哟2022-2024年最全的计算机软件毕业设计选题

如何实现微服务

一、问题拆解1.1、客户端如何访问这些服务原来的Monolithic方式开发,所有的服务都是本地的,UI可以直接调用;现在按功能拆分成独立的服务,跑在独立的虚拟机上的Java进程了。客户端UI如何访问他的?后台有N个服务,前台就需要记住管理N个服务,一个服务下线/更新/升级,前台就要重新部署,这明显不符合我们拆分的理念

【LeetCode题目详解】第十章 单调栈part02 ● 503.下一个更大元素II ● 42. 接雨水 (day59补)

本文章代码以c++为例!一、力扣第503题:下一个更大元素II题目:给定一个循环数组nums(nums[nums.length-1]的下一个元素是nums[0]),返回nums中每个元素的下一个更大元素。数字x的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的

vvic API接口接入说明:解锁新一代数据可视化的无限可能

随着大数据时代的来临,数据可视化已成为我们理解、分析和呈现复杂数据的重要手段。在这个领域中,vvic以其独特的优势,引领着数据可视化的发展潮流。其强大的API接口,更是为开发者提供了无限可能,让数据可视化变得更为简单、直观和生动。vvicAPI接口是一个高度灵活、易于使用的工具,旨在帮助开发者快速创建出美观、功能丰富的

web应用及微信小程序版本更新检测方案实践

背景:随着项目体量越来越大,用户群体越来越多,用户的声音也越来越明显;关于应用发版之后用户无感知,导致用户用的是仍然还是老版本功能,除非用户手动刷新,否则体验不到最新的功能;这样的体验非常不好,于是我们团队针对该问题给出了相应的解决方案来处理;技术栈:vue3+ts+vite+ant-design-vue1.web应用

热文推荐