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

news2024/9/25 17:13:25

前言

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

常有以下两种写法:

  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类型指针

后记

于是皆大欢喜。

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

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

相关文章

Java课题笔记~ 使用 AspectJ 的 AOP 配置管理事务(掌握)

使用 XML 配置事务代理的方式的不足是&#xff0c;每个目标类都需要配置事务代 理。当目标类较多&#xff0c;配置文件会变得非常臃肿。 使用 XML 配置顾问方式可以自动为每个符合切入点表达式的类生成事务代 理。其用法很简单&#xff0c;只需将前面代码中关于事务代理的配置…

【C++】开源:CGAL计算几何库配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍CGAL计算几何库配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;…

COCOS项目运行的时候图片模糊的原因

1、首先。用X坐标来分析&#xff0c;如果size*Anchor Position有小数&#xff0c;如上图57*0.5667695.5。这样就会导致x模糊。如果y同样计算结果包含小数&#xff0c;那么y也会模糊。xy同时模糊的情况是最模糊的。 2、如果当前node没有问题&#xff0c;那么就要检查上级node是…

Linux学习之awk字段

awk把每行内容称之为记录&#xff0c;而使用特殊字符分割之后的字符串称为 字段。 字段的引用 echo a : 1 : good :::: >> awktest.txt echo b : 2 : well :::: >> awktest.txt echo c : 3 : food :::: >> awktest.txt echo d : 4 : hood :::: >> aw…

effective c++学习笔记(前五章)

目录 一 让自己习惯C01 视C为一个语言联邦02 尽量以const&#xff0c;enums&#xff0c;inline替换#define**指针常量--指针类型的常量&#xff08;int * const p)****常量指针—指向“常量”的指针&#xff08;const int * p&#xff0c; int const * p&#xff09;**类静态常…

Java分布式微服务4——异步服务通讯(RabbitMQ)中间件

文章目录 微服务的远程异步调用MQ介绍RabbitMQRabbitMQ结构RabbitMQ的单机部署1.下载镜像2.安装MQ RabbitMQ入门常见消息模型 SpringAMQPSpringAMQP实现基础消息队列SpringAMQP实现工作队列SpringAMQP实现发布订阅1. Fanout Exchange 广播模式2. Direct Exchange 路由模式3. To…

Add-in Express for Microsoft Office and Delphi Crack

Add-in Express for Microsoft Office and Delphi Crack 适用于Microsoft Office和Delphi VCL的Add-in Express使您能够在几次点击中为Microsoft Office开发专业插件。它生成基于COM的项目&#xff0c;这些项目包含Microsoft Office外接程序或智能标记的所有必要功能&#xff0…

3分钟创建新生分班查询二维码,无需技术、0成本

作为教师&#xff0c;我们深知分班是一项极其重要的任务&#xff0c;需要综合考虑学生的性格、能力和兴趣等多个方面&#xff0c;以确保每个学生都能够获得最佳的学习环境和成绩。在本文中&#xff0c;我将分享一种便捷的方式来告知家长有关分班录取情况的方法。 通常&#xf…

深度学习关键要素:数据集汇总与分享

引言 在深度学习的应用中&#xff0c;数据被认为是最重要的因素之一。因此&#xff0c;选择一个好的数据集对于深度学习的成功至关重要。在选择数据集时&#xff0c;不仅需要关注数据量的大小、多样性以及质量&#xff0c;还要考虑数据集是否代表了所研究问题的真实情况。本文…

分布式应用:Zabbix代理服务器与SNMP监控

目录 一、理论 1.分布式监控 2.Zabbix代理服务器部署 3.配置 agent 使用 proxy 4.设置 Zabbix-SNMP 监控 二、实验 1.Zabbix代理服务器部署 2.配置 agent 使用 proxy 3.设置 Zabbix-SNMP 监控 三、总结 一、理论 1.分布式监控 &#xff08;1&#xff09;作用&#x…

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

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

Linux 上安装部署Nacos

标题&#xff1a;在Linux上安装和部署Nacos Nacos是一个开源的分布式服务发现和配置管理平台&#xff0c;它可以帮助开发人员实现微服务架构中的服务注册、发现和动态配置管理。 步骤1&#xff1a;准备工作 在开始安装Nacos之前&#xff0c;确保您已经具备以下条件&#xff1…

VS通过TCPIP与visionpro通讯

效果图 服务器端 visionpro配置服务器端&#xff0c;配置端口号、需要发送的数据等 客户端 vs编写代码接收数据 主要是复制的例程&#xff0c;到时候编写的时候可以借鉴。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Dat…

使用 `nmcli` 在 CentOS 8 上添加永久路由

CentOS 8 使用 NetworkManager 作为默认的网络管理工具&#xff0c;因此我们可以使用 nmcli 工具来实现相同的目标。使用 nmcli 可以更加直观地管理路由&#xff0c;并且更符合 CentOS 8 的默认网络管理方式。 以下是使用 nmcli 在 CentOS 8 上添加永久路由的步骤&#xff1a;…

类加载机制——双亲委派机制

类加载器分类 类加载器 类加载器&#xff08;英文&#xff1a;ClassLoader&#xff09;负责加载 .class 字节码文件&#xff0c;.class 字节码文件在文件开头有特定的文件标识。ClassLoader 只负责 .class 字节码文件的加载&#xff0c;至于它是否可以运行&#xff0c;则由 E…

【论文阅读】基于深度学习的时序异常检测——TimesNet

系列文章链接 参考数据集讲解&#xff1a;数据基础&#xff1a;多维时序数据集简介 论文一&#xff1a;2022 Anomaly Transformer&#xff1a;异常分数预测 论文二&#xff1a;2022 TransAD&#xff1a;异常分数预测 论文三&#xff1a;2023 TimesNet&#xff1a;基于卷积的多任…

《乡村振兴战略下传统村落文化旅游设计》浙江新华书店已售罄!

《乡村振兴战略下传统村落文化旅游设计》浙江新华书店已售罄&#xff01;

CTF Stegano练习之隐写初探

今天要介绍的是CTF练习中的Stegano隐写题型 。做隐写题的时候&#xff0c;工具是很重要的&#xff0c;接下来介绍一些工具。 1、TrID TrID是一款根据文件二进制数据特征进行判断的文件类型识别工具。虽然也有类似的文件类型识别工具&#xff0c;但是大多数都是使用硬编码的识…

11个点告诉你 如何用Docker+jenkins 运行 python 自动化

一、实现思路 在 Linux 服务器安装 docker 创建 jenkins 容器 根据自动化项目依赖包构建 python 镜像(构建自动化 python 环境) 运行新的 python 容器&#xff0c;执行 jenkins 从仓库中拉下来的自动化项目 执行完成之后删除容器 二、环境准备 Linux 服务器一台(我的是 C…

面向数据科学家和分析师的统计基础

推荐&#xff1a;使用 NSDT场景编辑器助你快速搭建可编辑的3D应用场景 “统计学是科学的语法。 卡尔皮尔逊 统计学在数据科学和数据分析中的重要性不容低估。统计提供了查找结构和提供更深入数据见解的工具和方法。统计学和数学都喜欢事实&#xff0c;讨厌猜测。了解这两个重要…