C语言易错知识点(3):字符数组的修改、sscanf、sprintf

news2024/11/25 2:21:41

字符数组是一个很细节的语法,涉及很多知识点,这篇文章我主要分享一下如何理解字符数组,以及对应的sscanf、sprintf有什么用

1.字符数组的初始化以及内容修改易错点

字符数组的初始化方式有两种,一种是直接用字符串进行初始化,另一种是大括号加上字符或字符串进行初始化

8b82c40a3d2f40aeba75c57c6dfbf247.png

这两种初始化方式均可,但是如果我现在想要更改数组的内容呢,那应该怎样操作?

很多人会第一时间想到直接给arr赋上一个新的字符串,但这显然是不行的。

55eaaeef02944073b5799eb7a3be0d27.png

接下来分析原因:

a.数组名的理解:我们要清楚字符数组的数组名是首元素地址。更详细地说,数组名arr是一个指针类型,其存储的值是首元素地址。对于这个变量有一个特殊操作就是&arr,这个操作是取出整个数组的地址,整个数组的地址是首元素的地址,所以&arr和arr得到的值是相同的。但由于这个特殊操作,我们无法得到存储arr这个指针的地址,不过这确实没有任何意义,很多人甚至都意识不到这个问题。62316d19a20a4dc5be0a82d68e46bdbd.png

arr这个指针还有个常属性,即arr存储的值不能被修改,类似于const int* p,这就导致arr的指向的空间区域在一开始就确定了,不能被修改了。

b.表达式的返回值:我们还要清楚表达式的返回值是存储在一个临时变量里的,这个临时变量同样具有常属性,这个临时变量我们是看不到的,如果有变量接收就把这个临时变量的值赋给这个变量。如果学过C++的引用,那么我们对这个临时变量的印象就会很深刻。

在字符数组的两种初始化表达式语句中,"Hello"返回的值是字符'H'的首元素地址,{'Hell", 'o'}返回的也是括号内第一个字符'H'的地址。更详细一点,就是这些初始化表达式的值(地址)存到一个临时变量里,再把临时变量里的这个地址赋给arr这个指针,完成初始化。

后续对字符串的访问其实就是靠的这个返回的地址的。

下面看一种情况:

8a88f02b8c38425db14edcfef4a9233e.png

这种情况也同理,只有在定义的时候,在arr这个指针还没有明确指向哪一块空间的时候,我们可以对它初始化,但如果不初始化,那么编译器会自动分配一块空间并把这块空间的最低地址赋给指针arr,这个时候arr就再也无法进行修改了。在上面这张图中,我们可以看到如果我们想要将"Hello"存到数组,直接赋值操作是不行的,因为就像上面所说的,arr = "Hello";本质是修改arr这个指针存储的值,这是绝对不允许的。我们明显需要其它方法来实现这种操作,达到在这块指定的空间里修改值的操作。

2.为什么字符数组会遇到这种情况

其实arr具有的常属性适用于所有的数组,一旦数组被定义了,首元素的地址是一定不能变的。

至于在int、float、double等类型的数组我们很少遇到这个情况,是因为几乎没有人会写出下面的代码:

b224a25c1569403eb3fd6de541433058.png

一般而言,我们都会针对arr[0]这种写法来修改数组里面的值,这其实就相当于在指定空间里面修改值的操作,而不是直接去修改arr指向的空间。

但是字符数组里面存储的信息大多是连续的,如一个单词,一个句子,我们需要批量修改字符数组里面的值,单个字符修改太慢,且又不能使用循环来解决,因此我们才会容易犯上面的错误。而这个需求在其它类型的数组里面遇到的情况相对较少,通常都是针对某个数据进行修改,如果是批量修改,写很容易通过循环来解决。

3.字符串或内存函数解决方案

有以下几种函数可以帮助我们批量修改字符串中的值,它们都是直接到对应内存区域里修改值实现的。

(1)strcpy

标准格式:char * strcpy ( char * destination, const char * source )

(2)strcat

标准格式:char * strcat ( char * destination, const char * source );

(3)memcpy

标准格式:void * memcpy
 ( void * destination, const void * source, size_t num );

(4)memmove 

标准格式:void * memmove ( void * destination, const void * source, size_t num );

其中内存函数的第三个参数是拷贝的字节,一般情况推荐用memmove 

4.sscanf和sprintf

上面的字符串函数和内存函数已经可以实现我们全部的需求,但是仍然不方便,这个时候就可以考虑sprintf。

sprintf就是将我们想要输入的任何数据直接存入字符数组中。

ba51f418545e4bf5ae7c6c2c6daebb1a.png

我们把数组的地址传过去,函数就能自动找到对应的区域并将这块区域的数据进行修改。

这非常方便,同时这个函数也可以使用占位符,和printf一致。

57f96d03636e49d4ba260de389ebd413.png

sscanf也是对字符数组内的数据进行操作,和scanf的功能类似。但是scanf是需要我们从屏幕中输入数据,再进行读取。而sscanf是直接在字符串中对数据进行读取。读取的规则和scanf一致。

d15f0aa5d73f4078a5c8f091f506a9b4.png

 

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

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

相关文章

【SCI绘图】【热力图系列1 R】多特征相关性分析热力图R语言实现

SCI,CCF,EI及核心期刊绘图宝典,爆款持续更新,助力科研! 本期分享: 【SCI绘图】【热力图系列1 R】多特征相关性分析热力图R语言实现 1.环境准备 library(gplots) library(RColorBrewer) 2.数据示例 ###…

Qt快速入门到熟练(3.程序运行发布与设置图标)

程序运行发布 当我们执行过qt过后,将会在项目目录里面生成出一个debug构建目录,点击进去选择debug文件夹,就可以看到我们生成出来的可执行文件。 很显然我们的项目就叫做MyFirstWidget,所以生成的可执行文件在没有人为设置的情…

深入理解JVM垃圾收集器

相关系列 深入理解JVM垃圾收集算法-CSDN博客 目前市面常见的垃圾收集器有Serial、ParNew、Parallel、CMS、Serial Old、Parallel Old、G1、ZGC以及有二种不常见的Epsilon、Shenandoah的,从上图可以看到有连线的的垃圾收集器是可以组合使用,是年轻代老年代…

LeetCode初级算法书Java题解日常更新

LeetCode初级算法高效题解(含思路注释) 文章目录 LeetCode初级算法高效题解(含思路注释)前言一、数组1.删除排序数组中的重复项2.买卖股票的最佳时机 II3.旋转数组4.存在重复元素 总结 前言 决定用四个月过一下算法 一、数组 1.…

全国月均太阳辐射空间分布数据/月度降雨量分布/月均气温分布

引言 我国幅员辽阔,地形复杂,位于亚欧大陆东部,太平洋西岸。气候特征为:季风气候明显,大陆性气候强,气候类型复杂多样,水热同期。我国太阳辐射西部多于东部,北部多于南部&#xff0c…

【算法基础】插入排序与二分查找、升级二分查找

文章目录 1. 插入排序1.1 插入排序的思想1.2 插入排序的实现 2. 普通二分查找2.1 普通二分查找的思想2.2 普通二分查找的实现 3. 升级二分查找3.1 升级二分查找思想3.2 升级二分查找实现 1. 插入排序 1.1 插入排序的思想 插入排序很类似于已有一副有序的扑克牌,不断…

【企业场景】设计模式重点解析

设计模式 在平时的开发中,涉及到设计模式的有两块内容: 我们平时使用的框架(比如spring、mybatis等)我们自己开发业务使用的设计模式。 在平时的业务开发中,其实真正使用设计模式的场景并不多,虽然设计号…

Excel全套213集教程

Excel全套213集教程 包含技术入门93集 图表17集 数据透视35集 公式函数68 基础入门 93节 https://www.alipan.com/s/cMxuPstkS1x 提取码: 77dd 点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视…

Springboot使用教程

二、配置文件 SpringBoot使用一个全局的配置文件,配置文件名是固定的; •application.properties •application.yml 1.配置文件的作用: 修改SpringBoot自动配置的默认值;SpringBoot在底层都给我们自动配置好; Y…

【DM8】列表分区List

范围分区是按照某个列上的数据范围进行分区的,如果某个列上的数据无法通过划分范围的方法进行分区,并且该列上的数据是相对固的一些值,可以考虑使用 LIST 分区。一般来说,对于数字型或者日期型的数据,适合采用范围分区…

《价值》-张磊-高瓴资本-6-高瓴公式

第六章 高瓴公式 1.时间回报公式 所谓时间的价值,可以从这两个方面来理解: 一方面,一笔好的投资,其投资收益会随着时间的积累而不断增加,时间是好生意的朋友。另一方面,真正好的投资&#xff…

stm32与esp8266WIFI模块

硬件介绍 WIFI模块ESP-01S 使用AT指令控制1-ESP8266-AT指令初试化及部分基础知识_ch_pd-CSDN博客 项目需求 通过ESP-01SWIFI模块控制LED状态模拟插座 串口1用于与ESP8266通讯,串口2连接PC,用于打印log,查看系统状态 项目接线 将WIFI模块的…

thinkphp6中使用监听事件和事件订阅

目录 一:场景介绍 二:事件监听 三:配置订阅 一:场景介绍 在项目开发中有很多这样的场景,比如用户注册完了,需要通知到第三方或者发送消息。用户下单了,需要提示给客服等等。这些场景都有一个…

R语言 多组堆砌图

目录 数据格式 普通绘图 添加比例 R语言 堆砌图_r语言堆砌图-CSDN博客 关键点在于数据转换步骤和数据比例计算步骤&#xff0c;然后个性化调整图。 ①data <- melt(dat, id.vars c("ID"))##根据分组变为长数据 ②#计算百分比## data2 <- ddply(data, …

线上研讨会 | 新一代数字化技术赋能机器人及智能产线行业高质量发展

随着智能制造的快速推进&#xff0c;制造业转型升级到了关键阶段。越来越多的企业以数字化技术搭配智能机器人及智慧产线&#xff0c;主动实现数字化转型。达索系统3D体验平台是实现企业数字化转型的新一代数智化平台&#xff0c;基于型、数字驱动、数字化连续技术&#xff0c;…

.NET 设计模式—装饰器模式(Decorator Pattern)

简介 装饰者模式&#xff08;Decorator Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许你在不改变对象接口的前提下&#xff0c;动态地将新行为附加到对象上。这种模式是通过创建一个包装&#xff08;或装饰&#xff09;对象&#xff0c;将要被装饰的对象包裹起来…

OAuth2.0客户端和服务端Java实现

oauth2 引言 读了《设计模式之美》和《凤凰架构》架构安全篇之后&#xff0c;决定写一个OAuth2.0的认证流程的Demo&#xff0c;也算是一个阶段性的总结&#xff0c;具体原理实现见《凤凰架构》(架构安全设计篇)。 涉及到的源码可以从https://github.com/WeiXiao-Hyy/oauth2获…

【MacOs】proxychains配置使用

一、开始 1. 安装proxychains 使用brew进行安装 brew install proxychains-ng没有homebrew的&#xff0c;可以使用该命令安装 /usr/bin/ruby -e "$(curl -fsSL https://cdn.jsdelivr.net/gh/ineo6/homebrew-install/install)"2. 配置代理配置文件 cd /opt/homeb…

用Python+OpenCV截取视频中所有含有字幕的画面

1、需求背景 有的视频文件的字幕已经压制到了视频的图像中&#xff0c;不能单独提取出字幕文件。网上的 “提取视频字幕” 网站多为提取视频中的字幕文件&#xff0c;而非识别视频图像中的字幕。少数通过OCR技术识别画面中字幕的工具需要在线运行、运行速度较慢&#xff0c;或…

React - 你知道在React组件的哪个阶段发送Ajax最合适吗

难度级别:中级及以上 提问概率:65% 如果求职者被问到了这个问题,那么只是单纯的回答在哪个阶段发送Ajax请求恐怕是不够全面的。最好是先详细描述React组件都有哪些生命周期,最后再回过头来点题作答,为什么应该在这个阶段发送Ajax请求。那…