函数返回值作为函数参数的C传递地址

函数返回值作为函数参数的C传递地址,c,function,memory-address,C,Function,Memory Address,我有两个职能: void a(int * p); int b(); 是否可以将函数b返回值的地址传递给函数a如下:a(&b()) 不,你不能在C中这样做。还要注意的是,C没有像在C++中那样被称为引用的东西 因此,C有指针来实现相同的行为 要在C中实现相同的目标,请使用临时变量 int val; val = b(); a( &val ); // & is called as "address of" operator in C 为了回答为什么C中没有引用,据我所知,指

我有两个职能:

void a(int * p);
int b();

是否可以将函数
b
返回值的地址传递给函数
a
如下:
a(&b())

不,你不能在
C
中这样做。还要注意的是,
C
没有像在
C++
中那样被称为引用的东西

因此,
C
指针来实现相同的行为

要在
C
中实现相同的目标,请使用临时变量

int val;
val = b();
a( &val );    // & is called as "address of" operator in C


为了回答为什么
C
中没有引用,据我所知,指针和引用是为了达到相同的目标-最小化或避免数据复制。对于这个
C
,指针已经足够好了,尽管从技术上讲,两者在
C++
(作为参考)

方面都有一些不同,只是使用了一个临时变量:

int result = b();
a(&result);

编辑:显然还有一种使用复合文字的方法,在这里的另一个答案中有描述。

否-返回值的地址是什么?您需要将返回值存储在变量中,然后传入该变量的地址。

您可以将对
b()
的引用作为
a
的参数传递,然后从
a
调用
b

void a(void (*b)(int)) {
   // call b
   int local_var = b(<something>);
}
void a(void(*b)(int)){
//打电话给b
int local_var=b();
}
第C11号说明(强调我的):

6.5.3.2.1

一元运算符和运算符的操作数应为一个函数指示符a[]一元运算符*的结果,或一个左值,该左值指定的对象不是位字段,且未使用寄存器存储类说明符声明

现在它显然不是一个函数,一个
[]
或一元
*
。让我们看看什么是左值:

6.3.2.1

左值是一个表达式(对象类型不是void),它可能 指定一个对象;64)如果左值在计算时未指定对象,则 行为是未定义的

64)名称“左值”最初来自赋值表达式E1=E2,其中左 操作数E1必须是(可修改的)左值。也许最好把它看作是代表 对象“”定位器值“”。本国际标准中描述了有时称为“右值”的内容 作为“表达式的值”

左值的一个明显例子是对象的标识符。再举一个例子,如果E是一元数 表达式是指向对象的指针,*E是一个左值,用于指定E指向的对象


简而言之,左值表示一个对象。由于
b()
不指定特定对象,因此它不是左值。你也可以看到
b()=2是错误的。

一个复合文字似乎可以做到这一点(需要C99编译器):


输出为
5

为什么?还有其他解决方案吗?当然返回值是临时的-获取它的地址怎么可能有用?尽管这里有大多数答案,但使用复合文字是可能的。哇,你从一个完全不同的角度看待这个问题。你喜欢Lisp吗?:-)@JamesMcLaughlin我真的很喜欢Lisp(好的方案),所以Lisp很好。谢谢你的澄清!尽管如此,使用复合文字仍然是可能的,请参见我的答案。@dreamlax,复合文字在您的答案中生成一个匿名对象,因此它基本上与编写
int res=b()相同;a&res。我的回答是为什么OP的代码不能工作。虽然你的答案很好,但我从来没有想到你可以这么做。有一种方法可以不用临时变量,使用复合文字。这一种看起来很神奇,但我必须在C99之前的版本中使用编译器,因此不支持复合文字。不过,我最喜欢这个“解决方案”。@papaiatis:C99已经快14岁了,也许是时候更新了:)我希望我可以。:)我也无能为力。
int a()
{
    return 5;
}

void b(int *a)
{
    // do something with a
    printf("%d\n", *a);
}

int main(void)
{
    b(&(int){ a() });
}