设置整个数组的值的最简单方法是啥?

Posted

技术标签:

【中文标题】设置整个数组的值的最简单方法是啥?【英文标题】:What is the easiest way to set the value of an entire array?设置整个数组的值的最简单方法是什么? 【发布时间】:2010-06-09 22:20:02 【问题描述】:

我当前的项目要求我根据其他一些值填充一个数组。我知道有捷径:

int arr[4][4] =  0,0,0,0 , 0,0,0,0 , 0,0,0,0 , 0,0,0,0 ;

但在这种情况下,我需要在声明后填充数组。我目前的代码格式如下:

int arr[4][4];
if(someothervariable == 1)
    arr =  1,1,1,1,
            1,2,3,4,
            2,,3,4,5,
            3,4,5,6 ;

但它不会编译。在我的情况下,有没有办法使用提到的快捷方式?如果没有,最好的修复方法是什么?我很欣赏一种无需显式分配每个元素即可设置它的方法?即:arr[0][0] = ...

【问题讨论】:

原文中有多余的逗号吗? 在第一种情况下,快捷方式是int arr[4][4] = 。你上面的肯定是一个“长切”:)) C++1x 以其统一的初始化语法来拯救!不幸的是,它尚未广泛使用。 【参考方案1】:

使用 std::copy() 怎么样?

int arr[4][4];
if(someothervariable == 1)
        const static int a2[4][4] =  1,1,1,1,
                                      1,2,3,4,
                                      2,3,4,5,
                                      3,4,5,6 ;
        std::copy(&a2[0][0], &a2[0][0]+16, &arr[0][0]);

【讨论】:

这将在实践中起作用,但从正式和迂腐的角度来说,将 2D 数组重新解释为 1D 数组是非法的。更准确地说,在&a2[0][0] 上使用距离该指针超过 4 步的指针算术在形式上是非法的。做&a2[0][0] + 16 是未定义的行为。同样,这通常在实践中起作用。 感谢您让我重新阅读标准!我记住了the same array object(5.7/6)和arrays in C++ are stored row-wise(8.3.4/9)这两个词,但你是对的,在每行之间实现一个带有填充字节的二维数组是合法的(就像它拥有 &arr 是合法的(在数组到指针的转换之前)!= &arr[0][0]),在这种情况下会失败。【参考方案2】:

不,数组初始化语法用于数组初始化。不过,如果所有值都是相同的字节,则可以使用 memset。

boost.assign 库为修改/填充集合添加了一些有趣的语法,但 AFAIK 它不支持 C 样式数组(仅支持 C++ 和 Boost 容器)。

【讨论】:

【参考方案3】:

在当前版本的 C++ 语言中,唯一的方法是从一些原始版本中复制它

int arr[4][4];

if (someothervariable == 1)

  const int SOURCE[4][4] = // make it `static` if you prefer
   
    1, 1, 1, 1,
    1, 2, 3, 4,
    2, 3, 4, 5,
    3, 4, 5, 6 
  ;

  assert(sizeof arr == sizeof SOURCE); // static assert is more appropriate
  memcpy(&arr, &SOURCE, sizeof arr);

如果编译器不够聪明,无法自行优化,源“常量”可以声明为static,以避免重新初始化。

在该语言的未来版本中,计划提供类似于 C 的复合文字的功能,这将支持立即初始化(基本上是您在原始帖子中尝试做的)。

【讨论】:

这有一个C++ 标记(不是C 标记),所以我更喜欢std::copy()(并希望它在适当的时候回退到std::memcpy())。 Cubbi did that right. @sbi:不幸的是,数组类型在 C++ 中是不可分配的,这就是为什么没有立即合法的基于 std::copy 的解决方案。 Cubbi 做错了(正式地说),因为他将 2D 数组重新解释为 1D 数组。这在 C++ 中是形式上非法的,并且迂腐(调试)实现有权在该代码上崩溃。一个std::copy 没有优雅的解决方案。您必须进行嵌套复制才能以正确的方式复制 2D 数组。 你说得有道理。虽然我无法想象二维数组不连续的实现,但如果是,使用std::memcpy() 会一样好。 哈!除非您不使用内置插件!然后,使用std::copy() 会导致“更少的UB”,然后使用std::memcpy() 会。 :)【参考方案4】:

如果你想用单个值填充数组:

#include<algorithm>
#include<vector>

// ...
std::vector<int> arr;
std::fill(arr.begin(), arr.end(), VALUE);  // VALUE is an integer

如果你想计算每个元素的值:

struct get_value 
    int operator()() const  /* calculate and return value ... */ 
;

std::generate(arr.begin(), arr.end(), get_value());

【讨论】:

【参考方案5】:

如果您将所有内容都设置为相同的值(例如零),您也许可以逃脱...

memset (arr, 0, sizeof (arr));

请注意,这充满了危险。你必须知道你的字体大小和所有的爵士乐。

但是,这似乎对您来说还不够。如果你想用不同的值填充数组,我只能想到两种方法。

方法#1。 (可能会很痛)

arr[0][0] = 1;
...
arr[0][3] = 1;
arr[1][0] = 1;
...
arr[1][3] = 4;
arr[2][0] = 2;
...
arr[2][3] = 5;
arr[3][0] = 3;
...
arr[3][3] = 6;

方法#2。 预定义一组数组,并使用指针在它们之间切换;

int  arr1[4][4] = 
        0,0,0,0,
        0,0,0,0,
        0,0,0,0,
        0,0,0,0 ;
int  arr2[4][4] = 
        1,1,1,1,
        1,2,3,4,
        2,,3,4,5,
        3,4,5,6 ;

int *arr[4];

现在您只需要设置 *arr[] 的四 (4) 个值,而不是设置所有内容。当然,这只有在你的数组将被预先确定的常量填充时才有效。

希望这会有所帮助。

【讨论】:

我想你的意思是int (*arr)[4]。在 C++ 中,不妨这样做:int (&amp;arr)[4] = (someothervariable == 1) ? arr2 : arr1.【参考方案6】:

我不确定我是否喜欢这个解决方案,但是如果你将数组包装在一个结构中,那么 C/C++ 会给你分配方便,而代价是必须使用结构名称来获取数组:

typedef struct 
    int data[4][4];
 info_t;

info_t arr;

if (someothervariable == 1)
    static const info_t newdata =   // since this is static const, there generally
                                      // won't be a copy - that data will be 'baked' 
                                      // into the binary image (or at worst a
                                      // single copy will occur)
        1,1,1,1,
        1,2,3,4,
        2,3,4,5,
        3,4,5,6 
    ;
    arr = newdata;  // easy to assign new data to the array


int somethingelse = arr.data[1][2]; // a tiny bit less convenient to get 
                                    //    to the array data

【讨论】:

这是 C++,所以typedef 不是必需的。 (顺便说一句,他的不便可以通过重载operator[]info_t 来克服。)【参考方案7】:
int arr[4][4];
if (someothervariable == 1) 
     int tmp[4][4] =  1, 1, 1, 1, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6 ;
     arr = tmp;

【讨论】:

数组不可赋值。 arr = tmp 不会编译。

以上是关于设置整个数组的值的最简单方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

从数据框中的所有列中获取值的最简单方法是啥[重复]

在视图中访问 Phalcon 配置值的最简单方法是啥?

检查数组中的索引或键的最简单方法是啥?

从 HtmlHelper 的扩展方法中传递的 lambda 表达式中获取属性值的最简单方法是啥?

在 2D 矢量中的预定位置更改多个值的最简单方法是啥?

将数组转换为向量的最简单方法是啥?