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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C

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

C++

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

Q&A

解決済

5回答

1066閲覧

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

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

C++

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

0グッド

0クリップ

投稿2017/12/18 11:45

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

例えば

c

1/*なんかよくわからないけど個人的に不安*/ 2static int a = b;

c

1/*なんかよくわからないけど個人的にこっちの方が安全そうに見える*/ 2static int a = 0; 3a = b;

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

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


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

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

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


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

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

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

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

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

投稿2017/12/18 13:28

LLman

総合スコア5592

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/12/18 14:07

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

0

こんにちは。

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

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

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

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

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

投稿2017/12/18 12:57

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/12/18 14:02

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

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
yumetodo

総合スコア5850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/12/18 13:52

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

0

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

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

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

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

C

1static int a; 2a = b;

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

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

投稿2017/12/18 12:12

otn

総合スコア84423

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/12/18 13:58

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

0

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

投稿2017/12/18 12:02

TaroToyotomi

総合スコア1430

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/12/18 13:54

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問