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

我发誓我曾经知道一个简单的方法。在我的情况下,我可以使用memset(),但没有一种方法来做到这一点,这是建立在C语法?


当前回答

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

#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

其他回答

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

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

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

除非该值为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。 C在C23之前是不允许的:

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

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

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

而“0”并不一定意味着“全位零”,所以使用上面的是 比memset()更好、更可移植。(浮点值将是 初始化为+0,指向空值,等等)

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

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

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

我在这个问题中没有看到任何要求,所以解决方案必须是通用的:初始化一个未指定的可能是多维数组,由一个初始成员值的未指定的可能是结构元素构建:

#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*)start+element_size

我知道用户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()函数以支持这些类型。


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