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

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

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

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

Q&A

解決済

5回答

4039閲覧

C言語 変数宣言と定義の違い

lolo333

総合スコア4

C

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

0グッド

0クリップ

投稿2020/08/28 08:10

C言語初心者です。変数の定義と宣言の違いがよく分かりません。

・変数宣言は (記憶クラス指定子、)型宣言子、変数名 のように宣言する。
・変数の定義はその変数用の記憶域を実際に確保するが、変数宣言は実際に確保するわけではない。
・変数を定義すると、同時に変数を宣言したことになる。

以上の三点は分かっているのですが、プログラムにおいて、宣言と定義はどう見分けたら良いでしょうか?
また、変数の定義と変数宣言を見分けられることは、必要なことでしょうか?(この違いを意識する必要はないのでしょうか?)

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

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

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

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

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

guest

回答5

0

JIS X3010:2003(ISO/IEC 9899:1999)

text

16.9.2 外部オブジェクト定義 2意味規則 3 オブジェクトの識別子の宣言がファイル有効範囲及び初期化子をもつ場合, 4その宣言を識別子の外部定義という。 5 ファイル有効範囲のオブジェクトの識別子を,初期化子を使わず,かつ, 6記憶域クラス指定子なしか又は記憶域クラス指定子 static で宣言する場合, 7そのオブジェクトの識別子の宣言を仮定義(tentativedefinition)という。 8翻訳単位が,ある識別子に対する仮定義を一つ以上含み,かつその識別子に 9対する外部定義を含まない場合,その翻訳単位に,翻訳単位の終わりの時点での 10合成型,及び 0 に等しい初期化子をもったその識別子のファイル有効範囲の 11宣言がある場合と同じ規則で動作する。 12 オブジェクトに対する識別子の宣言が仮定義であり,内部結合をもつ場合, 13その宣言の型は不完全型であってはならない。 14 15例1. 16 int i1 = 1; // 定義,外部結合 17 static int i2 = 2; // 定義,内部結合 18 extern int i3 = 3; // 定義,外部結合 19 int i4; // 仮定義,外部結合 20 static int i5; // 仮定義,内部結合 21 22 int i1; // 正しい仮定義,前の定義を参照する 23 int i2; // 前に内部結合をもつ定義があるため, 24 // 結合の不一致が生じ,6.2.2 によって 25 // 動作は未定義となる 26 int i3; // 正しい仮定義,前の定義を参照する 27 int i4; // 正しい仮定義,前の定義を参照する 28 int i5; // 前に内部結合をもつ定義があるため, 29 // 結合の不一致が生じ,6.2.2 によって 30 // 動作は未定義となる 31 32 extern int i1; // 外部結合をもつ前の定義を参照する 33 extern int i2; // 内部結合をもつ前の定義を参照する 34 extern int i3; // 外部結合をもつ前の定義を参照する 35 extern int i4; // 外部結合をもつ前の定義を参照する 36 extern int i5; // 内部結合をもつ前の定義を参照する

規格書では「変数」の代わりに「オブジェクト」という用語を使っています。
例1 はすべて「オブジェクトの宣言」です。
「= 値」という初期化子を持つものを「定義」としています。

以上は外部オブジェクト定義に関するもので、グローバル変数の宣言に関するものです。
関数の内部のローカル変数の宣言については少し事情が異なります。

「定義」の意味を記憶域を割り付けるものであるとするなら、
int i4; も定義となります。
ローカル変数の宣言に仮定義はありません。
int i4; という同じ宣言を 2つ書いたら二重定義エラーです。

投稿2020/08/29 01:54

kazuma-s

総合スコア8224

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

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

0

プログラムにおいて、宣言と定義はどう見分けたら良いでしょうか?

C言語ならば、グローバル変数かつexternが頭についてる奴が宣言です。
それ以外は定義(と宣言)です。(基本的には)

変数の定義と変数宣言を見分けられることは、必要なことでしょうか?

ライブラリを使う側ならば意識する必要はありません。
C/C++共用ライブラリを作る場合かつグローバル変数を作りたい場合には宣言が必要になります。

というのも、C++にはODRというルールがあり同じ変数を定義する事ができず
ヘッダに定義を書いてしまうとODR違反になってしまいます。

まぁ、とはいってもグローバル変数を複数のソース間で共有する事自体があまりよくない考えなので
基本的には変数の宣言を使う必要はありません。

投稿2020/08/28 08:44

編集2020/08/28 08:47
asm

総合スコア15149

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

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

0

変数の定義と変数宣言を見分けられることは、必要なことでしょうか?

まぁ場合により(?)必要になるだろうとは思いますが,
「ぐ… どっちだ……?」ってなるような機会はそう多くないと思います.

例えばCには"仮定義"だとか何とかいう面倒そうな話があった気がしますが,
とりあえずそういう面倒な話があるということを一度どこかで読むなりして知識として知っておけば,
あとはわざわざそんな面倒なことになりそうな書き方をしないようにしておけば良いのではないかと.

投稿2020/08/28 08:32

fana

総合スコア11996

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

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

0

プログラムにおいて、宣言と定義はどう見分けたら良いでしょうか?

また、変数の定義と変数宣言を見分けられることは、必要なことでしょうか?(この違いを意識する必要はないのでしょうか?)

言葉は悪いですが、一瞬で見分ける方法はありません。
visual studioの場合変数の上で右クリックを押下すると「定義へ移動」という項目が表示されるので、気になるならみに行くと良いでしょう。
会社によっては先頭に「D_」や「E_」を付けろと言うルールがあるところもあります。
GitHubにアップされているコードも書き方が様々で統一出来ていない面もありますが、よくやる方法はgoogleのコーディング規約に従うのが良いかと思います。

投稿2020/08/28 08:27

編集2020/08/28 08:29
stdio

総合スコア3307

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

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

lolo333

2020/08/28 08:30

詳しく教えていただきありがとうございます。よく分かりました!
guest

0

ベストアンサー

宣言は、他の場所で定義したものを宣言してそのソースコードで使えるようにします。
定義と区別するため、外部参照という意味でextern というキーワードを先頭に付けます。

externがない変数宣言は、変数の定義、ということになります

まあ、定義のない宣言、とか宣言の重複、とかはコンパイルエラーやリンクエラーになるので、エラーメッセージをよく見ていれば簡単にわかります。
ですんで、エラーとしてはそんなに深刻に考えるもんではないと思います

投稿2020/08/28 08:25

y_waiwai

総合スコア88042

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

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

lolo333

2020/08/28 08:30

分かりました!ありがとうございます。
kazuma-s

2020/08/28 12:35

次のコードをコンパイルしてみてください。 ファイル名の拡張子は .c にして、Cコンパイラでコンパイルしてください。 ----------------------- #include <stdio.h> int a; int a; int main(void) { a = 34; printf("%d\n", a); } ------------------------ エラーになりますか? extern int a; ではなく int a; ですね。 これが定義なら、二重定義のエラーになるというんですか? なりませんよね。 回答が間違っていても、 質問者にはそれが間違っていることが分からないのは仕方がありません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問