トップページ⇒prog
75コメント25KB

めっちゃ初心者です(C言語)

■ このスレッドは過去ログ倉庫に格納されています
0001GutsNGNG
C言語始めて作り始めたんですけど
簡単なプログラムばっかなのに
ちゃんと動作できなくて、、、
ソースをHPにのっけてるんで、
ここ変だよとかおしえてくれたらうれしいです
ここの掲示板でいってくれてもいいし 自分の掲示板でもいいでっす
http://www.fsinet.or.jp/~icho/guts/

0002名無しさんNGNG
110が'n'なら、'1'や'0'は何?

rand()が返す値は?

↓これならどう? これの意味は?
if( com == (you - '0') )
0003新開地商店街NGNG
全然間違いではないんだけど……
数を入力させた後で、当てるべき乱数を生成するってのは、
なんか後出しみたいで心情的にヤだ(笑)
0004名無しさんNGNG
atoiはマズいんじゃねえか?
引数はNULLエンドの文字列にしなきゃ。
0005名無しさんNGNG
・エラーコードを返すわけでもないんだし、main()がintである必然性は???
・引数がないときにわざわざ(void)と書くのは一般的なんだろうか???
・フラグを立ててループを抜けるよりもbreakの方が良くない???
・配列のサイズは#defineのでやらないと嫌われるかも
>3
だよねえ、すごく抵抗ある。
0006名無しさんNGNG
んー、atoi()の引数に&がついているのを見たのは初めてです。
0007まずはNGNG
見やすいソースの書き方を身につけよう。
0008名無しさんNGNG
>・エラーコードを返すわけでもないんだし、main()がintである必然性は???

ふつ〜int
0009名無しさんNGNG
>・引数がないときにわざわざ(void)と書くのは一般的なんだろうか???

Cなら一般的じゃない?
0010>5NGNG
>・エラーコードを返すわけでもないんだし、main()がintである必然性は???

『main関数をreturnで抜けると、』の板を読んでよ。
初心者にウソ教えないでほしいな。
0011GutsNGNG
>3
あはは、そうですねゲームやってるときそーいうっぽいのに
であうと 僕もイヤでしたからこれからは乱数は先にだしときます

>4
えーと、、、もうちょっと詳しくおしえてもらえないでしょうか?

>5
えーと int main(void)
はチャット式です(わかりますよね?
webではあそこでまなびましたので、、、
本ももってますけど チャット式に、、、
あと配列のサイズ??を#defineですか?
これもよくわかりませーん #defineはわかりますけど、、、(いちおー

>6
ひろさんというかたが教えてくれました。

>7
はい! ほんと見ずらいですよね、、、
あう、、、長々とレスつけてしまった
レスついてたのがうれしくて、、、
げ、、、学校遅刻だよ(−−;;

0012むふーんNGNG
fgets で文字列取り込み>文字列を atoi にぶちこむ。
ループはfor(;;)で breakで抜けた方がいいかな。
ちゃんとリファレンス読んでる?
0013名無しさんNGNG
ねぇねぇ、HTMLで<PRE></PRE>ってタグがあるんだけど
プログラムの表示のところで使ってみない? 楽だし綺麗だよ。

それとC言語の本ってどこの書籍だろう?
00145NGNG
>『main関数をreturnで抜けると、』の板を読んでよ。
なるほど、納得。
ところで、それは板じゃなくってスレッドでしょ? ウソ教えないでね。
00154NGNG
>Guts
これ動かしてみな。どうなる?

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char a = 0@` b = '1'@` c = '2'@` d = '3'@` e = 0;
printf("%d\n"@` atoi(&c));
return 0;
}

それから、ひろさんは信用しねえほうがいいと思うぞ。
0016名無しさんNGNG
チャット式とやらを覗かせてもらったけど、
考え直したほうが良いと思う。

「わかりやすい」と「ただしい」の区別はわかるよね? > 1
0017#10423NGNG
>15
ANSI準拠のCだと、「鼻から牛乳」でもOKだよね
0018GutsNGNG
>13
タグ教えてくれてありがとうございます
早速つかってますー
あと本は林晴比古のC言語入門のスーパービギナーとシニアです
ちなみにシニア編はまだほとんど読み進めてません。

>15
えーと 2と表示されましたけど、、、
ひろさん信用しないほうがいいですかね?
掲示板であのatoiの使い方はイレギュラーだったっていってますけど?

>16
それはわかりますけど、、、
チャット式はどこらへんが正しくないですか??

0019GutsNGNG
あーあとHP更新しました
ちょっと新しくなった数当てみてみてください
0020むふーんNGNG
なかなかいいよ。
srandは最初に1回でいい。
あと、continue っていう命令を調べてみて。
0021>GutsNGNG
continueを使いなはれ>これでまたwhileの最初に戻すにはどうすりゃいいんだろ
0022名無しさんNGNG
ねぇねぇ、コマンドプロンプトでプログラムのテストをしない?
そうすれば最後に出てくる謎のgetchar()は不要だし。
0023むふーんNGNG
>15
ほんとか?普通(普通って何だ?)23だろ?
追加。
getsで取り込むの止めてfgets使ったほうがいい。
gets使うくらいならscanf使いなよ。
0024むふーんNGNG
上は>18の間違い。ごめんよ。
0025#10423NGNG
>23
間違い!!
0026うーん、、NGNG
15のプログラムは間違いですねぇ…
18さんの結果が2になったのは運が良かっただけですね。
23さんは妄想入ってるが、これがstaticな変数だったら運の良い
処理系に当たった場合にそうなるけどね。
0027むふーんNGNG
ああ%dか。%sだと思ってたよ、、
0028GutsNGNG
>むふーんさん
えー、、、2なんですけど、、、
他の人はどうです??

あとcontinueでしたね、、、
こんな基本もわからないなんて、、、
0029むふーん NGNG
printf("%d\n"@` atoi(&c));
の部分を
printf("%d\n"@` atoi(&a));
や
printf("%d\n"@` atoi(&b));
にして実行形式にしてみて。
0030むふーんNGNG
>27
あれ?そうじゃないや?また馬鹿な事かいてる、、
0031GutsNGNG
&aにしたら0でしたけど
&bにしたら11になりましたー
0032むふーん NGNG
というよりきかなくても、もう分かってるでしょ。
文字列は'\0'==0で終わりでatoiは文字列を数値に変換。

0033GutsNGNG
>むふーんさん
、、、わからない、、、(ばか
0034むふーんNGNG
Cの文字列ってのは 0で終わってないといけないの。
それでatoiは文字列を扱うわけ。
&cは'2'を指しているけど、その指している次の位置は
0とは保証されないから、文字列の"2"では無いと。
するとatoiはうまく変換しないはずなんだけど、
たまたま&cの次の位置が数字ではなかったんでしょう。
0035GutsNGNG
なんとなくわかったような気がします
atoiは文字列を扱うから文字列じゃなかったらへんになるみたいな感じですか?(−−;
0036名無しさんNGNG
プログラムNO.6 数当て改改 に対するコメントです。
1. すでに 12 でむふーんさんが指摘しているが、gets を使っている。
2. 負の値をいれたときのエラーのチェックがない。
3. hogehoge といった文字をいれたときの動作がおかしい。
4. rand の使い方があまりよくない。

1 は絶対 fgets にするべき。
2 については簡単に直せると思うので特にヒントなし。
3 についてはそもそも atoi のようなエラーのチェックが
難しい関数を使わずに、sscanf か strtol を使うようにする。
また、rand で 0 から 9 の乱数が欲しいときには次のように
する方が良い(rand 関数の性質上)。
com = rand() / (RAND_MAX/10)

0037GutsNGNG
>36
1、fgets勉強してみまっす
2、あっ負の数値のエラーチェックか、、、忘れてた
3 というーか数字以外いれたら変ですよねゼンブ
 数字以外だったらはじくようにしなきゃ、、、
4、なんでかはよくわかりませんがそうしときます、、、
003836NGNG
> 37
数字以外をはじくのには sscanf を使うのがたぶん
一番楽ですよ。挑戦してみてください。
それから、rand の使い方ですが、一般に rand の
返す値の下の方の桁は乱数としては非常に質の悪い
ものになります(rand%10 は末尾を使いますよね)。
上の桁を使うために割算を使うわけです。

0039GutsNGNG
うー今日はあんまり時間を使えないからちょっとだけ、、、
今度は数あて以外のつくってみます、、、

>36さんむふーんさん
fgetsつかってみました
間違ってるかもしれませんが、、、
sscanfもつかてみました。
詳しくはHPみてください
004036NGNG
お時間がないようなので、要点のみ。
1. fgets の使い方が正しくない。
before が配列として宣言されている場合は次のようにする。
fgets(before@` sizeof(before)@` stdin);
sizeof(before) の値は自分で printf で確かめてみて。
また、fgets のエラーチェックもした方が良い(そうしないと
入力が EOF の場合の動作がおかしくなる)。
一番手を抜いた場合でも次のようになる(と思う)。
if (! fgets(before@` sizeof(before)@` stdin)) {
printf("読み込みエラー\n");
exit(1);
}
2. せっかく sscanf を使っているのにエラーをチェックしていない。
sscanf は代入がうまくいった(読み込めた)要素の数を返すので
次のようにするべき。
if (sscanf(before@` "%d"@` &after) != 1 || (after >= 10 || after < 0))
そうしないと sscanf が失敗したときの after の値を参照してしまう。
(はじめに 0~9 を入力しておいて次に "hoge" のような文字列を
入力すると分かるはず)

0041>40NGNG
sizeof(before)-1じゃない?
0042> 41NGNG
fgets は最大@` (第 2 引数 - 1)文字を読む関数なので
sizeof(before) でいいのでは?

0043>42NGNG
41です。

あれ、そうだったっけ? > 第2パラメータの解釈

もう随分長いことfgets()なんて使ってないから、
曖昧な記憶でもの申したかもしれません。
申し訳ない。
0044GutsNGNG
とりあえず36さんのエラーチェックだけとりいれて
寝てしまいました(笑
これからプログラムくみはじめます。
どんなの組めば良いですかねー?
0045>44NGNG
はのいの塔。
0046名無しさんNGNG
<PRE></PRE>でプログラムソースをHTMLに書き込むと
<>が消えてしまいます。そこでこれらを&lt;と&gt;に
書き換えるプログラムを作ってみましょう。

どういう風に動作すれば良いか。
どのように処理をすれば良いか。
どこを工夫すれば便利か。

0047↑NGNG
<を&lt;、>を&gt;って事ね。
0048GutsNGNG
>46さん
あっそれやります
付加機能もつけたやつを作りたいです
いまからファイル処理関係勉強します。
(僕のHPのNextプログラムってとこ見てください(^^))

>45さん
はのいの塔ってなんですか??
0049GutsNGNG
こんばんわー
ちょっと疑問におもったこと書きに来ました
ちょっとまずこのサンプルみてください、、、

#include<stdio.h>

int (*get_sign)();
int iget_sign(int *a);/*なんで引数がポインタなの?*/
int fget_sign(double *a);/*ここも*/


int main(void)
{
int sgn@`idt=5;
double fdt=-3.14;
int i;


get_sign=iget_sign;
sgn =get_sign(&idt);
printf("data:%d sgn:%d\n"@`idt@`sgn);

get_sign=fget_sign;
sgn =get_sign(&fdt);
printf("data:%f sgn:%d\n"@`fdt@`sgn);
return(0);
}

int iget_sign(int *a)
{
if (*a==0) return 0;
else if (*a>0) return 1;
else return -1;
}

int fget_sign(double *a)
{
if (*a==0) return 0;
else if (*a>0) return 1;
else return -1;
}
関数のポインタの章を読んでたらこんなのがでてきたんです。
えーっと コメントのとこにあるように
なんで関数の引数がポインタになってるんでしょう?
試しにポインタじゃなくしてやってみたんですが
別になんら動作はかわらないですよね?
ただたんなる好みなんでしょうか?
0050名無しさんNGNG
単に好みの問題と言う感じがします。
あと、便乗質問なんですけど、
int (*func)();
という宣言のとき、func の引数は不明という
意味なんでしょうか?

0051#10423NGNG
>49のGuts
サンプルの関数では、関数の引数がポインタ変数である必要は
ないし、プログラム全体の動作もかわりません。

>50
そのとおりです。
コンパイル時に、型チェックをしたい場合は、
int (*func)(void*);
ですね。(本来は、こう書くべきだと思うが...)
0052名無しさんNGNG
関数のポインタの使い方の例としては、標準関数のqsort)が良いのでは?
のパラメータとして渡す関数のポインタを変更して、昇順のソートにしてみたり、降順のソートにしてみたり、構造体の配列へのソートにして、各メンバ毎にソートするとか。

#qsortがブラックボックスとかいう突っ込みは返せないが。
0053名無しさんNGNG
うーん、なんか面白そうなところ勉強してるね〜。

・関数の引数
 "Call by value"、もしくは「値による呼び出し」って項目を索引から探して学ぶべし。
 そして必ず理解すべし。Cの一つの「肝」に関わるところです。
 ちなみにそのサンプルでは51の方が書いているようにポインタ変数である理由はありません。

・関数へのポインタ
 51の方の説明にちょっと補足。
 Cだとint (*func)()は仮引数仕様がないので適当に使う事が出来てしまいます。
 でもそれはとても危険である事を理解しましょう。試しにこのプログラムの
 sgn = get_sign(&idt);
 を
 sgn = get_sign(idt);
 に書き換えてもすんなりコンパイル出来てしまいますが、実行すれば
 当然引数がおかしいので異常終了します。

 int (*func)(void *)って書いておけばコンパイルの時点で
 「引数が変」って出るでしょ?(試すべし)

 という事できちんと仮引数も書いておきましょう。
 いずれC++もやりたくなるだろうし。
005450 > 51NGNG
どうもありがとうございます。
ただ単に int (*get_sign)(void*) にしただけだと、
結局コンパイル時に get_sign と iget_sign の型が
合わないという warning が出るので int (*get_sign)()
はどうなっているのか疑問だったのですが、おかげで
すっきりしました。

0055名無しさんNGNG
C++だとint (*func)()はint (*func)(void)となりますね。
0056GutsNGNG
あー
引数がなにもかいてないのは
54さんがいってるように警告がでるから
って本にはかいてました
0057> 56NGNG
その本は腐っているんでは?
int (*get_sign)(void*);
int iget_sign(void *p);
int fget_sign(void *p);
と宣言しておいて、
int iget_sign(void *p)
{
int *a = p;
....
}
とするのがまっとうだと思うんですけどね。

0058#10423NGNG
>56
57さんの言うとおり、その本、腐りきってますね。
どんな本だか知らないけど、初心者向けの本だとしたら
ワーニングは危険だって教えないといけないのに、
単に、ワーニングを出なくするっていうのは良くないですなぁ。
0059うーん、NGNG
恐いな、warning出さないための小細工って。

結局53の人が書いているような間違い(引数の型の相違)を
未然に防ぐためにきちんとコンパイラが教えてくれるのに
それを無視するなんて。

そういう本を読んでいると「筋」が悪くなるよ。
0060GutsNGNG
本の名前は
新C言語入門 シニア編 林晴比古

問題の部分をぜんぶ書き写してみました

「ここでget_signのプロトタイプ宣言では引数を空にしています。
本当は、
int (*get_sign)(void *a);
とするところですが、チェックの厳しいコンパイラでは
iget_sign(int *型の引数)、dget_sign(double *型の引数)との型の
不一致が警告されますので、わざと空にしています。
これは「了解している警告」を避けるために、ときどき使われるテクニックです。」

そのまま転載です。
結構説明してくれてるんで親切だとおもうんですけどね、、、
0061名無しさんNGNG
ねぇねぇ、53の方が例であげていた

> 試しにこのプログラムの
> sgn = get_sign(&idt);
> を
> sgn = get_sign(idt);
> に書き換えても...

って試してみた? warningもerrorも出ずに
コンパイルできるよね。でも実行すると異常終了。
これについてどう思う?
0062名無しさんNGNG
新C言語入門 シニア編 林晴比古
私も最初この本で勉強しました
いい本だと思います
0063> 62NGNG
直接その本を読んだことがないので、確かなことは言えないですが、
同じ著者が書いた別の本がぼろくそ言われてるところをみると危ないのでは?
http://kjmcci.kct.ne.jp/~fuji/computerbooks/c/cprepro.hayashi.html

0064GutsNGNG
いまハノイの塔やってます、、、
むづかしい、、、
再帰がまだちゃんと理解でけん、、、
0065うーむNGNG
63さんの指摘ページの引用です、
>typedefによる型定義とマクロによる型定義が同じである、と書かれている。
>いつからそんなことになったんだよ。根本的に違うぞ。
林晴比古って人は、型の存在意義を理解してないんじゃないかな?
恐らくこの人にはC++の本は書けないだろうなぁ。。。
0066>64NGNG
再帰はアルゴリズムの中でも特に重要なので、是非ともマスターして
欲しい。
なぜ重要なのかというと、再帰でしか解けないものが沢山あるんです。
例えば数式処理の括弧ですね。括弧の中も式だから再帰になるんだが、
再帰アルゴリズムを用いない限り、ネストの大きさが固定されてしま
います。
ハノイの塔は再帰の例で必ず登場しますが、簡単な例として素晴らしい
です。時間が掛かっても理解することをお勧めしますです。
0067AONGNG
>66
再帰的アルゴリズムを理解できたら、再帰呼び出しを使用しないで、
再帰を実現する実装を出来るようになれば、よりよいですね。。。
0068>66NGNG
自前スタックをリンクリストで作ったり
処理キュー作ったりしてやっちゃだめ?
006966NGNG
>67 AOさん
昔ふぉーとらんでやった事が…(^_^;)
しかし、、可読性が悪かったような。
>66
コード見たくないです。(笑)
再帰といえどもスタックは有限なので、あまり深いネストにしない
事を前提にした、手抜き再帰なるものも有ります。
単にルーチンをネスト分だけコピーして、エディタで名前を変える
だけです。
ステップ数が評価の対象になる、古びたお客様に大変有効です。(笑)
007066NGNG
あ、、間違った。>66は68さんへの誤りです。
0071AONGNG
>69
うーん、今でも、Win95/98は、スタック不足が起こりやすいんで、
再帰呼び出しを避けて書く事はありますね。。。
まぁ、可読性は書き方次第だと思いますが。。。
0072うにゃNGNG
わたしも今読んでます。
林晴比古新C言語入門スーパービギナー編。
シニア編も買おうと思ってたけど、ちょっと考えちゃうな。
本屋で見た限りでは一番読みやすそうだったから買ってしまったんだけど・・・
まなさまお勧めのC入門本はなんですか?
0073うにゃNGNG
まなさま→みなさま です。しつれいしました。
0074へなちょこ大学生NGNG
今、C++で整数のキュー作ってます。
配列で、最後と最初がつながっているやつ。
tailが最後まで行ったら最初に戻ったり、
headを追い越さないようにとかの、エラー処理が
難しいです。。。
再帰を使った方がいいのでしょうか?
というか、再帰を使わないと作れない??

奇遇ですが、僕も林晴比古氏のその本を読んでます。
なんか、見やすいし、初心者が手にしたくなる本なんですよね。
0075名無しさんNGNG
キューに再帰は要らないでしょう。

ついでに、せっかくC++なら
整数に限らずtemplate使った方が…
■ このスレッドは過去ログ倉庫に格納されています