C++ C++;功能';是否传递了默认参数?

C++ C++;功能';是否传递了默认参数?,c++,parameter-passing,C++,Parameter Passing,假设我有以下代码: #include <iostream> using namespace std; int defaultvalue[] = {1,2}; int fun(int * arg = defaultvalue) { arg[0] += 1; return arg[0]; } int main() { cout << fun() << endl; cout << fun() << endl;

假设我有以下代码:

#include <iostream>

using namespace std;

int defaultvalue[] = {1,2};
int fun(int * arg = defaultvalue)
{
    arg[0] += 1;
    return arg[0];
}

int main()
{
   cout << fun() << endl;
   cout << fun() << endl;

   return 0;
}
这是有意义的,因为指针
*arg
操纵了数组
defaultvalue
。但是,如果我将代码更改为:

#include <iostream>

using namespace std;

int defaultvalue[] = {1,2};

int fun(int arg[] = defaultvalue)
{
    arg[0] += 1;
    return arg[0];
}

int main()
{
   cout << fun() << endl;
   cout << fun() << endl;

   return 0;
}
此外,当我打印出
defaultvalue
时:

cout << defaultvalue[0] <<endl;
cout
我的问题是,在第二个示例中,是否应该按值传递函数参数,以便arg的更改不会对defaultvalue产生影响

没有

不可能按值传递数组(非常感谢,C!),因此,作为一种“折衷”(读:设计失败),函数参数列表中的
int[]
实际上意味着
int*
。所以你的两个程序是相同的。甚至写
int[5]
int[24]
int[999]
实际上意味着
int*
。荒谬,不是吗

<>在C++中,我们更倾向于使用<代码> STD::数组< /代码>数组:它是一个数组包装类,它具有适当的对象语义,包括可复制的。您可以通过值将它们传递到函数中


实际上,
std::array
的引入主要是为了使这些愚蠢而令人惊讶的原生数组语义过时。

当我们声明这样的函数时

int func(int* arg);
还是这个

int (func(int arg[])
它们在技术上是一样的。这是一个表现力的问题。在第一种情况下,API作者建议函数应该接收指向单个值的指针;而在第二种情况下,它表明它需要一个数组(例如,长度未指定,可能以nullptr结尾)

你也可以写

int (func(int arg[3])
这在技术上也是一样的,只是它会提示API用户他们应该传入一个至少包含3个元素的
int
数组。在这些情况下,编译器不会强制执行任何这些添加的修饰符


如果您想将数组复制到函数中(以非黑客方式),您首先要在调用代码中创建一个数组的副本,然后将该副本向前传递。或者,作为更好的选择,使用
std::array
(如@LightnessRacesinOrbit所建议)。

正如其他人所解释的,当您将
int-arg[]
作为函数参数,括号内的任何内容都不重要(您甚至可以使用int-arg[5234234],它仍然可以工作),因为它不会改变它仍然只是一个普通的int*指针的事实

如果您确实想确保函数接受数组[],最好像这样传递它

template<size_t size>
void func (const int (&in_arr)[size])
{
    int modifyme_arr[100];
    memcpy(modifyme_arr, in_arr, size);

    //now you can work on your local copied array
}

int arr[100];
func(arr);

这些是传递简单数组的正确方法,因为它可以保证您得到的是一个数组,而不仅仅是一个随机int*指针,函数不知道它的大小。当然,您可以传递“count”值,但如果您犯了一个错误,而它不是正确的,该怎么办?那么您将得到缓冲区溢出。

作为函数参数类型,
int*
int[]
完全相同。
*arg
不是指针。C程序员注意:通过定义带有数组成员的结构,可以获得与C中的
std::array
相同的效果;然后可以按值传递该结构类型。还有另一个选项:传递对固定大小的C数组的引用可以防止指针衰减,但实际上se最好使用std::array。@amon注意KerrekSB的解决方案(和OP的问题)解决了轻松传递数组副本的需要。@amon:虽然是这样,但这与OP的要求相反;)什么是“技术上”的意思?它们在哪一方面不一样?我看到这个“提示”抓住了那些不知道参数
int[]
int[42]
int*
是相同的人,因此如果他们传递了一个长度错误的数组,或者甚至期望数组按值传递,那么他们会期望编译器出错。因此,我更喜欢这样说,并在非技术意义上使用
int*
@KerrekSB,例如视觉上。但我们不要被语义冲昏头脑。@juanchopanza有一种方法,但你必须在某个地方划出一条线,而不仅仅是说,谁对语言理解不够好,谁就可以口述编码约定。有点同意。我认为这更像是一个危险信号,无论是谁写的,都不太懂这门语言。很多时候,我是对的。但我看到的许多编码约定都集中在那些对语言理解不够好的人身上。对于C++来说,大多数人都是。我不是下流者,我在这里看不到技术上的错误。但是这里有一个暗示,OP已经声明了一个大小为的正式数组参数,我看不到这样的情况,OP希望复制这个参数。这是完全相反的。@cheers-sandhth.-Alf:the
{1,2}
隐式地大小为2,无论OP是什么intentions@LightnessRacesinOrbit不完全是这样,因为我的模板函数从一开始就是const定义的(这意味着它不受op所希望的更改的影响),并且它实际上接受int[]数组(我觉得这也是op想要的)(任何大小),我在函数中添加了一个主体来“复制”arr值,尽管代码非常明显
int (func(int arg[3])
template<size_t size>
void func (const int (&in_arr)[size])
{
    int modifyme_arr[100];
    memcpy(modifyme_arr, in_arr, size);

    //now you can work on your local copied array
}

int arr[100];
func(arr);
    void func (const int (&arr)[100])
    {

    }

    func(arr);