iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >为什么数组不可以直接赋值
  • 883
分享到

为什么数组不可以直接赋值

2023-06-15 14:06:09 883人浏览 安东尼
摘要

这篇文章主要介绍“为什么数组不可以直接赋值”,在日常操作中,相信很多人在为什么数组不可以直接赋值问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”为什么数组不可以直接赋值”的疑惑有所帮助!接下来,请跟着小编一起来

这篇文章主要介绍“为什么数组不可以直接赋值”,在日常操作中,相信很多人在为什么数组不可以直接赋值问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”为什么数组不可以直接赋值”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

为什么数组不可以直接赋值

一、前言

C/C++  语言中,数组类型的变量是不可以直接赋值的。但是如果把数组放在结构体中,然后对结构体变量进行赋值,就可以实现把其中的数组内容进行复制过去。

二、数组的各种操作

1. 错误代码

int a[5] = {1, 2, 3, 4, 5}; int b[5]; b = a;

对于上面的赋值语句,编译器会报错 error: assignment to expression with array  type,即:不能对一个数组类型的变量进行赋值。

那么编译器此时是如何来解释 a 和 b 的?下面会说到这个问题。

有一个地方提一下:第一条语句中的 = 操作,不是赋值,而是初始化。C/c++ 语法规定在定义变量的时候,是可以使用 操作符 =  来进行初始化操作的。

2. 利用结构体来复制数组

typedef struct {     int arr[5]; } array_wrap;  array_wrap a = {{1, 2, 3, 4, 5}}; array_wrap b; b = a;

这里的赋值操作是针对结构体变量,C 语言标准允许这种行为,是合法的,变量 a  中的所有内容(也就是这个变量占用过的那一块内存空间中的内容)会原样的复制到变量 b 中。

3. 其他复制方式

既然不能直接对数组类型的变量进行赋值,只能寻求其他的替代方式,例如:

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区

  2. 利用 memcpy(b, a, sizeof(int) * 5); 复制一整段内存空间中的内容;

  3. 利用 for/while 等循环语句,逐个复制数组中每一个元素: b[i] = a[i];

三、语言标准和编译器

C/C++ 只是一门高级语言,是被标准委员会从无到有设计出来的,因此我们编程时需要严格遵守这些规则。

这些规则中,就包括这么一条:只有标量和结构体,才能出现在赋值操作符=的左侧。

但是数组类型并不是一个标量,因此不能对结构体执行赋值操作。

理论上,如果 C/C++  语言愿意的话,是"可以"对数组直接赋值的(那就要修改语法标准),只不过标准委员会在经过各种场景的权衡利弊之后,做出了目前这样的规定,这是对各种考虑到的因素进行权衡之后的结果。

也就是说,目前标准中对于数组操作的方式,是利大于弊。

既然标准已经是制定成这样的了,我们就来分析一下编译器是如何来遵循、实现这个标准的。

1. 数组与指针的暧昧关系

很多人都这样记忆:数组名就是数组开始地址的指针。这是不对的,或者说不严谨的。

在 C/C++ 中,数组就是数组,指针就是指针。数组在内存中有确定的空间(每个元素的大小 x 元素个数)。

只不过在表达式中,数组名会“临时的”表示数组中第一个元素的常量指针(前提条件:在没有操作符 sizeof 和 & 的情况下)。

对于下面这段代码,打印结果是相同的:

int a[5] = {1, 2, 3, 4, 5}; printf("a = %p \n", a); printf("&a = %p \n", &a);

第一个 printf 中,a 会“临时的”代表指向第一个元素的常量指针。

第二个 printf 中,a 就表示一个数组,与指针没有半毛钱的关系,前面加上取地址符  &,就表示获取这个数组所在的地址,这个地址与第一个元素的地址是重合的。

注意:代码在被编译成二进制文件之后,没有任何变量的概念,全部是用地址来“传递” C/C++ 代码中的变量。

2. 为什么不能对数组变量赋值

有了上面的基础理解就好办了,对于下面的这段代码:

int a[5] = {1, 2, 3, 4, 5}; int b[5]; b = a;

在赋值语句 b = a 中,左侧的 b 是一个数组类型,右侧的 a  被编译器“临时的”代表第一个元素的常量指针,但是数组不是一个标量,不可以放在赋值运算符=的左侧,因此编译器就抱怨:非法!

既然在一个表达式中,数组名被临时的表示第一个元素的常量指针,那么就说明我们不能对数组名本身进行计算,例如:不能进行 a++, a-- 等操作。

例如:下面这的遍历方式是非法的:

int a[5] = {1, 2, 3, 4, 5}; for (int i = 0; i < 5; i++) {     // 常量指针,不可以进行递增操作     printf("a[%d] = %d \n", i, *a++); }

3. 函数形参是数组的情况

考虑下面这个函数:

void func(int arr[5])  {     for (int i = 0; i < 5; ++i)      {         printf(*arr++);  // 合法!     } }

形参 arr 在形式上好像是一个数组,实际上被编译器当做指针,也就是相当于:void func(int *arr),因此,在 printf  打印语句中,可以对 arr 进行递增操作。

PS: 这种场景下都需要额外的传递一个参数,来告知元素的个数。

调用这个函数的代码如下:

int a[5] = {1, 2, 3, 4, 5}; fun(a);

数组名临时代表第一个元素的常量指针,在传参的时候,形参 arr 的值就是数组中第一个元素的内存地址。

4. 为什么结构体中的数组可以复制

有了前面的语法标准,这个问题似乎不用再讨论了~~

赋值的目的是什么?就是让一块内存空间的内容,与另一块内存空间中的内容完全相同。如果想要完成复制操作,那么就需要知道这块内存空间的大小。

编译器是知道一个结构体变量所占用的空间大小的,所以当复制的时候,类似于 memcpy 一样,把一个结构体变量所占空间按照 byte to byte  的方式复制过去。

5. 参数传递和返回值

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区

  2. 在调用函数时,实参到形参的传递;

  3. 函数执行结束后的返回值;

这两个场景中都涉及到变量的赋值问题。

关于参数传递,上面已经说了:编译器是把形参当做普通的指针类型的。

对于函数返回值来说,同样的道理,也不能直接返回一个数组,因为它仅仅是临时性的代表第一个元素的常量指针。

当然,可以利用结构体的可赋值特性,把数组包裹在其中,以此达到复制的效果。

到此,关于“为什么数组不可以直接赋值”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: 为什么数组不可以直接赋值

本文链接: https://www.lsjlt.com/news/280562.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 为什么数组不可以直接赋值
    这篇文章主要介绍“为什么数组不可以直接赋值”,在日常操作中,相信很多人在为什么数组不可以直接赋值问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”为什么数组不可以直接赋值”的疑惑有所帮助!接下来,请跟着小编一起来...
    99+
    2023-06-15
  • php可不可以直接输出数组
    这篇文章主要介绍“php可不可以直接输出数组”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“php可不可以直接输出数组”文章能帮助大家解决问题。php可以直接输出数组,有两种方法:1、用print_r...
    99+
    2023-06-30
  • php为什么数组值不能重复?如何避免?
    PHP数组是一种常用的数据类型,用于存储大量数据并进行操作。在使用PHP数组时,有一些基本的规则需要遵守。其中之一就是数组值不能重复。这意味着,在同一个数组中,不能使用相同的值作为键或元素。为什么数组值不能重复?数组是一种特殊的变量类型,可...
    99+
    2023-05-14
    php php数组
  • 阿里云数据库为什么你不买可以吗?
    随着云计算的普及,越来越多的企业开始使用阿里云数据库。但是,有些人可能对阿里云数据库抱有疑问,是否一定要购买?答案是,是否需要购买阿里云数据库取决于你的具体需求和预算。 首先,我们需要了解阿里云数据库是什么。阿里云数据库是一种基于云计算技术...
    99+
    2023-11-18
    阿里 不买 数据库
  • python函数的默认参数为什么不可以定义可变类型
    这篇文章主要介绍“python函数的默认参数为什么不可以定义可变类型”,在日常操作中,相信很多人在python函数的默认参数为什么不可以定义可变类型问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”python函...
    99+
    2023-06-29
  • 什么mysql设置了密码之后,本地还可以直接访问,不需要输入密码就可以登录数据库了?
    应为数据库里面有空用户 select * from mysql.user  where user=''; 查询如果有,把他删了...
    99+
    2022-10-18
  • 云服务器可以存储数据嘛为什么用不了
    云服务器可以存储数据,但如果你是在公共云服务器上存储数据,那么使用云服务器存储和使用本地数据存储是两种不同的方式。 公共云服务器是由许多云计算服务提供商提供的,包括Amazon、Google、Microsoft、IBM等。这些服务提供商使...
    99+
    2023-10-27
    什么用 服务器 数据
  • 云服务器可以存储数据嘛为什么不能用
    云服务器可以存储数据,但使用它们存储数据的方式可能会受到许多限制,例如数据安全措施的限制、数据保护政策的限制等。此外,云服务平台通常是按量计费的,因此如果使用云服务器存储数据,您可能需要支付额外的费用。 另外,云服务器也可能无法提供与本地...
    99+
    2023-10-27
    不能用 服务器 数据
  • 为什么 Python 中的 f-string 可以连接字符串与数字
    这篇文章主要讲解了“为什么 Python 中的 f-string 可以连接字符串与数字”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“为什么 Python 中的 f-string 可以连接字符...
    99+
    2023-06-15
  • 云服务器可以存储数据嘛为什么不能存储
    云服务器可以存储数据,但前提是您必须确保存储的数据是安全的。为了确保存储数据的安全性,您需要遵循以下几点: 保密性:云服务提供商必须采取措施来保护存储在数据中心中的数据,以确保数据是机密的。这意味着他们必须确保数据不与第三方共享或泄露给...
    99+
    2023-10-27
    服务器 数据
  • 为什么ASP.NETCore数据库连接串的值和appsettings.json配的不一样?
    目录一、配置读取顺序二、分析三、演示1.读取Providers2.读取配置值一、配置读取顺序 ASP.NET Core 中的配置是使用一个或多个配置提供程序执行的,配置提供程序使用各...
    99+
    2022-11-13
  • 为什么可以Python中使用f-string 连接字符串与数字
    本篇文章为大家展示了为什么可以Python中使用f-string 连接字符串与数字,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。下面以字符串和数字为例,看看强行操作会产生什么结果:>>&...
    99+
    2023-06-06
  • ASP.NET Core数据库连接串的值为什么和appsettings.json配的不一样
    这篇“ASP.NET Core数据库连接串的值为什么和appsettings.json配的不一样”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收...
    99+
    2023-06-29
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作