How to initialize all members of an array to the same value?

后端 未结 23 1814
清歌不尽
清歌不尽 2020-11-21 04:34

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

相关标签:
23条回答
  • 2020-11-21 05:23

    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.

    0 讨论(0)
  • 2020-11-21 05:26

    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.

    0 讨论(0)
  • 2020-11-21 05:26

    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;
    }
    
    0 讨论(0)
  • 2020-11-21 05:26

    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
    
    0 讨论(0)
  • 2020-11-21 05:27

    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.

    0 讨论(0)
提交回复
热议问题