C语言指针相关练习题

C语言指针相关练习题

文章目录

  • C语言指针相关练习题
    • 题目一
    • 题目二
    • 题目三
    • 题目四
    • 题目五
    • 题目六
    • 题目七

题目一

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

第一题来说是比较简单的,先来看看代码运行结果
在这里插入图片描述

数组名的理解

  1. sizeof(数组名) 计算的是整个数组的大小
  2. &数组名 取出的是整个数组的地址
  3. 除上面两种情况,数组名都指数组的首元素地址

有了对数组名的理解,这题就好做了
&a+1 取出数组的地址然后+1,指跳过这个数组,指向数组之后的空间
数组地址应存放在数组指针中,int (*p)[ 5 ]中,强制类型转换成 int *类型存放在int *类型的指针中
无论什么类型的指针都可以存放任意类型的地址
*(a + 1) a是首元素的地址,+1指向第二个元素,解引用得到第二个元素 2
*(ptr - 1) ptr存放的是数组+1之后的地址,指向数组之后,-1之后指向数组中最后一个元素 5

题目二

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

代码运行结果如下:
在这里插入图片描述

printf("%p\n", p + 0x1);

%p打印的是地址,0x1表示16进制,也就是1,指针加整数跳过多少字节的空间取决于指针的类型,在上述代码中p是结构体指针,同时题目给的结构体为20个字节,所以p + 0x1 跳过了20个字节,也就是 100014,%p打印的是十六进制的,所以是01000014

printf("%p\n", (unsigned long)p + 0x1);

在上述代码中将p的类型从结构体指针强制类型转换成了unsigned int类型,即无符号整型,p + 0x1也就变成了整数之间的加减,100001,由于是以十六进制的方式打印的,所以是00100001

printf("%p\n", (unsigned int*)p + 0x1);

在上述代码中将p的类型从结构体指针强制类型转换成了unsigned int*类型,是无符号整型指针,指针加减整数取决与类型的大小,unsigned int是4个字节的,所以p + 0x1 跳过了4个字节,也就是100004,由于打印的是十六进制的,所以是00100004

题目三

#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,3,5
在这里插入图片描述
然后定义了一个整型指针指向二维数组的首元素,然后跳过p[0]访问的也是首元素,所以打印的是 1

题目四

#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]是指向数组中4个int类型的元素,数组a[5][5]的地址要存到int (*ptr) [5] 这样的数组指针中去,
两者存在着类型差异,但是不影响,a数组每四个元素存到p中去,二维数组是连续存放的,示意图如下:
在这里插入图片描述

&p[4][2] - &a[4][2] 也就是指针 - 指针 的绝对值计算的是两个地址之间的元素个数
所以得到 -4
%p打印的是地址,地址在内存中是补码的形式 十六进制打印
所以我们要将-4转化为二级制的补码
-4的原码1000 0000 0000 0000 0000 0000 0000 0100
-4的反码1111 1111 1111 1111 1111 1111 1011
-4的反码1111 1111 1111 1111 1111 1111 1100
每四个二级制位转换为
FF FF FF FC

%d打印的整型,也就是 -4

题目五

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

代码运行结果如下:
在这里插入图片描述
(int*)(&aa + 1) 是取出数组的地址然后+1,跳过整个数组,指向数组之后的空间,然后将其强制类型转换为int类型存放到ptr1中
(int
)(*(aa + 1))是数组首元素地址+1,二维数组的首元素是a[0],也就是第一行的元素,得到aa[1][0]的地址,然后解引用再强制类型转换,存放到ptr2中
所以ptr1指向的是数组之后的空间,ptr2指向的是数组aa[1][0]
与题目一致
*(ptr1-1) ptr1 - 1 指向的是10这个元素的地址,然后解引用得到10
*(ptr2-1) ptr2 - 1 指向的是5这个元素的地址,然后解引用得到5

题目六

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

代码运行结果如下:
在这里插入图片描述
a[]是个指针数组,存放的是三个字符串的地址,pa指向a的首元素地址,示意图如下:
在这里插入图片描述
pa++,指针偏移一个字节,得到第二个元素的地址,也就是 at
所以打印的是 at

题目七

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

代码运行结果如下:
在这里插入图片描述
代码示意图如下:
在这里插入图片描述

 printf("%s\n", **++cpp);

一开始cpp是指向cp的首元素的,当使用++之后cpp指向了cp的第二个元素,也就是c+2的地址
然后第一次解引用拿到了c+2,
再解引用得到c的第三个元素,所以会打印POINT
现在cpp指向cp的第二个元素

 printf("%s\n", *--*++cpp+3);

由于加法的优先级最低,使用+3最后计算
++cpp,cpp从指向cp的第二个元素变成了指向第三个元素
解引用拿到了cp第三个元素c+1
然后再–c+1得到c这个地址
解引用就得到c 也就是c的首元素ENTER
最后+3 从第四个字符开始打印
所以会打印ER
现在cpp指向cp的第三个元素

 printf("%s\n", *cpp[-2]+3);

cpp[-2] 等价于 *( *(cpp-2))+3
cpp-2,cpp从指向第三个元素变成了指向第一个元素
第一次解引用得到 c+3
第二次解引用得到了c+3指向的元素 也就是FIRST
最后再+3 从这个元素的第四个字符开始打印
所以会打印ST
现在cpp还是指向第三个元素

 printf("%s\n", cpp[-1][-1]+1);

cpp[-1][-1]+1 等价于 *( *(cpp-1)-1)+1
cpp-1 cpp从指向cp第三个元素变成指向了第二个元素
然后解引用得到c+2
然后再减去1 c+2-1
然后解引用得到了c+1 也就是NEW
最后再+1 从第二个字符开始打印
所以会打印EW

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用Python画一棵树

&#x1f38a;专栏【不单调的代码】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【如愿】 &#x1f970;欢迎并且感谢大家指出我的问题 文章目录 &#x1f339;Turtle模块&#x1f384;效果&#x1f33a;代码&#x1f6f8;代码…

城市生命线丨桥梁健康结构监测系统作用如何

截至2022年底&#xff0c;我国拥有公路桥梁103.3万座&#xff0c;总长约8576万延米&#xff0c;其中特大桥8816座&#xff0c;总长约1621万延米。 为了确保这些桥梁的安全&#xff0c;需要进行定期的检测和维护&#xff0c;及时发现和解决桥梁存在的问题。 同时&#xff0c;政…

杭电oj 2064 汉诺塔III

#include <stdio.h>void main() {int n, i;long long sum[35] { 2,8,26 };for (i 3; i < 35; i)sum[i] 3 * sum[i - 1] 2;while (~scanf_s("%d", &n))printf("%lld\n", sum[n - 1]); }

9.4 Windows驱动开发:内核PE结构VA与FOA转换

本章将继续探索内核中解析PE文件的相关内容&#xff0c;PE文件中FOA与VA,RVA之间的转换也是很重要的&#xff0c;所谓的FOA是文件中的地址&#xff0c;VA则是内存装入后的虚拟地址&#xff0c;RVA是内存基址与当前地址的相对偏移&#xff0c;本章还是需要用到《内核解析PE结构导…

带记忆的超级GPT智能体,能做饭、煮咖啡、整理家务!

随着AI技术的快速迭代&#xff0c;Alexa、Siri、小度、天猫精灵等语音助手得到了广泛应用。但在自然语言理解和完成复杂任务方面仍然有限。 相比文本的标准格式&#xff0c;语音充满复杂性和多样性&#xff08;例如&#xff0c;地方话&#xff09;,传统方法很难适应不同用户的…

NX二次开发UF_CAM_PREPRO_mark_model_as_cam 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CAM_PREPRO_mark_model_as_cam Defined in: uf_cam_prepro.h int UF_CAM_PREPRO_mark_model_as_cam(tag_t model ) overview 概述 This function will mark the facet model as…

c++学习之哈希

目录 1.关于unordered系列关联式容器 2.关于unordered_map 3.哈希&#xff08;散列&#xff09;表的实现 一&#xff0c;直接定址法 二&#xff0c;除留余数法 方法一&#xff1a;闭散列&#xff1a;开放定址法 方法二&#xff1a;闭散列&#xff1a;哈希桶/拉链法 4.哈希…

设计模式——RBAC 模型详解

1.什么是 RBAC 呢&#xff1f; RBAC 即基于角色的权限访问控制&#xff08;Role-Based Access Control&#xff09;。这是一种通过角色关联权限&#xff0c;角色同时又关联用户的授权方式。 简单地说&#xff1a;一个用户可以拥有若干角色&#xff0c;每一个角色又可以被分配…

maven打包可执行jar含依赖lib

修改pom.xml <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><!-- jdk8可用&#xff0c;其他jdk版本可能需改插件版本 --><version>2.3.7.RE…

内存可见性与指令重排序

文章目录 内存可见性内存可见性问题代码演示JMM&#xff08;Java Memory Model&#xff09; 指令重排序指令重排序问题代码演示指令重排序分析 volatile关键字volatile 保证内存可见性 & 禁止指令重排序volatile 不保证原子性 在上一节介绍线程安全问题的过程中&#xff0c…

【计算思维】蓝桥杯STEMA 科技素养考试真题及解析 2

1、兰兰有一些数字卡片&#xff0c;从 1 到 100 的数字都有&#xff0c;她拿出几张数字卡片按照一定顺序摆放。想一想&#xff0c;第 5 张卡片应该是 A、11 B、12 C、13 D、14 答案&#xff1a;C 2、按照下图的规律&#xff0c;阴影部分应该填 A、 B、 C、 D、 答案&am…

汇编-PROC定义子过程(函数)

过程定义 过程用PROC和ENDP伪指令来声明&#xff0c; 并且必须为其分配一个名字(有效的标识符) 。目前为止&#xff0c; 我们所有编写的程序都包含了一个main过程&#xff0c; 例如&#xff1a; 当要创建的过程不是程序的启动过程时&#xff0c; 就用RET指令来结束它。RET强制…

Arthas 监听 Docker 部署的java项目CPU占比高的信息

1、Linux上安装Arthas wget https://alibaba.github.io/arthas/arthas-boot.jar2、docker ps 查看目标项目的容器ID 3、copy Arthas 到目标容器中 (注意有 &#x1f615; ) docker cp arthas-boot.jar d97e8666666:/4、进入到目标容器目录中 docker exec -it d97e8666666 /b…

FFmpeg 6.1 开放源码多媒体框架近日发布了重大更新

导读FFmpeg 6.1 开放源码多媒体框架近日发布了重大更新&#xff0c;带来了新功能、新解码器、新过滤器和许多其他变化。 在 FFmpeg 6.0 “Von Neumann “版本发布八个多月后&#xff0c;FFmpeg 6.1 被命名为 “Heaviside”&#xff0c;引入了多线程 Vulkan 硬件加速解码&#x…

【React-Router】路由快速上手

1. 创建路由开发环境 # 使用CRA创建项目 npm create-react-app react-router-pro# 安装最新的ReactRouter包 npm i react-router-dom2. 快速开始 // index.jsimport React from react; import ReactDOM from react-dom/client; import ./index.css; import App from ./App; i…

在终端输入任意的英文字符串,求最后一个单词的长度

实例要求&#xff1a;1、在终端输入任意的英文字符串 s&#xff0c;由若干单词组成&#xff0c;单词前后用一些空格字符隔开&#xff1b;2、返回字符串中 最后一个 单词的长度&#xff1b;3、单词 是指仅由字母组成、不包含任何空格字符的最大子字符串&#xff1b;示例代码&…

2023亚太杯数学建模竞赛(亚太赛)选题建议+初步分析

如下为C君的2023亚太杯数学建模竞赛&#xff08;亚太赛&#xff09;选题建议初步分析&#xff1a; 提示&#xff1a;DS C君认为的难度&#xff1a;C<A<B&#xff0c;开放度&#xff1a;A<B<C。 以下为ABC题选题建议及初步分析&#xff1a; A题&#xff1a;Image…

Day38力扣打卡

打卡记录 网格中的最小路径代价&#xff08;动态规划&#xff09; 链接 class Solution:def minPathCost(self, grid: List[List[int]], moveCost: List[List[int]]) -> int:m, n len(grid), len(grid[0])f [[0x3f3f3f3f3f] * n for _ in range(m)]f[0] grid[0]for i i…

文本分析:NLP 魔法!

一、说明 这是一个关于 NLP 和分类项目的博客。NLP 是自然语言处理&#xff0c;目前需求量很大。让我们了解如何利用 NLP。我们将通过编码来理解流程和概念。我将在本博客中介绍 BagOfWords 和 n-gram 以及朴素贝叶斯分类模型。这个博客的独特之处&#xff08;这使得它很长&…

轻量封装WebGPU渲染系统示例<38>- 动态构建WGSL材质Shader(源码)

实现原理: 基于宏定义和WGSL功能文件实现 当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/rendering/src/voxgpu/sample/DynamicShaderBuilding.ts 当前示例运行效果: 此示例基于此渲染系统实现&#xff0c;当前示例TypeScript源码如下&#x…