C ++を使用して複数の変数を1行で宣言および定義するにはどうすればよいですか?


172

私はいつもこれらの3つの変数を宣言した場合、それらはすべて値0になることを

int column, row, index = 0;

しかし、インデックスだけがゼロに等しく、他は844553や2423445のようにジャンクであることがわかりました。

新しい行で各変数を宣言せずに、これらのすべての変数をゼロに初期化するにはどうすればよいですか?


36
これらの1行の多変数宣言には注意してください。通常の整数のリストが続くintポインターを宣言することは、思ったよりも簡単です(int* a, b, c;見た目と同じことはしません)。
Chris Eberle

4
=0定義には、3つだけの変数があります。そして、本当に多くの変数が必要な場合は、配列を試してください。int a[10]={0}それぞれa[i]が0に初期化されます。
2011

コンパイラは、合理的なプログラマが期待する動作とは異なる動作をする場合、その構造を許可してはなりません... imho
cph2117

1
@ cph2117妥当なプログラマは、「うーん、この構文は文法がどのようにバインドされているかに応じていくつかの異なることを意味する可能性がある」と考え、標準を調べてどちらが正しいかを見つけ、それを続行します。
underscore_d 2017年

これをやめる。コードを読みにくくするだけです。高水準言語でコードを書くことのポイントは、メンテナが簡単に読めるようにすることです。
マーティンヨーク

回答:



161

宣言するとき:

int column, row, index = 0;

インデックスのみがゼロに設定されます。

ただし、以下を実行できます。

int column, row, index;
column = index = row = 0;

しかし個人的に私は指摘されている以下を好む。
私の見解では、これはより読みやすい形式です。

int column = 0, row = 0, index = 0;

または

int column = 0;
int row = 0;
int index = 0;

3
最後の2つの間で、2つの値が本当に同じ型である必要があるか(bool previousInputValue, presentInputValue;)、またはたまたま同じ型である必要があるかどうかに基づいて決定しますが、実際にそうである必要はありません(将来的には変更uint8_t height, width;uint8_t height; uint16_t width;れる可能性があり、uint8_t height; uint8_t width;はじめに)。
altendky 2015年

uint8_t height; uint16_t width;代わりに書くことはuint8_t height, width;将来10文字を節約するからです。:-)もちろん、好きなようにそれを行うことができます。簡単に読めるようにしてください。したがって、最後の形式が最も明示的です。
マット

最後の形式は、各変数の型を示し、各変数が初期化されていることを明確にする点で、最も明確です。とはいえ、列と行が同じ型であると予想されるかどうかは明示されていません。多分私達は両方の明示性を好むでしょうint presentValue = 0; typeof(presentValue) previousValue = presentValue;が、私はそれtypeof()が非標準のGCC拡張であると信じています。
altendky

49

@ジョシュが言ったように、正しい答えは次のとおりです。

int column = 0,
    row = 0,
    index = 0;

ポインタについても同じことを注意する必要があります。この:

int* a, b, c;

以下と同等です。

int *a;
int b;
int c;

34
私はそのポインタのことを嫌います、それは意味がありません。アスタリスクはタイプの一部であるため、すべてに適用する必要があります。場合を想像unsigned long x, y;宣言xとしてunsigned longしかし、y同じようにunsigned、別名unsigned int!それはまったく同じです!</ rant>
カムジャクソン

6
それは理にかなっている。「int * a、b、c;」
Jeroen 2013

7
@JeroenBollenええ、型の代わりに変数名の横にポインタアスタリスクを書くのは理にかなっていますが、それ自体は意味がありません。上で述べたように、アスタリスクは名前の一部ではなく型の一部であるため、型でグループ化する必要があります。
カムジャクソン

11
一方で、実際には、値int *a*a表す手段として、*が必ずしも型の一部であるとは限りませんint
mdenton8 2014年

2
ポイントはすでに作成されていますが、それに追加するだけで基本的に型が欠けていますが、それでもポインタを作成できます。したがって、なぜvoid* aコンパイルされ、void *a, b, cそうならないでしょう。この合理化は私には有効です。
Josh C

24

1行に1つの変数/オブジェクトを宣言すると、この問題が解決されるだけでなく、コードが明確になり、ポインターを宣言する際のばかげた間違いを防ぐことができます。

ただし、質問に直接回答するには、各変数を明示的に0に初期化する必要があります。int a = 0, b = 0, c = 0;


16
int column(0), row(0), index(0);

このフォームは、特にそれらのコンストラクターが複数の引数を取る場合に、カスタムタイプでも機能することに注意してください。


2
そして今日では統一された初期化(C ++ 17がこれを修正するまで保留中auto...):int column { 0 }、row { 0 }、index { 0 } ;
underscore_d


4

可能なアプローチ:

  • すべてのローカル変数をゼロで初期化します。
  • アレイ、memsetまたはアレイを持ってい{0}ます。
  • グローバルまたは静的にします。
  • それらをに入れるかstructmemsetまたはそれらをゼロに初期化するコンストラクターを用意します。

#define COLUMN 0 #define ROW 1 #define INDEX 2 #define AR_SIZE 3 int Data [ AR_SIZE ]; //単なるアイデア。
アジェイ

申し訳ありませんが、答えに「Have a array、memset or {0} the array。」という行を含めたのはなぜですか?
Mateen Ulhaq

memset(データ、0、sizeof(データ)); //これを論理的にパックできる場合。
アジェイ2011

2

私はこれをお勧めしませんが、本当に1行で0を1回だけ書いている場合は、次のようにすることもできます。

int row, column, index = row = column = 0;

0

他の人が述べたように、C ++ 17以降では、複数の変数の割り当てに構造化バインディングを利用できます。

これstd::arrayテンプレート引数の控除を組み合わせると、型や値を繰り返さずに、任意の数の変数に値を割り当てる関数を書くことができます

#include <iostream>
#include <array>

template <int N, typename T> auto assign(T value)
{
    std::array<T, N> out;
    out.fill(value);
    return out;
}

int main()
{
    auto [a, b, c] = assign<3>(1);

    for (const auto& v : {a, b, c})
    {
        std::cout << v << std::endl;
    }

    return 0;
}

Demo


-13

初期化せずに変数を宣言すると、メモリから乱数が選択され、変数はその値に初期化されます。


7
あんまり。コンパイラーは、「この変数はアドレスxxxにある」と決定します。アドレスxxxにあるものを(初期化または割り当てによって)明示的に設定しない限り、何でも初期値になります
pm100

3
@ pm100はより優れてますが、ユーザーへの嫌がらせにつながらない些細な実装にも当てはまります...初期化されていない変数を使用するとUBになるため、理論的にはあらゆるコードを含めて何でも起こります。その変数を使用して、プログラムから単純に取り除かれます-これは、最適化が機能しているときに特に可能性があります。
underscore_d 2016年

1
その変数の値は、それが取得したアドレスにあるもの、つまりジャンクです。
ペドロヴェルネッティ2018

@PedroVernetti新しい変数が宣言されて偶然同じアドレスを取得する前に、指定されたアドレスに何があったかは問題ではありません。ユーザーが値で初期化せずに新しい変数を宣言し、値を割り当てる前に変数を読み取る場合、プログラムは未定義の動作をします。これは「ランダム」や「ジャンク」よりもはるかに悪いため、回避する必要があります。
underscore_d
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.