お世話になっております。
早速、質問をさせて頂きます。
#include <stdio.h>
main()
{
int c;
c = getchar();
while (c != EOF)
{
putchar(c);
c = getchar();
}
}
Q1. EOF とはstdio.h が用意している定数ということ、EOF には -1 が定義されているという認識ですが、正しいのでしょうか。
Q2. getchar()、putchar() 関数は定義していなくてもエラーが発生せず使用できますが、なぜですか?
色々調べたのですが、コンパイラが準備している関数でコンパイルする際に使用できるようになるという曖昧な認識でいます。この場合、コンパイルして作られるオブジェクトコードには上記関数が追加されているということですか。
Q3. getchar()、putchar() 関数の中身の処理はどうなっているのか確認を行うことはできないのでしょうか。
Q4. 関数は定義する、変数は宣言すると宣言と定義の使い分けはあってますか。
以上、宜しくお願い致します。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
EOF とはstdio.h が用意している定数ということ、EOF には -1 が定義されているという認識ですが、正しいのでしょうか。
前者のみ正しいです。EOF
の実際の値は、負であること以外は処理系定義です。
getchar()、putchar() 関数は定義していなくてもエラーが発生せず使用できますが、なぜですか?
#include<stdio.h>
の中に宣言(もしマクロだったとしたら定義)が書かれています。
getchar()、putchar() 関数の中身の処理はどうなっているのか確認を行うことはできないのでしょうか。
標準ライブラリのソースコードがコンパイラに付属しているのでしたら、そちらをご確認ください。
関数は定義する、変数は宣言すると宣言と定義の使い分けはあってますか。
違います。宣言と定義はそれぞれ別な意味を持っています。関数の宣言だけ行うこともあります。
投稿2020/06/11 09:11
総合スコア146018
0
Q1.EOFは(−1)と定義されている場合が多いです。実際はWindowsならctl+z,Unix系ならctl+dでOSから通知を受けます、それをライブラリが-1(0xFFFFFFFF)として通知してくるだけです。(なのでgetchar()の復帰値がintになっている訳です。
Q2,Q3.ワーニングは出ると思いますが?内部については処理系依存なのでデバッガで追いかけましよう
・・・アセンブラになると思いますが・・・
text
1ts.c:4:4: warning: implicit declaration of function 'putchar' is invalid in C99 [-Wimplicit-function-declaration] 2 putchar('\n'); 3 ^ 41 warning generated. 5usr ~/Project/test % cat ts.c 6 7int main(void) 8{ 9 putchar('\n'); 10 11 return 0; 12}
投稿2020/06/11 09:14
編集2020/06/11 09:20総合スコア6851
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/06/12 02:28
0
ベストアンサー
A2.
一般的な使われ方として、「C言語ソースをコンパイルする」「実行可能なバイナリファイルを作る」は異なるフェーズに分かれています。
ソースファイル1ファイルくらいであればまとめて行えますが、規模が大きくなればファイルを分けて「分割コンパイル」を行いますので、明確にフェーズが分かれます。
コンパイルする時には宣言によって関数の情報が分かっていれば十分で、これは #include している <stdio.h> ヘッダや、そこから間接的に #include されるヘッダに含まれています。
コンパイルによってできる「オブジェクトファイル」には、その関数の定義 ( から生成された機械語群 ) はありません。
これが「実行可能なバイナリファイルを作る」時に、別途用意されたコンパイル済みの別ファイルと「リンク」という処理で結合されます。この時は ( 例外もありますが ) リンクするファイルのどこかに関数定義がないとエラーになります。
getchar()
やputchar()
は標準で使われる関数なので、特に意識しなくてもシステムで用意されたファイルと自動的にリンクされて使えますが、使う関数によっては明示的にリンク対象を指示する必要があります。
※例えば数学系の関数の sin()
,cos()
等は -lm
というオプションを指定することによって、libm というモノ ( ライブラリと呼ばれる ) をリンクします。( Linux/UNIX系開発環境の場合 )
投稿2020/06/11 12:21
総合スコア1681
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/06/12 02:04
2020/06/12 02:51
2020/06/12 03:33
0
Q4.宣言と定義について
一般的には定義は実体を伴う、宣言は実体を伴わないと考えれば良いと思います。
C 宣言と定義 | Microsoft Docs
"宣言" では、特定の変数、関数、型、およびその属性の間の関連付けが設定されます。
変数の "定義" では宣言と同じ関連付けが設定されますが、さらに、変数にストレージが割り当てられます。
あるソースに定義があれば、別のソースでその定義を利用する場合は宣言すれば良いだけです。
int x; /定義であり宣言でもある/
extern int x; /宣言のみで別ソースで定義した変数を利用可能/
関数プロトタイプは、関数の名前、戻り値の型、および仮パラメーターの型と数を設定します。 関数定義には、関数本体が含まれます。
int func(); /宣言のみで内容がない/
int func(){} /宣言でもあるが定義でもあり内容がある。/
投稿2020/06/11 10:33
総合スコア4
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/06/12 02:07
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。