如何将一个常量数组文字传递给一个不使用变量C/C++的指针函数?

sin*_*oth 29 c c++ function

如果我有一个看起来像这样的原型:

function(float,float,float,float)
Run Code Online (Sandbox Code Playgroud)

我可以传递这样的值:

function(1,2,3,4);
Run Code Online (Sandbox Code Playgroud)

所以,如果我的原型是这样的:

function(float*);
Run Code Online (Sandbox Code Playgroud)

有什么办法可以达到这样的目的吗?

function( {1,2,3,4} );
Run Code Online (Sandbox Code Playgroud)

只是在没有创建临时变量的情况下寻找一种懒惰的方法,但我似乎无法确定语法.

Ada*_*eld 33

您可以使用复合文字在C99(但不是 ANSI C(C90)或C++的任何当前变体)中执行此操作.有关血腥细节,请参阅C99标准的6.5.2.5节.这是一个例子:

// f is a static array of at least 4 floats
void foo(float f[static 4])
{
   ...
}

int main(void)
{
    foo((float[4]){1.0f, 2.0f, 3.0f, 4.0f});  // OK
    foo((float[5]){1.0f, 2.0f, 3.0f, 4.0f, 5.0f});  // also OK, fifth element is ignored
    foo((float[3]){1.0f, 2.0f, 3.0f});  // error, although the GCC doesn't complain
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

GCC还将此作为C90的扩展.如果用-std=gnu90(默认)编译-std=c99,或者-std=gnu99,它将编译; 如果你编译-std=c90,它不会.


GMa*_*ckG 19

这标记为C和C++,所以你会得到截然不同的答案.

如果您需要四个参数,可以执行以下操作:

void foo(float f[])
{
    float f0 = f[0];
    float f1 = f[1];
    float f2 = f[2];
    float f3 = f[3];
}

int main(void)
{
    float f[] = {1, 2, 3, 4};
    foo(f);
}
Run Code Online (Sandbox Code Playgroud)

但这是相当不安全的,因为你可以偶然做到这一点:

void foo(float f[])
{
    float f0 = f[0];
    float f1 = f[1];
    float f2 = f[2];
    float f3 = f[3];
}

int main(void)
{
    float f[] = {1, 2}; // uh-oh
    foo(f);
}
Run Code Online (Sandbox Code Playgroud)

通常最好将它们作为单独的参数.既然你不应该使用原始数组,你可以这样做:

#include <cassert>
#include <vector>

void foo(std::vector<float> f)
{
    assert(f.size() == 4);

    float f0 = f[0];
    float f1 = f[1];
    float f2 = f[2];
    float f3 = f[3];
}

int main(void)
{
    float f[] = {1, 2, 3, 4};
    foo(std::vector<float>(f, f + 4)); // be explicit about size

    // assert says you cannot do this:
    foo(std::vector<float>(f, f + 2));
}
Run Code Online (Sandbox Code Playgroud)

一个改进,但不是很多.您可以使用boost::array,但不是错误的大小不匹配,它们被初始化为0:

#include <boost/array.hpp>

void foo(boost::array<float, 4> f)
{
    float f0 = f[0];
    float f1 = f[1];
    float f2 = f[2];
    float f3 = f[3];
}

int main(void)
{
    boost::array<float, 4> f = {1, 2, 3, 4};
    foo(f);

    boost::array<float, 4> f2 = {1, 2}; // same as = {1, 2, 0, 0}
    foo(f2);
}
Run Code Online (Sandbox Code Playgroud)

当添加初始化列表构造函数时,这将全部在C++ 0x中修复:

#include <cassert>
#include <vector>

void foo(std::vector<float> f)
{
    assert(f.size() == 4);

    float f0 = f[0];
    float f1 = f[1];
    float f2 = f[2];
    float f3 = f[3];
}

int main(void)
{
    foo({1, 2, 3, 4}); // yay, construct vector from this

    // assert says you cannot do this:
    foo({1, 2});
}
Run Code Online (Sandbox Code Playgroud)

也许boost::array还有:

#include <boost/array.hpp>

void foo(boost::array<float, 4> f)
{
    float f0 = f[0];
    float f1 = f[1];
    float f2 = f[2];
    float f3 = f[3];
}

int main(void)
{
    foo({1, 2, 3, 4});

    foo({1, 2}); // same as = {1, 2, 0, 0} ..? I'm not sure,
                 // I don't know if they will do the check, if possible.
}
Run Code Online (Sandbox Code Playgroud)


ezp*_*zpz 5

您可以创建复合文字:

function ((float[2]){2.0, 4.0});
Run Code Online (Sandbox Code Playgroud)

虽然,我不确定你为什么要经历这个麻烦.ISO不允许这样做.

一般来说,应避免使用这样的快捷方式,以便在所有情况下都具有可读性; 懒惰不是一个好习惯(个人意见,当然)

  • C99 是“ISO”,允许在标准中使用复合文字。它只是在 C90 上不可用,也不能移植到 C++。 (2认同)