关于在c++中使用数组名作为函数参数,或者使用数组名的地址作为函数参数问题的一些研究

前言

使用数组名作为函数参数,或者使用数组名的地址作为函数参数,常常出现于对于字符串的读入问题之中。

常有以下两种写法:

  1. 这是使用数组名作为函数参数
#include<cstdio>
char s[100];
int main() {
	scanf("%s",s);
}

在编译时不会出现报错和警告。

2.这是使用数组名的地址作为函数参数

#include<cstdio>
char s[100];
int main() {
	scanf("%s",&s);
}

在编译的时候不会报错,默认不会有警告。但是编译选项中开启-Wall(显示全部警告)就会出现警告。

在这里插入图片描述

警告的原因是,scanf函数的%s选项期望获得一个字符类型的地址,作为读入字符串的起始地址。而&s事实上是一个字符数组类型的地址,而不是字符类型地址。

-Wall编译选项会检查scanf对应的不定参数列表中提供的类型是否正确,因此会警告。不开启-Wall选项则不会检查是否正确,则不会警告。

区别

然而这样的写法虽然会引起编译的警告,但并不会导致编译错误,而且也不会引发程序运行的错误。

准确来说,在大部分实现上,二者达到的目的是一样的。
尽管在标准中,并不确保scanf提供参数类型错误时,也会得到正确的结果,但是由于实现的关系,往往能得到正确的结果。

但是这两种方法仍然是有微小的区别的,在我们将s[0]作为读入的第一个字符的时候,两者没有区别,但假如我们将s[1]作为读入的第一个字符,那它们将会出现不同的结果。

s[0]作为第一个字符

第一种写法

#include<cstdio>
char s[100];
int main() {
	scanf("%s",s);
	printf("%s",s);
}

运行结果正确:

在这里插入图片描述

第二种写法

#include<cstdio>
char s[100];
int main() {
	scanf("%s",&s);
	printf("%s",s);
}

运行结果正确:

在这里插入图片描述

以s[1]作为第一个字符

第一种写法

#include<cstdio>
char s[100];
int main() {
	scanf("%s",s+1);
	printf("%s",s+1);
}

运行结果正确:

在这里插入图片描述

第二种写法

#include<cstdio>
char s[100];
int main() {
	scanf("%s",&s+1);
	printf("%s",s+1);
}

运行结果错误:
在这里插入图片描述

这是实际上是发生了访问越界,可以放大一下访问倍数,就会报运行错误:

#include<cstdio>
char s[2000];
int main() {
	scanf("%s",&s+20);
	printf("%s",s+20);
}

运行错误:
在这里插入图片描述

具体区别

对于这个字符数组:

char s[10]{};

首先我们知道,s和&s在数值上确实是相等的,但是其指向的类型并不相同。
但是我们知道s+1与&s+1在数值上不一定是相等的:
可以用这个程序对比一下:

#include<iostream>
using namespace std;
int main() {
	char s[10]{};
	auto p=&s;
	cout<<p<<endl;
	cout<<p+1<<endl;
	
	cout<<endl;
	
	cout<<static_cast<void*>(s)<<endl;
	cout<<static_cast<void*>(s+1)<<endl;
	
	这里要用关键字static_cast将s的类型从char*转化为void*,是因为cout默认会将char*按照字符串格式输出,而不会选择输出一个地址
	这里不使用c风格强制类型转换主要是出于习惯
}

我们发现,s+1与s相差了1,而&s+1与&s却相差了10:

在这里插入图片描述

原因

要弄清楚这个问题的原因,就需要先了解清楚s和&s有什么区别。也就是数组名和数组名的地址有什么区别。

那么首先我们要知道,将普通变量+1后,其数值会增加1。但是将指针变量+1后,增加的值等于其指向的类型占用的字节数。
如果我们认为int是4个字节,那么也就是说:

int a[]={0,1};
int* p=a[0];
p++; 此时p数值增加了4,指向了a[1]的位置
此时 *p=1

同理,如果是char类型指针,那么+1后,其数值只会增加1,因为char类型只占用一个字节。

其次,我们需要知道计算机程序在运行中必须要跟踪的数据的三个信息:

  1. 变量被存储在哪里
  2. 变量的值是多少
  3. 变量的类型是什么

我们知道,数组名在C++中通常被看做是指向数组第一个元素的指针,也就是说,s被看做是一个指向s[0]位置的char类型指针,也就是char*。
(当然这个说法并不准确,事实上,s的类型在程序中被跟踪为一个“长度为10的字符数组”,但是s+1则只被识别为“指向s[1]位置的字符指针”)

使用typeid方法获得的类型信息:

这里的"A"表示“array”,是数组。
“10”表示数组长度。
“P”表示一个指针。
“c”表示“char”。
在这里插入图片描述

我们将s看作是指向数组第一个元素的指针,因此s+1比s增加了一个字节,也就是一个char类型的长度。

我们同样可以打出&s的类型:
在这里插入图片描述
这表明编译器认为&s是一个指向长度为10的字符数组的指针,因此&s+1与&s之间相差了10个字节。
指向数组的指针,这个类型十分复杂,以至于用常规方法很难只用一条语句就把它声明出来。
我想到三个方法可以把它声明出来:

  1. 可以使用decltype方法自动推导类型:
decltype(s) *p=&s;
  1. 可以使用auto方法自动推导类型:
auto p=&s;
  1. 可以使用多条语句来声明此类型
	typedef char T[10]; 先用typedef语句声明一个T类型,T类型是一个长度为10的字符数组
	T* p=&s; 			再声明一个T类型指针

后记

于是皆大欢喜。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

抖音商品上架有攻略:详细介绍步骤与注意事项

抖音是一款非常流行的短视频分享平台&#xff0c;也是一个非常适合进行商品销售的平台。上架商品是在抖音上进行电商销售的重要一环&#xff0c;下面不若与众将介绍抖音商品的上架流程和注意事项。 1. 注册账号和认证&#xff1a;首先&#xff0c;你需要在抖音平台上注册一个账…

MYSQL06高级_为什么使用索引、优缺点、索引的设计、方案、聚簇索引、联合索引、注意事项

文章目录 ①. 为什么使用索引②. 索引及其优缺点③. InnoDb - 索引的设计④. InnoDb中的索引方案⑤. 索引 - 聚簇索引⑥. 索引 - 二级索引⑦. B树索引的注意事项⑧. MyISAM中索引方案 ①. 为什么使用索引 ①. 索引是存储引擎用于快速找到数据记录的一种数据结构,就好比去图书馆…

图像 检测 - RetinaNet: Focal Loss for Dense Object Detection (arXiv 2018)

图像 检测 - RetinaNet: Focal Loss for Dense Object Detection - 密集目标检测中的焦点损失&#xff08;arXiv 2018&#xff09; 摘要1. 引言2. 相关工作3. 焦点损失3.1 平衡交叉熵3.2 焦点损失定义3.3 类别不平衡与模型初始化3.4 类别不平衡和两级检测器 4. RetinaNet检测器…

Springboot中使用过滤器校验PSOT类型请求参数内容

目录 目的 实现步骤 完整代码 目的 在Springboot中创建过滤器&#xff0c;用来过滤所有POST类型请求并获取body中的参数进行校验内容是否合法&#xff1b;该方法仅适用于POST类型请求&#xff0c;因为POST和GET请求的参数位置不一样所以处理方式也不一样&#xff0c;如果想要…

flutter 没有open android module in Android studio 插件代码爆红

参考 1.结论 其实就是缺少这个文件 2.解决方案有两个 2.1 方案一 手动创建一个,命名规则是项目名字‘_android’‘.iml’ 内容如下: <?xml version"1.0" encoding"UTF-8"?> <module type"JAVA_MODULE" version"4">&l…

IoTDB在springboot2中的(二) 查询

上一章我们处理的基本的构建接入&#xff0c;以及插入的处理&#xff0c;那么接下来我们进行查询的操作处理。 我们继续在IoTDBSessionConfig工具类中加入查询的方法处理 /*** description: 根据SQL查询最新一条数据* author:zgy* param sql sql查询语句&#xff0c;count查询…

基于Java开发的企业级数字化采购系统

一、项目介绍 一款全源码可二开&#xff0c;可基于云部署、私有部署的企业级数字化采购管理系统&#xff0c;供应商全生命周期管控&#xff0c;公开询价管理&#xff0c;招标&#xff0c;定标&#xff0c;评审&#xff0c;生成订单&#xff0c;送货&#xff0c;收货全流程管理…

(十一)大数据实战——hadoop高可用之HDFS手动模式高可用

前言 本节内容我们介绍一下hadoop在手动模式下如何实现HDFS的高可用&#xff0c;HDFS的高可用功能是通过配置多个 NameNodes(Active/Standby)实现在集群中对 NameNode 的热备来解决上述问题。如果出现故障&#xff0c;如机器崩溃或机器需要升级维护&#xff0c;这时可通过此种…

【perl】报错合集

perl报错合集 &#xff08;注&#xff1a;可能会不定时更新&#xff09; 1.Name “main::x” used only once: possible typo at … 1.Name "main::x" used only once: possible typo at ...给某个变量赋值但是从来没有用它&#xff0c;或者变量之只用一次但没有…

Nginx(1)

目录 1.Nginx概述2.Nginx的特点3.Nginx主要功能1.反向代理2.负载均衡 1.Nginx概述 Nginx (engine x) 是一个自由的、开源的、高性能的HTTP服务器和反向代理服务器&#xff0c;也是一个IMAP、POP3、SMTP代理服务器。 Nginx是一个强大的web服务器软件&#xff0c;用于处理高并发…

仅使用 CSS 创建打字机动画效果

创建打字机效果比您想象的要容易。虽然实现这种效果的最常见方法是使用 JavaScript&#xff0c;但我们也可以使用纯 CSS 来创建我们的打字机动画。 在本文中&#xff0c;我们将了解如何仅使用 CSS 创建打字机动画效果。它简单、漂亮、容易。我们还将看看使用 CSS 与 JavaScrip…

百度资深PMO阚洁受邀为第十二届中国PMO大会演讲嘉宾

百度在线网络技术&#xff08;北京&#xff09;有限公司资深PMO阚洁女士受邀为由PMO评论主办的2023第十二届中国PMO大会演讲嘉宾&#xff0c;演讲议题&#xff1a;运筹于股掌之间&#xff0c;决胜于千里之外 —— 360斡旋项目干系人。大会将于8月12-13日在北京举办&#xff0c;…

大模型开发(十六):从0到1构建一个高度自动化的AI项目开发流程(中)

全文共1w余字&#xff0c;预计阅读时间约40~60分钟 | 满满干货(附代码)&#xff0c;建议收藏&#xff01; 本文目标&#xff1a;通过LtM提示流程实现自动构建符合要求的函数&#xff0c;并通过实验逐步完整测试code_generate函数功能。 代码下载点这里 一、介绍 此篇文章为…

【ChatGPT 指令大全】怎么使用ChatGPT来帮我们写作

在数字化时代&#xff0c;人工智能为我们的生活带来了无数便利和创新。在写作领域&#xff0c;ChatGPT作为一种智能助手&#xff0c;为我们提供了强大的帮助。不论是作文、文章&#xff0c;还是日常函电&#xff0c;ChatGPT都能成为我们的得力助手&#xff0c;快速提供准确的文…

HTTP——九、基于HTTP的功能追加协议

HTTP 一、基于HTTP的协议二、消除HTTP瓶颈的SPDY1、HTTP的瓶颈Ajax 的解决方法Comet 的解决方法SPDY的目标 2、SPDY的设计与功能3、SPDY消除 Web 瓶颈了吗 三、使用浏览器进行全双工通信的WebSocket1、WebSocket 的设计与功能2、WebSocket协议 四、期盼已久的 HTTP/2.01、HTTP/…

“委屈”退市,达利并不“无辜”

文 | 螳螂观察 作者 | 青月 “我吃零食&#xff0c;不是因为肚子饿&#xff0c;只是有点馋。” 第一次听到这话的时候&#xff0c;达利食品的创始者许世辉&#xff0c;还是一个平平无奇的打工人&#xff0c;和很多的工友挤在一个小宿舍里&#xff0c;而其中有位工友特别爱吃…

【并发编程】无锁环形队列Disruptor并发框架使用

Disruptor 是苹国外厂本易公司LMAX开发的一个高件能列&#xff0c;研发的初夷是解决内存队列的延识问顾在性能测试中发现竟然与10操作处于同样的数量级)&#xff0c;基于Disruptor开发的系统单线程能支撑每秒600万订单&#xff0c;2010年在QCn演讲后&#xff0c;获得了业界关注…

24届近5年东南大学自动化考研院校分析

今天给大家带来的是东南大学控制考研分析 满满干货&#xff5e;还不快快点赞收藏 一、东南大学 学校简介 东南大学是我国最早建立的高等学府之一&#xff0c;素有“学府圣地”和“东南学府第一流”之美誉。东南大学前身是创建于1902年的三江师范学堂。1921年经近代著名教育家…

本地构建包含java和maven的镜像

目录 1.前提条件 2.下载 2.1.创建Dockerfile 3.构建镜像 参考文章 1.前提条件 本地环境需要的系统和软件 win10 Docker Desktop Powershell 图1 Win10安装Docker后&#xff0c;直接在Powershell使用Docker命令 有些Developer不习惯win10系统&#xff0c;却想要使用Lin…

让三驾马车奔腾:华为如何推动空间智能化发展?

上个月&#xff0c;国务院常务会议审议通过了《关于促进家居消费的若干措施》&#xff0c;其中明确提出了“推动单品智能向全屋智能发展创新培育智能消费”“开展数字家庭建设试点”等推动全屋智能拼配发展的建议与方案。 可以说&#xff0c;以整屋为单位的空间智能品类&#x…