函数调用的双括号?

5

考虑以下代码:

#include <stdio.h>

int aaa(char *f, ...)
{
    putchar(*f);    
    return 0;
}

int main(void)
{
    aaa("abc");
    aaa("%dabc", 3); 
    aaa(("abc"));
    aaa(("%dabc", 3));
    return 0;
}

我想知道以下代码的含义:

这是为什么:

    aaa("abc");
    aaa("%dabc", 3); 
    aaa(("abc"));

不出错地运行,但第四行(如下所示):
    aaa(("%dabc", 3));

产生以下错误:

main.c:15:2: 警告:传递参数 1 给 'aaa' 的类型不匹配,整数转换为指针

main.c:3:5: 注意:期望的类型是 'char *',但实际传递的类型是 `int'


3
这些是括号,而非方括号。 - user703016
4个回答

13

这个陈述

aaa(("%dabc", 3));

使用参数("%dabc", 3)调用函数aaa,返回值为3

查阅逗号运算符获取更多信息。


1
...并且 3char* 不兼容(即 aaa 的第一个参数的类型),因此编译器会给出警告。 - pmg
有人为什么会写 aaa(("abc")) 呢?这些双括号有什么用处吗? - Eregrith
1
有时在调用宏时,需要在参数周围添加额外的括号,例如当该参数本身是一个可变参数列表,随后要传递给可变参数函数时。但我认为对于直接的函数调用来说,这样做从来没有意义。 - Paul R
当该参数本身是一个 vararg 参数列表,随后将传递给 vararg 函数时。你能举个例子吗? - vv1133
2
典型的例子是调试打印宏,在其中您可以将 printf 参数列表作为一个参数传递,例如 DEBUG_PRINT(DBG_LEVEL_1, ("%s = %d", "foo", foo)); 其中 DEBUG_PRINT 宏定义为 #define DEBUG_PRINT(level, args) if (level > gDebugLevel) printf args - Paul R

2
在数学中,函数调用内部的括号被解释为分组,例如:(1)*(2)1*2 是相同的,但是 (1+2)*3 不等于 1+2*3
在第一个例子中,aaa(("abc")):先计算内部的括号,但是 ("abc")"abc" 相同,因此这等价于只调用 aaa("abc")
在第二个例子中,aaa(("abc",3)):内部表达式是 ("abc",3),即 逗号运算符 生效并且 "abc" 被舍弃,留下 3 作为参数传递给 aaa。编译器报错是因为 3 的类型是 int 而不是 char*,所以你没有正确调用该函数。

1

lvalue(“xxx”,val)评估“xxx”,然后评估val并将结果返回到括号中的最后一个值,即val。 aaa(...)中的括号是参数。


我会删除我的回答,Joachim的回答更好 :-) - Peter Miehle

1

因为传递给函数的参数是("%dabc", 3),它本身调用了逗号运算符并返回3的值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接