如何将数组的所有成员初始化为相同的值?

发布于 2024-07-06 20:44:27 字数 171 浏览 11 评论 0原文

我有一个用C编写的大数组(不是C++,如果这有区别的话)。 我想初始化相同值的所有成员。

我可以发誓我曾经知道一个简单的方法来做到这一点。 在我的例子中,我可以使用 memset() ,但是没有一种方法可以直接内置到 C 语法中吗?

I have a large array in C (not C++ if that makes a difference). I want to initialize all members of the same value.

I could swear I once knew a simple way to do this. I could use memset() in my case, but isn't there a way to do this that is built right into the C syntax?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(27

多彩岁月 2024-07-13 20:44:27

除非该值为 0(在这种情况下,您可以省略初始化程序的某些部分
并且相应的元素将被初始化为0),没有简单的方法。

不过,不要忽视明显的解决方案:

int myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };

缺少值的元素将被初始化为 0:

int myArray[10] = { 1, 2 }; // initialize to 1,2,0,0,0...

因此这会将所有元素初始化为 0:

int myArray[10] = { 0 }; // all elements 0

在 C++ 中,空的初始化列表也会将每个元素初始化为 0。
在 C23 之前,C 中不允许

int myArray[10] = {}; // all elements 0 in C++ and C23

请记住,如果没有,具有静态存储持续时间的对象将初始化为 0
指定了初始化器:

static int myArray[10]; // all elements 0

并且“0”并不一定意味着“全位零”,因此使用上面的是
比 memset() 更好、更便携。 (浮点值将是
初始化为+0、指向空值的指针等)

Unless that value is 0 (in which case you can omit some part of the initializer
and the corresponding elements will be initialized to 0), there's no easy way.

Don't overlook the obvious solution, though:

int myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };

Elements with missing values will be initialized to 0:

int myArray[10] = { 1, 2 }; // initialize to 1,2,0,0,0...

So this will initialize all elements to 0:

int myArray[10] = { 0 }; // all elements 0

In C++, an empty initialization list will also initialize every element to 0.
This is not allowed with C until C23:

int myArray[10] = {}; // all elements 0 in C++ and C23

Remember that objects with static storage duration will initialize to 0 if no
initializer is specified:

static int myArray[10]; // all elements 0

And that "0" doesn't necessarily mean "all-bits-zero", so using the above is
better and more portable than memset(). (Floating point values will be
initialized to +0, pointers to null value, etc.)

岁月静好 2024-07-13 20:44:27

如果您的编译器是 GCC,您可以使用以下“GNU 扩展”语法:

int array[1024] = {[0 ... 1023] = 5};

查看详细说明:
http://gcc.gnu.org/onlinedocs/gcc -4.1.2/gcc/Designated-Inits.html

If your compiler is GCC you can use following "GNU extension" syntax:

int array[1024] = {[0 ... 1023] = 5};

Check out detailed description:
http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html

§对你不离不弃 2024-07-13 20:44:27

要静态初始化具有相同值的大型数组,无需多次复制粘贴,可以使用宏:

#define VAL_1X     42
#define VAL_2X     VAL_1X,  VAL_1X
#define VAL_4X     VAL_2X,  VAL_2X
#define VAL_8X     VAL_4X,  VAL_4X
#define VAL_16X    VAL_8X,  VAL_8X
#define VAL_32X    VAL_16X, VAL_16X
#define VAL_64X    VAL_32X, VAL_32X

int myArray[53] = { VAL_32X, VAL_16X, VAL_4X, VAL_1X };

如果需要更改值,则只需在一处进行替换。

编辑:可能有用的扩展

(由 Jonathan Leffler 提供)

您可以轻松地概括这一点:

#define VAL_1(X) X
#define VAL_2(X) VAL_1(X), VAL_1(X)
/* etc. */

可以使用以下命令创建变体:

#define STRUCTVAL_1(...) { __VA_ARGS__ }
#define STRUCTVAL_2(...) STRUCTVAL_1(__VA_ARGS__), STRUCTVAL_1(__VA_ARGS__)
/*etc */ 

适用于结构或复合数组。

#define STRUCTVAL_48(...) STRUCTVAL_32(__VA_ARGS__), STRUCTVAL_16(__VA_ARGS__)

struct Pair { char key[16]; char val[32]; };
struct Pair p_data[] = { STRUCTVAL_48("Key", "Value") };
int a_data[][4] = { STRUCTVAL_48(12, 19, 23, 37) };

宏名称是可以协商的。

For statically initializing a large array with the same value, without multiple copy-paste, you can use macros:

#define VAL_1X     42
#define VAL_2X     VAL_1X,  VAL_1X
#define VAL_4X     VAL_2X,  VAL_2X
#define VAL_8X     VAL_4X,  VAL_4X
#define VAL_16X    VAL_8X,  VAL_8X
#define VAL_32X    VAL_16X, VAL_16X
#define VAL_64X    VAL_32X, VAL_32X

int myArray[53] = { VAL_32X, VAL_16X, VAL_4X, VAL_1X };

If you need to change the value, you have to do the replacement at only one place.

Edit: possible useful extensions

(courtesy of Jonathan Leffler)

You can easily generalize this with:

#define VAL_1(X) X
#define VAL_2(X) VAL_1(X), VAL_1(X)
/* etc. */

A variant can be created using:

#define STRUCTVAL_1(...) { __VA_ARGS__ }
#define STRUCTVAL_2(...) STRUCTVAL_1(__VA_ARGS__), STRUCTVAL_1(__VA_ARGS__)
/*etc */ 

that works with structures or compound arrays.

#define STRUCTVAL_48(...) STRUCTVAL_32(__VA_ARGS__), STRUCTVAL_16(__VA_ARGS__)

struct Pair { char key[16]; char val[32]; };
struct Pair p_data[] = { STRUCTVAL_48("Key", "Value") };
int a_data[][4] = { STRUCTVAL_48(12, 19, 23, 37) };

macro names are negotiable.

瞎闹 2024-07-13 20:44:27

如果要确保数组的每个成员都被显式初始化,只需在声明中省略维度即可:

int myArray[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

编译器将从初始化列表中推导出维度。 不幸的是,对于多维数组,只能省略最外层的维度:

int myPoints[][3] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };

可以,但

int myPoints[][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };

不行。

If you want to ensure that every member of the array is explicitly initialized, just omit the dimension from the declaration:

int myArray[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

The compiler will deduce the dimension from the initializer list. Unfortunately, for multidimensional arrays only the outermost dimension may be omitted:

int myPoints[][3] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };

is OK, but

int myPoints[][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };

is not.

星軌x 2024-07-13 20:44:27

我看到一些使用这种语法的代码:

char* array[] = 
{
    [0] = "Hello",
    [1] = "World"
};   

它变得特别有用的是,如果您正在创建一个使用枚举作为索引的数组:

enum
{
    ERR_OK,
    ERR_FAIL,
    ERR_MEMORY
};

#define _ITEM(x) [x] = #x

char* array[] = 
{
    _ITEM(ERR_OK),
    _ITEM(ERR_FAIL),
    _ITEM(ERR_MEMORY)
};   

即使您碰巧将一些枚举值写得乱序,这也可以使事情保持有序。 。

有关此技术的更多信息,请参阅 此处此处

I saw some code that used this syntax:

char* array[] = 
{
    [0] = "Hello",
    [1] = "World"
};   

Where it becomes particularly useful is if you're making an array that uses enums as the index:

enum
{
    ERR_OK,
    ERR_FAIL,
    ERR_MEMORY
};

#define _ITEM(x) [x] = #x

char* array[] = 
{
    _ITEM(ERR_OK),
    _ITEM(ERR_FAIL),
    _ITEM(ERR_MEMORY)
};   

This keeps things in order, even if you happen to write some of the enum-values out of order.

More about this technique can be found here and here.

酒绊 2024-07-13 20:44:27
int i;
for (i = 0; i < ARRAY_SIZE; ++i)
{
  myArray[i] = VALUE;
}

要好。

int myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5...

我认为这比数组大小发生变化

int i;
for (i = 0; i < ARRAY_SIZE; ++i)
{
  myArray[i] = VALUE;
}

I think this is better than

int myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5...

incase the size of the array changes.

似梦非梦 2024-07-13 20:44:27

您可以按照上面详细说明的那样完成整个静态初始化程序,但是当您的数组大小发生变化时(当您的数组 embiggens 时,如果您不添加适当的额外初始化程序,您会得到垃圾),这可能是一个真正的麻烦。

memset 为您提供了完成工作的运行时命中,但正确完成的代码大小命中不会受到数组大小更改的影响。 当数组大于几十个元素时,我几乎在所有情况下都会使用此解决方案。

如果静态声明数组确实很重要,我会编写一个程序来为我编写该程序,并将其作为构建过程的一部分。

You can do the whole static initializer thing as detailed above, but it can be a real bummer when your array size changes (when your array embiggens, if you don't add the appropriate extra initializers you get garbage).

memset gives you a runtime hit for doing the work, but no code size hit done right is immune to array size changes. I would use this solution in nearly all cases when the array was larger than, say, a few dozen elements.

If it was really important that the array was statically declared, I'd write a program to write the program for me and make it part of the build process.

青朷 2024-07-13 20:44:27

我知道最初的问题明确提到了 C 而不是 C++,但是如果您(像我一样)来这里寻找 C++ 数组的解决方案,这里有一个巧妙的技巧:

如果您的编译器支持 折叠表达式,您可以使用模板魔法和 std::index_sequence 生成一个初始值设定项列表,其值是你要。 您甚至可以constexpr它并感觉自己像个老板:

#include <array>

/// [3]
/// This functions's only purpose is to ignore the index given as the second
/// template argument and to always produce the value passed in.
template<class T, size_t /*ignored*/>
constexpr T identity_func(const T& value) {
    return value;
}

/// [2]
/// At this point, we have a list of indices that we can unfold
/// into an initializer list using the `identity_func` above.
template<class T, size_t... Indices>
constexpr std::array<T, sizeof...(Indices)>
make_array_of_impl(const T& value, std::index_sequence<Indices...>) {
    return {identity_func<T, Indices>(value)...};
}

/// [1]
/// This is the user-facing function.
/// The template arguments are swapped compared to the order used
/// for std::array, this way we can let the compiler infer the type
/// from the given value but still define it explicitly if we want to.
template<size_t Size, class T>
constexpr std::array<T, Size> 
make_array_of(const T& value) {
    using Indices = std::make_index_sequence<Size>;
    return make_array_of_impl(value, Indices{});
}

// std::array<int, 4>{42, 42, 42, 42}
constexpr auto test_array = make_array_of<4/*, int*/>(42);
static_assert(test_array[0] == 42);
static_assert(test_array[1] == 42);
static_assert(test_array[2] == 42);
static_assert(test_array[3] == 42);
// static_assert(test_array[4] == 42); out of bounds

您可以查看代码工作中(在 Wandbox)

I know the original question explicitly mentions C and not C++, but if you (like me) came here looking for a solution for C++ arrays, here's a neat trick:

If your compiler supports fold expressions, you can use template magic and std::index_sequence to generate an initializer list with the value that you want. And you can even constexpr it and feel like a boss:

#include <array>

/// [3]
/// This functions's only purpose is to ignore the index given as the second
/// template argument and to always produce the value passed in.
template<class T, size_t /*ignored*/>
constexpr T identity_func(const T& value) {
    return value;
}

/// [2]
/// At this point, we have a list of indices that we can unfold
/// into an initializer list using the `identity_func` above.
template<class T, size_t... Indices>
constexpr std::array<T, sizeof...(Indices)>
make_array_of_impl(const T& value, std::index_sequence<Indices...>) {
    return {identity_func<T, Indices>(value)...};
}

/// [1]
/// This is the user-facing function.
/// The template arguments are swapped compared to the order used
/// for std::array, this way we can let the compiler infer the type
/// from the given value but still define it explicitly if we want to.
template<size_t Size, class T>
constexpr std::array<T, Size> 
make_array_of(const T& value) {
    using Indices = std::make_index_sequence<Size>;
    return make_array_of_impl(value, Indices{});
}

// std::array<int, 4>{42, 42, 42, 42}
constexpr auto test_array = make_array_of<4/*, int*/>(42);
static_assert(test_array[0] == 42);
static_assert(test_array[1] == 42);
static_assert(test_array[2] == 42);
static_assert(test_array[3] == 42);
// static_assert(test_array[4] == 42); out of bounds

You can take a look at the code at work (at Wandbox)

笑咖 2024-07-13 20:44:27

这是另一种方法:

static void
unhandled_interrupt(struct trap_frame *frame, int irq, void *arg)
{
    //this code intentionally left blank
}

static struct irqtbl_s vector_tbl[XCHAL_NUM_INTERRUPTS] = {
    [0 ... XCHAL_NUM_INTERRUPTS-1] {unhandled_interrupt, NULL},
};

请参阅:

C- Extensions

指定inits

那么问一个问题:什么时候可以使用C扩展呢?

上面的代码示例位于嵌入式系统中,永远不会看到来自其他编译器的信息。

Here is another way:

static void
unhandled_interrupt(struct trap_frame *frame, int irq, void *arg)
{
    //this code intentionally left blank
}

static struct irqtbl_s vector_tbl[XCHAL_NUM_INTERRUPTS] = {
    [0 ... XCHAL_NUM_INTERRUPTS-1] {unhandled_interrupt, NULL},
};

See:

C-Extensions

Designated inits

Then ask the question: When can one use C extensions?

The code sample above is in an embedded system and will never see the light from another compiler.

蓬勃野心 2024-07-13 20:44:27

有点半开玩笑的回答; 编写该语句

array = initial_value

用您最喜欢的支持数组的语言(我的是 Fortran,但还有很多其他语言) ,并将其链接到您的 C 代码。 您可能希望将其包装为外部函数。

A slightly tongue-in-cheek answer; write the statement

array = initial_value

in your favourite array-capable language (mine is Fortran, but there are many others), and link it to your C code. You'd probably want to wrap it up to be an external function.

时光病人 2024-07-13 20:44:27

为了初始化“普通”数据类型(如 int 数组),您可以使用括号表示法,但如果数组中仍有空间,它会将最后一个之后的值清零:

// put values 1-8, then two zeroes
int list[10] = {1,2,3,4,5,6,7,8};

For initializing 'normal' data types (like int arrays), you can use the bracket notation, but it will zero the values after the last if there is still space in the array:

// put values 1-8, then two zeroes
int list[10] = {1,2,3,4,5,6,7,8};
☆獨立☆ 2024-07-13 20:44:27

如果数组恰好是 int 或任何具有 int 大小的数组,或者您的内存模式的大小恰好适合 int 的时间(即全零或 0xA5A5A5A5),则最好的方法是使用 memset()

否则在循环中调用 memcpy() 移动索引。

If the array happens to be int or anything with the size of int or your mem-pattern's size fits exact times into an int (i.e. all zeroes or 0xA5A5A5A5), the best way is to use memset().

Otherwise call memcpy() in a loop moving the index.

北城挽邺 2024-07-13 20:44:27

有一种快速方法可以用给定值初始化任何类型的数组。 它非常适合大型阵列。 算法如下:

  • 初始化数组的第一个元素(通常方式)
  • 将已设置的部分复制到未设置的部分,每次下一次复制操作将大小加倍

对于1 000 000元素< code>int 数组,它比常规循环初始化快 4 倍(i5、2 核、2.3 GHz、4GiB 内存、64 位):

循环运行时间 0.004248 [秒]

memfill () 运行时间 0.001085 [秒]


#include <stdio.h>
#include <time.h>
#include <string.h>
#define ARR_SIZE 1000000

void memfill(void *dest, size_t destsize, size_t elemsize) {
   char   *nextdest = (char *) dest + elemsize;
   size_t movesize, donesize = elemsize;

   destsize -= elemsize;
   while (destsize) {
      movesize = (donesize < destsize) ? donesize : destsize;
      memcpy(nextdest, dest, movesize);
      nextdest += movesize; destsize -= movesize; donesize += movesize;
   }
}    
int main() {
    clock_t timeStart;
    double  runTime;
    int     i, a[ARR_SIZE];

    timeStart = clock();
    for (i = 0; i < ARR_SIZE; i++)
        a[i] = 9;    
    runTime = (double)(clock() - timeStart) / (double)CLOCKS_PER_SEC;
    printf("loop runtime %f [seconds]\n",runTime);

    timeStart = clock();
    a[0] = 10;
    memfill(a, sizeof(a), sizeof(a[0]));
    runTime = (double)(clock() - timeStart) / (double)CLOCKS_PER_SEC;
    printf("memfill() runtime %f [seconds]\n",runTime);
    return 0;
}

There is a fast way to initialize array of any type with given value. It works very well with large arrays. Algorithm is as follows:

  • initialize first element of the array (usual way)
  • copy part which has been set into part which has not been set, doubling the size with each next copy operation

For 1 000 000 elements int array it is 4 times faster than regular loop initialization (i5, 2 cores, 2.3 GHz, 4GiB memory, 64 bits):

loop runtime 0.004248 [seconds]

memfill() runtime 0.001085 [seconds]


#include <stdio.h>
#include <time.h>
#include <string.h>
#define ARR_SIZE 1000000

void memfill(void *dest, size_t destsize, size_t elemsize) {
   char   *nextdest = (char *) dest + elemsize;
   size_t movesize, donesize = elemsize;

   destsize -= elemsize;
   while (destsize) {
      movesize = (donesize < destsize) ? donesize : destsize;
      memcpy(nextdest, dest, movesize);
      nextdest += movesize; destsize -= movesize; donesize += movesize;
   }
}    
int main() {
    clock_t timeStart;
    double  runTime;
    int     i, a[ARR_SIZE];

    timeStart = clock();
    for (i = 0; i < ARR_SIZE; i++)
        a[i] = 9;    
    runTime = (double)(clock() - timeStart) / (double)CLOCKS_PER_SEC;
    printf("loop runtime %f [seconds]\n",runTime);

    timeStart = clock();
    a[0] = 10;
    memfill(a, sizeof(a), sizeof(a[0]));
    runTime = (double)(clock() - timeStart) / (double)CLOCKS_PER_SEC;
    printf("memfill() runtime %f [seconds]\n",runTime);
    return 0;
}
乱世争霸 2024-07-13 20:44:27
int array[1024] = {[0 ... 1023] = 5};

由于上述工作正常,但请确保 ... 点之间没有空格。

int array[1024] = {[0 ... 1023] = 5};

As the above works fine but make sure no spaces between the ... dots.

心欲静而疯不止 2024-07-13 20:44:27
  1. 如果您的数组被声明为静态或全局的,则所有元素
    数组中已经有默认值 0。
  2. 一些编译器在调试模式下将数组的默认值设置为 0。
  3. 将默认值设置为 0 很容易:
    int array[10] = {0};
  4. 但是,对于其他值,您可以使用 memset() 或循环;

例子:

int array[10];
memset(array,-1, 10 *sizeof(int));
  1. If your array is declared as static or is global, all the elements
    in the array already have default default value 0.
  2. Some compilers set array's the default to 0 in debug mode.
  3. It is easy to set default to 0 :
    int array[10] = {0};
  4. However, for other values, you have use memset() or loop;

example:

int array[10];
memset(array,-1, 10 *sizeof(int));
风吹雨成花 2024-07-13 20:44:27

没有人提到访问初始化数组的元素的索引顺序。 我的示例代码将给出一个说明性示例。

#include <iostream>

void PrintArray(int a[3][3])
{
    std::cout << "a11 = " << a[0][0] << "\t\t" << "a12 = " << a[0][1] << "\t\t" << "a13 = " << a[0][2] << std::endl;
    std::cout << "a21 = " << a[1][0] << "\t\t" << "a22 = " << a[1][1] << "\t\t" << "a23 = " << a[1][2] << std::endl;
    std::cout << "a31 = " << a[2][0] << "\t\t" << "a32 = " << a[2][1] << "\t\t" << "a33 = " << a[2][2] << std::endl;
    std::cout << std::endl;
}

int wmain(int argc, wchar_t * argv[])
{
    int a1[3][3] =  {   11,     12,     13,     // The most
                        21,     22,     23,     // basic
                        31,     32,     33  };  // format.

    int a2[][3] =   {   11,     12,     13,     // The first (outer) dimension
                        21,     22,     23,     // may be omitted. The compiler
                        31,     32,     33  };  // will automatically deduce it.

    int a3[3][3] =  {   {11,    12,     13},    // The elements of each
                        {21,    22,     23},    // second (inner) dimension
                        {31,    32,     33} };  // can be grouped together.

    int a4[][3] =   {   {11,    12,     13},    // Again, the first dimension
                        {21,    22,     23},    // can be omitted when the 
                        {31,    32,     33} };  // inner elements are grouped.

    PrintArray(a1);
    PrintArray(a2);
    PrintArray(a3);
    PrintArray(a4);

    // This part shows in which order the elements are stored in the memory.
    int * b = (int *) a1;   // The output is the same for the all four arrays.
    for (int i=0; i<9; i++)
    {
        std::cout << b[i] << '\t';
    }

    return 0;
}

输出是:

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

11      12      13      21      22      23      31      32      33

Nobody has mentioned the index order to access the elements of the initialized array. My example code will give an illustrative example to it.

#include <iostream>

void PrintArray(int a[3][3])
{
    std::cout << "a11 = " << a[0][0] << "\t\t" << "a12 = " << a[0][1] << "\t\t" << "a13 = " << a[0][2] << std::endl;
    std::cout << "a21 = " << a[1][0] << "\t\t" << "a22 = " << a[1][1] << "\t\t" << "a23 = " << a[1][2] << std::endl;
    std::cout << "a31 = " << a[2][0] << "\t\t" << "a32 = " << a[2][1] << "\t\t" << "a33 = " << a[2][2] << std::endl;
    std::cout << std::endl;
}

int wmain(int argc, wchar_t * argv[])
{
    int a1[3][3] =  {   11,     12,     13,     // The most
                        21,     22,     23,     // basic
                        31,     32,     33  };  // format.

    int a2[][3] =   {   11,     12,     13,     // The first (outer) dimension
                        21,     22,     23,     // may be omitted. The compiler
                        31,     32,     33  };  // will automatically deduce it.

    int a3[3][3] =  {   {11,    12,     13},    // The elements of each
                        {21,    22,     23},    // second (inner) dimension
                        {31,    32,     33} };  // can be grouped together.

    int a4[][3] =   {   {11,    12,     13},    // Again, the first dimension
                        {21,    22,     23},    // can be omitted when the 
                        {31,    32,     33} };  // inner elements are grouped.

    PrintArray(a1);
    PrintArray(a2);
    PrintArray(a3);
    PrintArray(a4);

    // This part shows in which order the elements are stored in the memory.
    int * b = (int *) a1;   // The output is the same for the all four arrays.
    for (int i=0; i<9; i++)
    {
        std::cout << b[i] << '\t';
    }

    return 0;
}

The output is:

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

11      12      13      21      22      23      31      32      33
半葬歌 2024-07-13 20:44:27

抛开所有的争论,简短的答案是,如果你在编译时打开优化,你不会做得比这更好:

int i,value=5,array[1000]; 
for(i=0;i<1000;i++) array[i]=value; 

额外的好处:代码实际上是清晰的:)

Cutting through all the chatter, the short answer is that if you turn on optimization at compile time you won't do better than this:

int i,value=5,array[1000]; 
for(i=0;i<1000;i++) array[i]=value; 

Added bonus: the code is actually legible :)

白昼 2024-07-13 20:44:27

我知道用户 Tarski 以类似的方式回答了这个问题,但我添加了更多细节。 请原谅我的一些 C 语言,因为我对它有点生疏,因为我更倾向于使用 C++,但就这样了。


如果您提前知道数组的大小...

#include <stdio.h>

typedef const unsigned int cUINT;
typedef unsigned int UINT;

cUINT size = 10;
cUINT initVal = 5;

void arrayInitializer( UINT* myArray, cUINT size, cUINT initVal );
void printArray( UINT* myArray ); 

int main() {        
    UINT myArray[size]; 
    /* Not initialized during declaration but can be
    initialized using a function for the appropriate TYPE*/
    arrayInitializer( myArray, size, initVal );

    printArray( myArray );

    return 0;
}

void arrayInitializer( UINT* myArray, cUINT size, cUINT initVal ) {
    for ( UINT n = 0; n < size; n++ ) {
        myArray[n] = initVal;
    }
}

void printArray( UINT* myArray ) {
    printf( "myArray = { " );
    for ( UINT n = 0; n < size; n++ ) {
        printf( "%u", myArray[n] );

        if ( n < size-1 )
            printf( ", " );
    }
    printf( " }\n" );
}

上面有一些注意事项; 其一是 UINT myArray[size]; 在声明时并未直接初始化,但是下一个代码块或函数调用确实将数组的每个元素初始化为您想要的相同值。 另一个需要注意的是,您必须为您将支持的每种类型编写一个初始化函数,并且还必须修改printArray() > 支持这些类型的函数。


您可以使用此处找到的在线编译器尝试此代码。

I know that user Tarski answered this question in a similar manner, but I added a few more details. Forgive some of my C for I'm a bit rusty at it since I'm more inclined to want to use C++, but here it goes.


If you know the size of the array ahead of time...

#include <stdio.h>

typedef const unsigned int cUINT;
typedef unsigned int UINT;

cUINT size = 10;
cUINT initVal = 5;

void arrayInitializer( UINT* myArray, cUINT size, cUINT initVal );
void printArray( UINT* myArray ); 

int main() {        
    UINT myArray[size]; 
    /* Not initialized during declaration but can be
    initialized using a function for the appropriate TYPE*/
    arrayInitializer( myArray, size, initVal );

    printArray( myArray );

    return 0;
}

void arrayInitializer( UINT* myArray, cUINT size, cUINT initVal ) {
    for ( UINT n = 0; n < size; n++ ) {
        myArray[n] = initVal;
    }
}

void printArray( UINT* myArray ) {
    printf( "myArray = { " );
    for ( UINT n = 0; n < size; n++ ) {
        printf( "%u", myArray[n] );

        if ( n < size-1 )
            printf( ", " );
    }
    printf( " }\n" );
}

There are a few caveats above; one is that UINT myArray[size]; is not directly initialized upon declaration, however the very next code block or function call does initialize each element of the array to the same value you want. The other caveat is, you would have to write an initializing function for each type you will support and you would also have to modify the printArray() function to support those types.


You can try this code with an online complier found here.

何止钟意 2024-07-13 20:44:27

对于延迟初始化(即类成员构造函数初始化)请考虑:

int a[4];

unsigned int size = sizeof(a) / sizeof(a[0]);
for (unsigned int i = 0; i < size; i++)
  a[i] = 0;

For delayed initialization (i.e. class member constructor initialization) consider:

int a[4];

unsigned int size = sizeof(a) / sizeof(a[0]);
for (unsigned int i = 0; i < size; i++)
  a[i] = 0;
无妨# 2024-07-13 20:44:27

如果预先知道数组的大小,则可以使用 Boost 预处理器 C_ARRAY_INITIALIZE 宏来为您完成这项肮脏的工作:

#include <boost/preprocessor/repetition/enum.hpp>
#define C_ARRAY_ELEMENT(z, index, name) name[index]
#define C_ARRAY_EXPAND(name,size) BOOST_PP_ENUM(size,C_ARRAY_ELEMENT,name)
#define C_ARRAY_VALUE(z, index, value) value
#define C_ARRAY_INITIALIZE(value,size) BOOST_PP_ENUM(size,C_ARRAY_VALUE,value)

If the size of the array is known in advance, one could use a Boost preprocessor C_ARRAY_INITIALIZE macro to do the dirty job for you:

#include <boost/preprocessor/repetition/enum.hpp>
#define C_ARRAY_ELEMENT(z, index, name) name[index]
#define C_ARRAY_EXPAND(name,size) BOOST_PP_ENUM(size,C_ARRAY_ELEMENT,name)
#define C_ARRAY_VALUE(z, index, value) value
#define C_ARRAY_INITIALIZE(value,size) BOOST_PP_ENUM(size,C_ARRAY_VALUE,value)
旧伤还要旧人安 2024-07-13 20:44:27

用零初始化 -

  char arr[1000] = { 0 };

最好使用普通的“for 循环”来初始化除 0 以外的值。

  char arr[1000];
  for(int i=0; i<arr.size(); i++){
     arr[i] = 'A';
  }

To initialize with zeros -

  char arr[1000] = { 0 };

It is better to do with normal "for loop" for initialing other than 0.

  char arr[1000];
  for(int i=0; i<arr.size(); i++){
     arr[i] = 'A';
  }
够运 2024-07-13 20:44:27

正如克莱门斯·西拉夫(Clemens Sielaff)的回答的后续行动。 此版本需要 C++17。

template <size_t Cnt, typename T>                                               
std::array<T, Cnt> make_array_of(const T& v)                                           
{                                                                               
    return []<size_t... Idx>(std::index_sequence<Idx...>, const auto& v)        
    {                                                                           
        auto identity = [](const auto& v, size_t) { return v; };                
        return std::array{identity(v, Idx)...};                                 
    }                                                                           
    (std::make_index_sequence<Cnt>{}, v);                                       
}

您可以在此处查看其实际效果。

Just as a follow up of the answer of Clemens Sielaff. This version requires C++17.

template <size_t Cnt, typename T>                                               
std::array<T, Cnt> make_array_of(const T& v)                                           
{                                                                               
    return []<size_t... Idx>(std::index_sequence<Idx...>, const auto& v)        
    {                                                                           
        auto identity = [](const auto& v, size_t) { return v; };                
        return std::array{identity(v, Idx)...};                                 
    }                                                                           
    (std::make_index_sequence<Cnt>{}, v);                                       
}

You can see it in action here.

幼儿园老大 2024-07-13 20:44:27

方法一:

int a[5] = {3,3,3,3,3}; 

形式化初始化技术。

方法2:

int a[100] = {0};

但值得注意的是,

int a[10] = {1}; 

不会将所有值初始化为 1

则这种初始化方式专门用于 0 ,因此它总是首选这样做

如果您只是执行

int a[100];

某些编译器倾向于采用垃圾值的操作,

int a[1000] = {0};

method 1 :

int a[5] = {3,3,3,3,3}; 

formal initialization technique.

method 2 :

int a[100] = {0};

but its worth to note that

int a[10] = {1}; 

doesn't initialize all values to 1

this way of initialization exclusively for 0

if you just do

int a[100];

some compilers tend to take garbage value hence its always preferred to do

int a[1000] = {0};
臻嫒无言 2024-07-13 20:44:27

我想说,指定的初始化器是迄今为止最好的解决方案,但有一种特殊情况无法应用它们:

  1. 您必须使用事先不知道的配置大小来初始化数组; 并且
  2. 数组的元素不应为零; 并且
  3. 由于某种原因你不能使用 gcc 语法。

如果允许使用宏,则可以使用预处理器。

// macros.h
#define INDEX_SEQUENCE(X) _indexseq_expand(X)
#define _indexseq_expand(X) _indeseq_concat(_indexseq, X)

#define _indexseq_concat(a, b) _indexseq_concat_expand(a, b)
#define _indexseq_concat_expand(a, b) a##b

#define _indexseq1 0
#define _indexseq2 _indexseq1, 1
// generate as above to a given max size

#define APPLY_FOR_EACH(macro, ...) _foreach(macro, _vaargsn(__VA_ARGS__), __VA_ARGS__)
#define _foreach(macro, n, ...) _foreach_concat(_foreach, n)(macro, __VA_ARGS__)

#define _foreach_concat(a, b) _foreach_concat_expand(a, b)
#define _foreach_concat_expand(a, b) a##b

#define _foreach1(macro, i) macro(i)
#define _foreach2(macro, i, ...) macro(i) _foreach1(__VA_ARGS__)
// generate as above to a given max size

#define _vaargsn(...) _vaargsnpp(__VA_ARGS__, _vaargsnidx())
// macros below shall be generated as well until a given max size
#define _vaargsnpp(_1, _2, _3, N, ...) N
#define _vaargsnidx() 3, 2, 1

然后,您可以这样初始化数组:

#define CONFIGURED_SIZE 42

struct complex_struct {
    int zero, one;
    float pi;
    unsigned index;
};

#define INIT(I) { 0, 1, 3.14159f, I },
struct complex_struct array[CONFIGURED_SIZE] = {
    APPLY_FOR_EACH(INIT, INDEX_SEQUENCE(CONFIGURED_SIZE))
};

限制:

  • 编译器的预处理器宏扩展的大小有限
  • CONFIGURED_SIZE 应为纯整数,不允许使用表达式或后缀

I'd say that designated initializers are the best solution so far but there is a corner case where they can't be applied:

  1. you have to initialize an array with configured size which you don't know in advance; and
  2. the elements of your array shall not be zero; and
  3. you can't use gcc syntax, for a reason or another.

You can use the preprocessor, if you are allowed to use macros.

// macros.h
#define INDEX_SEQUENCE(X) _indexseq_expand(X)
#define _indexseq_expand(X) _indeseq_concat(_indexseq, X)

#define _indexseq_concat(a, b) _indexseq_concat_expand(a, b)
#define _indexseq_concat_expand(a, b) a##b

#define _indexseq1 0
#define _indexseq2 _indexseq1, 1
// generate as above to a given max size

#define APPLY_FOR_EACH(macro, ...) _foreach(macro, _vaargsn(__VA_ARGS__), __VA_ARGS__)
#define _foreach(macro, n, ...) _foreach_concat(_foreach, n)(macro, __VA_ARGS__)

#define _foreach_concat(a, b) _foreach_concat_expand(a, b)
#define _foreach_concat_expand(a, b) a##b

#define _foreach1(macro, i) macro(i)
#define _foreach2(macro, i, ...) macro(i) _foreach1(__VA_ARGS__)
// generate as above to a given max size

#define _vaargsn(...) _vaargsnpp(__VA_ARGS__, _vaargsnidx())
// macros below shall be generated as well until a given max size
#define _vaargsnpp(_1, _2, _3, N, ...) N
#define _vaargsnidx() 3, 2, 1

You can then initialize your array as such:

#define CONFIGURED_SIZE 42

struct complex_struct {
    int zero, one;
    float pi;
    unsigned index;
};

#define INIT(I) { 0, 1, 3.14159f, I },
struct complex_struct array[CONFIGURED_SIZE] = {
    APPLY_FOR_EACH(INIT, INDEX_SEQUENCE(CONFIGURED_SIZE))
};

Limitations:

  • limited size of preprocessor macro expansion of your compiler
  • CONFIGURED_SIZE shall be a plain integer, no expressions are allowed nor suffixes
内心荒芜 2024-07-13 20:44:27

回到过去(我并不是说这是一个好主意),我们设置第一个元素,然后:

memcpy (&element [1], &element [0], sizeof (element) -sizeof (element [0]);

甚至不确定它是否还能工作(这取决于 memcpy 的实现),但它通过重复将初始元素复制到下一个元素来工作 - 甚至适用于结构数组。

Back in the day (and I'm not saying it's a good idea), we'd set the first element and then:

memcpy (&element [1], &element [0], sizeof (element)-sizeof (element [0]);

Not even sure it would work any more (that would depend on the implementation of memcpy) but it works by repeatedly copying the initial element to the next - even works for arrays of structures.

吃→可爱长大的 2024-07-13 20:44:27

我认为问题中没有要求,因此解决方案必须是通用的:初始化未指定的可能多维数组,该数组由具有初始成员值的未指定的可能结构元素构建:

#include <string.h> 

void array_init( void *start, size_t element_size, size_t elements, void *initval ){
  memcpy(        start,              initval, element_size              );
  memcpy( (char*)start+element_size, start,   element_size*(elements-1) );
}

// testing
#include <stdio.h> 

struct s {
  int a;
  char b;
} array[2][3], init;

int main(){
  init = (struct s){.a = 3, .b = 'x'};
  array_init( array, sizeof(array[0][0]), 2*3, &init );

  for( int i=0; i<2; i++ )
    for( int j=0; j<3; j++ )
      printf("array[%i][%i].a = %i .b = '%c'\n",i,j,array[i][j].a,array[i][j].b);
}

结果:

array[0][0].a = 3 .b = 'x'
array[0][1].a = 3 .b = 'x'
array[0][2].a = 3 .b = 'x'
array[1][0].a = 3 .b = 'x'
array[1][1].a = 3 .b = 'x'
array[1][2].a = 3 .b = 'x'

编辑:start+element_size更改为(char*)开始+元素大小

I see no requirements in the question, so the solution must be generic: initialization of an unspecified possibly multidimensional array built from unspecified possibly structure elements with an initial member value:

#include <string.h> 

void array_init( void *start, size_t element_size, size_t elements, void *initval ){
  memcpy(        start,              initval, element_size              );
  memcpy( (char*)start+element_size, start,   element_size*(elements-1) );
}

// testing
#include <stdio.h> 

struct s {
  int a;
  char b;
} array[2][3], init;

int main(){
  init = (struct s){.a = 3, .b = 'x'};
  array_init( array, sizeof(array[0][0]), 2*3, &init );

  for( int i=0; i<2; i++ )
    for( int j=0; j<3; j++ )
      printf("array[%i][%i].a = %i .b = '%c'\n",i,j,array[i][j].a,array[i][j].b);
}

Result:

array[0][0].a = 3 .b = 'x'
array[0][1].a = 3 .b = 'x'
array[0][2].a = 3 .b = 'x'
array[1][0].a = 3 .b = 'x'
array[1][1].a = 3 .b = 'x'
array[1][2].a = 3 .b = 'x'

EDIT: start+element_size changed to (char*)start+element_size

蓝梦月影 2024-07-13 20:44:27
#include<stdio.h>
int main(){
int i,a[50];
for (i=0;i<50;i++){
    a[i]=5;// set value 5 to all the array index
}
for (i=0;i<50;i++)
printf("%d\n",a[i]);
   return 0;
}

它将给出 o/p 5 5 5 5 5 5 ...... 直到整个数组的大小

#include<stdio.h>
int main(){
int i,a[50];
for (i=0;i<50;i++){
    a[i]=5;// set value 5 to all the array index
}
for (i=0;i<50;i++)
printf("%d\n",a[i]);
   return 0;
}

It will give the o/p 5 5 5 5 5 5 ...... till the size of whole array

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文