c++ - 在作用域之间传递数组变量
问题描述
我的第一个问题。在'maning-up'学习c ++时,我让自己陷入了纠结的范围内。我的理解是函数中定义的变量不应该超出范围。但是我一直像下面这样,它每次都可以正常工作。我错过了什么?
我在 ns1.cpp 中定义了一些内联函数,如下所示:
namespace ns1 {
inline void func1(float x[3]);
}
ns1::func1(float x[3]){
//(do stuff to x)
}
在 class_a.cpp 中很远的函数中,我通常像这样使用:
include "ns1.h"
...
void class_a::func2(){
float f[3];
ns1::func1(f)
//f comes back in great shape! No runtime or compilation errors or anything.
}
我的预感是,要么 a)由于 ns1 中的函数是内联的,因此编译器将 func1 的指令放在 func2 的范围内,并且以某种方式不会导致超出范围的类型错误,或者,b)我很幸运并且之前存在行为问题我。
编辑:我让他的问题太复杂了。为简洁起见,我的意思是“您可以在一个函数/范围内创建变量并将它们发送到另一个函数/不同范围的参数的范围之外吗?”。基于 Mooing Ducks 在下面的回答,我可以看到如果发送了指针并且函数更改了指针指向的数据,数组将如何工作。但是,在一个作用域/函数中创建其他变量类型(如 int、char)并将其作为参数发送到另一个函数是不是很糟糕?
解决方案
C++ 有一个非常愚蠢的怪癖,即函数不能按值将数组作为参数。
inline void func1(float x[3]); //x isn't actually an array :(
通常,所有参数都是值的副本。除了数组。相反,C++ 默默地将所有数组值参数转换为指针。所以实际上是:
inline void func1(float* x);
你甚至会发现sizeof(f)
infunc2
大约是 12(一个包含 3 个浮点数的数组,每个浮点数约为 4 个字节),而sizeof(x)
infunc1
大约是 8(一个指针),尽管它们看起来都是相同的类型,这真的如果您不小心,会导致问题。
此外,由于数组可以默默地衰减为指针,func1
因此能够通过这个指针修改f
变量。func2
void class_a::func2(){
float f[3];
ns1::func1(f); //f decays to a pointer, so it passes a pointer to the first item.
即使对于经验丰富的 C++ 开发人员来说,这也是非常令人惊讶的,这也是为什么我们学会了几乎从不按值传递数组的原因。相反,显式传递一个指针 ( float* x, int size
) ,或者一个引用数组 ( float (&x)[3]
) ,或者一个std::array
( std::array<float,3> x
),其中任何一个都可以直观地表现。
有趣的旁注:
void class_a::func2(){
float f[1024];
ns1::func1(f); //f decays to a pointer, so this also compiles :(
所以绝对更喜欢按值避免数组参数。
推荐阅读
- mysql - 仅当列名不为 Null 时选择
- arrays - 从对象中删除数组组件
- alexa - 使用 Alexa 搜索州和县
- android - 使用 Detox 在 React Native 中进行端到端测试 [不渲染资产和图像]
- django - 使用嵌套的外键序列化 ManyToManyField
- clickatell - 收到消息“消息传递状态ERROR_DELIVERING”,有没有办法自动重新发送短信?
- angular - 从Typescript angular中的json对象获取数组
- generics - Kotlin 将泛型类转换为 Unit
- html - 多个相同大小的 SVG 元素在 DOM 上显示不同的大小
- javascript - CSS 动画 - classList 仅更改第一个实例