用C ++玩一下。我真正想要做的是能够设置一个具有为数组或指针参数定义的默认值的函数。为了简单起见,我们只使用一个数组。像这样:
void experimentA(char a[3] = {'a', 'b', 'c'});
编译器(带GNU99的LLVM GCC 4.2)抱怨“预期表达式”。这是非常迟钝的,但同事告诉我,这种情况正在发生,因为我试图分配的'值'是静态分配的,而我试图将其分配给(a[3]
)的变量是auto
但我不能完全确定是否是这种情况,因为我能够做到这一点:
void experimentB(char a[3] = "abc");
编译器只是警告我不推荐使用string-literal到char *转换。
我不明白“abc”与{'a','b','c'}的根本区别在于如何引起这种差异。非常感谢任何见解!
答案 0 :(得分:7)
你的同事错了,或者你误解了。
理解的第一个线索是你不能在C或C ++中将数组作为函数参数。原因是历史性的。因此,当您编写void experimentA(char a[3] ...)
时,编译器会自动将其转换为指针,即void experimentA(char* a ...)
。所以真正的问题是为什么"abc"
是a的合适默认值而{ 'a', 'b', 'c' }
不是。原因是编译器解释说,"abc"
是一个表达式而{ 'a', 'b', 'c' }
不是(它是一个初始化者)。在C ++中有一些地方可以使用初始化器,有些则不能。参数的默认值恰好是您不能的地方之一。
答案 1 :(得分:4)
当你使用字符串文字“abc”时,它由编译器在内存中的某个地方分配,并且指向其第一个字符的指针用作默认值。因此,对于编译器,代码就是:void experimentA(char a[3] = 0x12345678);
。
对于第二种情况,数组文字不是由编译器作为字符串分配的(我会看到语言中的某些不一致)。
答案 2 :(得分:2)
"abc"
是一个表达式。当它用于初始化array of char
类型的变量时,它恰好与所有其他表达式不同。
{'a','b','c'}
不是表达式,而是初始化程序。它只在语法上允许在变量定义中。在那里,语法允许表达式或非表达式初始化程序,但这并不意味着初始化程序可以在其他任何地方用作表达式。
答案 3 :(得分:1)
"abc"
是一个表达式,{'a', 'b', 'c'}
是一个静态初始值设定项。后者仅允许在变量声明中使用。由于我不知道的原因,默认值的参数具有不同的语法规则,不允许使用静态初始化器。
在C ++ 0x中允许使用静态初始值设定项时会有一些重大更改,但我不确定它会如何影响相关案例。
答案 4 :(得分:1)
默认参数必须有效。
你可以打电话
F( “ABC”)
但从不
F({ 'A', 'B', 'C'});
“abc”实际上是内存中的地址,{'a','b','c'}表示初始化数组或结构/类。
答案 5 :(得分:0)
一种简单的方法是通过普通的旧函数重载。例如,下面模拟format参数的默认参数值,即char * type:
reportlab