C++ 在作用域之间传递数组变量

C++ 在作用域之间传递数组变量,c++,C++,我的第一个问题。在学习“C++”时,我会陷入一个范围的纠结中。我的理解是,函数中定义的变量不应该超出范围。但我一直都是这样,就像下面的很多,它的工作没有任何问题的每一次。我错过了什么 我在ns1.cpp中定义了一些内联函数,如下所示: namespace ns1 { inline void func1(float x[3]); } ns1::func1(float x[3]){ //(do stuff to x) } 在远离类_a.cpp的函数中,我通常这样使用: include

我的第一个问题。在学习“C++”时,我会陷入一个范围的纠结中。我的理解是,函数中定义的变量不应该超出范围。但我一直都是这样,就像下面的很多,它的工作没有任何问题的每一次。我错过了什么

我在ns1.cpp中定义了一些内联函数,如下所示:

namespace ns1 {

inline void func1(float x[3]);

}

ns1::func1(float x[3]){

//(do stuff to x)

}

在远离类_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);
您甚至会发现
func2
中的
sizeof(f)
约为12(一个由3个浮点组成的数组,每个浮点约为4字节),而
func1
中的
sizeof(x)
约为8(一个指针),尽管它们看起来都是相同的类型,如果您不小心,这确实会导致问题

此外,由于数组可以静默地衰减为指针,
func1
可以通过该指针修改
func2
中的
f
变量

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 x


有趣的旁注:
void class_a::func2(){
float f[1024];
ns1::func1(f); //f decays to a pointer, so this also compiles :(

因此,我们更倾向于通过值来避免数组参数。

无论
内联
,这都会发生,所以这是一种危险的做法<代码>内联也不是你认为它的意思:)另外,如果函数接受一个普通的
浮点
而不是一个数组,你会期望它工作吗,或者你会认为这是一样的事情吗?@KenWayneVanderLinde“无论内联如何,这都会发生”意味着无论内联如何,每次都会工作?@KenWayneVanderLinde,我一直在使用数组很多,所以认为这可能是相关的。我希望在func2中定义的任何变量都会失败,无论其类型如何,因为它超出了范围。但它每次都能工作(我会把它放在注释中,因为它没有涵盖问题的实质)“但是在一个作用域/函数中创建int、char等其他变量类型并将其作为参数发送到另一个函数是不是很糟糕?”。参数的全部用途是能够向函数发送内容。感谢您提供有用的额外信息。我认为我的问题更基本,应该是“你能在一个范围(函数)中创建变量,并在C++规则手册中作为参数传递给另一个吗?”你可以吗?@ SLeXOV:按值传递应该被命名为副本,这是一个不同于调用方的变量。但是,passbyreference将传递对调用方变量的引用,从而允许被调用方修改它。(如
浮点(&x)[3]所观察到的)
sample.啊,我觉得有些神经元在连接。所以当你在一个作用域中创建一个变量并“发送”给另一个作用域时,你实际上是在发送它的副本。数组是不同的,因为你发送的是指针而不是数组的副本?我如何标记为答案?编辑找到了它…@slexov:是的。默认情况下,参数总是副本。But您也可以将引用或指针作为参数发送,并允许您修改它们引用的变量,而不管它位于何处或谁拥有它。数组是一个令人讨厌的例外,因为它看起来应该是一个副本,但实际上它传递了一个指针:(