ページ 1 / 1
雑談ですが・・・
Posted: 2007年6月13日(水) 21:37
by ビギナー
はじめまして、c言語をはじめたばかりの者ですが
c言語ってなかなか馴染めなくて、くじけそうになってます。
レスを見てみるとすごく詳しく(しかも即答)回答されてますが、皆さん
c言語歴はどのくらいなのですか?
あと、いろんな方法があると思いますが、どうしたらc言語を効率よく学習できるか教えてください。
TO 管理人さん
初めてで良くわからないのですが、こういう質問ってしたらいけなかったらすみません
Re:雑談ですが・・・
Posted: 2007年6月13日(水) 22:38
by バグ
私は去年の4月に今の会社に拾ってもらってからなので、約1年2ヵ月でしょうか…。
C言語は全く未経験でしたので大変でしたが、なんとか食らい付いてます(苦笑)
効率の良い勉強法は、色々な人達のプログラムを見る事と、ひたすら自分で書く事ですね。後は『とりあえずググる』でしょうか?(笑)
この3つと本人のやる気があれば、1ヵ月もあれば簡単なソフトを組めるようになると思います。
Re:雑談ですが・・・
Posted: 2007年6月14日(木) 00:05
by ビギナー
こんにちは。
私はC言語に出会って2ヶ月くらいでしょうか、minamiさんの作成しているプログラムと似ていて
ここに、たどり着きました。
Webも初心者のため、自分がなにを質問したいのやら、調べたいのやらで・・・、
ここは、皆さん回答が早く親切で丁寧なことにおどろきました。
今は、minamiさんの「アルファベットの検定」でフリオさん回答を参考に
アルファベットの出現頻度検定と連検定をして各検定の最大値を求めたところです。
Re:雑談ですが・・・
Posted: 2007年6月14日(木) 00:09
by YuO
> 皆さん c言語歴はどのくらいなのですか?
えーっと,最初に使ったのは中1の頃あたりだからたぶん1992-3年,Quick C 2.0を使ったのが最初だと思います。
ただ,当時はQuick Basic 4.5 + MASM 5に対して利点を感じず,あまり勉強しなかったです。
# far pointerだのnear pointerだのややこしく,アセンブラで書いた方が楽だったし。
次に顔を見せるのが1995年。第二種受けた時に,午後をCASLとCで受けた覚えが。
まじめに使い始めたのは大学2年@1998年,サークルでWin32のプログラムを組んだ時ですね。
VS97を持っていたのでWin32の本買ってきて,1月前後でくみました。
# 今となっては汚点としかいえないような汚いC++ (ほぼC) コードですが。
規格書に手を出したのが2002年頃だったかと。
> あと、いろんな方法があると思いますが、どうしたらc言語を効率よく学習できるか教えてください。
良い本で勉強することと,とにかくプログラムを作ることでしょうか。
あとは結論だけを求めないことです。
なぜそれでできるのかを考えることによって,目の前の問題は確かに結論だけ求めるよりも時間がかかりますが,
その分理解できれば応用がききますから,それ以降の問題について時間の短縮になります。
ある程度なれてきたならば,実装と規格を分離して考えることも重要かなぁ,と。
実際にどのように実装されているかも勉強になりますし,規格上どうなっているのかも勉強になります。
ポインタなどは,実装をまったく勘案せずに理解できて初めてポインタが解ったといえると思っています。
Re:雑談ですが・・・
Posted: 2007年6月14日(木) 00:32
by ビギナー
「良い本で勉強すること」ですか、今は課題提出の期限に追われ課題か課題に近いサンプルが
掲載されている本が「良い本」と思ってしまっています。
課題の合間に、買ってきた本のサンプルは一通り作ってみましたが
まだまだ、タイプ打鍵訓練状態です(「おまじないと思ってください」と書いてあり鵜呑みに)。
Re:雑談ですが・・・
Posted: 2007年6月14日(木) 01:53
by 管理人
ビギナーさん、全然OKですよ!
どんな投稿でもかまいませんのでご自由に^^
・・・最近忙しくてなかなか掲示板の方お答えが出来ません;
先1週間提出しないといけないものだけで5つもあるし・・(泣
私は大学に入って初めてPCを触った超初心者です。
実質プログラムを勉強して2年程度でしょうか。
情報学科に行きながら全くcになじめず、授業もわからず、全く勉強しませんでした・・。
そんな時、一つのライブラリが私にプログラムの面白さを教えてくれました。
それが「ゲームプログラミングの館」でも紹介しているDXライブラリです。
自分でゲームが作れるということにものすごく感動したのを覚えています。
う、、ちょっと時間が無いので、詳しくお話出来ないのが残念です。
私が一番いいと思った入門書は「新版 明解C言語」です。入門編と実践編があるので、順に読めばよくわかりますよ。
特にこの本でなくても、「自分が読めそうだ」と思う本を見つけることが大事だと思うので、
大きな本屋にいって端から読んでみるのがいいと思います。
一番最短のプログラミングの勉強方は「とにかくプログラムを書いてみる」と言う事だと思います。
プログラミングは数学と同じだと思います。
高校の時、数学の教科書を眺めていた時の事を思い出してください。
数学の教科書や参考書を一通り読んで「あ~なるほど~」とか納得したとしましょう。
しかしいざ教科書を閉じて練習問題をしようとしても、「あれ?」と思うでしょう。
プログラムも同じで、とにかく自分で書いてみる、コンパイルしてみる、演習が大事だと思います。
参考書を読んでは、そのつど面倒でも、わかりきっていても、プログラムを自分で書いて実行してみること、これがホントに大事です!
Re:雑談ですが・・・
Posted: 2007年6月14日(木) 13:13
by ビギナー
「ゲームプログラミングの館」見せていただきました。
丁寧な解説つきで、時間ができたら試してみたいです。
で、なにより好きになるきっかけって大事かと思いました。
「新版 明解C言語」今度、本屋で手にとってみます。
みなさん、早い時期にいろいろ作成しているみたいなので
おどろきです、これから興味のあることを探して、いろいろ
試してみようと思います。
Re:雑談ですが・・・
Posted: 2007年6月14日(木) 15:36
by 管理人
もう一つ効率よく勉強するには、一つの解説から自分で10も20も調べてみること、
コンパイルしてみることだと思います。
例えば、scanfの使い方を解説書を読んで勉強したとしましょう。
int a;
scanf("%d",&a);
「%dってprintfで使ったな~。まぁprintfで使った奴を""の中に書いて、変数の前に&つけときゃいいんだな」
こんな感じでscanfについての勉強はもう終わりにしたAさんがいたとしましょう。
Bさんは違いました。
「
int型がこうならdoble型はどうなるのか調べてみよう。
double a;
scanf("%lf",&a);
何!%fじゃなくて%lfって書くのかぁ。printfと同じ記号だと思ってちゃいけないんだな。
printfで%lfって書くとどうなるだろう。
じゃ文字列はどうだろう?
char a[10];
scanf("%s",a);
あれ?文字列の時は「&」が変数の前についてないぞ?どうしてだろう。。。
その理由は・・
」
こんな感じで意欲的に調べていきました。
AさんとBさんのスキルの差は今後歴然となる事はあたりまえですよね。
参考書に書いてあることだけじゃなく、書いてあることを元に、「じゃこのときどうなるんだろう?」と意欲的に調べてみることこそ大事だと思います。
そうしてif文、printf文、scanf文、乱数などが勉強できたら、自分でそれで出来る何かプログラムを作ってみることです。
if文、printf文、scanf文、乱数の使い方さえわかれば「ジャンケン」位の簡単なゲームは作れますよね。
乱数でランダムな数を作り、それを3種類に対応させ、グー、チョキ、パーとする。
scanfで取り込んだ、プレイヤーの意思がグーで、かつ、乱数で出たコンピュータの手がチョキならプレイヤーの勝ち!
こんな感じでゲームが作れます。
私が初めて作ったゲームはジャンケンでした。
「自分で何か作ってみること」にこそ面白さがあり、勉強してばかりで退屈になってしまうこともありません。
面白さがわかれば、「ここ実現したいんだけど、それにはどうするんだろう・・」と、そんな疑問から意欲的に自分で調べるはずです。
勉強だと思ったら限界がありますが、趣味と思えば限界は無いはずです。
楽しみながらプログラミングを頑張ってください☆
Re:雑談ですが・・・
Posted: 2007年6月14日(木) 19:13
by ビギナー
じゃんけんゲームを作ってみました
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(void)
{
int playerH,comH,res;
char ch;
/*乱数生成*/
srand((unsigned)time(NULL));
printf("1:グー 2:チョキ 3:パー\nいずれかを入力せよ: ");
scanf("%d",&playerH);
if(playerH<1 || playerH>3) return -1;/*エラー処理 入力範囲は1~3*/
playerH--; /*playerHの値を0~2範囲*/
comH = rand()%3;/*コンピュータの手を生成*/
switch(comH){
case 0:printf("コンピュータはグー\n");
break;
case 1:printf("コンピュータはチョキ\n");
break;
case 2:printf("コンピュータはパー\n");
break;
}
/*結果*/
res=(comH - playerH+3)%3;
if(res==2) res=-1;
switch(res){
case 1:printf("プレーヤーの勝ち\n");
break;
case -1:printf("プレーヤーの負け\n");
break;
case 0:printf("あいこ\n");
break;
}
return 0;
}
一回、一回プログラムが終了してしまうので改良するべき点等あるかとは
思いますが、とりあえず作成してみました。
Re:雑談ですが・・・
Posted: 2007年6月14日(木) 20:03
by 管理人
お~キレイなプログラム書いていらっしゃるじゃないですか^^
私は初めてこれを作った時、どうやったら総当りのif文を書かずに済むか結構悩んだ覚えがあります。
何とないプログラムの中にも結構アルゴリズムを考えないといけない要素ってあるものですよね!
ジャンケンの次は「ノット17」を作りました。
これは1人1~3まで数える事が出来、1から順番に一人3までの数を数え、17を言ってしまった人が負けというゲームです。
システムとの場合、1:1でやる事になるので、結構簡単に最も勝率の高いプログラムを書く事が出来ますよ☆
まず「どうやったら最強になるのかな?」と考えました。一人3まで数えられるのなら3の倍数が関係しそうだな・・とか考えました。
これはjuliusを使って、音声入力で文字列を取り込み、linuxに標準で入っていた音声読み上げ機能を使って出力させました。
つまり音声入力を受け付けて、音声出力するわけですから、キーボードは一切使わず、本当に人と遊んでいるような感じにしました。
その時の様子を動画に納めたのがこれです。
http://dixq.net/movie/not17.3G2
(公開終了)
デフォルトが最強なので、何も考えなかったら絶対負けますw
Re:雑談ですが・・・
Posted: 2007年6月14日(木) 22:12
by フリオ
ちょっと気づいたことを、
"char ch"は使ってないので、消しておいたほうがいいです。
"%"は、"負 % 正"、"正 % 負"の結果は、処理系定義なので、
結果表示は、
switch((comH + 3 - playerH) % 3){
case 0: printf("あいこ\n");
break;
case 1: printf("プレーヤーの勝ち\n");
break;
case 2: printf("プレーヤーの負け\n");
break;
}
などとしたほうがいいです。
他に、
char *result[/url] = {"あいこ", "プレーヤーの勝ち", "プレーヤーの負け",};
を、宣言し、
printf("%s\n", result[(comH + 3 - playerH) % 3]);
とする方法もあります。
Re:雑談ですが・・・
Posted: 2007年6月14日(木) 22:19
by なぎ
ちょっと茶々入れますが……
自動車教習所に行くと、自動車の運転技術だけではなく、交通法規も教えてくれます。
それと同じように、C言語の知識だけではなく、プログラミング一般の知識も押さえると、いいと思います。
また、プログラミングにおいて、「試行錯誤」には注意が必要です。
試行錯誤で問題を解決すること自体は悪くないのですが、問題が解決したと思った時点で、それでよしとせず、なぜ解決したのか、本当に解決したのかという、チェックをする習慣は大切です。
その習慣がないと、当てずっぽうでプログラムを直して、なんだか動いたからOKという行動パターンをとりがちになります。実際、そういう行動パターンは、そんなに珍しいことではありません。
具体的に、じゃんけんゲームのプログラムですが、たとえば、
> res=(comH - playerH+3)%3;
> if(res==2) res=-1;
という処理の判断は分かれるところです。
これが正しくじゃんけんの勝ち負けを判断していると、すぐには、わからないからです。
すぐにはわからないところというのは、万一バグが潜んでいると、発見が遅れるもとになります。
また、「if(res==2) res=-1;」というのは、どうも、試行錯誤の残骸に見えてしまいますが、いかがでしょうか。
その後の勝敗判定の swich() で、case ラベルを、0, 1, 2 にすれば、この if() は不要になると思います。
逆に言えば、なぜ、わざわざ res を 2 から -1 に差し替えているのか、わかりにくいところです。
プログラミング技法としては、こういう場合、デシジョンテーブルというものもあります。
こんな表を作ります。
computer gu choki pa
hito
gu aiko hito com
choki com aiko hito
pa hito com aiko
これを、2次元配列で表現して、じゃんけんの手の組み合わせ部分の値を返すと
どちらが勝ったかわかるという仕掛けです。
この方法の利点は、ロジック自体は単純で、表の検証は(プログラムを知らなくても)
誰でもできるということです。また、汎用性は非常に高くて、変則じゃんけんにもそのまま対応します。
ただ、(誰でもできるという一方で)表の作成や検証は結構面倒ではありますね。
Re:雑談ですが・・・
Posted: 2007年6月14日(木) 22:56
by フリオ
何を書いているんだ。
> "%"は、"負 % 正"、"正 % 負"の結果は、処理系定義なので、
> 結果表示は、
> switch((comH + 3 - playerH) % 3){
> case 0: printf("あいこ\n");
> break;
> case 1: printf("プレーヤーの勝ち\n");
> break;
> case 2: printf("プレーヤーの負け\n");
> break;
> }
> などとしたほうがいいです。
これは、勘違いなので、忘れてください。orz
# パスワードを入れてなかったので、編集できない。
Re:雑談ですが・・・
Posted: 2007年6月15日(金) 09:05
by ビギナー
皆さん、ご指導ありがとうございます。
・勝ち負けに判定の処理の方法や結果の保存はどうすればよいのか
・「あいこ」でプログラムが終了するのは不自然なのかな
などを思い作成しました。
まだ理解できないことが多いので勉強しながら、いろいろ試したいと思います。
Re:雑談ですが・・・
Posted: 2007年6月17日(日) 00:24
by 雷
>・勝ち負けに判定の処理の方法や結果の保存はどうすればよいのか
ファイルに保存なら:fputsなどを調べて見るといいかな?(難しいところもありますが…w
何回か回して、その結果を最後に表示するなら、配列を使えば良いと思います。(やる回数(三回やるだけとか…)に制限付けないとややこしそうですが・・・(汗
>・「あいこ」でプログラムが終了するのは不自然なのかな
for()やdo{}while();やwhlie()などを使えば、その不自然さはなくなりますよ^^
その時、関数&#defineを覚えてみるといいかもしれません。
特に、関数は作業が楽になりますよ~(・・;
なんにしても、一つ一つ追加していくと、やりやすいと思います。
で、出来た後に、一から考えながら作り直すと、短くなったりするんですが…w
頑張ってください!
Re:雑談ですが・・・
Posted: 2007年6月20日(水) 01:41
by ビギナー
デシジョンテーブルはまだ手がつけられませんが、
修正してみました。
c言語以外の課題も多く、めげそうです。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(void)
{
int playerH,comH,res;
/* 乱数系列の変更 */
srand((unsigned) time(NULL));
do{
printf("1:(グー) 2:(チョキ) 3:(パー)\nいずれかを入力: ");
scanf("%d",&playerH);
if(playerH<1 || playerH>3) return -1;/*エラー処理 入力範囲は1~3*/
playerH--; /*playerHの値を0~2範囲*/
comH = rand()%3;/*コンピュータの手を生成*/
switch(comH){
case 0:printf("コンピュータはグー\n");
break;
case 1:printf("コンピュータはチョキ\n");
break;
case 2:printf("コンピュータはパー\n");
break;
}
/*結果*/
if(comH == playerH){
printf("あいこ\n");
}
else if(playerH == 1 && comH == 2){
printf("プレイヤーの勝ち\n");
}
else if(playerH == 2 && comH == 3){
printf("プレイヤーの勝ち\n");
}
else if(playerH == 3 && comH == 1){
printf("プレイヤーの勝ち\n");
}
else{
printf("コンピュータの勝ち\n");
}
}
while(comH == playerH);
return 0;
}
Re:雑談ですが・・・
Posted: 2007年6月21日(木) 12:33
by 雷
>int playerH,comH,res;
を
int playerH=0,comH=0,res;
…resって使ってないよね?過去の遺産かな??
>if(playerH<1 || playerH>3) return -1;/*エラー処理 入力範囲は1~3*/
を
if(playerH>=1 && playerH<=3)
にすると、エラーではなく、再度入力を求めれるようになります。
>playerH--; /*playerHの値を0~2範囲*/
は初めから0~2にはなぜしなかったのでしょうか?
それか、
printf("1:(グー) 2:(チョキ) 3:(パー)\nいずれかを入力: ");
scanf("%d",&playerH);
if(playerH<1 || playerH>3) return -1;/*エラー処理 入力範囲は1~3*/
comH = (rand()%3) + 1;/*コンピュータの手を生成*/
switch(comH){
case 1:printf("コンピュータはグー\n");
break;
case 2:printf("コンピュータはチョキ\n");
break;
case 3:printf("コンピュータはパー\n");
break;
と、してみてはどうでしょうか?
それと、
「再度勝負しますか?」(Yes:1/No:0)
を用いて、何度も対戦できるようにしたほうが面白いのでは?と思います。
どうでしょうか?
#defineや関数などと混ぜて作ったのを添付しておきましたので、良かったら参考に…なるかな?(汗
ミスがあったら教えてください…
Re:雑談ですが・・・
Posted: 2007年6月21日(木) 14:40
by Justy
>ミスがあったら教えてください…
強いて挙げるなら、scanfのところでアルファベットとかが
入力されるとおかしなことになる、くらいでしょうか。