C言語の電卓におけるincludeについて

C言語の電卓におけるincludeについて質問です。

プログラミング言語C第2版 ANSI規格準拠
B.W.カーニハン・D.M.リッチー著

質問1.
4章にある電卓プログラムですが、getch.cがcalc.hをincludeしないのはなぜですか?
解説よろしくお願いします

calc.h
#difine NUMBER '0'

main.c
#include <stdio.h>
#include <stdlib.h>
#include "calc.h"
#difine MAXOP 100

getop.c
#include <stdio.h>
#include <ctype.h>
#include "calc.h"

stack.c
#include <stdio.h>
#include "calc.h"
#difine MAXVAL 100

getch.c
#include <stdio.h>


質問2.
第4章までしか読んでいませんが、「関数で返さない値はゴミ(garbage)になる」と書いていました。

関数で返さない値は、関数から抜けると消えるものと思っていたので驚きました。
関数で返さない値の後処理はどうすればいいのですか?


質問3.
外部変数と静的変数の違いは?

―メモ―
局所変数 自動変数     main内の変数     int x;
                         static int x; 永久的なメモリが与えられることを意味する
外部変数          main外の変数     static int x;
静的変数          関数内の変数     static int x;
レジスタ変数        変数をレジスタに置く register int x;


以上、有識者の方、教えてくださいmm

このQ&Aに関連する最新のQ&A

A 回答 (10件)

>4章にある電卓プログラムですが、getch.cがcalc.hをincludeしないのはなぜですか?



手元にその書籍がないんですが、"getch.c"では"calc.h"で定義や宣言しているものを使っていないからでしょう。
それ以外の"main.c","getop.c","stack.c"は、NUMBERなどを使っているはず。

>関数で返さない値は、関数から抜けると消えるものと思っていたので驚きました。
>関数で返さない値の後処理はどうすればいいのですか?

スタック上にとられる、通常の変数の値なら、関数(というより、変数が宣言されたスコープ)を抜ければ、自動的に領域が開放されるので後処理は不要です。
しかし、malloc()や new などで動的に領域確保された変数の場合は、それぞれ free() や delete を明示的に呼ぶ後処理が必須です。
これらを忘れると、メモリリークを起こします。


>外部変数と静的変数の違いは?

>外部変数          main外の変数     static int x;
>静的変数          関数内の変数     static int x;

外部変数は通常、別なコンパイル単位("*.c"ファイルなど)からアクセスできるものを指します。
なので、staticは指定しません。
私なら、このように分類します

>局所変数 自動変数 関数内の変数  int x;
>     静的変数 関数内の変数  static int x; //永久的なメモリが与えられることを意味する
>外部変数      関数外の変数  int x; //ヘッダファイルで extern int x; と宣言
>ファイル静的変数  関数外の変数  static int x;
    • good
    • 0
この回答へのお礼

ありがとうございます。
みなさまの意見を統括し、自分なりの回答が出ました。
また、間違っていたら教えてください。
数日したら締め切りたいと思いますので、誤りがありましたら、数日中にお願いします。

―質問1の回答―
getch.cがcal.hの内容を使用していないため。

―質問2の回答―
returnがなくてもreturnを明示的に書きなさい。そしてreturn voidと書きなさい。
そうしなければreturnが返す値はゴミです。

int型などは関数を抜けた後も残りますが、違うプログラムがロードされたときに上書きされますから、
後でロードされたプログラムがきちんと初期化処理をすれば動作しますので、開放しなくても大丈夫です。

malloc()や new などで動的に領域確保された変数を開放するのは当たり前。
それぞれ free() や delete を明示的に呼ぶ後処理が必須です。

int型も関数を抜けての残るが、同じ領域が使われるためきちんと動くわけですね。
ブロックから出ると値が無効になるって習ったのでやはりどちらにしろ驚きです。

―質問3の回答―
局所変数 自動変数 関数内の変数  int x;
     静的変数 関数内の変数  static int x; //永久的なメモリが与えられることを意味する
外部変数      関数外の変数  int x; //ヘッダファイルで extern int x; と宣言
ファイル静的変数  関数外の変数  static int x;

お礼日時:2009/05/17 15:59

>書かなくてもいいけど書いた方がいいよと著者は言っています。


>ゴミになるから。

戻り値がある関数の場合、呼び出し元に対して「必ず」何らかの値を戻さねばなりません。
そうしなかった場合、その関数から呼び出し元が受け取る値は、文字どおり「ゴミ」です。

一方、戻り値がない関数の場合、最後の実行文を実行した後「だけで」呼び出し元に戻るのであれば、
return; はあってもいいし、なくてもいいです。
こちらの場合、ゴミなるものはいっさい出ません。
    • good
    • 0
この回答へのお礼

ありがとうございます。

この質問は数日経ったので締め切らせていただきます。
ありがとうございましたmm

お礼日時:2009/05/19 16:40

>returnがなくてもreturnを明示的に書きなさい。

そしてreturn voidと書きなさい。

戻り値の型がvoidである(呼び出し元に何も返さない)関数では、
「return; を明示的に書かねばならない」ということはありません。
関数の途中で呼び出し元に戻るときは当然 return; が必要ですが、
関数の最後で呼び出し元に戻るときは return; を書いてもいいし、書かなくてもいいです。

また、return void; は正しくありません。やってみればわかります。
void は型名で、return int; などとは書けないのと同じです。
    • good
    • 0
この回答へのお礼

ありがとうございます。

return文がおかしいことがわかりました。
大変為になりました。

>return; を書いてもいいし、書かなくてもいいです。
書かなくてもいいけど書いた方がいいよと著者は言っています。
ゴミになるから。

いま6章です。
わかるようなわからないようなと言ったところです。
ということはわかってませんね・・・
多分、1回読んだだけではわからないのか。

ただ僕がアホなだけなのか。。

お礼日時:2009/05/18 16:51

質問1と質問3は、#6さんが既にご回答なさっている通りです。



質問2について、原文では以下のようになっています。

 The return statement is the mechanism for returning a value from the called function to its caller. Any 'expression'(任意の「式」) can follow return:

 return expression;

 The 'expression' will be converted to the return type of the function if necessary.
Parentheses are often used around the 'expression', but they are optional.

 The calling function is free to ignore the returned value.
 Furthermore, there need be no 'expression' after return; in that case, no value is returned to the caller.


 Control also returns to the caller with no value when execution "falls off the end" of the function by reaching the closing right brace.
 It is no illegal, but probably a sign of trouble, if a function returns a value from one place and no value from another.
 In any case, if a function fails to return a value, its "value" is certain to be garbage.

 一つの関数が、或る場所では返り値を返し、別の場所では返り値を返さない場合があったとしても、合法である、トラブルのサインにはなるだろうが。
 どんな場合にせよ、関数が返り値を返すことに失敗した場合、その返り値のもとになっている変数は、ゴミになる(不要な物として消滅する)。


「関数で返さない値は、関数から抜けると消えるもの」も、この場合の「ゴミ」と同義です。

>関数で返さない値の後処理はどうすればいいのですか?

何もしなくていいです。
    • good
    • 0
この回答へのお礼

ありがとうございます。

お礼日時:2009/05/18 16:47

>#3さん


>外部変数は通常、別なコンパイル単位("*.c"ファイルなど)からアクセスできるものを指します。
>なので、staticは指定しません。

関数の外で定義する変数にstatic属性を付ける例はいくらでもあります。
#6さんの回答や、私の#4をお読みになって、認識を改められる方がよいです。
    • good
    • 0
この回答へのお礼

ありがとうございます。
みなさまの意見を統括し、自分なりの回答が出ました。
また、間違っていたら教えてください。
数日したら締め切りたいと思いますので、誤りがありましたら、数日中にお願いします。

―質問1の回答―
getch.cがcal.hの内容を使用していないため。

―質問2の回答―
returnがなくてもreturnを明示的に書きなさい。そしてreturn voidと書きなさい。
そうしなければreturnが返す値はゴミです。

int型などは関数を抜けた後も残りますが、違うプログラムがロードされたときに上書きされますから、
後でロードされたプログラムがきちんと初期化処理をすれば動作しますので、開放しなくても大丈夫です。

malloc()や new などで動的に領域確保された変数を開放するのは当たり前。
それぞれ free() や delete を明示的に呼ぶ後処理が必須です。

int型も関数を抜けての残るが、同じ領域が使われるためきちんと動くわけですね。
ブロックから出ると値が無効になるって習ったのでやはりどちらにしろ驚きです。

―質問3の回答―
局所変数 自動変数 関数内の変数  int x;
     静的変数 関数内の変数  static int x; //永久的なメモリが与えられることを意味する
外部変数      関数外の変数  int x; //ヘッダファイルで extern int x; と宣言
ファイル静的変数  関数外の変数  static int x;

お礼日時:2009/05/17 16:01

= 質問1 =


getch.c が calc.h を include していないのは、他の方も指摘している通り、getch.c 内では calc.h の内容を使用していないからでしょう。

ただ、calc.h には getch.c にある関数の宣言が書かれているので、include する方が好ましいように思います。include することにより、calc.h にある宣言と getch.c にある定義の内容が食い違ってしまう書き間違いをした場合にコンパイラがエラーを検出してくれるようになってミスに気づきやすくなるからです。

= 質問2 =
引用されている文は4.1節の後半にあるものだと思いますが、ここに書かれているのは関数内で単に return と書いた場合に関数の呼び出し側へどのような値が返されるのかという話で、その場合には「ゴミ」が返されるという説明に読めます。

この文は、関数内で使用した変数が破棄されるかどうかという話とは無関係だと思います。

= 質問3 =
外部変数とは、関数の外で定義された変数のことです。
静的変数とは、(定義が関数の外か中かは関係なく)「static」付きで定義された変数のことです。

外部変数は、変数を複数の関数から参照したい場合に使用します。
静的変数は、外部変数に対する場合と内部変数に対する場合で用途が異なります。
外部変数に対する静的変数は、その外部変数が定義されているファイル以外のファイルに書かれている関数からはその変数を参照できないようにしたい場合に使用します。
内部変数に対する静的変数は、内部変数の値を関数がreturnした後も保持し続けたい場合に使用します。
    • good
    • 0
この回答へのお礼

ありがとうございます。
みなさまの意見を統括し、自分なりの回答が出ました。
また、間違っていたら教えてください。
数日したら締め切りたいと思いますので、誤りがありましたら、数日中にお願いします。

―質問1の回答―
getch.cがcal.hの内容を使用していないため。

―質問2の回答―
returnがなくてもreturnを明示的に書きなさい。そしてreturn voidと書きなさい。
そうしなければreturnが返す値はゴミです。

int型などは関数を抜けた後も残りますが、違うプログラムがロードされたときに上書きされますから、
後でロードされたプログラムがきちんと初期化処理をすれば動作しますので、開放しなくても大丈夫です。

malloc()や new などで動的に領域確保された変数を開放するのは当たり前。
それぞれ free() や delete を明示的に呼ぶ後処理が必須です。

int型も関数を抜けての残るが、同じ領域が使われるためきちんと動くわけですね。
ブロックから出ると値が無効になるって習ったのでやはりどちらにしろ驚きです。

―質問3の回答―
局所変数 自動変数 関数内の変数  int x;
     静的変数 関数内の変数  static int x; //永久的なメモリが与えられることを意味する
外部変数      関数外の変数  int x; //ヘッダファイルで extern int x; と宣言
ファイル静的変数  関数外の変数  static int x;

お礼日時:2009/05/17 16:00

>#1さん


>静的変数と対比するなら、動的変数。

静的(static)変数と対比するのは、自動(automatic)変数です。
対比する点は、変数の寿命がどこで尽きるか、というところです。

一般的な用語としてならば、静的(static)と動的(dynamic)とを
対比させることに問題はありません。
しかし、C言語においてはそうではありませんね。
    • good
    • 0
この回答へのお礼

ありがとうございます。
みなさまの意見を統括し、自分なりの回答が出ました。
また、間違っていたら教えてください。
数日したら締め切りたいと思いますので、誤りがありましたら、数日中にお願いします。

―質問1の回答―
getch.cがcal.hの内容を使用していないため。

―質問2の回答―
returnがなくてもreturnを明示的に書きなさい。そしてreturn voidと書きなさい。
そうしなければreturnが返す値はゴミです。

int型などは関数を抜けた後も残りますが、違うプログラムがロードされたときに上書きされますから、
後でロードされたプログラムがきちんと初期化処理をすれば動作しますので、開放しなくても大丈夫です。

malloc()や new などで動的に領域確保された変数を開放するのは当たり前。
それぞれ free() や delete を明示的に呼ぶ後処理が必須です。

int型も関数を抜けての残るが、同じ領域が使われるためきちんと動くわけですね。
ブロックから出ると値が無効になるって習ったのでやはりどちらにしろ驚きです。

―質問3の回答―
局所変数 自動変数 関数内の変数  int x;
     静的変数 関数内の変数  static int x; //永久的なメモリが与えられることを意味する
外部変数      関数外の変数  int x; //ヘッダファイルで extern int x; と宣言
ファイル静的変数  関数外の変数  static int x;

お礼日時:2009/05/17 16:00

>#2さん


>静的変数は、ある関数内でのみアクセスできる変数

誤解があるようです。
static変数には、関数内部のstatic変数と関数外部のstatic変数とがあります。

関数内部のstatic変数は、関数内部のauto変数とは異なり、
その関数を抜けた後も寿命を保ちます。

関数外部のstatic変数は、その関数を含む翻訳単位内に属する他の関数からも等しくアクセスできます(ファイルスコープ)。
言い方を変えると、関数外部のstatic変数には、
その変数を定義した翻訳単位の外からは見えない、という特徴があります。
    • good
    • 0
この回答へのお礼

ありがとうございます。
みなさまの意見を統括し、自分なりの回答が出ました。
また、間違っていたら教えてください。
数日したら締め切りたいと思いますので、誤りがありましたら、数日中にお願いします。

―質問1の回答―
getch.cがcal.hの内容を使用していないため。

―質問2の回答―
returnがなくてもreturnを明示的に書きなさい。そしてreturn voidと書きなさい。
そうしなければreturnが返す値はゴミです。

int型などは関数を抜けた後も残りますが、違うプログラムがロードされたときに上書きされますから、
後でロードされたプログラムがきちんと初期化処理をすれば動作しますので、開放しなくても大丈夫です。

malloc()や new などで動的に領域確保された変数を開放するのは当たり前。
それぞれ free() や delete を明示的に呼ぶ後処理が必須です。

int型も関数を抜けての残るが、同じ領域が使われるためきちんと動くわけですね。
ブロックから出ると値が無効になるって習ったのでやはりどちらにしろ驚きです。

―質問3の回答―
局所変数 自動変数 関数内の変数  int x;
     静的変数 関数内の変数  static int x; //永久的なメモリが与えられることを意味する
外部変数      関数外の変数  int x; //ヘッダファイルで extern int x; と宣言
ファイル静的変数  関数外の変数  static int x;

お礼日時:2009/05/17 16:00

こんにちは。



>質問1
getch.c内で、calc.hで定義されている情報(プロトタイプやグローバル変数など)を参照する必要がないからだと思います。
getch.cの全文を見ていないので推測ですが。

>質問2
関数内部で使用した変数(=メモリ)は、関数を抜けるとそのままになります。malloc()などを用いて明示的に確保したのであれば、抜ける前にリソースの開放をする必要があります。(これを忘れることをメモリリークと呼びます。プログラマを悩ませるバグの1つです)
int型などは関数を抜けた後も残りますが、違うプログラムがロードされたときに上書きされますから、後でロードされたプログラムがきちんと初期化処理をすれば動作しますので、開放しなくても大丈夫です。

>質問3
外部変数(=グローバル変数)は、あるプログラムコード上のどの関数からもアクセス(読み書き)できる変数です。
静的変数は、ある関数内でのみアクセスできる変数で、他の関数内で同名の変数を定義したとき同一のものとして処理され、その関数からもアクセスできるようになるものです。
他の関数内で呼び出さないのであれば、静的変数も自動変数と大差ありません(そうする意味もありませんし)
    • good
    • 0
この回答へのお礼

ありがとうございます。
みなさまの意見を統括し、自分なりの回答が出ました。
また、間違っていたら教えてください。
数日したら締め切りたいと思いますので、誤りがありましたら、数日中にお願いします。

―質問1の回答―
getch.cがcal.hの内容を使用していないため。

―質問2の回答―
returnがなくてもreturnを明示的に書きなさい。そしてreturn voidと書きなさい。
そうしなければreturnが返す値はゴミです。

int型などは関数を抜けた後も残りますが、違うプログラムがロードされたときに上書きされますから、
後でロードされたプログラムがきちんと初期化処理をすれば動作しますので、開放しなくても大丈夫です。

malloc()や new などで動的に領域確保された変数を開放するのは当たり前。
それぞれ free() や delete を明示的に呼ぶ後処理が必須です。

int型も関数を抜けての残るが、同じ領域が使われるためきちんと動くわけですね。
ブロックから出ると値が無効になるって習ったのでやはりどちらにしろ驚きです。

―質問3の回答―
局所変数 自動変数 関数内の変数  int x;
     静的変数 関数内の変数  static int x; //永久的なメモリが与えられることを意味する
外部変数      関数外の変数  int x; //ヘッダファイルで extern int x; と宣言
ファイル静的変数  関数外の変数  static int x;

お礼日時:2009/05/17 15:59

> 質問3.


> 外部変数と静的変数の違いは?
対比するものが、無意味です。
外部変数と対比するなら、ローカル変数。
静的変数と対比するなら、動的変数。

です。
    • good
    • 0
この回答へのお礼

ありがとうございます。
みなさまの意見を統括し、自分なりの回答が出ました。
また、間違っていたら教えてください。
数日したら締め切りたいと思いますので、誤りがありましたら、数日中にお願いします。

―質問1の回答―
getch.cがcal.hの内容を使用していないため。

―質問2の回答―
returnがなくてもreturnを明示的に書きなさい。そしてreturn voidと書きなさい。
そうしなければreturnが返す値はゴミです。

int型などは関数を抜けた後も残りますが、違うプログラムがロードされたときに上書きされますから、
後でロードされたプログラムがきちんと初期化処理をすれば動作しますので、開放しなくても大丈夫です。

malloc()や new などで動的に領域確保された変数を開放するのは当たり前。
それぞれ free() や delete を明示的に呼ぶ後処理が必須です。

int型も関数を抜けての残るが、同じ領域が使われるためきちんと動くわけですね。
ブロックから出ると値が無効になるって習ったのでやはりどちらにしろ驚きです。

―質問3の回答―
局所変数 自動変数 関数内の変数  int x;
     静的変数 関数内の変数  static int x; //永久的なメモリが与えられることを意味する
外部変数      関数外の変数  int x; //ヘッダファイルで extern int x; と宣言
ファイル静的変数  関数外の変数  static int x;

お礼日時:2009/05/17 15:59

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QLISPのマクロと他の言語のマクロの違い

LISPのマクロは強力と言われていますが、他の言語の言うマクロとはどう違うのでしょうか?

Aベストアンサー

ここでいう「マクロ」は一言で言うと「プログラムを生成する機能」ですね。
例えばCのマクロを例に上げますと、
#define MAX(a, b) (a) > (b) ? (a) : (b)
というようなマクロを定義すると、後に
MAX(10, x)
と書いた際に
(10) > (x) ? (10) : (x)
というプログラムがコンパイル時に生成されます。

Cなどのマクロは、マクロ専用の文法があり、
マクロで書けるものにはある程度の制限が付きます。例えば、
「マクロの引数が定数の際に奇数か偶数かで『生成するプログラム』を変える」
などといった複雑なことはできません。

一方、Lispのマクロは、Lispそのもので書くことが可能で、
任意のプログラムをマクロとして書くことができます。
マクロの中で条件分岐やループなど、なんでも出来てしまいます。
これにより、コンパイル時にマクロの引数の型や値に応じて
生成するプログラムを変えることで最適化を行ったり、
新たな言語機能(と対応する文法)を追加するようなことが可能です。

例えば、昔のLispにはオブジェクト指向の機能がありませんでしたが、
マクロを使うことで、後からオブジェクト指向の機能を付け加えることができました。
また、Common Lispのオブジェクト指向の機能が独特で嫌いな人は、
マクロを使うことでJava風のオブジェクト指向の機能を追加するようなことも可能です。
極端な話、Lispの上で別の言語が作れてしまうわけです。

コンパイル時に任意のプログラムを実行できるという点では、
C++のテンプレートとも似ているといえますが、
C++のテンプレートはテンプレート専用の文法を用いる必要ある点がLispと異なります。
C++をそれなりに書ける人でも、テンプレートで任意のプログラムを書こうとすると、
かなりの苦労を強いられます。テンプレートの文法がC++の文法と異なるのが苦労する原因の一つです。
一方、Lispのマクロは、Lisp自身で書けるため、
Lispが書ける人なら誰にだって書けてしまうわけです。

以上がLispのマクロが強力と言われる要因(の一部)です。
実際に使われてみると色々と実感できると思いますよ。

ここでいう「マクロ」は一言で言うと「プログラムを生成する機能」ですね。
例えばCのマクロを例に上げますと、
#define MAX(a, b) (a) > (b) ? (a) : (b)
というようなマクロを定義すると、後に
MAX(10, x)
と書いた際に
(10) > (x) ? (10) : (x)
というプログラムがコンパイル時に生成されます。

Cなどのマクロは、マクロ専用の文法があり、
マクロで書けるものにはある程度の制限が付きます。例えば、
「マクロの引数が定数の際に奇数か偶数かで『生成するプログラム』を変える」
などといった複雑なことはで...続きを読む

QC言語のプログラムで#includeを使わず#includeだけで

C言語のプログラムで#include<math.h>を使わず#include<stdio.h>だけで√(sqrt)を表現することは可能でしょうか?

Aベストアンサー

ご自分で sqrt 関数を作れば可能です。
こんな感じでしょうか。

#include <stdio.h>

static double
sqrt (double s)
{
 double x = s / 2.0;
 double last_x = 0.0;

 while (x != last_x)
 {
  last_x = x;
  x = (x + s / x) / 2.0;
 }

 return (x);
}

int
main (int argc, char * argv[])
{
 printf ("sqrt (%f) = %f\n", 3.0, sqrt (3.0));
}

Qlispとその他関数型言語について

「lispを学べば悟りが開ける」という言葉をよく聞きます。

l他のプログラミング言語哲学とは一線を画すほどの教示をもった言語という印象を持ちます。

僕もlispを少し学んだだけですが「悟り」は開けませんでした。

しかし他の関数型言語(haskellとか)ではそういう話は聞きません。

なぜでしょうか。

やっぱ括弧ですか。

Aベストアンサー

他の言語が、まだまだ歴史が浅く、使っている人、特にカリスマと呼べるような人が少ないからではないでしょうか。
それに「haskellを学べば..」などといまさら言っても、二番煎じになってしまいますし。

Qint main()、void main()、void main(void)、int main(void)

今日、大学でC言語の講義の時間、先生が、

#include <stdio.h>

void main(void){

}

と宣言してプログラムを書くと教えていました。
main関数には、
main()
void main()
void main( void )
int main()
int main( void )

と、人によりいくつかの描き方があったりします。
どれが本当は正しいのでしょうか?
void mainはすべきではないとなんかの本で読んだのですが・・。

Aベストアンサー

通称C89という以前の言語規格(現行コンパイラの多くが準拠)では、下記のいずれかが正しい。
int main(int argc, char *argv[])
int main(void)

但し、最新のC言語規格(通称C99)では、
<ISO/IEC9899:1999>
or in some other implementation-defined manner.
</ISO/IEC9899:1999>
となっているので、処理系が戻り値のvoidを認めていればvoidも可。
# 組込み系などで戻り値を使わない環境もあるためでしょうか。

なので、コンパイラのマニュアルで戻り値のvoidにしていい/しろと書いてない限り、
voidは言語仕様的には正しくない。(でも動くものもある)

QLISPで C言語のフォーマット書式の"%02d"

LISPで C言語のフォーマット書式の"%02d"にあたる記述の仕方がわかりません。どのようにすればよいのでしょうか?

Aベストアンサー

Common Lisp で良いのですよね?

(dolist (num '(5 10 200))
(princ (format nil "~2,'0D~%" num)))

実行結果:
05
10
200


format関数
http://www.yuasa.kuis.kyoto-u.ac.jp/~hiraisi/format-func.html

Q#include

#include <stdio.h>の <> の意味と
#include "xxxxx.h"の "" の意味を教えてください。

Aベストアンサー

厳密な定義を、「JIS X3010:2003 - 6.10.2 ソースファイル取り込み」から引用します。

---- 引用ここから ----
制約 #include指令は, 処理系で処理可能なヘッダ又はソースファイルを識別しなければならない。
意味規則 次の形式の前処理指令
    # include <h文字列> 改行
は, 処理系定義の場所を順に探索して, <区切り記号と>区切り記号の間で指定した文字列で一意に決まるヘッダを見つけ, そのヘッダの内容全体でこの指令を置き換える。どのようにして探索の場所を指定するか, またどのようにしてヘッダを識別するかは, 処理系定義とする。
 次の形式
    # include "q文字列" 改行
は, 二つの"区切り文字の間で指定した文字列で一意に決まるソースファイルの内容全体で, この指令を置き換える。指定したソースファイルの探索順序は処理系定義とする。この探索をサポートしていない場合, 又は探索が失敗した場合, 同じ文字列(もしあれば>文字を含めて)を含む次の知れに読み替えたのと同じ規則で再処理する。
    # include <h文字列> 改行
---- 引用ここまで ----

要するに、<xxx>の場合は処理系定義のヘッダ(ファイルとは限らない)を取り込み、"xxx"の場合はソースファイルを取り込むということです。いずれも探索場所やその順序は処理系定義です。

よくある誤解は、
・ヘッダは必ずファイルである。
・"xxx"ではカレントディレクトリや取り込もうとしたファイルと同じディレクトリから探索を始める。
といったものです。このように実装されている処理系が多いことは確かですが、標準規格ではそのような規定はありません。
使用している処理系がどのような実装になっているかは、マニュアルに記載があるかと思います。

厳密な定義を、「JIS X3010:2003 - 6.10.2 ソースファイル取り込み」から引用します。

---- 引用ここから ----
制約 #include指令は, 処理系で処理可能なヘッダ又はソースファイルを識別しなければならない。
意味規則 次の形式の前処理指令
    # include <h文字列> 改行
は, 処理系定義の場所を順に探索して, <区切り記号と>区切り記号の間で指定した文字列で一意に決まるヘッダを見つけ, そのヘッダの内容全体でこの指令を置き換える。どのようにして探索の場所を指定するか, またどのようにして...続きを読む

Qlispの入門書

lispの入門書を探しています。

lispの書き方をただ説明するだけでなく、他の言語と違ってどういう利点が
あるのかを説明したものがいいです。

なにかおすすめの本があったら教えてください。

Aベストアンサー

・The Little Schemer
Lispの最高の入門書です。一問一答を追っていくことで、リスト操作やLispプログラムを作っていく感覚について皮膚で理解できるようになります。
英語ですが、難しい文章はないのでそれほど問題ないはず。
環境の整えかたなどの記述はいっさいありません。 "Lisp" を実践して学ぶ本です。

・プログラミングGauche
Lispの方言の一つにSchemeという言語があります。その一つの処理系であるGaucheの本です。さいきん出たばっかり。
Gauche のさまざまな組み込み関数を利用することで関数型プログラミングを実践していきます。
日本語で勉強したいならこちらです。

・リスト遊び
日本語だとこの辺も入門書です。あまり詳しく知りませんが、Emacs Lispの本です。
筆者はEmacs上でemailを読めるMewというソフトウェアの開発者でもあるそうです。

Lispの良さについてはネット上の文章を読む方がよろしいかと。適当に、LispとかPaul GrahamとかShiroとかのキーワードを探してみてください。
「ハッカーと画家」を読むのも良いですね。


Lispコミュニティにコミットするのがいちばんですが。

・The Little Schemer
Lispの最高の入門書です。一問一答を追っていくことで、リスト操作やLispプログラムを作っていく感覚について皮膚で理解できるようになります。
英語ですが、難しい文章はないのでそれほど問題ないはず。
環境の整えかたなどの記述はいっさいありません。 "Lisp" を実践して学ぶ本です。

・プログラミングGauche
Lispの方言の一つにSchemeという言語があります。その一つの処理系であるGaucheの本です。さいきん出たばっかり。
Gauche のさまざまな組み込み関数を利用することで関数...続きを読む

Q   #include

   #include<stdio.h>
#include<math.h>

int main(void)
{
int i,n,limit;
printf("data? ");
scanf("%d",&n);
i(n>=2){
limit=int)sqrt(n);
for(i=limit;i1;i--){
if(n%i==0)
break;
}
if(i==1)
printf("素数\n);
else
printf("素数でない\n");
}
return 0;
}

というプログラムがあるのですが、それを改良して int型(符号付32ビット整数)および、unsigned int型(符号なし32ビット整数)のそれぞれの最大の素数を求めよという問題があり、ただし、エラトステネスのふるいは使わずに、上のプログラムを改良してみよという問題がどっかにあったんですが、全然わからないので、教えてください。

   #include<stdio.h>
#include<math.h>

int main(void)
{
int i,n,limit;
printf("data? ");
scanf("%d",&n);
i(n>=2){
limit=int)sqrt(n);
for(i=limit;i1;i--){
if(n%i==0)
break;
}
if(i==1)
printf("素数\n);
else
printf("素数でない\n");
...続きを読む

Aベストアンサー

最初に。
このプログラム、ところどころ打ち間違いがあります。直しておきましょう。
i(n>=2){
limit=(int)sqrt(n);
for(i=limit;i>=1;i--){

まず、プログラムを、機能ごとに分けて考えます。

printf("data? ");
scanf("%d",&n);
が素数判定する数値nを決めるところ

if(n>=2){
から return 0 ; の前の
}
までがn が素数かの判定しているところ
です。

では、改造に入ります。
intの範囲での最大の素数、ということなので、 intの最大値 から順番に素数判定を行い、最初に見つかった素数が、求める値、となります。

元はnをキーボードから入力しています。
これをキーボード入力ではなく、プログラム中で「intの最大値 から順番に」するには、どうしたらいいと思いますか?

元の判定部は
if(i==1)
printf("素数\n);
else
printf("素数でない\n");
です。これは n に対して「素数/素数でない」と表示されます。
改造するときに
・「素数でない」という表示は必要でしょうか?
・「素数」という表示ではnはわかりません。 nも表示するにはどうしたらいいと思いますか?
・素数が見つかったら、ループを抜けないと、int型の全ての素数を表示するプログラムになってしまいます。ループを抜けるにはどうしたらよいでしょうか?

以上の考えかたで、改造できると思いますが、いかがでしょうか。

unsigned int版へは次の2点を変更します。
・計算に使う変数はunsigned intにする必要がある。
・nはunsigned intの最大値から順番に

最初に。
このプログラム、ところどころ打ち間違いがあります。直しておきましょう。
i(n>=2){
limit=(int)sqrt(n);
for(i=limit;i>=1;i--){

まず、プログラムを、機能ごとに分けて考えます。

printf("data? ");
scanf("%d",&n);
が素数判定する数値nを決めるところ

if(n>=2){
から return 0 ; の前の
}
までがn が素数かの判定しているところ
です。

では、改造に入ります。
intの範囲での最大の素数、ということなので、 intの最大値 から順番に素数判定を行い、最初に見つかった素数が...続きを読む

Q初めて関数型言語を学ぶとしたら、どの言語がお奨めですか?

初めて関数型言語を学ぶとしたら、どの言語がお奨めですか?
JavaScriptをやっていて、関数型言語に興味を持ちました。

いままで、勉強した言語はC < Java < Python < JavaScriptです。(右側の方が比重・興味が大きい)
現在、Web系志望の学生なので、その辺を踏まえてアドバイスいただけると助かります。

今のところ興味を持ってるのは、Common Lisp/Haskellあたりです。

よろしくお願いします。

Aベストアンサー

C言語が「関数型」?なのか、と言われると多分違うと思うんですけどね。普通は命令型/手続き型に分類されるんじゃないか、と思います。

ちなみに、JavaScriptはSchemeに影響を受けてる言語です。それで言うと、SchemeかCommon Lispがいいんじゃないのかな、とは思いますがね。ただ、あんまり関数型、って感じで書かれている本は少ないと思います。

Web系志望と言う事なんで、Common Lispですと、

ANSI Common Lisp: http://www.pej-hed.jp/washo/288.html
にHTML生成のトピックあり。

実践Comon Lisp: http://ssl.ohmsha.co.jp/cgi-bin/menu.cgi?ISBN=978-4-274-06721-1
にAllegro Serveと言うライブラリを利用したWebプログラミングの例があり。HTML生成の例もあり。
原著のサイトでは、
http://www.gigamonkeys.com/book/practical-web-programming-with-allegroserve.html
http://www.gigamonkeys.com/book/practical-an-html-generation-library-the-interpreter.html
http://www.gigamonkeys.com/book/practical-an-html-generation-library-the-compiler.html
辺り。

プログラミング言語Lisp: http://ascii.asciimw.jp/books/books/detail/4-7561-3926-4.shtml
CL-HTTPと言うライブラリを用いたWebサーバーの説明が載っています。
ただし、本自体はMacintosh用の商用実装、Mac Common Lisp

Mac Common Lisp:
http://www.digitool.com/

を用いたものなんで、注意する必要があります。Macを持ってないならあまりお薦めしません。また、若干古い本ですね。

Haskellの方は良く分かりませんが、Common LispならそれなりにWeb関係の簡単なアプリの書き方も紹介されている、と言う事です。

参考までに。

C言語が「関数型」?なのか、と言われると多分違うと思うんですけどね。普通は命令型/手続き型に分類されるんじゃないか、と思います。

ちなみに、JavaScriptはSchemeに影響を受けてる言語です。それで言うと、SchemeかCommon Lispがいいんじゃないのかな、とは思いますがね。ただ、あんまり関数型、って感じで書かれている本は少ないと思います。

Web系志望と言う事なんで、Common Lispですと、

ANSI Common Lisp: http://www.pej-hed.jp/washo/288.html
にHTML生成のトピックあり。

実践Comon Lisp: http://s...続きを読む

Q#include

#include <stdio.h>

struct st
{
char a[3];
short b;
char c[7];
long d;
char e[5];
};

int main(void)
{
printf("%d\n",sizeof(struct st));
return 0;
}

コンパイルオプションでアライメントを変化させながら(1,2,4,…)
sizeof(struct st)の変化を見たいのですが、コンパイルする時に
どのようにすれば良いのでしょうか?当方、gccを使用しております。

あと、ついでなんですが、警告オプションは-Wと-Wallしかないのでしょうか?

Aベストアンサー

GCCのマニュアル
http://gcc.gnu.org/onlinedocs/index.html
日本語訳は古いバージョンのしか見つからなかった。

> アライメントを変化させながら
http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html#Variable-Attributes

コンパイラオプションでやるなら、-Dでマクロを使うなりして。
インテルプロセッサだと
http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/i386-and-x86_002d64-Options.html#i386-and-x86_002d64-Options

> -mpreferred-stack-boundary=num
> -mincoming-stack-boundary=num
というあたりも関係あるかも

>警告オプションは-Wと-Wallしかないのでしょうか
http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/Warning-Options.html#Warning-Options

GCCのマニュアル
http://gcc.gnu.org/onlinedocs/index.html
日本語訳は古いバージョンのしか見つからなかった。

> アライメントを変化させながら
http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html#Variable-Attributes

コンパイラオプションでやるなら、-Dでマクロを使うなりして。
インテルプロセッサだと
http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/i386-and-x86_002d64-Options.html#i386-and-x86_002d64-Options

> -mpreferred-stack-boundary=num
> -mincoming-stack-boundary=num
とい...続きを読む


人気Q&Aランキング

おすすめ情報