質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.83%

  • C

    3351questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • C++

    3148questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

C言語のしょうもない質問です。

解決済

回答 5

投稿

  • 評価
  • クリップ 0
  • VIEW 313

syoshinsha

score 17

前提・実現したいこと

しょうもない質問だったらすみません。初期化する理由って初期化しないと変数に不定な値が入るからですよね。だったら、初期化するときに変数に変数を代入するのって、あまりよろしくないんですか?なんか変数って名前見る限り安定してなくて、代入した変数がおかしかったら、動作不安定になりそうじゃない?

例えば

/*なんかよくわからないけど個人的に不安*/
static int a = b;
/*なんかよくわからないけど個人的にこっちの方が安全そうに見える*/
static int a = 0;
a = b;
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

+3

こんにちは。

初期化する理由って初期化しないと変数に不定な値が入るからですよね。

その通りですね。
初期化していないローカル変数を持つ関数の振る舞いは呼び出す度に異なるかも知れませんが、期待したとおりに動作することもあります。
そして、ある日、不定なローカル変数の値が嫌な値になり、期待はずれの動作をしバグが顕在化するのです。しかも再現性がありません。

更に、プログラマはテストした時にその関数は正常に動作しているので、まさかそこが原因と思わず、関係ないところばかりデバッグし、直したつもりで直ってないままリリースするわけです。そして「直ってないじゃないか!!」と怒られます。マジ、いやなシナリオです。

だったら、初期化するときに変数に変数を代入するのって、あまりよろしくないんですか?

ですので、初期化した変数を代入したのであれば、上記シナリオを回避出来ますから一安心です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/18 23:02

    回答ありがとうございました。たしかに初期化しておくとバグの箇所が特定しやすくていいと思いました。

    キャンセル

checkベストアンサー

+2

広い意味で初期化とは、語弊を恐れずに言えば、プログラマからみて、変数の状態がわかるようにすることです。

しかし、厳密には初期化とは変数の定義時に値を設定することを指します。

int a = 0;//初期化
a = b;//代入

なのでa = bは初期化ではなく代入になります。


ところで変数にstaticがついている時は、明示的な初期化がない場合、0初期化されると規格に定められています。

どこで定められているかというと、C11規格書には

§6.7.9 Initialization
10 If an object that has automatic storage duration is not initialized explicitly, its value is
indeterminate. If an object that has static or thread storage duration is not initialized explicitly, then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules,
and any padding is initialized to zero bits;
— if it is a union, the first named member is initialized (recursively) according to these
rules, and any padding is initialized to zero bits;

のように書かれているんですね。

つまり、

static int v1 = 2;//明示的に初期化されている。値は2
static int v2;//明示的に初期化されていない。値は0

となり、値は不定じゃないんですね。


あああ、C++に毒されていた。

そういえばCはstatic変数とconst修飾されている変数は別として(volatile修飾のときの扱いは忘れた)、変数の定義と同時じゃなくても最初の代入まで初期化という扱いでしたね、ちくせう。

static int n1;//非明示的初期化
n1 = 2;//代入
static int n2;//非明示的初期化
int main(void)
{
    int a;
    a = 3;//Cだとこれも初期化

    const int b = 0;//const修飾されているときは定義と同時にしか初期化できない

    n2 = 3;//代入

    return 0;
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/18 22:52

    さまざまな意見がありましたが、一番早かったのでベストアンサーとさせていただきました。ほかの人の意見も踏まえて考えたところ、こういうものにはケースバイケースな部分もあると思ったので、自分自身でプログラムの勉強をしていきながら判断していこうと思います。回答ありがとうございました。

    キャンセル

+2

質問者の方の発想は、素朴ではあるけど、別にそんなおかしくないと思います。
というよりむしろ、筋の良い感覚だと思います。と、擁護する回答も書いてみます。


「変数は変化するから、不安定じゃないの?」という疑問を突き詰めていくと、
関数型プログラミング参照透過という考え方にたどり着きます。
不変にできる変数は、なるべく不変にしよう、というやり方です。

質問文は初期化の話だけですが、関数型では、
初期化したらなるべく再代入しない、というのが推奨されています。

もちろん、いきなり関数型(言語)に取り組むのは難しいと思いますが、
考え方として知っておくだけでも、将来的に筋が良い伸び方をすると思います。


それから、変数の初期化だけとっても、
言語によって、場合によっては、null(nil)になったりするので、
Cの仕様から見るとやや冗長な記述でも、
なるべく変数を初期化しておくのは、そんな悪い習慣ではないと思います。

効率性より移植性」というやつで、
言語仕様の知識を駆使して、冗長性を排除すれば、行数や字数が多少短くなっても、
他言語に移植したとたん、バグになったり、移植しにくかったりするので、
決め打ちできるところは、決め打ちしておく」素直なコードの方が良いです。

具体的に言うと、たとえば、「変数がゼロに初期化される仕様と、
IF文でゼロが偽であることを利用して、未初期化を判定する」とか、
色々な要素を駆使すると、他言語に移すときなどに分かりづらい。

移植先の言語では「空の文字列も暗黙の型変換でゼロに変換される(PHP)」から……
なんて、トリッキーなことをやりだすと、実際のコードでは想像するより複雑化します。

そういう凝ったことは、少なくとも慣れないうちは、手を出さない方が良いです。
それより素直に「a = 0」に初期化するコードの方が、追いやすく、直しやすくて好きです。
読みやすさ、分かりやすさ、安定性、を主な基準にして書くのがオススメです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/18 23:07

    回答ありがとうございました。たしかに言語によって使用が微妙に異なる場合があるので移植することを考えれば、多少長くなっても確実なプログラムを書いたほうがバグとかで困らなくてよさそうですね。

    キャンセル

0

初期化されていない変数で初期化するのは初期化の意味がありませんね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/18 22:54

    回答ありがとうございます。説明不足ですみませんでした。

    キャンセル

0

宣言時に初期化する理由としては、
・初回の代入をコンパクトに書きたい
・宣言時にしか書けない書式がある
(C だと、int x[3] = {1,2,3};とは書けるが、宣言以外だと代入を3つ書かないといけない)
など。

初期化しないと変数に不定な値が入るから

はちょっとずれた感じです。

個人的には、宣言と代入は分けて書きたいので、

static int a;
a = b;


と書きますね。それ以降は代入しない定数的な変数は別。

あと、2つ目のコードは、直後にaに代入するのに、宣言で= 0するのは無意味。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/18 22:58

    回答ありがとうございました。たしかに直後にaを代入するならあまり意味がないですね。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.83%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C

    3351questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • C++

    3148questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。