指针运算典型例题解析

news2025/5/11 7:12:54

1.题目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;
}

解析:

运行结果:

2.题目2

在X86(32位)环境下,假设结构体的大小是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;
}

解析:

考察的是“指针+-整数”的问题

+0x1就是结构体指针+1,要跳过一个结构体,结构体的大小是20个字节,所以就是+20字节 —— 如果是10进制则是:0x100020,但是现在是16进制,所以是0x100014

p 强制转换为 unsigned long,不是指针类型了,整型值+1,就是+1,所以是0x100001

unsigned int* 强制转换为,无符号整型的指针,+1是跳过一个整型的4个字节,所以是0x100004

运行结果:

3.题目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;
}

解析:

调试一下,观察一下a中的内容:

不是:

01
23
45

的原因是因为:

int a[3][2] = { (0, 1), (2, 3), (4, 5) };

不是:

int a[3][2] = { {0, 1}, {2, 3}, {4, 5} };

所以,按照逗号表达式计算括号中保留了:1,3,5. 又因为是3行两列的,所以用 0 补位。

a[0] 是第一行的数组名,数组名表示首元素的地址,其实就是&a[0][0]

p[0] —— *(p + 0)——*p ——  1

运行结果:

4.题目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;
}

解析:

考察的是指针 - 指针,其结果的绝对值是指针和指针之间的元素个数。

a 是二维数组

p 是数组指针,p 指向的数组是 4 个整型元素的

分析如下:

%d 是打印有符号的整数

%p 是打印地址的

  1. 数组和指针的类型差异

    • a 是一个 int[5][5] 类型的二维数组。
    • p 是一个指向 int[4] 的指针,即每次移动会跳过 4 个 int
  2. 指针运算规则

    • 指针相减的结果是两个地址之间的元素个数,而非字节数。
    • &p[4][2] 相当于 p + 4*4 + 2 = p + 18(跳过 18 个 int)。
    • &a[4][2] 相当于 a + 4*5 + 2 = a + 22(跳过 22 个 int)。
  3. 地址计算

    • 假设 a 的起始地址为 0x0,则:
      • &p[4][2] 的地址为 0x0 + 18*4 = 0x48(每个 int 占 4 字节)。
      • &a[4][2] 的地址为 0x0 + 22*4 = 0x58
    • 地址差值为 0x48 - 0x58 = -0x10(即 - 16 字节),但指针相减结果为 -16 / 4 = -4

运行结果:

5.题目5

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

解析:

12345
678910

*(aa+1)—— aa[1]

aa[1] 是第二行的数组名

数组名表示首元素地址

aa[1] 也是 &aa[1][0]

&aa[1] 第二行的地址

sizeof(aa[1])计算的是第二行的大小

运行结果:

6.题目6

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

解析:

a 是指针数组

a 是 char* 型的

pa 是 char** 型的

*pa 就是解引用是 at

运行结果:

7.题目7

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

解析:

初始状态:

  • c 是一个字符指针数组,包含 4 个字符串常量的地址。

  • cp 是一个二级指针数组,初始化为 {c+3, c+2, c+1, c}

  • cpp 是一个三级指针,初始指向 cp 的起始位置。

第一次 printf**++cpp

  1. ++cpp 使 cpp 指向 cp[1](即 c+2)。

  2. *cpp 解引用得到 c+2

  3. **cpp 进一步解引用得到 c[2],即字符串 "POINT"

输出POINT

第二次 printf*--*++cpp+3

  1. ++cpp 使 cpp 指向 cp[2](即 c+1)。

  2. *cpp 得到 c+1

  3. --*cpp 将 c+1 减 1,变为 c(即 cp[3] 的原始值)。

  4. *--*cpp 解引用得到 c[0](字符串 "ENTER")。

  5. +3 跳过前 3 个字符,指向 "ER"

输出ER

第三次 printf*cpp[-2]+3

  1. cpp[-2] 等价于 *(cpp-2),指向 cp[0](即 c+3)。

  2. *cpp[-2] 解引用得到 c[3](字符串 "FIRST")。

  3. +3 跳过前 3 个字符,指向 "ST"

输出ST

第四次 printfcpp[-1][-1]+1

  1. cpp[-1] 指向 cp[1](即 c+2)。

  2. cpp[-1][-1] 等价于 *((c+2)-1),即 c[1](字符串 "NEW")。

  3. +1 跳过首字符,指向 "EW"

输出EW

关键注意点:

  • 指针运算直接修改了 cpp 和 cp 中的值(如 --*cpp)。

  • 下标访问(如 cpp[-2])基于当前 cpp 的位置计算。

  • 字符串偏移(如 +3)从字符串起始位置向后跳过指定字符数。

运行结果:

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

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

相关文章

DAX 权威指南1:DAX计算、表函数与计算上下文

参考《DAX 权威指南 第二版》 文章目录 二、DAX简介2.1 理解 DAX 计算2.2 计算列和度量值2.3 变量2.3.1 VAR简介2.3.2 VAR的特性 2.4 DAX 错误处理2.4.1 DAX 错误类型2.4.1.1 转换错误2.4.1.2 算术运算错误2.4.1.3 空值或 缺失值 2.4.2 使用IFERROR函数拦截错误2.4.2.1 安全地进…

使用 NV‑Ingest、Unstructured 和 Elasticsearch 处理非结构化数据

作者&#xff1a;来自 Elastic Ajay Krishnan Gopalan 了解如何使用 NV-Ingest、Unstructured Platform 和 Elasticsearch 为 RAG 应用构建可扩展的非结构化文档数据管道。 Elasticsearch 原生集成了行业领先的生成式 AI 工具和提供商。查看我们的网络研讨会&#xff0c;了解如…

20250508在WIN10下使用移远的4G模块EC200A-CN直接上网

1、在WIN10/11下安装驱动程序&#xff1a;Quectel_Windows_USB_DriverA_Customer_V1.1.13.zip 2、使用移远的专用串口工具&#xff1a;QCOM_V1.8.2.7z QCOM_V1.8.2_win64.exe 3、配置串口UART42/COM42【移远会自动生成连续三个串口&#xff0c;最小的那一个】 AT命令&#xf…

C++(6):逻辑运算符

目录 1. 代码示例 示例 1&#xff1a;基础用法 示例 2&#xff1a;条件判断 2. 短路求值&#xff08;Short-Circuit Evaluation&#xff09; 代码示例 3. 实际应用场景 场景 1&#xff1a;输入合法性验证 场景 2&#xff1a;游戏状态判断 4. 注意事项 逻辑运算符用于组…

NXP iMX8MP ARM 平台多屏幕克隆显示测试

By Toradex秦海 1). 简介 NXP i.MX8MP ARM SoC 支持 3 路 Display Controller 分别提供 DSI/HDMI/LVDS 显示输出&#xff0c;在 Yocto Linux BSP 下采用 Wayland Backend 基于 DRM subsystem 显示驱动&#xff0c;前端默认基于 Weston Compositor。因此在默认情况下连接多个屏…

【数据结构】——栈

一、栈的概念和结构 栈其实就是一种特殊的顺序表&#xff0c;其只允许在一端进出&#xff0c;就是栈的数据的插入和删除只能在一端进行&#xff0c;进行数据的插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的元素遵循先进后出LIFO&#xff08;Last InFirst O…

Navicat中保存的数据库密码找回 Java 8

导出数据库连接打开导出的connections.ncx文件找到加密的password放入java程序中解密即可 package com.asia.card.cloud.enterprise.api;import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.nio.cha…

vs code管理员权限启动问题

vs code非管理员启动可以正常启动用管理员启动vs code&#xff0c;会提示 解决办法 找到argv.json文件在argv.json文件中添加 "disable-chromium-sandbox": true重启vs code即可

Spring Cloud与Service Mesh集成:Istio服务网格实践

文章目录 引言一、Spring Cloud与Service Mesh概述二、Istio服务网格架构三、Spring Cloud与Istio集成的基础设施准备四、服务发现与负载均衡五、流量管理与弹性模式六、安全通信与认证授权七、可观测性集成八、配置管理集成总结 引言 微服务架构已成为现代分布式系统的主流设…

React+Taro选择日期组件封装

话不多说&#xff0c;直接上效果 1.页面渲染时间模块 {this.renderCalendarPopup()}2.引入时间组件弹层&#xff0c;state中加入showPopup(控制什么时候展示时间选择弹层)&#xff0c;time(选择后的时间值) private renderCalendarPopup () > {const { showPopup, time…

C++进阶--AVL树的实现续

文章目录 C进阶--AVL树的实现双旋AVL树的查找AVL树的检验结语 很高兴和搭大家见面&#xff0c;给生活加点impetus&#xff0c;开启今天的比编程之路&#xff01;&#xff01; 今天我们来完善AVL树的操作&#xff0c;为后续红黑树奠定基础&#xff01;&#xff01; 作者&#x…

AutoGen+Deepseek+chainlit的简单使用

AutoGen 的应用场景 AutoGen 作为一个强大的多智能体协作框架&#xff0c;可用于多种复杂任务&#xff1a; 自动化工作流&#xff1a;构建由多个智能体组成的流水线&#xff0c;例如数据收集、分析、报告生成复杂问题分解&#xff1a;将难题拆解为子任务&#xff0c;分配给不…

采用SqlSugarClient创建数据库实例引发的异步调用问题

基于SqlSugar编写的多个WebApi接口&#xff0c;项目初始化时采用单例模式注册SqlSugarClient实例对象&#xff0c;前端页面采用layui布局&#xff0c;并在一个按钮事件中通过Ajax连续调用多个WebApi接口获取数据。实际运行时点击按钮会随机报下面几种错误&#xff1a; Execute…

第7次课 栈A

课堂学习 栈&#xff08;stack&#xff09; 是一种遵循先入后出逻辑的线性数据结构。 我们可以将栈类比为桌面上的一摞盘子&#xff0c;如果想取出底部的盘子&#xff0c;则需要先将上面的盘子依次移走。我们将盘子替换为各种类型的元素&#xff08;如整数、字符、对象等&…

软考-软件设计师中级备考 13、刷题 数据结构

倒计时17天时间不多了&#xff0c;数据库、UML、等知识点有基础直接略过&#xff0c;法律全靠考前的一两天刷题&#xff0c;英语直接放弃。 一、数据结构&#xff1a;链表、栈、队列、数组、哈希表、树、图 1、关于链表操作&#xff0c;说法正确的是&#xff1a; A)新增一个头…

centos的根目录占了大量空间怎么办

问题 当根目录磁盘不够时&#xff0c;就必须删除无用的文件了 上面的&#xff0c;如果删除/usr 或/var是可以释放出系统盘的 定位占空间大的文件 经过命令&#xff0c;一层层查哪些是占磁盘的。 du -sh /* | sort -rh | head -n 10 最终排查&#xff0c;是有个系统日志占了20…

电子电器架构 --- 新能源高压上下电那点事一文通

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…

每日算法-250510

每日算法学习记录 - 250510 1. LeetCode 2086. 喂食仓鼠的最小食物桶数 题目描述: 解题思路 这是一个典型的贪心问题。我们的目标是用最少的食物桶喂饱所有仓鼠。 解题过程 核心思想是&#xff1a;当遇到一只仓鼠时&#xff0c;如何放置食物桶才能最有效地利用这个桶。 …

渗透测试行业术语1

渗透测试行业术语1 1. 肉鸡 所谓“肉鸡”是一种很形象的比喻&#xff0c;比喻那些可以随意被我们控制的电脑&#xff0c;对方可以是 WINDOWS 系统&#xff0c;也可以是 UNIX/LINUX 系统可以是普通的个人电脑&#xff0c;也可以是大型的服务器我们可以象操作自己的电脑那样来操…

【大模型】使用 LLaMA-Factory 进行大模型微调:从入门到精通

使用 LLaMA-Factory 进行模型微调&#xff1a;从入门到精通 一、环境搭建&#xff1a;奠定微调基础&#xff08;一&#xff09;安装依赖工具&#xff08;二&#xff09;创建 conda 环境&#xff08;三&#xff09;克隆仓库并安装依赖 二、数据准备&#xff1a;微调的基石&#…