配列のすべてのメンバーを同じ値に初期化する方法は?


968

Cに大きな配列があります(違いがある場合はC ++ではありません)。同じ値のすべてのメンバーを初期化したい。

私はかつてこれを行う簡単な方法を知っていたと誓うことができました。memset()私の場合は使用できますが、C構文に組み込まれている方法はありませんか?


16
これまでのところ、C99以上で実行可能な指定された初期化子表記については、どの回答にも言及していません。例:enum { HYDROGEN = 1, HELIUM = 2, CARBON = 6, NEON = 10, … };およびstruct element { char name[15]; char symbol[3]; } elements[] = { [NEON] = { "Neon", "Ne" }, [HELIUM] = { "Helium", "He" }, [HYDROGEN] = { "Hydrogen", "H" }, [CARBON] = { "Carbon", "C" }, … };。省略記号を削除すると、これらのフラグメントはC99またはC11でコンパイルされます。
Jonathan Leffler、2014年

実際にabelenkyの答えは、指定された初期化子を使用していますが、完全に形成された初期化コードではありません
Rob11311

memset()は役立ちますが、値によって異なります。
Nick

2
memset()具体的な議論は:stackoverflow.com/questions/7202411/...私はそれだけで0のために働くと思う
チロSantilli冠状病毒审查六四事件法轮功

回答:


1239

その値が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 では許可されいません

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

初期化子が指定されていない場合、静的ストレージ期間のオブジェクトは0に初期化されることに注意してください。

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

そして、その「0」は必ずしも「すべてのビットがゼロ」を意味するわけではないため、上記を使用するほうがmemset()よりも優れており、移植性が高くなります。(浮動小数点値は+ 0、null値へのポインターなどに初期化されます)


27
C ++標準を読んで、int array [10] = {};を実行することもできます。ゼロに初期化します。これが有効なCであることを確認するC標準がありません。
workmad3 2008年

54
セクション6.7.8 C99標準の初期化を見ると、空の初期化リストが許可されているようには見えません。
Jonathan Leffler、

7
C99には、構造と配列の初期化のための素晴らしい機能がたくさんあります。それにはない(ただし、Fortran IV、1966年にあった)機能の1つは、配列の特定の初期化子を繰り返す方法です。
ジョナサンレフラー、

8
@CetinSert:それが機能しないとはどういう意味ですか?これは、この答えが行うべきことを正確に実行します。それはあなたのコードのコメントが言うことをしませんが、そのコメントは間違っています。
ベンジャミンリンドリー2013

9
@CetinSert:そのコメントで、すべての要素が-1に設定されると主張したのはあなただけです。この答えは、正しく、すべての指定されていない要素がゼロに設定されることを主張しています。コードの結果はこの主張と一致しています。
Benjamin Lindley 2013

394

コンパイラがGCCの場合、次の構文を使用できます。

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

詳細な説明を確認してくださいhttp : //gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html


12
そして、その構文により、コンパイルされたバイナリのファイルサイズが大幅に増加します。N = 65536(1024ではなく)の場合、バイナリのサイズが15 KBから270 KBにジャンプします。
Cetin Sert 2013年

50
@CetinSertコンパイラは、int静的データ(256 K)に65536 秒を追加する必要があります。これは、実際に確認したサイズの増加です。
qrdl 2013年

15
@CetinSertなぜ私は?これは標準的なコンパイラの動作であり、指定されたイニシャライザに固有ではありません。同じintように、静的に65536 秒を初期化int foo1 = 1, foo2 = 1, ..., foo65536 =1;すると、同じサイズが増加します。
qrdl 2013年

27
さらに良い: "int array [] = {[0 ... 1023] = 5}"、配列のサイズは自動的に1024に設定され、変更がより簡単で安全です。
フランソワ

4
@Francoisまたは2D配列のbool array[][COLS] = { [0...ROWS-1][0...COLS-1] = true}場合、完全な形式よりも読みやすいかどうかはわかりません。
g33kz0r 2013

178

複数のコピーと貼り付けなしで、同じ値で大きな配列を静的に初期化するには、マクロを使用できます。

#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 };

値を変更する必要がある場合は、1か所のみで交換を行う必要があります。

編集:考えられる便利な拡張機能

ジョナサンレフラーの礼儀)

これは次のように簡単に一般化できます。

#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) };

マクロ名は交渉可能です。


12
私はこれを極端な場合にのみ考慮します、確かにmemsetはそれを表現するよりエレガントな方法です。
u0b34a0f6ae 2009年

47
データをROM対応にする必要がある場合、memsetは使用できません。
ファルケン教授の契約が2010

9
プリプロセッサは実際には#definesからコードを生成します。配列の次元が大きくなると、実行可能サイズが大きくなります。しかし、間違いなく+アイデアのために;)
Leonid

7
@Alcott、古いコンピューター、そして多くの組み込みシステムでは、コードは最終的にEPROMまたはROMに配置されます。ROM対応とは、組み込みシステムでは「コードをフラッシュに書き込む」ことも意味するようになりました。これは、メモリにランタイムを書き込むことができないというほぼ同じ意味があるためです。つまり、メモリを更新または変更するmemsetまたはその他の命令は使用できません。ただし、定数は、プログラムを開始する前に表現およびフラッシュまたはROM化することができます。
ファルケン教授の契約が

4
@ u0b34a0f6ae:VAL_1Xが単一の整数ではなくリストの場合も、このメソッドを使用できることに注意してください。移行可能な状態と同様に、これは、EEPROMまたはフラッシュメモリの初期値を定義する組み込みシステムでの方法でもあります。どちらの場合も使用できませんmemset()
Martin Scharrer、2013

63

配列のすべてのメンバーが明示的に初期化されるようにするには、宣言から次元を省略します。

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} };

ではありません。


これは正しいです ?int myPoints[10][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };
Praveen Gowda IV 2012年4

10
いいえ。許可されていない最も内側の次元を省略しています。これにより、コンパイラエラーが発生します。
フランクSzczerba

4
初期化子と長さの推論の両方がC99で導入されました。
Palec、2014年

3
@Palec:いいえ—長さの推論は、先行標準のCの時代からCで行われています(K&R 1st Editionが公開されてから、おそらくそれより少し前です)。指定イニシャライザはC99の新機能ですが、これは指定イニシャライザを使用していません。
ジョナサンレフラー、2017

53

この構文を使用するコードをいくつか見ました。

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)
};   

これにより、enum-valueの一部が順不同で記述された場合でも、物事の順序が保持されます。

このテクニックの詳細については、こちらこちらをご覧ください


8
これはC99初期化構文であり、他の回答の一部ですでにカバーされています。宣言をにしchar const *array[] = { ... };たりchar const * const array[] = { ... };、にしたりすることもできますよね。
ジョナサンレフラー

22
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...

配列のサイズが変更された場合。


12
記録のために、それは基本的にただのより遅く、より冗長なバージョンですmemset(myArray, VALUE, ARRAY_SIZE);
Benson

18
どのようにmemsetを使用して、int配列を255より大きい値に初期化しますか?memsetは、配列がバイトサイズの場合にのみ機能します。
マット

21
@ベンソン:sizeof(int)> sizeof(char)のプラットフォームでは、上記のコードをmemsetに置き換えることはできません。それを試してみてください。
ChrisWue

13

上記のように静的イニシャライザ全体を実行できますが、配列サイズが変更されると(配列が大きくなると、適切な追加のイニシャライザを追加しないとガベージが発生します)、それは本当の厄介です。

memsetは、作業を実行するためのランタイムヒットを提供しますが、配列サイズの変更の影響を受けないコードサイズヒットはありません。配列がたとえば数十の要素よりも大きい場合は、ほとんどすべての場合にこのソリューションを使用します。

配列が静的に宣言されていることが本当に重要な場合は、プログラムを作成してビルドプロセスの一部にするプログラムを作成します。


memset配列の初期化に使用する例をいくつか追加していただけませんか?
ソパラホデアリエーレス

8

ここに別の方法があります:

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拡張機能はいつ使用できますか?

上記のコードサンプルは組み込みシステムにあり、別のコンパイラーからの光を見ることはありません。


6

「通常の」データ型(int配列など)を初期化するには、ブラケット表記を使用できますが、配列にまだスペースがある場合は、最後の値の後に値をゼロにします。

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

5

配列がintであるか、intサイズまたはmemパターンのサイズがintに正確に一致する場合(つまり、すべてゼロまたは0xA5A5A5A5)、memset()を使用するのが最善の方法です。です。

それ以外の場合は、インデックスを移動するループでmemcpy()を呼び出します。


5

ほんの少し舌を出した答え。ステートメントを書く

array = initial_value

お好みの配列対応言語(私はFortranですが、他にもたくさんあります)で、それをCコードにリンクします。おそらくそれをラップして外部関数にしたいと思うでしょう。


4

指定された値で任意のタイプの配列を初期化する高速な方法があります。大規模な配列で非常にうまく機能します。アルゴリズムは次のとおりです。

  • 配列の最初の要素を初期化します(通常の方法)
  • 設定されている部分を設定されていない部分にコピーし、次のコピー操作ごとにサイズを2倍にする

ための1 000 000素子intアレイは規則的なループ初期化(I5、2個のコア、2.3GHz帯、4GiBメモリ、64ビット)よりも高速の4倍です。

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;
}

2
申し訳ありませんが、これは真実ではありません。テスト中にコンパイル最適化をオンにするのを忘れたのかもしれません(デバッグモードでテストされましたか?)。これをテストすると、ループはmemfillよりもほぼ常に50%速くなります(マシンの負荷ジッターのため、「常に」)。そして、memset(a、0、sizeof(a));を使用します。ループフィルよりも2倍高速です。
RS1980 2016年

2
ベンチマークコードと同様に、非常に注意する必要があります。ループを追加してタイミングコードを10回実行する(そして配列のサイズを2倍にして20Mにする)ことを示しています—私にとって、macOS Sierra 10.12.3を搭載し、GCC 6.3.0を使用するMacBook Proで実行しています—ループの所要時間は約4600 µs、memfill()コードの所要時間は約1200 µsです。ただし、後続の反復では、ループに約900〜1000 µsかかりますが、memfill()コードには1000〜1300 µsかかります。最初の反復は、おそらくキャッシュを埋める時間に影響されます。テストを逆にすると、memfill()最初は遅い。
ジョナサンレフラー、2017

2

初期化された配列の要素にアクセスするためのインデックスの順序については誰も言及していません。私のサンプルコードは、説明的な例を示しています。

#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

4
<iostream>有効でないCとしてstd::coutstd::cinなどがその一部である、std::namespaceそしてCサポートしていませんnamespaces。代わりに使用<stdio.h>してみてくださいprintf(...)
Francis Cugler、

2

すべてのおしゃべりを切り抜けると、簡単に言えば、コンパイル時に最適化をオンにすると、これ以上の効果は得られません。

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

追加ボーナス:コードは実際には読みやすいです:)


7
質問は具体的に初期化を求めました。これは明示的に初期化ではなく、初期化後に割り当てられます。それはすぐに行われるかもしれませんが、それでも初期化ではありません。
アンディ

何度も呼び出される関数内の大規模な静的ルックアップテーブルにはまったく役立ちません。
Martin Bonnerがモニカ

...関数内の静的ルックアップテーブルが元の質問の一部であることを思い出さないでください-単純にしてください。とはいえ、@コミュニティはおそらくそれを釘付けにしたでしょう。
JWDN 2019

1
  1. 配列が静的またはグローバルとして宣言されている場合、配列内のすべての要素には、デフォルトのデフォルト値0がすでにあります。
  2. 一部のコンパイラは、デバッグモードで配列のデフォルトを0に設定します。
  3. デフォルトを0に設定するのは簡単です。intarray [10] = {0};
  4. ただし、他の値については、memset()またはループを使用する必要があります。

例:int array [10]; memset(配列、-1、10 * sizeof(int));


0
#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 ......配列全体のサイズまで


0

ユーザー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" );
}

上記の注意事項がいくつかあります。1つは、UINT myArray[size];宣言時に直接初期化されないことですが、次のコードブロックまたは関数呼び出しは、配列の各要素を必要な同じ値に初期化します。他の注意点は、サポートinitializing functionする各for を作成するtype必要があり、printArray()これらのタイプをサポートするように関数を変更する必要があることです。


ここにあるオンラインコンパイラでこのコードを試すことができます


0

初期化の遅延(つまり、クラスメンバーコンストラクターの初期化)については、以下を考慮してください。

int a[4];

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

0

私は元の質問が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で)作業中コードを見ることができます


-1

私は質問に要件がないので、解決策は一般的である必要があります:初期メンバー値を持つ、指定されていない可能性のある構造要素から構築された、指定されていない可能性のある多次元配列の初期化:

#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


1
これが解決策であるかどうか疑わしい。sizeof(void)が有効かどうかさえわかりません。
Chris Lutz、

3
動作しません。最初の2つだけが初期化され、残りはすべて初期化されません。Mac OS X 10.4でGCC 4.0を使用しています。
dreamlax 2009年

2番目のソースデータがmemcpy()宛先スペースと重複するため、これは未定義の動作を呼び出します。の単純な実装でmemcpy()は機能しますが、システムで機能させる必要はありません。
ジョナサンレフラー2017

-1

昔は(それが良い考えだとは言いませんが)、最初の要素を設定してから、次のようにします。

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

(memcpyの実装に依存する)それが機能するかどうかはわかりませんが、最初の要素を次の要素に繰り返しコピーすることで機能します。構造体の配列でも機能します。


それは確実に機能しません。私見、標準はmemcpy、オーバーラップの場合にボトムアップまたはトップダウンのコピー順序のように指定された機能を提供するはずでしたが、そうではありませんでした。
スーパーキャット

既に述べたように、これは確実に機能しないものでしたが、当時は、文書化されていない機能を回避するよりも効率性に重点を置いていました。メモリーを前方にコピーする方が効率的ですが、仕様に、後方にランダムな順序でコピーしたり、複数のスレッドに分割したりできないと言っているものはありません。memmove()は、干渉なしにコピーする機能を提供します。
マイク

これは別の回答のコードと同等であり、欠陥があります。を使用memmove()しても機能しません。
ジョナサンレフラー

-2

並行して言うと、コンマ演算子を式と組み合わせて使用​​すると、それが可能になると思います。

a[1]=1, a[2]=2, ..., a[indexSize]; 

または、単一の構成で意味する場合は、forループで行うことができます。

for(int index = 0, value = 10; index < sizeof(array)/sizeof(array[0]); index++, value--)
  array[index] = index;

//引数リストのカンマ演算子は、上記の並列演算子ではないことに注意してください。

配列のデクレレーションを初期化できます。

array[] = {1, 2, 3, 4, 5};

malloc / calloc / sbrk / alloca / etcを呼び出して、ストレージの固定領域をオブジェクトに割り当てることができます。

int *array = malloc(sizeof(int)*numberOfListElements/Indexes);

次の方法でメンバーにアクセスします。

*(array + index)

等。


カンマ演算子は、通常、左から右への評価を保証します。式に副作用がない場合、操作を並列化することは可能かもしれませんが、コンパイラがそうすることは珍しいでしょう。
ジョナサンレフラー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.