[错误]获取C++中临时数组的地址

[error]taking address of temporary array in C++?

本文关键字:数组 地址 错误 获取 C++      更新时间:2023-10-16

我在java中有一个函数

static int a2(int[] a)
{
int sumEven = 0;
int sumOdd = 0;
for (int i=0; i<a.length; i++)
{
  if (a[i]%2 == 0)
    sumEven += a[i];
  else
    sumOdd += a[i];
}
return sumOdd - sumEven;
}

我在java中从main调用它,例如

public static void main()
{
a2(new int[] {1});
a2(new int[] {1, 2});
a2(new int[] {1, 2, 3});
a2(new int[] {1, 2, 3, 4});
a2(new int[] {3, 3, 4, 4});
a2(new int[] {3, 2, 3, 4});
a2(new int[] {4, 1, 2, 3});
a2(new int[] {1, 1});
a2(new int[] {});
}

其中 a2 是函数,参数是数组。我想在 c++ 中实现同样的事情,但我无法像在 Java 中传递的那样传递数组以运行。它给出错误[错误]获取临时数组的地址。

在 c++ 中,我就是这样做的

f((int[4]) {1,2,3,4});

给出错误 => [错误]获取临时数组的地址。

如何实现这一点?

使用 std::vector 而不是处理低级数组:

int a2( const std::vector<int> &v )
{
    return std::accumulate( v.begin(), v.end(), 0, []( int a, int b ) {
        return a + ( b % 2 ? b : -b );
    } );
}
int main()
{
    a2( { 1, 2, 3 } );
}

现场示例

在 C/C++ 中,普通函数没有数组参数。虽然你可以写类似的东西

void f(int a[]) { }

但是 a 将衰减到指针而不是数组。

但是,如果您可以使用模板来解决此问题

template <typename T, std::size_t N>
void f(const T (&a) [N]) {}

或者正如其他人所建议的那样,std::vector可能是更好的选择,甚至是std::array .

例如,要使用临时数组,您可以这样做,

typedef int INTARRAY [];
f (INTARRAY{1, 2, 3, 4});

请注意,f的声明现在更改为使用 const T 而不是 T

对数组的引用在C++中的工作方式略有不同。函数签名需要更改为类似 *请注意,您可以添加const以绑定到临时

int a2(int(&a)[3]){/*..*/}

对于大小为 3 的数组。也就是说,必须在编译时知道大小。

如果你想采用不同大小的数组,要么更改函数以接受指针和类似的大小(在许多 C 样式程序中使用):

int a2(int* a, int array_size){/*..*/}

或者创建一个像 CS Pei 提到的模板(可能是最好的方法,并直接回答您关于数组引用的问题)

template <class T, int N>
int a2(T (&a) [N]) {/*..*/}

你来了

#include <iostream>
template <size_t N>
int f( const int ( &a )[N] )
{
    int sumEven = 0;
    int sumOdd = 0;
    for ( size_t i = 0; i < N; i++ )
    {
        if ( a[i] % 2 == 0 )
            sumEven += a[i];
        else
            sumOdd += a[i];
    }
    return sumOdd - sumEven;
}
int main() 
{
    std::cout << f( {1} ) << std::endl;
    std::cout << f( {1, 2} ) << std::endl;
    std::cout << f( {1, 2, 3} ) << std::endl;
    std::cout << f( {1, 2, 3, 4} ) << std::endl;
    std::cout << f( {3, 3, 4, 4} ) << std::endl;
    std::cout << f( {4, 1, 2, 3} ) << std::endl;
    return 0;
}

程序输出为

1
-1
2
-2
-2
-2

至于由您的表达式用作参数,例如此处

f((int[4]) {1,2,3,4});

然后

( int[4] ){ 1, 2, 3, 4 }

是在 C 中定义但未在C++中定义的复合文本。如果要编写使用复合文字的 C 程序,则该函数必须具有指定数组中元素数的第二个参数。

例如

#include <stdio.h>
int f( int a[], size_t n )
{
    int sumEven = 0;
    int sumOdd = 0;
    for ( size_t i = 0; i < n; i++ )
    {
        if ( a[i] % 2 == 0 )
            sumEven += a[i];
        else
            sumOdd += a[i];
    }
    return sumOdd - sumEven;
}
int main( void ) 
{
    printf( "%dn", f( ( int[] ){1}, 1 ) );
    printf( "%dn", f( ( int[] ){1, 2}, 2 ) );
    return 0;
}