関数の場合、定義や宣言の違いが分かるのですが・・・
変数の場合、定義と宣言の違いが分かりません。
#define N 10
これは、「定義である」ということは分かります。
char buf[N]; このように使えるはずです。
しかし、以下のようになると、どっちがどっちなのか分かりません。
int a; int b = 0;
本によっては「宣言する」と言っていますが、他のサイトでは、「定義する」と言っているんですが、どっちですか??
What is the difference between a definition and a declaration?
コンパイラが参照を解決するために必要な構文要素が「宣言」であり、リンカが参照をリンクさせるのに必要な構文要素が「定義」ということのようです。
「参照を解決する」??ちょっとよくわかりません。
数学的に言うと、定義は変化しないので、上記のようなものはすべて「宣言」と見なせるような気がするんですが・・・
また、上記のような int b = 0; は前提事項としての公理ともいえるような気がするのですが・・・どうでしょうか?
あ・・・公理も変化してはいけないのかな??
プリプロセッサの部分は全て公理と言える気がするんですが・・・
また、if() などの条件分岐は命題関数と言えますよね????
なら定理もありますかね?
if() → TRUE の中カッコの中・・・かな
数学やプログラミングに詳しい方、ぜひ教えてください。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/04/21 07:38
2017/04/21 07:39
2017/04/21 07:40
2017/04/21 07:46
回答7件
0
私の解釈です。言語は問いません。
「宣言」は識別子(変数名や関数名等)がプログラムにおいて何であるかと言うことをしますものです。変数を表す場合もあれば関数を表す場合もありますし、もしかしたらクラスや型かもしれません。また、名前空間とスコープの決定にも関わり、グローバル変数とローカル変数を区別するには、どこで宣言されているのかで決まります。
「定義」はプログラムにおいてその識別子の中身です。関数であればその内容、定数であればその定まった値そのもの、エイリアスであれば元の何かのことです。また、定数ではない変数については、その領域が定まるところのみを定義している場合があります(中身が何かまでは定義されない)。
以上のことから次のようなことが言えます。
- 「宣言」は矛盾がなければ複数回書いても問題ありません。対して、「定義」は一度きりである必要があります(言語によっては、同一内容であれば問題ないとなる物もありあます)。
- 「宣言」があればコード内でその識別子を使うことができ、「定義」は必須ではありません。しかし、最終的に実行されるプログラム全体としてはどこかに「定義」がなければなりません。
- **「宣言」と「定義」は兼ねることができます。ほとんどの場合において、「定義」は「宣言」を含んでいます。**ただし、「定義」の他に「宣言」が別途ある場合は、矛盾していてはいけません。
- **「定義」は何を定義しているかは言語や対象によって異なります。**定数ではそれが指し示す値そのものまで定義する場合もありますが、定数ではない変数では(変更される可能性があるため)それが指し示す値そのもを定義することはできません。
さらに言語によっては色々事情が異なります。
- 言語によっては「暗黙の宣言」があります。あるパターンの全ての識別子が暗黙的に「宣言」済みであると見なされます。(例: Rubyのインスタンス変数)
- 言語によっては「仮定義」があります。他に確定した定義があれば「宣言」とみなされ、なければ「仮定義」が確定した「定義」として見なされます。(例: Cの初期化子が無くexternでないグローバル変数)
- 言語によっては最初の代入が「宣言」や「定義」を兼ねる場合があります。(例: Pythonのローカル変数)
- 言語によっては「宣言」が後に書かれても巻き上げ(そのスコープのトップにあると解釈される)て宣言済みと解釈される場合があります。(例: JavaScriptのvar変数)
- 動的言語によってはコードの場所で識別子が解釈されるのではなく、実行時にそれまで宣言された物の中から識別子を探す場合があります(巻き上げと違って、識別子の認識自体が後からでも、実行時に認識済みならかまわないということ)。(例: Rubyの定数)
では、質問のコードがCだとして、どうなるかというと、これだけではわかりません。なぜなら、Cではスコープの場所によって事情が異なるからです。
C
1int a; 2int b = 0; 3int main(void) 4{ 5 return 0; 6}
上の場合は、int a;
は「宣言」かつ「仮定義」であり、他に定義がないため「定義」になります。int b = 0;
は「宣言」かつ「定義」です。なお、ここでは、記憶領域が定義されるだけであり、変数の値が定義されるわけではありません。値については初期値のみ与えられます。
C
1int a; 2int b = 0; 3int a = 1; 4int main(void) 5{ 6 return 0; 7}
上の場合は、int a = 1;
という「定義」が他にあるため、「仮定義」であるint a;
は「宣言」以上の意味を持ちません。
C
1int main(void) 2{ 3 int a; 4 int b = 0; 5 return 0; 6}
ローカル変数になると、両方とも「宣言」かつ「定義」になります。そのため、
C
1int main(void) 2{ 3 int a; 4 int b = 0; 5 int a = 0; 6 return 0; 7}
上のコードはコンパイルエラーになります。
最後に、Cのような命令型のプログラミング言語を数学的解釈をすることはかなり厳しいです。計算科学では数学から用語を取っていますが、命令型言語を通常の数学で表現することは困難です(例えば、x = x + 1
をどう解釈すれば良いのだろうか?※)。関数型言語や宣言型言語でなければ、解釈にどこか無理が出てくると思います。「公理」や「命題」を数学的に考えているのであれば、命令型言語で考えることは辞めた方が無難かと思います。
※ x <- return $ x + 1
としてなら解釈できないこともないかも知れません。
投稿2017/04/22 02:32
総合スコア21735
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/04/22 08:58
2017/04/22 11:53
0
ベストアンサー
C/C++の宣言と定義に関する私の理解です。
宣言は「名前の解決」です。
コンパイラーに対して「こういう名前の変数(あるいは関数、クラスなど)があるよ」と教えますが、宣言だけではその中身が何なのか、どこにあるのかまでは判りません。
定義は「仕様の確定」です。
その変数がどういう型でどのようにメモリに配置するのか、その関数がどんなコードを出力すればいいのか、そのクラスの中身はどのように記述されているのか、などをコンパイラーに教えるのが定義です。
定義すると自動的に名前の解決も行われるので、定義には宣言も含まれると言えます。ですので、文脈によっては定義のことを宣言と言ったりすることもありますが、混乱を避けるためには使い分けるのが望ましいとは思います。
投稿2017/04/21 12:16
総合スコア5938
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/04/21 12:22
2017/04/21 12:37
2017/04/21 12:39
2017/04/21 13:45
2017/04/21 14:17
2017/04/21 14:54
2017/04/21 15:19
2017/04/21 15:24 編集
2017/04/21 15:43
2017/04/22 00:12
0
こんにちは。
プログラミング言語一般ということですが、それでは「解」はないと思います。
そのプログラミング言語を定義した人がそれぞれの用語を定義するので、その用語の意味は言語毎に異なると思います。
例えば、C++はここに書かれてます。恐らく規格書もほぼ同じように書かれていると思います。
かなり厳密に定義されているようですが、正直複雑過ぎて良く分からんです。
C++の用語上「宣言」は「定義」を含むようですので全部ひっくるめて「宣言」と呼べば間違いになることはない筈です。
私自身は詳細まで記述されている宣言を「定義」と理解してます。C++的にも大きくは間違ってない筈と思います。
しかし、他の言語では通用しない筈です。
投稿2017/04/21 08:05
総合スコア23272
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
宣言 (declaration) と定義 (definition) の違い
名前 (識別子) の型をコンパイラに伝えるのが宣言で、その名前が参照している実体 (メモリ) を確保するのが定義です。
正確な内容は各言語の仕様書に書いていますと思いますが、私は(C/C++では)この説明が簡潔でしっくりきます。
ちなみに「変数 宣言 定義 違い」で検索して先頭に出てきたページです。
投稿2017/04/21 07:47
編集2017/04/21 07:50総合スコア38262
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/04/21 07:50
2017/04/21 07:53
2017/04/21 07:54
2017/04/21 07:56
2017/04/21 07:57
2017/04/21 08:09
2017/04/21 08:15
2017/04/21 08:17
2017/04/21 08:26
2017/04/21 08:28
2017/04/21 08:31
2017/04/21 08:32
2017/04/21 08:34 編集
2017/04/21 08:35
2017/04/21 16:08
2017/04/21 17:08
0
変数の場合は宣言と定義に違いは事実上ありません。これらに違いが生じるのは関数とか構造体の場合です。変数の場合について考えても答えは出ません。
宣言はあくまでも「ユーザ定義の語」を取り決めるだけです。したがって、関数の場合はプロトタイプ宣言という概念(関数の名前と引数、戻り値だけを決めるもので、具体的な処理の記述は行わない)が存在し、定義と宣言が異なります。一方で、**「変数の場合は語を宣言すること自体が定義」**ですから、事実上、宣言と定義が同一となります。
もちろん、言語によっては違いもあるかもしれませんが、少なくともCの場合はこうなります。
投稿2017/04/21 11:37
編集2017/04/21 11:50総合スコア4830
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
質問対象が過度に一般化されていて、答えようがない(or正解などない)ようにも感じます...
特定のプログラミング言語を取り上げるならば、"定義(definition)" や "宣言(declaration)" といった語の意味は、それぞれの「プログラミング言語仕様に依存する」としか言いようが無いです。
C/C++に限定された話ではありません。
とありますが、一応。(正確ではない)砕けた表現をするならば:
- 定義:実体(変数ならメモリ領域/関数なら命令列)の存在を示し、同時にその中身(変数なら値/関数なら処理)も規定します。
- 宣言:対応する実体がプログラム中のどこか別の場所に存在することを示します。
また、宣言と定義が同時に行われることもあります。たとえば初期値を指定する変数宣言は、その変数の定義でもあります。
コンパイラが参照を解決するために必要な構文要素が「宣言」であり、リンカが参照をリンクさせるのに必要な構文要素が「定義」ということのようです。
「参照を解決する」??ちょっとよくわかりません。
C/C++言語の仕様と、普通のC/C++処理系(=プリプロセッサ+コンパイラ+リンカ)では、上のような解釈になります。リンカ(linker)視点では:
- 定義:名前のついた実体。変数ならメモリ確保(用の指示)、関数なら機械語命令列を生成する。
- 宣言:実体がどこかに存在する。名前をもとに定義を探し出し、両者を紐付け、つまり参照を行う。
投稿2017/04/21 07:56
総合スコア6191
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/04/21 08:00 編集
2017/04/21 08:00
2017/04/21 08:05
2017/04/21 08:21 編集
2017/04/21 08:14
2017/04/21 08:27 編集
2017/04/21 08:24
2017/04/21 08:30
0
int a;
int b = 0;
一般的には引用の上は宣言であり、下は初期化ありの宣言、というかな。
定義ではないです。
投稿2017/04/21 07:33
総合スコア21
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/04/21 07:35
2017/04/21 07:43
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。