尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
C语言指针超级进阶:字符与字符串数组、string 库函数原型、指针与二维数组
1. 字符指针与字符串在 C 语言中字符串本质上是以\0结尾的字符数组。理解指针与字符串的关系是掌握指针进阶的第一步。1.1 用字符指针指向字符串#includestdio.hintmain(void){char*strhello csdn;printf(%s\n,str);return0;}这里str是一个字符指针指向字符串常量hello csdn的首字符。printf从该地址开始逐字节输出直到遇到\0为止。1.2 字符串常量不可被修改下面的写法会引发未定义行为char*strhello;str[0]H;/* 错误字符串常量通常存储在只读区 */正确做法是使用字符数组来存放可修改的字符串charbuf[]hello;buf[0]H;/* 正确buf 是栈上的可写内存 */1.3 字符数组与字符指针的区别对比项字符数组char s[]字符指针char *p内存来源栈或全局可写区指向字符串常量只读区内容可修改可以不可以指向常量时指针本身可变数组名是常量不可重新赋值可以改变指向sizeof含义整个数组字节数指针本身大小通常 8 或 4 字节#includestdio.hintmain(void){chars[]csdn;char*pcsdn;printf(sizeof(s) %zu\n,sizeof(s));/* 5含 \0 */printf(sizeof(p) %zu\n,sizeof(p));/* 8 或 4指针大小 *//* s p; 非法数组名不能作为左值 */ps;/* 合法指针可以重新指向 */return0;}2. 字符串数组字符串数组用于存放多个字符串常见有两种组织方式二维字符数组和指针数组。2.1 二维字符数组每个字符串占据固定长度的行适合长度相近且需要修改的场景#includestdio.hintmain(void){charnames[][16]{zhangsan,lisi,wangwu};for(inti0;i3;i){printf(%s\n,names[i]);}return0;}names[i]表示第i行的首地址类型为char *可以直接传给字符串处理函数。2.2 指针数组每个元素是指针指向不同长度的字符串内存更紧凑但指向常量时不可修改#includestdio.hintmain(void){constchar*colors[]{red,green,blue,yellow};for(inti0;i4;i){printf(%s\n,colors[i]);}return0;}2.3 两种写法对比二维字符数组内存连续、每行定长、内容可改适合固定长度的字符串集合。指针数组每行长度灵活、仅存地址更省内存但若指向字符串常量则内容不可改。3. 常用 string 库函数原型C 标准库string.h提供了一系列字符串操作函数。理解它们的函数原型与实现原理能更好地掌握指针运算。3.1 求长度strlensize_tstrlen(constchar*s);返回字符串长度不含结尾的\0。手写实现#includestddef.hsize_tmy_strlen(constchar*s){constchar*ps;while(*p!\0){p;}return(size_t)(p-s);}3.2 复制strcpy / strncpychar*strcpy(char*dest,constchar*src);char*strncpy(char*dest,constchar*src,size_tn);strcpy将src连同\0复制到dest不检查目标缓冲区大小易溢出。strncpy最多复制n个字符若src短于n则用\0补齐若src达到n仍未遇\0目标可能不以\0结尾。手写strcpy实现char*my_strcpy(char*dest,constchar*src){char*retdest;while((*dest*src)!\0){;}returnret;}推荐在日常开发中使用更安全的strncpy注意手动补\0或snprintf。3.3 拼接strcat / strncatchar*strcat(char*dest,constchar*src);char*strncat(char*dest,constchar*src,size_tn);strcat把src追加到dest末尾同样不检查缓冲区大小。strncat最多追加n个字符并始终补上\0相对更安全。手写strcat实现char*my_strcat(char*dest,constchar*src){char*retdest;while(*dest!\0){dest;}while((*dest*src)!\0){;}returnret;}3.4 比较strcmp / strncmpintstrcmp(constchar*s1,constchar*s2);intstrncmp(constchar*s1,constchar*s2,size_tn);按字典序逐字符比较返回负数表示s1 s2返回 0 表示相等返回正数表示s1 s2。手写strcmp实现intmy_strcmp(constchar*s1,constchar*s2){while(*s1!\0*s1*s2){s1;s2;}return(unsignedchar)*s1-(unsignedchar)*s2;}3.5 查找字符strchr / strrchrchar*strchr(constchar*s,intc);char*strrchr(constchar*s,intc);strchr返回字符c在字符串中首次出现的位置指针找不到返回NULL。strrchr返回最后一次出现的位置。手写strchr实现char*my_strchr(constchar*s,intc){while(*s!\0){if(*s(char)c){return(char*)s;}s;}if((char)c\0){return(char*)s;/* 匹配结尾 \0 */}returnNULL;}3.6 查找子串strstrchar*strstr(constchar*haystack,constchar*needle);在haystack中查找子串needle返回首次出现位置找不到返回NULL。手写实现#includestddef.hchar*my_strstr(constchar*haystack,constchar*needle){if(*needle\0){return(char*)haystack;}while(*haystack!\0){constchar*hhaystack;constchar*nneedle;while(*n!\0*h*n){h;n;}if(*n\0){return(char*)haystack;}haystack;}returnNULL;}3.7 使用示例#includestdio.h#includestring.hintmain(void){charbuf[32]hello;printf(len%zu\n,strlen(buf));/* 5 */strcpy(buf,world);strcat(buf,!);printf(%s\n,buf);/* world! */printf(cmp%d\n,strcmp(abc,abd));/* -1 或负数 */printf(chr%s\n,strchr(hello,l));/* llo */printf(str%s\n,strstr(hello,ll));/* llo */return0;}4. 指针与二维数组二维数组在内存中依然是按行连续存储的掌握「数组名 → 数组指针」的转换是指针进阶的关键。4.1 二维数组的内存布局#includestdio.hintmain(void){inta[2][3]{{1,2,3},{4,5,6}};printf(a[0][0] %d\n,a[0][0]);/* 1 */printf(%d\n,*(*a2));/* 3 */printf(%d\n,*(*(a1)0));/* 4 */return0;}内存布局如下a[0][0] 1a[0][1] 2a[0][2] 3a[1][0] 4a[1][1] 5a[1][2] 6a的类型是「指向int[3]的指针」即数组指针int (*)[3]。a i跳过一整行3 个int。*(a i)得到第i行的首地址再 j定位到该行第j个元素。因此a[i][j]等价于*(*(a i) j)。4.2 数组指针数组指针专门指向一个固定长度的数组#includestdio.hintmain(void){inta[2][3]{{1,2,3},{4,5,6}};int(*p)[3]a;/* p 指向 int[3] */for(inti0;i2;i){for(intj0;j3;j){printf(%d ,p[i][j]);}printf(\n);}return0;}其中int (*p)[3]表示「p 是一个指针指向包含 3 个int的数组」。4.3 数组指针与指针数组的区别这是最易混淆的知识点int(*p)[3];/* 数组指针指向 int[3]通常用于二维数组 */int*q[3];/* 指针数组q 有 3 个元素每个元素是 int* */优先级说明[]高于*所以int *q[3]先与[3]结合成数组元素是指针 → 指针数组。int (*p)[3]括号让p先与*结合成指针再指向数组 → 数组指针。指针数组示例#includestdio.hintmain(void){intx1,y2,z3;int*arr[3]{x,y,z};for(inti0;i3;i){printf(%d ,*arr[i]);}printf(\n);return0;}4.4 二维数组作为函数参数二维数组传参时第一维可以省略第二维必须指定本质上传入的是数组指针#includestdio.hvoidprint_matrix(int(*matrix)[3],introws){for(inti0;irows;i){for(intj0;j3;j){printf(%d ,matrix[i][j]);}printf(\n);}}/* 等价写法void print_matrix(int matrix[][3], int rows) */intmain(void){inta[2][3]{{1,2,3},{4,5,6}};print_matrix(a,2);return0;}matrix[i][j]同样等价于*(*(matrix i) j)理解这一点后即可灵活使用指针遍历二维数组。5. 总结字符指针char *指向字符串首地址指向的字符串常量不可修改。字符串数组二维字符数组内容可改、定长指针数组灵活省内存。string 库函数牢记strlen、strcpy、strcat、strcmp、strchr、strstr等原型体会指针移动的共性并注意缓冲区安全。指针与二维数组a[i][j]等价于*(*(a i) j)分清数组指针int (*p)[n]与指针数组int *p[n]。抓住「指针即地址、指针加减按其所指类型为单位移动」这一本质再结合上述原型与数组结构反复练习就能稳步跨过指针进阶这道坎。
RELATED

相关推荐

第一套行测真题做得一塌糊涂?先别急着放弃

第一套行测真题做得一塌糊涂?先别急着放弃

我至今记得自己第一套行测真题的分数,五十出头。做的时候手心冒汗,做完整个人是懵的,感觉前面几个月看的课全白学了。当时差点就想放弃,后来硬着头皮把这套题又啃了一遍,才发现第一套真题根本不是用来考分数的&#xf…

📅 2026/10/8 18:54:29
机器人与机电一体化3D数字孪生机器-Day1

机器人与机电一体化3D数字孪生机器-Day1

A001简介一、数字孪生概念1. 数字孪生实现流程核心定义:数字孪生是在虚拟环境中构建真实机器的能力,用于模拟其在生产线上的运行。实现步骤:拥有整台机器的CAD设计模型。将CAD模型导入物理模拟器。在模拟器中为模型添加动画和物理交互。测试整…

📅 2026/10/8 18:54:29
上下文注入时机:在对话中途插入新信息的技巧

上下文注入时机:在对话中途插入新信息的技巧

你正在和AI讨论一个方案,突然想起来有一个重要的数据还没告诉AI。你把数据贴了进去,结果AI"忽略"了它,还是按之前的信息在回答。为什么?因为你没有掌握"上下文注入"的时机和方法。一、为什么注入时机很重要 1…

📅 2026/10/8 18:54:29
MORE NEWS

更多资讯

📰

嵌入式形式化验证2026:从数学证明到量产代码的工程路径

摘要:形式化验证正在从学术研究走向嵌入式量产。AWS的Kani Rust验证器、CBMC的C语言验证工具和seL4微内核的形式化验证,代表了形式化方法在嵌入式领域的三条路径。2026年,CRA合规和功能安全认证正在推动形式化验证从“可选”变成“必需”。本…

📰

Python数据存储与运算机制详解:变量、浮点精度与位运算

我决定从安装完Python、打开编辑器敲下第一行代码那天说起。当时我给自己定的计划很简单:每天记一点笔记,把数据存储和运算这两个最基础的底座吃透。结果一学才发现,这两块内容看着不难,水却深得很——a 1这行代码背后发生了什么…

📰

大模型时代,普通程序员如何逆袭,你的经验比代码还值钱?

作者分享了自己作为普通程序员的焦虑与反思,在大模型AI时代,单纯依靠“写代码”的手艺已不足以应对竞争。文章指出,AI能替代手艺,但无法取代经验带来的判断力。普通程序员的核心竞争力在于“知道坑在哪”、“能翻译人话”和“知道…

📰

后端面试必问:54人项目请求链路从网关到事务全解析

你简历上写着“54 人共创的项目”,面试官点了点头,然后突然问了一句:“那你给我讲讲,一个请求从浏览器发出来,到页面拿到数据,这条请求链路是怎么走的?”这个场景我太熟了,我自己面过…

📰

计算机毕业设计|基于springboot + vue购物商城系统(源码+数据库+文档)

购物商城系统 目录 基于springboot vue购物商城系统 一、前言 二、系统功能演示 三、技术选型 四、其他项目参考 五、代码参考 六、测试参考 七、最新计算机毕设选题推荐 八、源码获取: 基于springboot vue购物商城系统 一、前言 博主介绍:✌…

📰

fast-element 的 TrustedTypesPolicy 类型:借助 Trusted Types 筑牢 DOM 安全边界

前端UI组件 【免费下载链接】fast The adaptive interface system for modern web experiences. 项目地址: https://gitcode.com/gh_mirrors/fa/fast 点击查看 免费下载 导读 本文围绕 microsoft/fast-element 公开导出的 TrustedTypesPolicy 类型展开&#xff0c…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬