【时时三省】(C语言基础)通过指针引用字符串

山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省

如在printf函数中输出一个字符串。这些字符串都是以直接形式(字面形式)给出的,在一对双撇号中包含若干个合法的字符。使用字符串的更加灵活方便的方法——通过指针引用字符串。

字符串的引用方式

在C程序中,字符串是存放在字符数组中的。想引用一个字符串,可以用以下两种方法。

( 1 )用字符数组存放一个字符串,可以通过数组名和下标引用字符串中一个字符,也可以通过数组名和格式声明“% s”输出该字符串。

例题1:

定义一个字符数组,在其中存放字符串" I love China !”,输出该字符串和第8个字符。

解题思路:

定义字符数组string,对它初始化,由于在初始化时字符的个数是确定的,因此可不必指定数组的长度。用数组名string和输出格式%s可以输出整个字符串。用数组名和下标可以引用任一数组元素。

编写程序:

运行结果:

程序分析:

在定义字符数组string时未指定长度,由于对它初始化,因此它的长度是确定的,长度应为14,其中13个字节存放" I love China ! "13个字符,最后一个字节存放字符串结束符' \0 '。数组名string代表字符数组首元素的地址。题目要求输出该字符串第8个字符,由于数组元素的序号从0起算,所以应当输出string [ 7 ],它代表数组中序号7的元素的值(它的值是字母C)。实际上string [ 7 ]就是* ( string + 7 ),string + 7是一个地址,它指向字符“C”。

( 2 )用字符指针变量指向一个字符串常量,通过字符指针变量引用字符串常量。

例题2:

通过字符指针变量输出一个字符串。

解题思路:

可以不定义字符数组,只定义一个字符指针变量,用它指向字符串常量中的字符。通过字符指针变量输出该字符串。

编写程序:

运行结果:

I love China!

程序分析:

在程序中没有定义字符数组,只定义了一个char*型的指针变量(字符指针变量)string,用字符串常量" I love China !”对它初始化。C语言对字符串常量是按字符数组处理的,在内存中开辟了一个字符数组用来存放该字符串常量,但是这个字符数组是没有名字的,因此不能通过数组名来引用,只能通过指针变量来引用。

对字符指针变量string初始化,实际上是把字符串第1个元素的地址(即存放字符串的字符数组的首元素地址)赋给指针变量string,使string指向字符串的第1个字符,由于字符串常量“Ilove China !”已由系统分配在内存中连续的14个字节中,因此,string就指向了该字符串的第一个字符。在不致引起误解的情况下,为了简便,有时也可说string指向字符串" I love China !”,但应当理解为“指向字符串的第1个字符”。

说明:有人误认为string是一个字符串变量,以为在定义时把“I love China !”这几个字符赋给该字符串变量,这是不对的。在C语言中只有字符变量,没有字符串变量。

分析定义string的行:

char * string = " I love China !”;

等价于下面两行:

char * string ;

string = " I love China ! ";

注意:string被定义为一个指针变量,基类型为字符型。请注意它只能指向一个字符类型数据,而不能同时指向多个字符数据,更不是把“Ilove China ! "这些字符存放到string中(指针变量只能存放地址),也不是把字符串赋给* string。只是把" I love China !”的第1个字符的地址赋给指针变量string。

不要认为上述定义行等价于

char * string ;

* string = " I love China !”;

可以对指针变量进行再赋值,如:

string = " I am a student , " ;

把字符串" I am a student .”的第一个字符的地址赋给指针变量string。此后string就指向" I am a student .”的第一个字符,不再指向" I love China !”的第一个字符了,因此不能再通过string引用字符串" I love China !”。

可以通过字符指针变量输出它所指向的字符串,如:

printf ( " % s\n " , string );

% s是输出字符串时所用的格式符,在输出项中给出字符指针变量名string,则系统会输出string所指向的字符串第1个字符,然后自动使string加1,使之指向下一个字符,再输出该字符…如此直到遇到字符串结束标志 \0 为止。注意,在内存中,字符串的最后被自动加了一个\0 ,因此在输出时能确定输出的字符到何时结束。可以看到,用%s可以对一个字符串进行整体的输入输出。

 

对字符串中字符的存取,可以用下标方法,也可以用指针方法。

例题3:

将字符串a复制为字符串b,然后输出字符串b。

解题思路:

定义两个字符数组a和b,用“I am a student .”对a数组初始化。将a数组中的字符逐个复制到b数组中。可以用不同的方法引用并输出字符数组元素,今用地址法算出各元素的值。

编写程序:

运行结果:

程序分析: 

程序中a和b都定义为字符数组,今通过地址访问其数组元素。在for语句中,先检查a [ i ]是否为 \0  ( a [ i ]是以* ( a + i )形式表示的)。如果不等于 \0 ,表示字符串尚未处理完,就将a [ i ]的值赋给b [ i ],即复制一个字符。在for循环中将a串中的有效字符全部复制给了b数组。最后还应将\0复制过去,作为字符串结束标志。故有

* ( b + i ) =' \0 ';

在第2个for循环中输出b数组中的元素,在printf函数中用下标法表示一个数组元素(即一个字符)。也可以用输出a数组的方法输出b数组。用以下一行代替程序的10 ~13行。

printf ( " string b is : % s\n " , b ) ;

程序中用逐个字符输出的方法只是为了表示可以用不同的方法输出字符串。

也可以用另一种方法,用指针变量访问字符串。通过改变指针变量的值使它指向字符串中的不同字符。

例题4:

用指针变量来处理例3问题。

解题思路:

定义两个指针变量p1和p2,分别指向字符数组a和b。改变指针变量pl和p2的值,使它们顺序指向数组中的各元素,进行对应元素的复制。

编写程序:

运行结果:

程序分析: 

p1和p2是指向字符型数据的指针变量。先使p1和p2分别指向字符串a和b的第1个字符。*p1最初的值是字母' I '。赋值语句“* p2 = * p1;”的作用是将字符' I ' ( a串中第1个字符)赋给p2所指向的元素,即b[ 0 ]。然后p1和p2分别加1,分别指向其下面的一个元素,直到*p1的值为'\0'止。

注意,p1和p2的值是不断在改变的,在for语句中的p1 ++和p2++使pl和p2同步移动。

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

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

相关文章

【Linux驱动-快速回顾】一文快速理解GIC内部寄存器对中断的控制

第一部分:GIC的功能和组成 1. GIC要解决的根本问题 在一个复杂的片上系统(SoC)中,有非常多的硬件模块(如定时器、串口、按键、DMA等),它们都需要在完成任务或遇到特定事件时通知CPU。同时&#…

【IoTDB 线上小课 17】开源 ≠ 免费,3 分钟总结开源商用指南

【IoTDB 视频小课】第十七期,解答你最关心的开源商业使用问题!关于 IoTDB,关于物联网,关于时序数据库,关于开源...一个问题重点,3-5 分钟,我们讲给你听:原来开源商业化有这么多规则开…

VUE项目学习笔记 v-for绑定数据,该数据异步获取,同时需要对v-for的DOM节点进行js操作

问题描述:项目里有一个轮播图,轮播图的图片数据从服务器获取,用v-for生成DOM在页面中显示,轮播图插件会通过new Swiper给DOM添加CSS、事件等,实现轮播效果。在这里存在操作顺序问题:当服务器返回图片数据后…

Science | 如何利用“T细胞+组蛋白乙酰化”两大国自然热点?T细胞耗竭机制与代谢-表观遗传调控的新范式

CD8⁺T细胞耗竭(T cell exhaustion)是肿瘤免疫治疗的核心瓶颈,其表观遗传重塑机制(如组蛋白修饰)是当前国自然重点资助的前沿方向。耗竭T细胞(TEX)是指在慢性感染(如持续性病毒感染&…

Logback 配置的利器:深入理解<property>与<variable>

在构建现代 Java 应用程序时,日志是不可或缺的一部分。一个健壮的日志系统不仅能帮助我们监控应用程序的运行状态,还能在问题发生时提供关键的诊断信息。Logback 作为 SLF4J 的一个流行实现,以其高性能和灵活的配置而广受开发者喜爱。 然而&a…

Java中excel字典转换

✅ 背景说明EasyExcel 原生的 ExcelProperty 注解不支持 dictType(不像那样有 Excel(dictType"xxx")),所以如果你想实现字典翻译功能,就需要自己实现 Converter 接口,比如 DictConvert。✅ 什么是 DictConve…

数据结构-3(双向链表、循环链表、栈、队列)

一、思维导图二、双向循环链表的判空、尾插、遍历(反向)、尾删class Node:def __init__(self, data):self.data dataself.next Noneself.prior Noneclass circularDoublyLinkedList():def __init__(self):self.head Noneself.tail Noneself.size 0def isEmpty(self):retu…

IDEA运行Tomcat一直提示端口被占用(也查不到该端口)

首先查看是否是因为Java程序异常终止,进程没有完全释放导致。打开资源管理器,找到所有的java.exe,强制结束任务。如果仍然不行,那就极可能还是开启了hyper-V虚拟化,查看排除的tcp端口范围端口号没被占用却提示占用&…

AWS Lambda 最佳实践:构建高效无服务器应用的完整指南

引言 AWS Lambda 作为无服务器计算的核心服务,让开发者能够专注于业务逻辑而无需管理服务器。本文将通过实际案例和代码示例,分享 Lambda 开发中的关键最佳实践。 1. 函数设计原则 单一职责原则 每个 Lambda 函数应该只做一件事,这样更容易测试、维护和扩展。 # ❌ 不推…

29、鸿蒙Harmony Next开发:深浅色适配和应用主题换肤

目录 应用深浅色适配 应用跟随系统的深浅色模式 应用主动设置深浅色模式 系统默认判断规则 使用建议与限制 设置应用内主题换肤 概述 自定义主题色 设置应用内组件自定义主题色 设置应用局部页面自定义主题风格 设置应用页面局部深浅色 系统缺省token色值 应用深浅…

源鉴SCA4.9︱多模态SCA引擎重磅升级,开源风险深度治理能力再次进阶

SCA技术已成为数字供应链开源治理的关键入口。源鉴SCA深度融合悬镜原创专利级AI智能代码疫苗技术,是国内首款集源码组件成分分析、代码成分溯源分析、制品成分二进制分析、容器镜像成分扫描、运行时成分动态追踪及开源供应链安全情报预警分析等六大核心引擎为一体的…

Git语义化提交规范及提交模板设置

Git语义化提交规范(Conventional Commits) 📚 常见的语义化提交类型包括:类型含义说明feat✨ 新增功能(feature)fix🐛 修复 bugdocs📚 修改文档(如 README)st…

用TensorFlow进行逻辑回归(五)

Softmax分类#List3-50%matplotlib inlineimport numpy as npimport tensorflow as tfimport matplotlib.pyplot as pltx1_label0 np.random.normal(1, 1, (100, 1))x2_label0 np.random.normal(1, 1, (100, 1))x1_label1 np.random.normal(5, 1, (100, 1))x2_label1 np.ran…

基于 Django + 协同过滤算法的电影推荐系统设计与实现

🎬 基于 Django 协同过滤算法的电影推荐系统设计与实现✍️ 本项目由成都理工大学宜宾校区的三位同学曾铭杨、杨皓麟、陈禧锦共同完成。项目以豆瓣电影数据为基础,通过协同过滤算法为用户构建个性化电影推荐服务,是一款集数据爬取、推荐算法…

小白全栈项目部署指南

小白全栈项目部署指南:前端后端数据库完整攻略 📖 写在前面 当你学会了基础的静态网站部署后,是不是想挑战更有趣的项目?比如一个能够注册登录、保存数据的完整应用? 这就需要学习全栈项目部署了! 别被&quo…

C# Linq 左关联查询详解与实践

在 C# 开发中,Linq(Language Integrated Query)提供了强大的数据查询能力,尤其是在处理集合间的关联操作时。本文将详细解析 C# Linq 中的左关联查询,并通过实际案例说明其用法。左关联查询基础左关联(Left…

【机器学习深度学习】LoRA 微调详解:大模型时代的高效适配利器

目录 前言 一、LoRA 的核心思想 二、LoRA 为什么高效? ✅ 1. 参数效率 ✅ 2. 内存友好 ✅ 3. 即插即用 三、LoRA 适用场景 四、LoRA 实践建议 五、LoRA 和全参数微调对比 六、 LoRA的具体定位 📌 总结 🔗 延伸阅读 前言 在大模型…

vue页面不销毁的情况下再返回,总是执行created,而不触发 activated

vue页面不销毁的情况下再返回,总是执行created,而不触发 activated 原因: 没有进行页面缓存地址和页面组件的name没对上 解决方案: 组件只有在被 包裹时才会触发 activated 和 deactivated 生命周期 如果没有被缓存,每次进入路由…

从 C# 到 Python:6 天极速入门(第二天)

作为一名资深 C# 开发者,我们在第一天已经掌握了 Python 的基础语法框架。今天我们将深入 Python 的特色语法与高级特性,通过实际项目开发场景的代码对比,理解这些特性在真实业务中的应用价值。一、简洁语法糖:项目开发中的实战应…

MyBatis 动态 SQL:让 SQL 语句随条件灵活变化

目录 1. 动态SQL 1.1. if 1.1.1. 持久层接口添加方法 1.1.2. 映射文件添加标签 1.1.3. 编写测试方法 1.2. where 1.3. set 1.4. choose、when、otherwise 1.5. foreach 1.5.1. 遍历数组 1.5.2. 遍历Collection 1.5.3. 遍历Map 2. 总结 前言 本文来讲解MyBatis的动…