> ところで「Javaの格言」という本では、 Pointのx, yをprivateにするメリットとして、
> マルチスレッド時の排他制御を挙げています。しかし、getX(), getY(), setX(), setY()
> を作ってそれぞれをsynchronizedにしたところで、この仕様ではマルチスレッドには
> 対応できません。ちょっと考えてみればわかるように、 getとsetが分かれていたり、
> setのXとYが分かれていたりしていたのでは、複数のスレッドで実行されたら結局
> 変なことが起きます。
複数のスレッドが同じPointオブジェクトを参照している場合、
ロックはメソッド単位ではなくインスタンス単位に存在するので、
getとsetが分かれていても問題無いと思うのですが。
> 掲示板に貼られた箇所以前の
> バグのせいで変なことが起こった可能性は否定できないので、
> まだそちらで再現できるのであれば、ソース全体を、手を加えずに
> そのまま、掲示板に貼っていただけませんか?
>
#include <stdio.h>
int main(void)
{
double height,weight,rohrer;
printf("あなたの身長を入力してください>");
scanf("%lf", &height);
printf("あんたの体重を入力してください>");
scanf("%lf", &weight);
rohrer=weight/(height*height*height)*10000000;
printf("あなたのローレル指数は%fです。\n", rohrer);
/*if文:ローレル判定の為*/
printf("判定:");
if(100<rohrer){
printf("痩せ過ぎです");
}else if(115<rohrer){
printf("痩せ気味です");
}else if(145<rohrer){
printf("標準です");
}else if(160<rohrer){
printf("デブ気味です");
}else{
printf("デブそのもの");
}
return 0;
}
ですね。
自分がよく行く HAPPY Macintosh Developing TIME!
http://homepage.mac.com/mkino2/
でも指摘してましたが、メッセージとメソッドを明確に分離している
プログラミング言語(Objective-Cとか)だと
「メッセージ送出=単なる関数呼び出し」にはならないです。
ここらへんはオブジェクト指向としての理念をどう実装するか
という問題で、静的なOOP言語の実装が「関数呼び出し」にしている
という楽屋裏の話なので、そういうのをうまくからめておかないと
よくC++プログラマが勘違いして説明している
「クラスとは構造体のことだ」に似た誤解を広めてしまう危険がある
と思います。実際のところ、おいらもObjective-Cをよくわかって
なかったとき、セレクタってC++のメンバ関数ポインタみたいなもんだ
という勘違いをしてたんですけどね。
安藤幸央さんのページで、Java 良本・Javaベストブックの投票
というものをやっています。
「Java謎+落とし穴 徹底解明」も、2票入ってますね。
疑り深いあなたのためのオブジェクト指向再入門
の、オセロを例に考える、ですが、(java のことは
知りませんが少なくとも C++ では) board がポインタ
なら、board.put(x,y) じゃなくて board->put(x,y)
なのでは?
> >そのくせ、if(0==x)という書き方を使って安全に配慮してたりして。
>
> これは今時は時代遅れのテクニックです。
> http://www.catnet.ne.jp/kouno/c_faq/c17.html
> の12.4でも
そのほか、Phinlodaさんの「Cプログラミングの秘訣」でも。
http://www.st.rim.or.jp/~phinloda/cprog.html
| 私が最後にこの間違いをしたのは、確か数年も前のことで、
| なんとこのバグを取るのに殆ど1日かかってしまいました。
| それみろ、言わんこっちゃない、定数を左に書いておけば
| 1日得したではないか、って? 残念ながら、それは外れです。
| なぜなら、私がこの時間違えたのは、比較の左右ともに
| 変数だったからです。左右ともに変数だと、どちらにどちらを
| 書いてもコンパイルは正常に終了してしまうのです。
コーディング規約ネタなら、このページは参考になると思います。
私としては、異論もなくはないですが、おおむね賛成です。
> つまり、今回のようなバグが発生した原因というのは、
>
> ifが持ってきた条件文と他のifによって追加された条件文が、
> 重なってしまった為に発生した。
>
> って事ですか?
この文章の意味は分かりませんが、掲示板に貼られた箇所以前の
バグのせいで変なことが起こった可能性は否定できないので、
まだそちらで再現できるのであれば、ソース全体を、手を加えずに
そのまま、掲示板に貼っていただけませんか?
いろんな人がいますからね。コの業界は。でも
>そのくせ、if(0==x)という書き方を使って安全に配慮してたりして。
これは今時は時代遅れのテクニックです。
http://www.catnet.ne.jp/kouno/c_faq/c17.html
の12.4でも
>これでは両辺が変数の場合のif(a = b)という誤りを捉えることはできない。
>こんな技を覚える暇があれば、lintの使い方 を覚えること。
と、しっかり批判されています。
> > > 「142.479137」は100よりも大きいですから、判定も狂っています。
> > …と書いてしまいましたが、これについては掲示板に貼られている
> > ソースだけで原因が分かりますね。不等号の向きが逆ですから。
> ぬはっ!?
> こんなミスがあったとは。
> と言いますか、142と言う値でなんの問題も無いと勘違いしてましたし。
142という数値は(おそらく)問題ないですけど、
(ぱ)さんは、142という値で「やせすぎ」と判定するのは
programの不具合だといっているんですよ。
このとびちよさんのprogramには2つの不具合があります。
一つは表示の問題。一つは上の判定箇所の問題です。
不等号の向きで解決するのは判定箇所の問題です。
142は100以上なので、やせすぎと判定するのは不具合です。
それは、不等号の向きが違うのが原因です。
でも、以下のprogramに対して、
printf("判定:");
if(100<rohrer){
printf("痩せ過ぎです");
期待される表示は、 「判定:痩せ過ぎです。」 ですが、
とびちよさんの環境では「判定:142.479137痩せ過ぎです。」と
表示されるんですよね?
これが、表示の問題です。
それは、このprogramからはありえないので、
programの他の部分の不具合と、何か環境の問題が含まれていると思われます。
とりあえず、programと、入力・出力を全部書き込んでみてください。
> つまり、今回のようなバグが発生した原因というのは、
> ifが持ってきた条件文と他のifによって追加された条件文が、
> 重なってしまった為に発生した。
> って事ですか?
この文章の以下の意味がわかりません。
ifが持ってきた条件文...
他のifによって追加された条件文...
ifが条件文を持ってきたり、追加したり、という表現は普通しませんよね?
また、この文章の意味はわかりませんが、
不等号の向きで判定を間違えることと 表示がおかしいこととは関係ないです。
> >・条件式での代入は原則禁止
> これは“if(a==b)”と書くつもりが“if(a=b)”となる事態を避ける
> という意味もあるような気が…うがった見方でしょうか…。
身近にif()文の条件式でif(a=b)の様な代入文を平気で使える人がいますが、
私はとても真似できません。怖くないのかしらって思っちゃう。
gccの-Wallでif(a=b)に警告が出るのをウザいとか言ってます。
これだから素性の知れないfreeのcompilerは使えないのじゃ。とか。
そのくせ、if(0==x)という書き方を使って安全に配慮してたりして。
でも、lintは通すので(void)printf()という使い方するんですよね。
その人とは本当にスタイルが合わないんですよ。私。
#うちの会社はスタイルに関してかなり寛容でルールが少ない(^^;)
> 個人的には、
> >while((c = getchar()) != EOF)
> がダメというなら、
> while(c = getchar(), c != EOF)
> は認めるとか通達を出したいところですが。LISPerを除いては
> カッコが入れ子になるのはプログラマーの負担になるから(笑)。
これを見てて最近やった手痛いミスを思い出しました。
gccの条件文内の代入に関する警告を信用しすぎてたんですが、
if ( (a==b) && (c==d) )と書くべきところで、
if ( (a= b) && (c==d) )と書いてしまったとか言うミス。
かなり長い時間デバッグしました。この部分で。
なぜ常に通過するんだこの条件式は?しかもaの値は変わるし。
gccのバグか?なんて言い出しかけたりして...f(^^;)。
条件式を2つ書いた場合、一つが代入式でもコンパイラは警告出さないんですよね。
でも、もし出すようにすると(そんなoptionあるのかな?)、
上のwhile()は両方とも警告対象になっちゃいますね。
> >・?:演算子は原則禁止(マクロ除く)
「?:」って、便利ですよね。関数の引数が条件で一部だけ変わるときとかに。
使えないと困るわけじゃないけど、行数が増えて嫌だなぁ。
> 最近のコンパイラは知りませんが、昔のコンパイラで最適化を最強に
> するとsetjmp/longjmpが含まれた箇所は軒並みコケてしまうのがあった
> ような記憶が…。
最適化って普通どれくらいでやってるんですかね。みなさんは。
うちは-O2(-xO2)にするというのが、暗黙のルールになっているようです。
実際、3以上の最適化って測ってみても効果がない様ですし。
5とかにすると遅くなるような結果が出ることもあるし。
2以上は安全ではないとか言う人もいますが、本当なのかしら?
私なんかは最適化が何をやってるのかあまりわかってないので
何も考えずに-O2をおまじないにしてますが。
> > 「142.479137」は100よりも大きいですから、判定も狂っています。
>
> …と書いてしまいましたが、これについては掲示板に貼られている
> ソースだけで原因が分かりますね。不等号の向きが逆ですから。
ぬはっ!?
こんなミスがあったとは。
と言いますか、142と言う値でなんの問題も無いと勘違いしてましたし。
つまり、今回のようなバグが発生した原因というのは、
ifが持ってきた条件文と他のifによって追加された条件文が、
重なってしまった為に発生した。
って事ですか?
解決したことですから書いてもどうしようも無いと思いますが、
一応私の環境は
WIN98SE
Borland のコンパイラver.5.5(最新版か?)
DOS
Lyre(このソフトが今のところ記述が最高にわかりやすいエディタ)
みたいなもんです。
> 「142.479137」は100よりも大きいですから、判定も狂っています。
…と書いてしまいましたが、これについては掲示板に貼られている
ソースだけで原因が分かりますね。不等号の向きが逆ですから。
こちらで、rohrer.cのソースに対し「printf("やせ過ぎ");」のように
改行を外したものを作成し、テストしてみましたが、同様の現象は
発生しませんでした。
> どうして\nを抜かすと、
>
> >判定:142.479137痩せ過ぎです。
>
> みたいなことになるのですか?
> 確か、改行の意味だと把握していたのですが・・・・・・。
改行の意味で合っています。
まあ、C言語なんてのは、領域破壊系のバグを入れると「何が起きるか
わからない」言語ですから、ここより前の記述によっては、こういう
現象が起きる可能性はなくはないですが、それにしてもちょっと
不思議な感じがします。
「142.479137」は100よりも大きいですから、判定も狂っています。
Win9x系のDOS窓は、
http://member.nifty.ne.jp/maebashi/seiha/hosoku004.html#dosmado
に挙げたようなバグがありましたから、その辺が絡んでいる可能性も
捨て切れませんが…
というわけでとびちよさんにお願いですが、
そちらで実行したrohrer.cのソースの全体を、ここに貼っていただけませんか?
また、確認ですが、環境は「bcc32 + Win98 + DOS窓」で合ってますよね?
ようやく、chapter1の終了までいきました。
終わったついでに、一つ疑問が残ったので質問。
>chapter1の最後のList1-6について
練習問題ということで、てきとうに書いてみて
コンパイルしてみたところミスはありませんでした。
そこで、出来あがったファイルを起動し結果を見てみると
>あなたのローレル指数は142.479137です。
>判定:142.479137痩せ過ぎです。
となりました。
ソースは、
printf("あなたのローレル指数は%fです。\n", rohrer);
/*if文:ローレル判定の為*/
printf("判定:");
if(100<rohrer){
printf("痩せ過ぎです");
>else ifが続きますが、やたら長くなるので略。
return 0;
}
となっていました。
printf("痩せ過ぎです");
を見ると解かるように、\nが書かれていなかったからなのですが、
どうして\nを抜かすと、
>判定:142.479137痩せ過ぎです。
みたいなことになるのですか?
確か、改行の意味だと把握していたのですが・・・・・・。
宜しくお願いします。
> ただ、「現代的な設計方針の中には、include のネストは禁止という
> ルールを設けても、特に問題ないようなものがある」というのが、
> ここでの僕の主張です。
ええと、私もkitさんも、
・「設計方針を問わず、include のネストは禁止」というのは
よくない。
・不完全型宣言を使うことで構造体の内容を隠蔽することで、
ヘッダファイルの依存関係を減らすことができる。
という点では同意してると思うんですよね。
その上で、#includeのネストを禁止されると困る「頻度」がどの程度か、
というのが問題なのだと思います。
> これに対し、DRW_Line.h 中の struct DRW_Line の定義が、
> struct DRW_Line {
> struct DRW_Point *start_point, *end_point;
> };
この場合は、DRW_Pointを不完全型で宣言するわけですよね。
「えー、たかがPointごときに〜?」と、私なら思います (^^;
Pointごときにヒープを使うのは富豪的プログラミングでは
許されるとしても、Cだとfree()の手間がありますし。
また、列挙や#defineは、不完全型で隠すことはできませんし。
> や、あるいは
> struct DRW_Line;
> だけだった場合、
このケースでは、DRW_Lineが不完全型宣言されているわけですが、
ではstruct DRW_Lineの宣言の本体はどこにあるかというと、
kitさんの前提では、DRW_Line.cでしょうか。
struct DRW_Lineはそれでよいかもしれませんが、たとえば、
「ウインドウ」を抽象化するDRW_Windowではどうでしょうか。
もちろん、使用者に対してはDRW_Windowは不完全型宣言にして
ポインタのみを提供します。しかし、DRW_Windowを参照する
.cファイルはDrawLib内部にはたくさんあるでしょうから、
構造体の定義は、プライベートヘッダファイルdrw_lib.hに
書くことになるはずです。
このとき、DRW_Window構造体は、Xlibの提供する型である
Windowをメンバに持つはずですから、drw_lib.hは
Xlib.hを#includeしなければなりません。
また、DrawLibがDRW_Windowごとに何らかの「描画モード」を持ち
使用者から制御可能であるのなら、DRW_Windowは
列挙型DRW_CurrentDrawingModeをメンバに持つはずで、
drw_lib.hはそれを宣言しているパブリックヘッダファイルを
#includeしなければなりません。
…とここまで書いて、想定している「モジュール」の粒度が
違うんじゃないかという気がしてきました。kitさん的には、
DRW_Window構造体も、DrawLib内部とはいえ「丸見え」にすべきでは
なくて、DRW_Window.c内に封入すべきなんでしょうか。
でも、そうだとしても、DRW_DrawLine.cではXlibのWindowが
必要になりそうですから、DRW_WindowにgetXWindow()を付けたとしても
その戻り値はXlibのWindowになるはずですし…
> コンバイルできないのなら、エラーメッセージが出たはずです。
> 質問するのなら、せめてエラーメッセージぐらいは付けてください。
あ、すいません。次から気をつけますね。
> 掲示板にソースをそのままコピペしたのであれば、同じメッセージがそちらでも
> 出ているはずですが、そのメッセージを見て、どう考えましたか?
考えたこと:セミコロンなのに、どの辺が不正なのか、
という辺りで行き詰まって進展できませんでした。
> カーソルを持っていけば分かるでしょう。要するにセミコロンが
> 全角になっているのです。
あぁ、なるほど。2バイト文字じゃあどうしようもありませんね(汗
わざわざ有難うございます。
出来るだけ自分で解決するようにしますね。
> ・条件式での代入は原則禁止
プログラムは単純であるに越したことはないですから、1行に多くの処理を
押し込むような書き方は避けるべきだと思います。だから
if ((fp = fopen("hoge", "r")) == NULL) {
/* エラー処理 */
}
というのを禁止、というのなら私は異論はありません。こんなのは
fp = fopen("hoge", "r");
if (fp == NULL) {
/* エラー処理 */
}
と書けばよいからです。実際私はそう書きます。
しかし、
> while((c = getchar()) != EOF)
この例では、こう書くことで、「c = getchar()」を一度しか書かずにすむ
というメリットがあるので、禁じられるとちょっと悲しいわけですよね。
「c = getchar()」を2回書くのは大変に汚いと私は思うので、
書くならこうでしょうか。
for (;;) {
c = getchar();
if (c == EOF)
break;
/* cを使う処理 */
}
> ・?:演算子は原則禁止(マクロ除く)
> ま、if〜elseで間に合うっちゃぁ間に合いますね
> (マクロ除く)というあたりが中途半端ではありますが
これは禁止でかまわないように思います。もちろんマクロは除いて。
たまに便利なことはありますが、乱用される危険のほうが大きいでしょう。
> ・関数へのポインタを返す関数の使用は原則禁止
> ん〜〜〜〜〜
> signal関数は使っちゃぁダメなのかなぁ・・・
「関数へのポインタを返す関数」を、「作ってはいけない」のではなく
「使ってはいけない」のでしょうか。だとするとさすがに困ることが
ありそうですが。
「関数へのポインタ」は、その柔軟さゆえに、プログラムを追いにくく
する面はかなりあると思うので、乱用は慎むべきだと思います。
実のところ私はポリモルフィズムにも同様の欠点があると思いますが。
それにしても、「関数へのポインタを返す関数」がダメってのは、
妙な限定条件ですね。
> ・setjmp/longjmpは厳禁
> 「原則禁止」じゃなくて「厳禁」と来ました。
setjmp/longjmpは使いようによっては便利ですけれど、
使うなら、プログラム全体で方針を決める必要がありますよね。
> みたな事になってますが、コンパイルできないのは何故でしょうか。
コンバイルできないのなら、エラーメッセージが出たはずです。
質問するのなら、せめてエラーメッセージぐらいは付けてください。
で、掲示板に書き込まれたソースをこっちでコピペしてbccでコンパイル
したところ、以下のエラーメッセージが出ました。
エラー E2206 bmi.c 8: 不正な文字 ';' (0x8147)(関数 main )
エラー E2379 bmi.c 9: ステートメントにセミコロン(;)がない(関数 main )
エラー E2206 bmi.c 11: 不正な文字 ';' (0x8147)(関数 main )
エラー E2379 bmi.c 12: ステートメントにセミコロン(;)がない(関数 main )
掲示板にソースをそのままコピペしたのであれば、同じメッセージがそちらでも
出ているはずですが、そのメッセージを見て、どう考えましたか?
エラーメッセージには行番号が出ています。最初のエラーは8行目で
起きていますから、この行です。
> printf("体重を入力してください>");
この行に、';'という不正な文字があると、コンパイラは言っています。
この行にあるセミコロンがなぜ「不正な文字」なのかは、その上に
カーソルを持っていけば分かるでしょう。要するにセミコロンが
全角になっているのです。
>・条件式での代入は原則禁止
これは“if(a==b)”と書くつもりが“if(a=b)”となる事態を避ける
という意味もあるような気が…うがった見方でしょうか…。
COBOLがどうのというより条件式では比較判断のみに押さえておくべきで
代入のような副作用が起きるのは美しくないとかそういう“美的(笑)”
センスで決めたとか…。よくわかりませんね。決めた人の意図が。
個人的には、
>while((c = getchar()) != EOF)
がダメというなら、
while(c = getchar(), c != EOF)
は認めるとか通達を出したいところですが。LISPerを除いては
カッコが入れ子になるのはプログラマーの負担になるから(笑)。
>・?:演算子は原則禁止(マクロ除く)
これは、ほとんどのプログラマーがLISPer的センスがないので
?:演算子に拒絶反応を示すからとかそんなのだろうか…。
聞くところによればC言語の入門書で使うなと指導しているものもあるとか。
単に入門書を書いた作者の頭がついていけないだけの気が(笑)。
>・関数へのポインタを返す関数の使用は原則禁止
これも、ほとんどのプログラマーがついていけないセンスだから
とかそんなのだろうか…。
>・setjmp/longjmpは厳禁
これは厳禁するほうが無難ですよ。だってgoto文をさらに凶悪にした
ようなものだから。最適化がからむと事故を起こす元凶にもなるし。
最近のコンパイラは知りませんが、昔のコンパイラで最適化を最強に
するとsetjmp/longjmpが含まれた箇所は軒並みコケてしまうのがあった
ような記憶が…。
> > 使うこともあれば、使わないこともあるんじゃないでしょうか。
> 場合によってはそうかもしれませんが…
まず一応確認ですけど、「設計方針を問わず、include のネストは
禁止」というのは、時代遅れなルールじゃないかと僕も思います。
ただ、「現代的な設計方針の中には、include のネストは禁止という
ルールを設けても、特に問題ないようなものがある」というのが、
ここでの僕の主張です。
> たとえばXlibを隠蔽する描画モジュール、DrawLibを作るとき、
> アプリケーションにはXPointは見せず、DrawLibが提供する
> DRW_Pointを見せるようにするとして、DRW_Libの内部関数や、
> プライベートな構造体にDRW_Pointが登場することは必然のように
> 思うんですけれども。
これは、ちょうど良い例なので、そのまま使わせてもらいます。
DRW_Lib.h 自身に、DRW_Point の定義が直接記述されていれば
(ぱ)さんの書かれた通りでしょう。でも、DRW_Lib.h の全ての型が、
それぞれ DRW_Point.h のような独立した公開ヘッダで記述されて
いれば、Indian Hill が禁止している意味でのヘッダのネストは
起きないのでは?
この場合、DRW_Lib.h は、
#include <DRW_Point.h>
#include <DRW_Line.h>
:
という風に #include の羅列のみから成るわけですが、これは
Indian Hillでも
| いくつかのソースファイルが多数の同じヘッダをインクルード
| しなければならないというような極端な場合は、共通する
| #include をひとつのインクルードファイルにまとめるのも
| よいだろう。
のようにネストとは別扱いされている部類だと思います。
そして、この場合、内部関数の実装では、#include <DRW_Lib.h>
は行わず、DRW_Point.c では #include <DRW_Point.h> のみ、
DRW_Line.c では、#include <DRW_Point.h> と #include <DRW_Line.h>
のみを含むようになるんではないでしょうか。
ここでもし、DRW_Line.h の中で struct DRW_Line が
struct DRW_Line {
struct DRW_Point start_point, end_point;
};
のように定義されていた場合、DRW_Line.h の先頭で
#include <DRW_Point.h> とした方が良い、
すなわち #include をネストさせた方が良いと僕も思います。
これに対し、DRW_Line.h 中の struct DRW_Line の定義が、
struct DRW_Line {
struct DRW_Point *start_point, *end_point;
};
や、あるいは
struct DRW_Line;
だけだった場合、DRW_Line.h は、DRW_Point.h を #include する
必要はないし、むしろ、しないようが良いでしょう。
現代の富豪的プログラミングでは、この2種類のDRW_Lineのうち、
後者のような設計が可能になってきており、パッケージ全体を
こういうポリシーで設計した場合には、#include のネストを
禁止したところで特に実害はないと思うというのが、僕の最初
のポストの主旨なわけです。
> Factoryでいろんなクラスを作成し、ポリモルフィズムで処理を分ければ、
> 列挙とunionとswitch caseに頼る必要はなくなる、ということですよね。
その通りです。switch 文のパラメータに列挙型が与えられている
ような場合のほとんどは、列挙型を使わずに、ポリモルフィズムを
使って書いた方が現代的ですよね。
> というわけで、列挙型の使用頻度は「低くなる」んですが、
> 「なくなる」わけではない
これは同感です。
さてさて
今日もいろいろ面白いのを見つけたので紹介します。
・条件式での代入は原則禁止
while((c = getchar()) != EOF)
は使ってはいけないみたいです。
ということは、この場合は、
c = getchar();
while(c != EOF)
{
/* cを使う処理 */
c = getchar();
}
って書けってことですかね?
確かにCOBOLとかだとこう書くのが一般的らしぃですが・・・
せっかくCを使うんなら、無理にCOBOLにあわせなくてもいいのに・・・
・?:演算子は原則禁止(マクロ除く)
ま、if〜elseで間に合うっちゃぁ間に合いますね
(マクロ除く)というあたりが中途半端ではありますが
・関数へのポインタを返す関数の使用は原則禁止
ん〜〜〜〜〜
signal関数は使っちゃぁダメなのかなぁ・・・
・setjmp/longjmpは厳禁
「原則禁止」じゃなくて「厳禁」と来ました。
これは理由として、連携して使うミドルウェアのTPモニタ側の都合だそうで、
まぁ納得のできる禁止事項でしたね。
勝手にlongjmpで戻られたりしたら、
トランザクションがどっかに消えてしまいそうですしね。
また識者の方々のコメントを頂戴したく思います。
ではまた。
#include <stdio.h>
int main(void)
{
int height;
int weight;
printf("身長を入力してください>");
scanf("%d", &height);
printf("体重を入力してください>");
scanf("%d", &weight);
printf("身長は%d\n", height);
printf("体重は%d\n", weight);
return 0;
}
みたな事になってますが、コンパイルできないのは何故でしょうか。
多分私がミスしていると思うのですが、御教授お願いします。
> DOSの本はさすがに売ってないんじゃないでしょうか(^^;
> ---と思いつつ探したら、こんな本がありました。著者は米田聡さんか…
一応、DOS本は1冊もってます。結構、前の出版ですが解説が詳しいのでよくつかってます。
ぐは・・・・・・。覚えられてましたか。
あの時は、早々に挫折してAUのxhtml basic と hdml 等を触ってたので、そっちを先にとっかかっていたら、あらこんなに時間が経ってしまったのね、みたいな(汗
昨日、この質問を書き込んでから、googleで関連情報を抜き出していたら、再起動するって書いてあって、解決しちゃったんですよね、実は。
てか、borland c++のヤツに再起動なんて一言も書かれていなかったんですけど、「システムいじっているから再起動しなくて良いのかな?」とか思っていたんですが・・・・・・なんだかなぁ。
兎に角、有難うございました。
コンパイルが出来るようになったので、こっからかなりお世話になっちゃうと思いますんで宜しくお願いします。
> 使うこともあれば、使わないこともあるんじゃないでしょうか。
場合によってはそうかもしれませんが…
> 階層化されたソフトウェアの場合、プライベートヘッダファイルを
> #include しているモジュールが呼ぶのは、より低レベルの非公開
> モジュールだけであり、公開されているレベルのインターフェースは
> 全く必要としないということも、ままあるような気がします。
たとえばXlibを隠蔽する描画モジュール、DrawLibを作るとき、
アプリケーションにはXPointは見せず、DrawLibが提供する
DRW_Pointを見せるようにするとして、DRW_Libの内部関数や、
プライベートな構造体にDRW_Pointが登場することは必然のように
思うんですけれども。
> データ受け渡し用の構造体や共通関数は、くだんのプログラムでは、
> より下位のレイヤで提供していて、それだけで独立したヘッダに
> 入っており、公開インターフェースには入っていませんでした。
もちろん、「より下位のレイヤ」(この場合のXlib)の型である
XPointも、DrawLibの内部実装で使いまくることになるかと思います。
> あと余談ですけど、オブジェクト指向的設計を用いた場合、列挙型の
> 使用頻度は低くなりますよね。伝統的設計で列挙型を使うケースの
> 多くで、代わりに Factory クラスなどを使うことになるので。
Factoryでいろんなクラスを作成し、ポリモルフィズムで処理を分ければ、
列挙とunionとswitch caseに頼る必要はなくなる、ということですよね。
というわけで、列挙型の使用頻度は「低くなる」んですが、
「なくなる」わけではないので、やっぱりJavaでは泣かされています。
> 私の時代(20年近く昔^^;)には、アスキーの「標準MS-DOS
> ハンドブック」あたりが定番だったんですが、今だとどう
> いう本がいいんでしょうね。
DOSの本はさすがに売ってないんじゃないでしょうか(^^;
---と思いつつ探したら、こんな本がありました。著者は米田聡さんか…
http://www.amazon.co.jp/exec/obidos/ASIN/4797320435/ref%3Dpd%5Fsim%5Fdp%5F4/249-7021655-2201111
Cを勉強する上では、コマンドラインが扱えないと
やっぱり困ると思うので、「体当たり学習〜」には
「かんたんDOS窓講座」という補足を入れておきました。
とはいえ、たかが見開きひとつで2ページの分量なので、
説明できたのはdir, cd, mkdir, ドライブ切り替え, および
doskey /insertだけですが...
もう少し詳しい説明はないものかとGoogleしたら、こんなページがありました。
「DOS窓探検隊」
http://www.geocities.co.jp/SiliconValley-Oakland/4777/index.html
ここもさほど詳しくはないようですが…
> 始めまして。とびちよと申します。
はじめまして…ではないような気がしますが。
http://member.nifty.ne.jp/maebashi/bbs/bbs10.html
ここの464で登場されている「とびちよ」さんと、ハンドルネームだけでなく
メールアドレスまで一致してるんですが…
まる1年、同じ問題で引っかかっていたのでしたら、力になれずすみませんでした。
> コマンド、ファイル名が違います。
kitさんからも返答がありましたが、これはPATHが設定されていないためです。
環境変数PATHについては、「体当たり学習〜」のp.32に説明があります。
ただ、そこでは、PATHの機能について説明しているだけで設定方法には
触れていませんから、ここで説明すると、
Win98なら、C:直下に「AUTOEXEC.BAT」というファイルがあると思います。
bccをC:直下にインストールしたのなら、AUTOEXEC.BATの末尾に
SET PATH=%PATH%;C:\Borland\Bcc55\bin
を追加し、PCを再起動してみてください。
ただし、これだけでは「コマンドまたはファイル名が違います」とは
言われなくなるでしょうが、bccは動きません。
bccをC:直下にインストールしたのなら、C:\borland\bcc55の下に
readme.txtというファイルがあるはずです。
このファイルにある手順を踏まないと、bcc32は動きません。
コピペするとこう。
| 2. インストール先の bin ディレクトリで次の手順を実行します。
| a. 既存のパスに "c:\Borland\Bcc55\bin" を追加します。
| b. bcc32.cfg ファイルを作成します。このファイルは,Include
| および Lib パスのコンパイラオプション(コンパイラの -I
| および -L スイッチ)を設定するものです。ファイルには次の
| 行を含めてください。
| -I"c:\Borland\Bcc55\include"
| -L"c:\Borland\Bcc55\lib"
| c. ilink32.cfg ファイルを作成します。このファイルは,Lib
| パスのリンカオプションを設定するものです。ファイルには
| 次の行を含めてください。
| -L"c:\Borland\Bcc55\lib"
aについては上で説明しました。あとはb, cをやればいいわけです。
旧掲示板のほうでdentomさんが紹介されているページでは、
自動設定ツールを紹介していますが、Cマガジンのページが移転して
しまったので現在は辿れませんね。新しいCマガジンのページで
検索かけてみましたが、見つかりませんでした。
> コマンド、ファイル名が違います。
> と表示されました。
ええと、たぶん Windows か MS-DOS に関する書籍で、
環境変数 PATH に関する事項を勉強された方が良いと
思います。プログラミングに関する書籍ではなく、
利用法に関する書籍にも解説があると思います。
これは、ある意味非常に初歩的な事項なので、こういう
レベルの事項を知らずに、ずっと難しいC言語による
プログラミングを勉強するのはかなり辛いと思います。
PATHに関する説明だけなら、そんなに難しくはないですけど、
たぶん、他にも沢山欠けている基本知識があると思うので。
私の時代(20年近く昔^^;)には、アスキーの「標準MS-DOS
ハンドブック」あたりが定番だったんですが、今だとどう
いう本がいいんでしょうね。