指针 + 1 到底加了多少?——指针运算的本质,Day12 学习记录
1. 指针运算的本质p1 不是地址加 1学指针的时候我一直以为p1就是地址值直接加 1。直到有一天写代码发现int *p和char *p做p1的结果完全不一样——同一个操作打印出来的地址偏移居然差了 4 倍。于是我明白了一件事指针加 1加的不是 1 个字节而是 1 个元素的大小。提出问题既然指针本身存的是一个地址值那p1到底加了多少为什么int*和char*的表现不同示例#includestdio.hintmain(){inta10;charcA;int*p_inta;char*p_charc;printf(p_int %p\n,p_int);printf(p_int 1 %p\n,p_int1);printf(p_char %p\n,p_char);printf(p_char 1 %p\n,p_char1);return0;}在我的机器上输出类似这样具体值每次运行不同但偏移规律固定p_int 0x7ffe1a3b5c2c p_int 1 0x7ffe1a3b5c30 ← 差 4 字节 p_char 0x7ffe1a3b5c2b p_char 1 0x7ffe1a3b5c2c ← 差 1 字节为什么这样p N的实际偏移字节数等于N × sizeof(基类型)。编译器在编译时就知道指针指向的类型占多大空间所以自动帮你算好偏移量。int在我的机器上占 4 个字节所以p_int 1地址向后跳 4。char占 1 个字节所以p_char 1地址向后跳 1。这个设计的好处是你不用自己算偏移字节数编译器帮你保证p1刚好指向「下一个元素」的起始位置。指针相减也是类似逻辑两个同类型指针相减结果是它们之间相差的元素个数不是字节数。比如(p 5) - p的结果是 5。一句总结指针运算的本质是元素级别的地址偏移步长取决于指针指向的类型大小不是机械的地址值加 1。2. 指针操作一维数组三种写法背后是同一条路学过指针运算的本质之后再回头看数组很多曾经模糊的地方突然通了。提出问题明明数组和指针是两个东西为什么a[i]和*(p i)能访问到同一个元素它们底层到底有什么关系示例#includestdio.hintmain(){intarr[]{10,20,30,40,50};int*parr;// arr 就是首元素地址 arr[0]// 三种等价写法for(inti0;i5;i){printf(%d ,arr[i]);// 下标法printf(%d ,*(pi));// 指针偏移法printf(%d ,p[i]);// 指针也可以像数组一样用下标}return0;}三种写法输出的结果完全相同10 20 30 40 50。为什么这样数组名arr在表达式中会被隐式转换成指向首元素的指针所以arr和p存的是同一个地址。编译器处理arr[i]时内部就是按*(arr i)来计算的——下标法只是指针偏移的语法糖。反过来指针p也能用p[i]这种写法因为p[i]同样等价于*(p i)。指针遍历数组的几种实际写法// 写法一下标法最直观for(inti0;i5;i){printf(%d ,arr[i]);}// 写法二指针偏移法逐步后移int*parr;for(inti0;i5;i){printf(%d ,*(pi));}// 写法三指针自增法最贴近“遍历”语义int*parr;for(inti0;i5;i){printf(%d ,*p);p;// 每次后移一个 int 元素}第三种写法最常见于实际项目每轮循环打印当前元素然后p让指针指向下一个元素直到遍历完整个数组。一句总结数组名就是首元素地址arr[i]和*(pi)和p[i]底层完全一致选择哪种写法只是习惯问题。3. 指针操作字符串字符指针遍历与 char* 和 char[] 的区别字符串本质上是一个以\0结尾的字符数组用指针操作字符串是 C 语言里非常高频的用法。提出问题给一个字符串怎么用指针遍历打印每个字符char *p和char s[]看起来都能存字符串它们到底有什么区别示例#includestdio.hintmain(){chars[]hello;char*ps;// p 指向 s 的首字符 hwhile(*p!\0){printf(%c,*p);p;// 指针后移一个 char即 1 个字节}printf(\n);return0;}输出hello。每次循环打印当前字符然后p让指针指向下一个字符直到遇见\0终止。为什么这样C 语言字符串以\0ASCII 码 0结尾所以while (*p ! \0)可以自然控制循环结束。p每次偏移sizeof(char) 1字节刚好指向下一个字符。char *p与char s[]的关键区别char *p hello;char s[] hello;本质指针指向字符串常量区数组在栈上开辟空间并拷贝内容可否修改内容❌ 不可改常量区只读修改会崩溃✅ 可改如s[0] H;指针本身可重新指向别的字符串数组名不可重新赋值踩坑实录我曾经写过char *p hello; p[0] H;想改成大写结果程序直接崩溃。原因就是p指向的是字符串常量区那片内存只读不可写。如果你需要可修改的字符串请用char s[] hello;。一句总结字符指针遍历字符串用*p ! \0判断结束char*指向常量区不可修改char[]在栈上可自由修改。4. const 修饰指针离谁近就限定谁const 修饰指针是初学者最容易混淆的点之一四种写法只差一个 const 的位置含义就完全不同。提出问题const char *s、char const *s、char *const s、const char *const s到底怎么区分有没有简单的记忆方法示例与对比写法含义通俗理解const char *s指向的内容不可修改不能通过*s改字符但s可以指向别处char const *s同上const 在*左边就行——const char *s是更常见的写法char const *s也合法但不常用和上一条完全等价char *const s指针本身不可修改s不能指向别处但可以通过*s改内容const char *const s两者都不可修改既不能改指向也不能改内容为什么这样记忆原则只有一句话const 离谁近就限定谁。const挨着char限定的是*s内容不可改。const挨着*s即*const s限定的是s本身指针不可改。实际应用建议函数形参如果只读不写一律用const char *。比如int puts(const char *s);调用者传字符串常量、数组名、const char*变量都能接住函数内部还不会误修改字符串代码更严谨。一句总结const 修饰指针看相对位置挨着类型限定内容挨着指针变量限定指向。5. 今日练习题解用指针思维实战两道题到做练习的时候我才发现光听懂原理不够真正写代码才能暴露理解漏洞。1单词倒置——「how are you」→「you are how」我当时的第一反应拆分单词存数组、反向拼接。但老师说有更简洁的两遍逆序法。正确思路先把整个字符串逆序how are you→uoy era woh再把每个单词单独逆序uoy→youera→arewoh→how整个过程用指针控制区间边界逆序函数只交换首尾字符。注意第一步逆序整个字符串时空格也被当作普通字符参与逆序会从中间被移到两端。不过没关系——后续对每个单词单独逆序时空格会自然归位完整代码#includestdio.h#includestring.h// reverse: 将字符串区间 [start, end) 内的字符逆序// 注意end 指向最后一个字符的下一位置即空格或\0不包含在交换中voidreverse(char*start,char*end){--end;// 让 end 指向最后一个有效字符while(startend){chartmp*start;// 交换首尾字符*start*end;*endtmp;start;end--;}}intmain(){charstr[]how are you;printf(原字符串: %s\n,str);intlenstrlen(str);// 第一步整个字符串逆序不包含 \0reverse(str,strlen);printf(整体逆序: %s\n,str);// 第二步逐个单词逆序char*pstr;while(*p!\0){// 跳过空格while(*p )p;if(*p\0)break;// 已到字符串末尾char*word_startp;// 单词起始位置// 找到单词结束下一个空格或字符串结尾while(*p! *p!\0)p;char*word_endp;// 单词结束位置指向空格或\0// 逆序当前单词reverse(word_start,word_end);}printf(单词逆序后: %s\n,str);return0;}编译运行结果原字符串: how are you 整体逆序: uoy era woh 单词逆序后: you are how最终结果正确。2间隔输出——「Computer Science」→「Cmue cec」思路从首字符开始每次跳过 1 个字符步长 2相当于只取偶数下标的字符。用指针实现就是p初始指向首字符每次p 2完整代码#includestdio.hintmain(){charstr[]Computer Science;char*pstr;printf(原字符串: %s\n,str);printf(间隔输出: );while(*p!\0){putchar(*p);// 打印当前字符p2;// 步长 2跳过下一个字符}printf(\n);return0;}编译运行结果原字符串: Computer Science 间隔输出: Cmue cec直到超出字符串末尾。一句总结指针解决字符串问题的关键是「用指针控制区间」而不是「用下标数位置」代码会更紧凑也更贴近内存思维。今日避坑指南坑现象正确理解p1 以为是地址加 1打印地址发现偏移数值不对偏移量 1 × sizeof(基类型)char *p abc; p[0]A;程序崩溃字面串在常量区不可写用char s[]用比较两个字符串永远不成立或结果不对比的是地址应使用strcmp()const 位置一头雾水四种写法混淆const 离谁近限定谁数组名和指针划等号以为sizeof(s)能拿到字符串长度数组名在多数表达式中会退化为指针但在sizeof和运算中不会退化因此sizeof(数组名)返回整个数组的字节数今日学习感悟今天才真正搞明白指针运算不是在玩地址数字游戏而是编译器在默默帮我按元素大小算偏移。以前记不住const的那几种写法现在用「离谁近就限定谁」这条口诀基本不会搞混了。写单词倒置的时候第一次没考虑\0逆序完打印多了一堆乱码找半天才发现是字符串结束符也被反转了——如果 reverse 函数把\0也纳入交换范围\0就会被移到开头导致字符串被截断。实际实现时reverse 的区间应排除\0只处理有效字符部分。这种低级错误真得亲自动手写过才会长记性。Day12 最大的收获指针不是玄学它是一套有规律可循的内存操作逻辑理解 sizeof 和元素粒度的概念就通了八成。

相关新闻

一文读懂android-EmojiCompat:从原理到实践

一文读懂android-EmojiCompat:从原理到实践

一文读懂android-EmojiCompat:从原理到实践 【免费下载链接】android-EmojiCompat Migrated: 项目地址: https://gitcode.com/gh_mirrors/an/android-EmojiCompat android-EmojiCompat是Android平台上的一个强大库,它能帮助开发者轻松实现表情符号…

2026/10/9 6:54:30 阅读更多 →
Kotlin Compile Testing:终极指南!如何在测试中无缝编译Kotlin与Java代码

Kotlin Compile Testing:终极指南!如何在测试中无缝编译Kotlin与Java代码

Kotlin Compile Testing:终极指南!如何在测试中无缝编译Kotlin与Java代码 【免费下载链接】kotlin-compile-testing A library for testing Kotlin and Java annotation processors, compiler plugins and code generation 项目地址: https://gitcode.…

2026/10/12 13:01:44 阅读更多 →
Stimulsoft Reports许可证转移操作指南与常见问题

Stimulsoft Reports许可证转移操作指南与常见问题

1. Stimulsoft Reports许可证转移操作指南作为一款功能强大的报表控件,Stimulsoft Reports在企业级报表开发中应用广泛。当我们需要更换开发设备或迁移工作环境时,许可证转移就成为必须掌握的关键操作。下面我将详细介绍完整的转移流程和注意事项。1.1 准…

2026/10/10 23:26:15 阅读更多 →

最新新闻

6.4k Stars!用Claude Code写论文的全套流水线,有人打包开源了:TaoToken统一Key接入实操

6.4k Stars!用Claude Code写论文的全套流水线,有人打包开源了:TaoToken统一Key接入实操

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 13:01:10 阅读更多 →
Python 读取数据库 BLOB 字段并落地文件:从连接配置到本地存储的完整实践

Python 读取数据库 BLOB 字段并落地文件:从连接配置到本地存储的完整实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 13:01:10 阅读更多 →
Composer 算法方法卡片(Algo Card)写作规范与模板指南:从骨架模板到源码级落地

Composer 算法方法卡片(Algo Card)写作规范与模板指南:从骨架模板到源码级落地

深度学习分布式训练模型优化 【免费下载链接】composer Supercharge Your Model Training 项目地址: https://gitcode.com/gh_mirrors/com/composer 点击查看 免费下载 导读 本文以 Composer 仓库中的「算法方法卡片(Algorithm Card)」写作…

2026/10/12 13:01:10 阅读更多 →
Pylint 检查详解:using-generic-type-syntax-in-unsupported-version(W2604)与 PEP 695 泛型语法兼容性

Pylint 检查详解:using-generic-type-syntax-in-unsupported-version(W2604)与 PEP 695 泛型语法兼容性

静态分析代码质量Lint开发工具 【免费下载链接】pylint Its not just a linter that annoys you! 项目地址: https://gitcode.com/gh_mirrors/pyl/pylint 点击查看 免费下载 导读 using-generic-type-syntax-in-unsupported-version(消息码 W2604&…

2026/10/12 13:01:09 阅读更多 →
Dapp-Learning Merkle Distributor Airdrop 实战:NFT/ERC20 空投与链上红包合约全解析

Dapp-Learning Merkle Distributor Airdrop 实战:NFT/ERC20 空投与链上红包合约全解析

示例工程区块链 【免费下载链接】Dapp-Learning Dapp learning project for developers at all stages. Becoming and cultivating sovereign individuals. Nonprofit organization. 项目地址: https://gitcode.com/gh_mirrors/da/Dapp-Learning 点击查看 免费下载 …

2026/10/12 13:01:09 阅读更多 →
机器学习最小可行知识链:从公式到可调试代码的完整实践

机器学习最小可行知识链:从公式到可调试代码的完整实践

简介:本资源是邹博主讲的《机器学习全方位解析:从基础到实践》配套教学包,面向零基础入门者与希望系统夯实理论与工程能力的学习者,解决机器学习概念抽象、代码实践脱节、算法调优无从下手等核心痛点。压缩包共613个文件&#xff…

2026/10/12 13:00:09 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →