【问题标题】:initializing an array of ints初始化一个整数数组
【发布时间】:2012-11-08 18:15:41
【问题描述】:

有没有人有办法将ints 的数组(任何多字节类型都可以)简单地初始化为非零和非-1 值?我的意思是,有没有办法在一个班轮中做到这一点,而不必单独执行每个元素:

int arr[30] = {1, 1, 1, 1, ...}; // that works, but takes too long to type

int arr[30] = {1}; // nope, that gives 1, 0, 0, 0, ...

int arr[30];
memset(arr, 1, sizeof(arr)); // That doesn't work correctly for arrays with multi-byte
                             //   types such as int

仅供参考,以这种方式在静态数组上使用 memset() 给出:

arr[0] = 0x01010101
arr[1] = 0x01010101
arr[2] = 0x01010101

另一个选项:

for(count = 0; count < 30; count++)
   arr[count] = 1;    // Yup, that does it, but it's two lines.

有人有其他想法吗?只要是 C 代码,解决方案就没有限制。 (其他库都可以)

【问题讨论】:

  • 有 wmemset() 用于“宽”字符数组
  • 其他库不需要>1行吗? #include libother
  • @MarcB - 还不错......两个小问题,首先我了解wchar_t is compiler-specific and can be as small as 8 bits,所以这可能是单字节。其次,我希望有一些可以在不同类型上工作的东西。但不是一个坏建议。谢谢。
  • Mac OS X 自 10.5 版起具有 memset_pattern4()memset_pattern8()memset_pattern16()
  • @mcalex - Touché。好的,“每个设置 1 班轮”怎么样,我们不会将 #includes 或更多选项计入 gcc

标签: c arrays initialization


【解决方案1】:

这是一个 GCC 扩展:

int a[100] = {[0 ... 99] = 1};

【讨论】:

  • 太棒了,我不知道语法。 +1
  • 请注意,其他任何使用此功能的人,数字和... 之间有空格,这很重要
  • @Mike 查看链接,也可以初始化多个范围和单个元素。
  • 如果我错了,请纠正我,但 C 语言中的指定初始化程序是:typedef struct { int x; int y} type; 然后type t = { .x=1, .y=2 }; 我从未见过 .. 表示法,也没有听说过它被称为指定初始化程序。我相信这是超出标准 C 指定初始化程序的一些 GCC 扩展。
  • @Lundin 它是一个 GCC 扩展,就像我提到的那样,它在 Designated Initializers 部分下的链接中进行了描述。我的答案已被编辑,我不确定它叫什么,但我认为“范围初始值设定项”可能更合适?
【解决方案2】:
for (count = 0; count < 30; count++) arr[count] = 1;

一行。 :)

【讨论】:

  • One line. :) 非常正确...此解决方案遵循法律条文
【解决方案3】:

您说了两行,但您可以使用逗号 ,operator 在一行中完成。

for(count = 0; count < 30 ; arr[count] = 1,count++);

【讨论】:

  • 我其实很喜欢这个解决方案,, 运算符太不用了。
  • 哪个逗号、运算符这么不用?我没听懂你。
  • 我会改写,“我喜欢这个解决方案,因为它使用逗号运算符,而人们使用的不够多”
  • 或者:for(count = 0; count &lt; 30; arr[count++] = 1);
  • 您也可以在一行中编写整个 C 程序。如果有人能就其意义提供一个理由,我会很高兴听到它。
【解决方案4】:

在初始化期间(而不是运行时)执行此操作的唯一明智方法似乎是:

#define ONE1     1
#define FIVE1    ONE1, ONE1, ONE1, ONE1, ONE1
#define TEN1     FIVE1, FIVE1
#define TWENTY1  TEN1, TEN1
#define FIFTY1   TWENTY1, TWENTY1, TEN1
#define HUNDRED1 FIFTY1, FIFTY1

int array [100][4] =
{
  HUNDRED1,
  HUNDRED1,
  HUNDRED1,
  HUNDRED1
};

接下来,#define ONE2 2 等等。你明白了。

编辑: 我写这么多宏的原因是为了展示这个解决方案的灵活性。对于这种特殊情况,您不需要所有这些。但是使用这样的宏,您可以快速灵活地编写任何类型的初始化列表:

{
  FIFTY1, FIFTY2,  // 1,1,1,1... 50 times, then 2,2,2,2... 50 times
  TWENTY3, EIGHTY4 // 3,3,3,3... 20 times, then 4,4,4,4... 80 times
  ... // and so on
};

【讨论】:

  • 非常简洁的解决方案,可读、可扩展和编译时!
  • @Lundin:这是迄今为止最好的、智能的和可读的。谢谢!
  • 您能否将其概括为采用要重复数字的函数?即#define ONE(n) 1,然后是#define FIVE(n) ONE(n), ONE(n), ONE(n), ONE(n), ONE(n),等等,所以你不需要为每个数字单独设置一组宏吗?
  • 实际上,通过一些巧妙的技巧,您甚至可以将其概括为函数 #define REPEAT(symbol, count),尽管我现在太累了,无法弄清楚它是如何工作的 :)
  • @NicHartley 确实,您可以使用此方法创建更优雅的宏。 #define FIVE(n) 确实比 FIVE1 看起来更漂亮。
【解决方案5】:

在 C 语言中,您通常会使用类似宏的宏开发自己的“支持库”

#define SET_ALL(a_, n_, v_)\
  do { size_t i, n = (n_); for (i = 0; i < n; ++i) (a_)[i] = (v_); } while(0)

#define SET_ALL_A(a_, v_) SET_ALL(a_, sizeof(a_) / sizeof *(a_), v_)
#define ZERO_ALL(a_, n_) SET_ALL(a_, n_, 0)
#define ZERO_ALL_A(a_) SET_ALL_A(a_, 0)

然后在你的代码中使用它们

int arr[30];

SET_ALL_A(arr, 1);

【讨论】:

  • 这实际上是一个真正的目标,为什么我没有想到只包含一个宏来处理它,这超出了我的能力......
  • 如果你像这样制作一个 icky 宏,为什么不写一个来真正初始化数组,而不是像这样在运行时设置它呢?假设“arr”具有静态存储持续时间,并且您希望利用此类变量的特殊初始化规则(它们在调用 main 之前初始化)。
  • @Lundin:如果我知道任何允许我按要求初始化数组的 C 功能,我会使用它。但唉,我不知道该怎么做。我认为上面的“icky 宏”是 C 语言中最好的东西。如果你能提出更好的建议,我会全力以赴。
【解决方案6】:

一行有指针!

for (int *p = a; p < (a + 30); p++) *p = 1;

或者如果您过早地担心重复计算(a + 30)会导致性能下降:

for (int *p = a + 30 - 1; p >= a; p--) *p = 1;

【讨论】:

  • 如果你想确保a + 30 只会计算一次,我会做for (int *p = a, *pEnd = a + 30; p &lt; pEnd; p++) *p = 1;。您的第二个 for 循环调用未定义的行为,因为它计算了超出范围的 a - 1p 不指向数组a,所以p &gt;= a 是未定义的。
【解决方案7】:

对于静态值的初始化,我通常认为将其输入为首选,如下所示:

int arr[30] = {1, 1, 1, 1, ...}; 

在这种情况下,编译器可以(并且通常会)在前导代码中吐出优化的初始化。

有时初始化更加动态,如下例所示:

int arr[30];
int x = fetchSomeValue();
for(int i=0; i<30; i++) arr[i] = x;

在这些情况下,您必须对其进行编码,一般规则是最大限度地提高可读性,而不是尽量减少输入。此代码将被编写一次并读取多次。

【讨论】:

    猜你喜欢
    • 2016-06-30
    • 1970-01-01
    • 1970-01-01
    • 2016-12-17
    • 2011-07-30
    • 2011-05-30
    • 1970-01-01
    • 2011-05-25
    • 1970-01-01
    相关资源
    最近更新 更多