C语言 之 理解指针(9)与指针相关的理解题

news2024/11/16 4:36:22

文章目录

  • 代码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+1) 中的a是首元素地址,a+1之后则是第二个元素的地址,再进行解引用,那么得到的就是第二个元素。
*(ptr - 1) 中,int* ptr = (int*)(&a + 1);,这里的&a 取的是整个数组的地址,虽然地址也是首元素地址,但是+1后跳过的是一整个数组,指向数组之后的位置,然后对ptr-1,那就回退一个空间,就指向了元素5的地址,再解引用得到的就是元素5啦。
如下图所示:
在这里插入图片描述

代码2

//在X86环境下
//假设结构体的⼤⼩是20个字节
//程序输出的结构是啥?
#include <stdio.h>
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;
}

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

解析:

这里已经知道结构体的大小是20个字节,这个结构体初始化了一个指针p,并且初始化指向了0x100000。
那么p+1,即结构体指针+1,就要跳过一个结构体,由于这个是16进制的形式,所以1 * 16^1 + 4 * 16^0 = 20,所以结果为 0x100014。
(unsigned long)p + 0x1; 这里将p强制转换成了长整形,整形+1,就是+1。
(unsigned int*)p + 0x1; 将p强制转换成了int* 类型 ,所以+1 跳过4个字节。

代码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 = a[0]; 而a[0]是第一行的数组名,数组名表示首元素,所以这里的a[0] 就相当于 &a[0][0],那结果不就是0吗?
这是我们认为的:
在这里插入图片描述

事实上是这样的
在这里插入图片描述
这是因为:
二维数组的初始化应该用{}进行初始化,而不是圆括号(),否则就成了逗号表达式

代码4

//假设环境是x86环境,程序输出的结果是啥?
#include <stdio.h>
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是一个数组指针,指向有4个整形元素的数组
p = a; a是首元素地址,这是将a的地址给p,让他们指向同一块地址
在这里a的类型是 int ( * ) [5] , p的类型是 int ( * )[4]
p[4][2] = *( * (p+4) + 2)
我们已知两个指针相减就是两个指针之间的元素个数
所以如图所示:
首先这是数组a
在这里插入图片描述

他们之间的关系
在这里插入图片描述
所以%d的打印结果是-4
而%p的结果如下:
在这里插入图片描述

代码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+1即跳过这个二维数组后,指向这个二维数组的后一个位置,所以打印结果时,*(ptr1 - 1) -1后到达10的位置,解引用即元素10,所以结果为10.
*(aa + 1) ,这就相当于aa[1],aa[1]是第二行的数组名,所以代表的是第二行的首元素地址,即&aa[1][0],所以指向的就是元素6的位置,打印时-1后指向的就是元素5的位置了

代码6

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

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

解析:

首先我们要知道a是一个字符指针数组
char** pa = a; 这是将数组a的地址给二级指针pa
所以现在的情况如图所示:
在这里插入图片描述
接着pa++,那么就跳过一个字节
就变成了这样
在这里插入图片描述
所以打印结果就为 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;
}

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

解析:

不得不承认,一开始看到这题的时候觉得天塌了,但是其实画图理解还是很好解决的。
首先,做这题之前,我们先要明白:
++,- -会真正改变值,会真正改变cpp的指向,即影响到后面的指向位置。
但是cpp[-2] = *(cpp-2)这样的不会使cpp发生真正改变,即在后面的语句中,cpp的指向会恢复到cpp[-2] = *(cpp-2)执行前的cpp的指向。
这是他们之间的关系图:
在这里插入图片描述
第一条打印:
在这里插入图片描述
第二条打印:
在这里插入图片描述
第三条打印:
在这里插入图片描述
第四条打印:
在这里插入图片描述


以上就是相关例题,如有讲解错误还请指出。

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

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

相关文章

B站千亿级点赞系统服务架构设计

B站千亿级点赞系统服务架构设计 原文链接&#xff1a;https://www.bilibili.com/read/cv21576373/ 原文作者&#xff1a;哔哩哔哩技术团队-芦文超 点赞的功能太过于简单不再赘述&#xff0c;大家可以点击原文链接简单看下便可知晓。 本讲结合B站知名UP主陆总监的一期视频(h…

【vue3|第21期】Vue3中Vue Router的push和replace方法详解

日期&#xff1a;2024年8月9日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xff…

Android系统Android.bp文件详解

文章目录 1. 基本语法结构2. 常见模块类型3. 模块属性常见属性包括&#xff1a; 4. 具体示例5. 高级功能5.1. 条件编译5.2. 变量定义与使用5.3. 模块继承 6. 总结 Android.bp 是 Android 构建系统&#xff08;Android Build System&#xff09;中的配置文件&#xff0c;用于描述…

C语言典型例题31

《C程序设计教程&#xff08;第四版&#xff09;——谭浩强》 习题2.8 请编写程序将China译为密码&#xff0c;密码的规律是&#xff1a;用原来字母后面的第4个字母代替原来的字母。 例如:C后面的4个字母是G&#xff0c;h后面第4个字母为l 代码&#xff1a; //《C程序设计教程…

TinyLLaVA: A Framework of Small-scale Large Multimodal Models

发表时间&#xff1a;22 Feb 2024 论文链接&#xff1a;https://arxiv.org/pdf/2402.14289 作者单位&#xff1a;SKLCCSE, Institute of Artificial Intelligence, Beihang University, Beijing, China Motivation&#xff1a;当前的大语言模型的参数量太大了&#xff0c;作…

flask学习-day1

介绍 django是大而全&#xff0c;flask是轻量级的框架 django提供非常多组件&#xff1a;orm/session/cookie/admin/form/modelform/路由/视图/模板/中间件/分页/auth/contentype/缓存/信号/多数据库连接 flask本身没有太多的功能&#xff1a;路由/试视图/模板/session/中间件…

【C++ 面试 - 基础题】每日 3 题(八)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏&…

24/8/9算法笔记 决策树VS线性回归

from sklearn.tree import DecisionTreeRegressorfrom sklearn.linear_model import LinearRegressionfrom sklearn import datasetsfrom sklearn.model_selection import train_test_split import numpy as np X,y datasets.load_diabetes(return_X_yTrue)#糖尿病数据 X_tra…

03、MySQL-DQL(数据查询语言)

目录 1、编写顺序 2、基本查询 3、条件查询 4、聚合函数 5、分组查询 6、排序查询 7、分页查询 8、执行顺序 1、编写顺序 SELECT 字段列表 FROM 表名列表 WHERE 条件列表 GROUP BY 分组字段列表 HAVING 分组后条件列表 ORDER BY 排序字段列表 LIMIT 分页参数2、基本查…

Cesium初探-相机

在 Cesium 中&#xff0c;相机&#xff08;Camera&#xff09;是一个非常重要的概念&#xff0c;它代表了用户观察 3D 场景的视角。相机不仅决定了用户看到的内容&#xff0c;还定义了观察的角度、距离和方向。理解 Cesium 中的相机是如何工作的对于创建有效的 3D 地图和地球应…

关于Redis的面试题(一)

一、为什么要使用Redis 内存数据库&#xff0c;速度很快工作单线程worker&#xff0c;串行化&#xff0c;原子操作&#xff0c;IO线程是多线程的。避免上下文切换使用 IO模型&#xff0c;天生支撑高并发kv模型&#xff0c;v具有类型结构具有本地方法&#xff0c;计算数据移动二…

政府经济学(练习题)

政府经济学&#xff08;练习题&#xff09; 一、单项选择题 政府经济活动的主体是&#xff08; &#xff09;。 A.各级政府 B.各级人大 C.各级政协 D.各级党委政府经济的依据主要是&#xff08; &#xff09;。 A.私人财产所有权 B.社会公共权力 C.道德劝说 D.法律制度1776年亚…

通过指令深入了解Linux 3

&#x1f308;个人主页&#xff1a;Yui_ &#x1f308;C语言笔记专栏&#xff1a;C语言笔记 &#x1f308;数据结构专栏&#xff1a;数据结构 文章目录 1.Linux下的基本指令1.1 more指令&#xff08;有更好的平替&#xff09;1.2 less指令1.3 head指令1.4 tail指令1.5 date指令…

二、Matlab图像处理基础

文章目录 一、Matlab图像处理工具箱二、图像文件的读取2.1 文件信息的读取2.2 图像文件的读取2.3 图像文件的保存2.4 图像文件的显示2.5 像素信息的显示 本章知识点总结 一、Matlab图像处理工具箱 在帮助文档可以搜索到图像处理工具箱的介绍 二、图像文件的读取 2.1 文件信息…

论文笔记:OneBit: Towards Extremely Low-bit Large Language Models

202402 arxiv 1 背景 模型量化主要通过把模型的线性层【nn.Linear】&#xff08;Embedding 层和 Lm_head 层除外&#xff09;转化为低精度表示实现空间压缩 此前工作的基础是利用 Round-To-Nearest&#xff08;RTN&#xff09;方法把高精度浮点数近似映射到附近的整数网格然而…

Sqlserver 创建只读权限用户

Sqlserver 创建只读权限用户 1、右键登录名->新建登录名 2、在常规选项卡中配置登录名、密码、数据库 3、服务器角色选项卡中配置只读角色 4、配置用户映射 5、安全对象选项卡和状态选项卡默认即可

Hadoop集群安装配置,spark集群安装配置

前提&#xff1a;准备3台linux服务器&#xff0c;并保证其网络可进行相互通信 假设三台机器IP分别为&#xff1a; 192.168.88.101 192.168.88.102 192.168.88.103一.配置三台服务器之间SSH免密登录,关闭防火墙&#xff0c;时间同步 三台服务器均执行以下1,2,3,4,5,6,8命令 1…

C++ primer plus 第17 章 输入、输出和文件:文件输入和输出03:文件模式:二进制文件

系列文章目录 17.4.5 文件模式 程序清单17.18 append.cpp 程序清单17.19 binary.cpp 文章目录 系列文章目录17.4.5 文件模式程序清单17.18 append.cpp程序清单17.19 binary.cpp17.4.5 文件模式1.追加文件来看一个在文件尾追加数据的程序。程序清单17.18 append.cpp2.二进制文…

05_ Electron 自定义菜单、主进程与渲染进程通信

Electron 自定义菜单、主进程与渲染进程通信 一、定义顶部菜单二、Electron 自定义右键菜单1、使用 electron/remote 模块实现 三、 Electron 主进程和渲染进程通信场景1&#xff1a;渲染进程给主进程发送异步消息场景2&#xff1a;渲染进程给主进程发送异步消息&#xff0c;主…

Vue3使用ECharts的自定义堆叠条形图(纵向)

先上效果图 展示区域 <div id"main" style"height: 300px; width: 100%"></div> 配置信息 每个种类的data数组是number数组&#xff0c;这里我使用的变量是从接口返回的数据&#xff0c;为了方便理解&#xff0c;年度考核的绿色种类&#x…