###前提・実現したいこと
しょうもない質問だったらすみません。初期化する理由って初期化しないと変数に不定な値が入るからですよね。だったら、初期化するときに変数に変数を代入するのって、あまりよろしくないんですか?なんか変数って名前見る限り安定してなくて、代入した変数がおかしかったら、動作不安定になりそうじゃない?
例えば
c
1/*なんかよくわからないけど個人的に不安*/ 2static int a = b;
c
1/*なんかよくわからないけど個人的にこっちの方が安全そうに見える*/ 2static int a = 0; 3a = b;
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答5件
0
質問者の方の発想は、素朴ではあるけど、別にそんなおかしくないと思います。
というよりむしろ、筋の良い感覚だと思います。と、擁護する回答も書いてみます。
「変数は変化するから、不安定じゃないの?」という疑問を突き詰めていくと、
関数型プログラミングの参照透過という考え方にたどり着きます。
不変にできる変数は、なるべく不変にしよう、というやり方です。
質問文は初期化の話だけですが、関数型では、
初期化したらなるべく再代入しない、というのが推奨されています。
もちろん、いきなり関数型(言語)に取り組むのは難しいと思いますが、
考え方として知っておくだけでも、将来的に筋が良い伸び方をすると思います。
それから、変数の初期化だけとっても、
言語によって、場合によっては、**null(nil)**になったりするので、
Cの仕様から見るとやや冗長な記述でも、
なるべく変数を初期化しておくのは、そんな悪い習慣ではないと思います。
「効率性より移植性」というやつで、
言語仕様の知識を駆使して、冗長性を排除すれば、行数や字数が多少短くなっても、
他言語に移植したとたん、バグになったり、移植しにくかったりするので、
「決め打ちできるところは、決め打ちしておく」素直なコードの方が良いです。
具体的に言うと、たとえば、「変数がゼロに初期化される仕様と、
IF文でゼロが偽であることを利用して、未初期化を判定する」とか、
色々な要素を駆使すると、他言語に移すときなどに分かりづらい。
移植先の言語では「空の文字列も暗黙の型変換でゼロに変換される(PHP)」から……
なんて、トリッキーなことをやりだすと、実際のコードでは想像するより複雑化します。
そういう凝ったことは、少なくとも慣れないうちは、手を出さない方が良いです。
それより素直に「a = 0」に初期化するコードの方が、追いやすく、直しやすくて好きです。
読みやすさ、分かりやすさ、安定性、を主な基準にして書くのがオススメです。
投稿2017/12/18 13:28
総合スコア5592
0
こんにちは。
初期化する理由って初期化しないと変数に不定な値が入るからですよね。
その通りですね。
初期化していないローカル変数を持つ関数の振る舞いは呼び出す度に異なるかも知れませんが、期待したとおりに動作することもあります。
そして、ある日、不定なローカル変数の値が嫌な値になり、期待はずれの動作をしバグが顕在化するのです。しかも再現性がありません。
更に、プログラマはテストした時にその関数は正常に動作しているので、まさかそこが原因と思わず、関係ないところばかりデバッグし、直したつもりで直ってないままリリースするわけです。そして「直ってないじゃないか!!」と怒られます。マジ、いやなシナリオです。
だったら、初期化するときに変数に変数を代入するのって、あまりよろしくないんですか?
ですので、初期化した変数を代入したのであれば、上記シナリオを回避出来ますから一安心です。
投稿2017/12/18 12:57
総合スコア23272
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
広い意味で初期化とは、語弊を恐れずに言えば、プログラマからみて、変数の状態がわかるようにすることです。
しかし、厳密には初期化とは変数の定義時に値を設定することを指します。
c
1int a = 0;//初期化 2a = 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;
のように書かれているんですね。
つまり、
c
1static int v1 = 2;//明示的に初期化されている。値は2 2static int v2;//明示的に初期化されていない。値は0
となり、値は不定じゃないんですね。
あああ、C++に毒されていた。
そういえばCはstatic変数とconst修飾されている変数は別として(volatile修飾のときの扱いは忘れた)、変数の定義と同時じゃなくても最初の代入まで初期化という扱いでしたね、ちくせう。
c
1static int n1;//非明示的初期化 2n1 = 2;//代入 3static int n2;//非明示的初期化 4int main(void) 5{ 6 int a; 7 a = 3;//Cだとこれも初期化 8 9 const int b = 0;//const修飾されているときは定義と同時にしか初期化できない 10 11 n2 = 3;//代入 12 13 return 0; 14}
投稿2017/12/18 12:00
編集2017/12/18 12:10総合スコア5850
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/12/18 13:52
0
宣言時に初期化する理由としては、
・初回の代入をコンパクトに書きたい
・宣言時にしか書けない書式がある
(C だと、int x[3] = {1,2,3};
とは書けるが、宣言以外だと代入を3つ書かないといけない)
など。
初期化しないと変数に不定な値が入るから
はちょっとずれた感じです。
個人的には、宣言と代入は分けて書きたいので、
C
1static int a; 2a = b;
と書きますね。それ以降は代入しない定数的な変数は別。
あと、2つ目のコードは、直後にa
に代入するのに、宣言で= 0
するのは無意味。
投稿2017/12/18 12:12
総合スコア84423
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/12/18 13:58
0
初期化されていない変数で初期化するのは初期化の意味がありませんね。
投稿2017/12/18 12:02
総合スコア1430
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/12/18 13:54
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/12/18 14:07