我想编写一个函数,将n
指针数组传递给float
,并返回一个包含n
float
值的新创建数组。这是代码:
float* duplicate(float* p[], int n){
float* const b = new float[n];
for (int i = 0; i < n; i++)
b[i] = *p[i];
return b;
}
我的问题是,我们为什么要将b
声明为 const
?如果我删除const
,结果会如何影响?非常感谢!
答案 0 :(得分:4)
将b
声明为
float* b = ...;
在这里同样有效。 const
表示存储在b
中的指针(指向float
s数组的开头)无法更改。
由于代码无论如何都没有尝试改变它(如果尝试的话它将无法编译),删除const
将没有任何区别。
const
是一种安全机制。程序员正在询问编译器&#34;告诉我是否尝试使用此变量做一些愚蠢的事情&#34;。作为一般规则,默认情况下制作const
是个好主意,除非您确实知道需要更改它们。这意味着你不会意外地分配给你并不意味着的东西,留下你可能难以追查的错误。
(可能还有一个论点,即编译器在const
中有更多的优化机会。在某些情况下可能也是如此,但这里有些不相关。安全性是这种情况下的主要关注点。)
但是在这种情况下,无论如何,所有手动内存管理和指针捣乱都会给你带来麻烦,你最好还是使用能够为你完成所有这些操作的库组件,例如std::vector
修改:为了完整起见,这是使用std::vector
的版本:
std::vector<float> duplicate(float* f[], std::size_t n)
{
std::vector<float> copyOfF;
copyOfF.reserve(n); // save enough space; not essential
std::transform(f, // front of f
f+n, // back of f
std::back_inserter(copyOfF), // push them into the vector
[](float* f){return *f;} ); // deref the pointers
return copyOfF; // will steal the internal array
}
答案 1 :(得分:2)
const
中的 float* const b
表示无法更改指针。例如,这将无法编译:
float* const b;
在您的情况下,如果删除const,则不会有任何改变。
答案 2 :(得分:0)
当您创建变量const
时,在初始化后无法更改其值。
所以,当你写:
float* const b = new float[n];
您告诉编译器b
的内容不会在下一行代码中更改。并且,如果由于某些原因,您更改它(例如通过重新分配b
变量),您将收到编译器错误。
您可以将const
视为&#34;只读&#34; ,即b
的值(new[]
返回的地址1}}调用)无法在以下代码行中进行更改。
请注意,您可以更改new[]
分配的内容!实际上,在编写代码时,const
仅适用于b
的值(即new[]
返回的内存地址),而不适用于数组指向的内容通过b
。
请注意,如果您编写如下代码:
const float* b = ...
那么,这是完全不同的。实际上,在这种情况下,您可以更改b
的值,例如您可以重新指定b
指向其他内容,但您无法更改{{1指向的数组的内容}}
您还可以结合两个b
的效果,例如
const
在这种情况下,您无法更改const float * const b = ...
的值(即您无法重新分配b
)或指向的数组内容b
。
当然,在您的情况下,由于您希望将一些内容写入使用b
分配的数组中,因此仅使用new[]
作为const
的值是有意义的(指针),而不是指向的数组。换句话说,b
指向的数组应该是读/写(即非b
),而不是只读(即const
)。
注意:在现代C ++中,通常最好使用一些容器类,例如const
,而不是使用raw {分配内存{1}}。
(使用std::vector
的一个优点是,由于vector的析构函数,new[]
中存储的内存和资源是自动释放。)
因此,除非这是学习实验代码,或者您有充分的理由使用std::vector
,否则请考虑在现代C ++中使用vector
来动态分配数组。