トップページ⇒tech
1001コメント269KB

C言語なら俺に聞け(入門篇) Part 24

■ このスレッドは過去ログ倉庫に格納されています
0001('A`)2008/01/23(水) 19:12:56
C言語の入門者向け解説スレです。
・C++言語はスレ違いです。
・分からない事をなるべく詳しく書いて下さい。
・ソースコードを晒すと答えやすくなるかもしれません。
・質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。

前スレ
C言語なら俺に聞け(入門篇) Part 23
http://pc11.2ch.net/test/read.cgi/tech/1198295362/

教えて欲しいのではなく丸投げしたいならこちらへ
C/C++の宿題を片付けます 103代目
http://pc11.2ch.net/test/read.cgi/tech/1200318925/
0002デフォルトの名無しさん2008/01/23(水) 19:16:03
Part 1 ttp://pc8.2ch.net/test/read.cgi/tech/1146700389/
Part 2 ttp://pc8.2ch.net/test/read.cgi/tech/1153818463/
Part 3 ttp://pc8.2ch.net/test/read.cgi/tech/1160682950/
Part 4 ttp://pc8.2ch.net/test/read.cgi/tech/1162999861/
Part 5 ttp://pc8.2ch.net/test/read.cgi/tech/1165022193/
Part 6 ttp://pc10.2ch.net/test/read.cgi/tech/1167325490/
Part 7 ttp://pc10.2ch.net/test/read.cgi/tech/1170064980/
Part 8 ttp://pc11.2ch.net/test/read.cgi/tech/1171946674/
Part 9 ttp://pc11.2ch.net/test/read.cgi/tech/1173284217/
Part 10 ttp://pc11.2ch.net/test/read.cgi/tech/1174290325/
Part 11 ttp://pc11.2ch.net/test/read.cgi/tech/1176800483/
0003デフォルトの名無しさん2008/01/23(水) 19:16:24
Part 12 ttp://pc11.2ch.net/test/read.cgi/tech/1178620766/
Part 13 ttp://pc11.2ch.net/test/read.cgi/tech/1179301993/
Part 14 ttp://pc11.2ch.net/test/read.cgi/tech/1181735298/
Part 15 ttp://pc11.2ch.net/test/read.cgi/tech/1182719692/
Part 16 ttp://pc11.2ch.net/test/read.cgi/tech/1184003625/
Part 17 ttp://pc11.2ch.net/test/read.cgi/tech/1185286631/
Part 18 ttp://pc11.2ch.net/test/read.cgi/tech/1187213990/
Part 19 ttp://pc11.2ch.net/test/read.cgi/tech/1190342593/
Part 20 ttp://pc11.2ch.net/test/read.cgi/tech/1192455273/
Part 21 ttp://pc11.2ch.net/test/read.cgi/tech/1194384258/
Part 22 ttp://pc11.2ch.net/test/read.cgi/tech/1196489491/
0004デフォルトの名無しさん2008/01/23(水) 19:18:18
printf("1乙\n");
0005デフォルトの名無しさん2008/01/23(水) 20:23:31
for( ; ; ){
    puts("1乙");
}
0006デフォルトの名無しさん2008/01/23(水) 21:03:28
while(1){
scanf("%c",&command);

switch(command){

{case'a'〜'c'}

case'd':
{exit(0);}←??

default{}
}}}
a〜cはプロトタイプ宣言した関数の呼び出しです。
dのときだけreturn 0;に飛ばしてループを終了させたいんですけどbreak使うんですかね?
このexit(0)を使うやり方だとどうもループさせた時に入力エラーが一回余分に出てしまいます;
0007デフォルトの名無しさん2008/01/23(水) 21:05:38
return 0; はどこですか
0008デフォルトの名無しさん2008/01/23(水) 21:17:48
入れるとしたら
default{…;}
}(1)}(2)}

(1)だと繰り返さず終わってしまうので(2)の方を考えてます。
0009デフォルトの名無しさん2008/01/23(水) 21:23:55
やりたいことがよく分からない。
直接 return 0; したらだめなのか?
0010デフォルトの名無しさん2008/01/23(水) 21:30:30
>>6
何をしたいのか整理してくれないか?
ついでに、擬似コードをやめてC言語で書いてくれ
0011デフォルトの名無しさん2008/01/23(水) 21:41:06
うーん、擬似コードがよくわかりません。そのまま書いたつもりなのですが…

あと一番上のscanf(%c,command)の%cを%xに、
case(a~d)を1~4に変えることで正常に作動させることができました;
0012デフォルトの名無しさん2008/01/23(水) 21:43:20
・・・お前の持っているCコンパイラは

case'a'〜'c'}

こんなコードもコンパイルしてくれんの?
0013デフォルトの名無しさん2008/01/23(水) 21:44:08
KY
0014デフォルトの名無しさん2008/01/23(水) 21:44:28
1~4って5だけどいいの?w
0015デフォルトの名無しさん2008/01/23(水) 21:53:27
それは 1^4 。
1~4 はコンパイルエラー。
0016デフォルトの名無しさん2008/01/23(水) 21:55:37
ついでに文句いうなら無限ループはwhile(1)よりfor(;;)のがいいよ
優秀なコンパイラたんだと警告だす
0017デフォルトの名無しさん2008/01/23(水) 21:57:34
それはむしろ無能だろ。
while(1) のみ定型句と見なしてエラー出さないくらいしてくれ。
0018デフォルトの名無しさん2008/01/23(水) 21:59:49
それはもう数年後に出る人工知能つきコンパイラたんにご期待ください
0019デフォルトの名無しさん2008/01/23(水) 22:08:10
int flg = 1;
while(flg){
scanf("%c",&command);
switch(command){
case 'a':
case 'b':
case 'c':
break;
case 'd':
flg = 0;
break;
default:
}
}

だせぇ・・・
while(command!='d')やらwhile(command)も考えたがダサい。
なんか上手いやり方ないか?
0020デフォルトの名無しさん2008/01/23(水) 22:09:39
まず何をやりたいのかをまとめてくれ。
0021デフォルトの名無しさん2008/01/23(水) 22:12:07
float f;

scanf("%f", &f);
printf("%f",f);

で、実行して、fに100.1とか入力すると、
100.09998とか表示されてしまうんですが、何故なのでしょうか?
0022デフォルトの名無しさん2008/01/23(水) 22:12:36
打ち切り誤差
0023デフォルトの名無しさん2008/01/23(水) 22:14:35
>>22
直す方法は何かなっいですか?
0024デフォルトの名無しさん2008/01/23(水) 22:15:37
double ならある程度マシにはなる。
それもいやなら固定小数点でググれ。
0025デフォルトの名無しさん2008/01/23(水) 22:16:10
printf("%.1f",f); でごまかす
0026デフォルトの名無しさん2008/01/23(水) 22:16:25
固定小数点でも同じだろ。
0027デフォルトの名無しさん2008/01/23(水) 22:17:07
10進固定小数点なら大丈夫だろ。
100.1 に関しては。
0028デフォルトの名無しさん2008/01/23(水) 22:18:23
「10進固定小数点」とか新語を作るなよ。
0029デフォルトの名無しさん2008/01/23(水) 22:19:58
BCDと固定小数点がごっちゃになってるやつ多いな。
0030デフォルトの名無しさん2008/01/23(水) 22:22:11
例えば10倍の下駄をはかせばいいだけだろ?
0031デフォルトの名無しさん2008/01/23(水) 22:30:58
すみません、21ですが、
誤差はしょうがないということでおkですね。
0032デフォルトの名無しさん2008/01/23(水) 22:33:55
常に値を 10 倍した形で int 型で扱えば大丈夫。
0033デフォルトの名無しさん2008/01/23(水) 22:37:39
質問です。
#include <stdio.h>

int main(void)
{
static char *month[] = {"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"};
int i;
char *p;
for(i = 0; i < sizeof(month)/sizeof(month[0]); i++){
for(p = month[i]; *p != '\0'; p++)
if(*p == 'r')
break;
if(*p != '\0')
puts(month[i]);}
return 0;
}
これを小文字のrだけじゃなく大文字のRも大丈夫なようにするにはどうすればいいのでしょうか?
0034デフォルトの名無しさん2008/01/23(水) 22:38:44
'R' とも比較する
0035デフォルトの名無しさん2008/01/23(水) 22:39:09
toupper((unsigned char)*p) == 'R'
0036デフォルトの名無しさん2008/01/23(水) 22:39:38
>>33
if((*p == 'r') || (*p == 'R'))

tolower()
0037デフォルトの名無しさん2008/01/23(水) 22:39:41
if(*p == 'r' || *p == 'R')
0038デフォルトの名無しさん2008/01/23(水) 22:43:00
あぁ成る程。||を使えばよかったんですね。
どうもありがとうございました。
0039デフォルトの名無しさん2008/01/23(水) 23:28:02
scanf()で文字を読み込むときに\nが残るってはなしじゃねーの?
0040デフォルトの名無しさん2008/01/24(木) 06:17:38
void wall(int p,int q)
{if (meiro[p][q]!=1)
{int dir;
meiro[p][q]=3;
dir = rand()%4+1;
if (dir==1&&meiro[p+2][q]!=3)
{meiro[p+1][q]=3;
wall(p+2,q);}
if (dir==2&&meiro[p-2][q]!=3)
{meiro[p-1][q]=3;
wall(p-2,q);}
if (dir==3&&meiro[p][q+2]!=3)
{meiro[p][q+1]=3;
wall(p,q+2);}
if (dir==4&&meiro[p][q-2]!=3)
{meiro[p][q-1]=3;
wall(p,q-2);
}}}
p,qはmeiro[p][q]に対応していて、meiro[偶数][偶数]の点です。
迷路を自動生成するプログラム作ってます。
色々調べて壁伸ばし法で作ることにして、wall関数なるものを自作しました。
0:道 1:壁 3:作りかけの壁

一応、迷路っぽいものはできるのですが、なんというかすかすかのものができてしまいます。
0041デフォルトの名無しさん2008/01/24(木) 10:09:40
続きは?
0042デフォルトの名無しさん2008/01/24(木) 18:13:59
>>40
C言語っつーよりアルゴリズムの問題だと思うけど、
どのみちそこだけ出されてもなんとも言えない
wallをどういう風に呼んでるかとか、
どのタイミングと条件でmeiro[x][y]を1にセットするのかとか
わからないと
0043デフォルトの名無しさん2008/01/24(木) 20:39:20
しかしみずれえソースだな
0044デフォルトの名無しさん2008/01/24(木) 20:45:25
>>40
伸ばす方向に壁ができてたらそれで終わりにしないで、空いている方向を選ぶようにしてみたら?
0045デフォルトの七資2008/01/24(木) 21:09:14
すいません初心者なんで教えてください。
for(j=0;j<=3;j++){
for(i=j+1;i<=4;i++){
if(a[j]<a[i]){
H=a[i];
a[i]=a[j];
a[j]=H;
}
}
}

この
H=a[i];
a[i]=a[j];
a[j]=H;
はどういう意味ですか?
0046デフォルトの名無しさん2008/01/24(木) 21:13:56
Hを仲介してa[i]とa[j]を入れ替えてるんだよ
0047デフォルトの名無しさん2008/01/24(木) 21:14:31
>>45
スワップ
aのi番目とj番目の要素を入れ替えてる
0048デフォルトの名無しさん2008/01/24(木) 21:14:58
Hを、一時的に値を保持する箱として使用し、
a[i]とa[j]の値を入れ替えている。
0049デフォルトの七資2008/01/24(木) 21:18:41
>>46
左から大きい順になるんですかね??
0050デフォルトの名無しさん2008/01/24(木) 21:19:13
左って何だ?
0051デフォルトの七資2008/01/24(木) 21:19:59
>>47 >>48
なるほど!
0052デフォルトの七資2008/01/24(木) 21:21:23
a[i] に与えた数値の並ぶ順です。
0053デフォルトの名無しさん2008/01/24(木) 21:26:45
バブルソートだね
0054デフォルトの名無しさん2008/01/24(木) 21:30:24
for(j=0;j<=3;j++){
  for(i=j+1;i<=4;i++){
   if(a[j]<a[i]){
     H=a[i];
     a[i]=a[j];
     a[j]=H;
   }
  }
}

半角スペース" "の変わりに、前角スペース" "を使うとずれないよ。
0055デフォルトの名無しさん2008/01/24(木) 21:32:38
専ブラならポップアップさせればずれないものもあるよ
0056デフォルトの名無しさん2008/01/24(木) 21:37:21
&nbsp;なら消えない半角空白が作れる。
&nbsp;と普通の空白を交互に置いてもいける。
0057デフォルトの名無しさん2008/01/24(木) 21:37:57
&nbsp; ってコピペすると変にならね?
0058デフォルトの名無しさん2008/01/25(金) 00:14:32
>>57
専ブラによる
0059デフォルトの名無しさん2008/01/25(金) 01:56:46
すみません!C言語初心者ですが質問です。
以下のプログラムをコンパイルしてみたところ、
よく分からないエラーが出ました。

#include<stdio.h>
#include<stdlib.h>
typedef struct{
char *word;
int num;
} BUCKET;//7行目

main(int argc, char* argv[])
{
int i,j;
if(argc<2){
printf("一つ以上の引数を入力してください\n");
exit(1);
}
BUCKET p[argc-1];//16行目
}

↓エラー内容
・・・\kadai51.c(16) : error C2275: 'BUCKET' : typedef 識別子に、クラス メンバ アクセス演算子 (->) を使用しました。
・・・\kadai51.c(7) : 'BUCKET' の宣言を確認してください。
・・・\kadai51.c(16) : error C2146: 構文エラー : ';' が、識別子 'p' の前に必要です。
・・・\kadai51.c(16) : error C2065: 'p' : 定義されていない識別子です。
・・・\kadai51.c(16) : error C2109: 配列または、ポインタでない変数に添字が使われました。

OSはWinXP、コンパイラはVisualC++6.0を使用しました。

XPではCは正しくコンパイルできないのですか?
誰か教えてください!
0060デフォルトの名無しさん2008/01/25(金) 02:00:39
>>59
>BUCKET p[argc-1];//16行目
VCでは可変長配列はサポートされてない。
というかC言語のつもりならブロックの途中に宣言入れちゃ駄目だよ?
0061デフォルトの名無しさん2008/01/25(金) 02:02:35
ああC99なら途中で宣言してもいいのか
どっちにしろVCはC99に対応してないけど
0062デフォルトの名無しさん2008/01/25(金) 02:02:58
VC++6では配列の個数に変数は指定できない
BUCKECT p[ 100 ]にしてみろ。
可変個にしたければmalloc使うかC++に乗り換えるか。
0063定数にして余分に取る2008/01/25(金) 02:04:55
#include<stdio.h>
#include<stdlib.h>
typedef struct{
char *word;
int num;
} BUCKET;//7行目

main(int argc, char* argv[])
{
int i,j;
if(argc<2){
printf("一つ以上の引数を入力してください\n");
exit(1);
}
BUCKET p[10];//16行目
}
0064592008/01/25(金) 02:07:12
あー・・・ではコマンドで設定した分だけを変数確保というのは
できないんですね・・・

pを固定長にして試してみます。
どうもありがとうございました。
0065デフォルトの名無しさん2008/01/25(金) 02:25:54
mallocしろよ
0066デフォルトの名無しさん2008/01/25(金) 02:32:29
vector< BUCKET > p(argc);
が初心者向け
0067672008/01/25(金) 03:02:03
C++でプログラミングしていて、
main関数の中の途中で2次元配列を宣言したら実行時エラーになりました。

char hairetu[500][500];のように宣言したら、
abc.exeは動作を中止しました、と言って止まります。

この配列には代入も何もしていません。
宣言だけでエラーになります。
グローバル変数に移動するとそのエラーは消えました。

C++では変数の宣言はどこでも可能なはずですが、
なぜ実行時エラーになってしまうのでしょうか?
0068デフォルトの名無しさん2008/01/25(金) 03:09:05
サイズがデカイ 250000バイト
new vector つかえ
0069デフォルトの名無しさん2008/01/25(金) 03:11:09
なにさっきからvectorとか言ってんだと思ったらC++かよ。
スレ違いだ。
0070デフォルトの名無しさん2008/01/25(金) 03:11:12
char **p= new char [500];
for(int n=0;n<500;n++)p[n]=new char [500];
p[0][0]=100;
ならできるはず
0071デフォルトの名無しさん2008/01/25(金) 03:17:25
最後の
p[0][0]=100;
てのは何ざんしょ
0072デフォルトの名無しさん2008/01/25(金) 03:32:17
代入してみた゜
0073デフォルトの名無しさん2008/01/25(金) 04:08:42
Javaの授業で変数宣言は1行に複数宣言するのは危険だから1行につき1つの宣言にしろと言われたんですが、
これはC言語も同じなのですか?後どうして危険なんですか?
0074デフォルトの名無しさん2008/01/25(金) 04:15:09
>>73
そんな話聞いた事ないなぁ
0075672008/01/25(金) 04:19:27
char hairetu[500][500];で質問した67です。

68さん、69さん、70さん、71さん、72さん、
質問に答えてくれてありがとうございます。

私の質問はC言語でなくC++に関するものなので
スレ違いでしたらすみません。

---

エラーの原因はメイン関数の中で500*500の配列は大きすぎるから、
ということでいいのでしょうか?

グローバル変数の場所で宣言するなら事前に確保できるので
エラーにならない、と。

メイン関数を走らせている最中に変数を確保するには
newやvectorで確保する方がいい、ということでしょうか。
0076デフォルトの名無しさん2008/01/25(金) 04:25:00
スレ違いだと言う点含め大体あってる
0077672008/01/25(金) 04:40:16
76さんありがとうございます。

疑問が解決しました。みなさんありがとうございました。
また、スレ違いすみませんでした。
0078デフォルトの名無しさん2008/01/25(金) 05:11:52
>>75
Cには以下の4つの領域があります。
コード(code)->プログラム
データ(data)->外部変数
ヒープ(heap)->malloc,new
スタック(stack)->関数の内部変数

このうち、スタック領域のサイズはデータ、ヒープより小さいく、大きな配列を
確保しようとすると最大サイズを超えることがあるということです。
0079デフォルトの名無しさん2008/01/25(金) 08:28:28
>>73
たぶん言いたいことは宣言じゃなくて定義な。
Javaでそんな話は聞いたことないがCならポインタじゃないかなぁ?
int * hoge, fuga;とか
0080デフォルトの名無しさん2008/01/25(金) 08:41:23
C99, Java, C++ などでは、変数を定義するときに同時に初期化すれば
自然と一変数ごとに一行となる。

構造体メンバ(やクラスのメンバ変数、フィールド)は、
きちんとコメントをつけると、一行ずつのほうが書きやすい。

ごくたまに、 int x, y; のように非常に関連性の高い変数を
同じ行で定義することもないわけではない。
0081デフォルトの名無しさん2008/01/25(金) 08:42:47
>>80
そ、そんな宗派が・・・
0082デフォルトの名無しさん2008/01/25(金) 13:31:20
#include<stdio.h>
main{
char *month[12] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
int i;

for(i = 0; i < 12; i++){
if(*month[i] == 'r' || *month[i] == 'R')
puts(month[i]);
}
}
これで実行してみた所何も出てこなかったのですが、何ででしょうか?
0083デフォルトの名無しさん2008/01/25(金) 13:34:17
>>82
Rで始まる月は無いから。
0084デフォルトの名無しさん2008/01/25(金) 13:43:41
牡蠣を食うつもりだったのか
0085デフォルトの名無しさん2008/01/25(金) 13:48:03
strchr使え
0086デフォルトの名無しさん2008/01/25(金) 15:00:24
2つの整数を入力した後、それらの最大公約数と
最小公倍数を求めなさい。

このプログラムをお願いします。



0087デフォルトの名無しさん2008/01/25(金) 15:05:31
宿題スレに池。
0088デフォルトの名無しさん2008/01/25(金) 15:09:33
>>86
うせろ屑
0089デフォルトの名無しさん2008/01/25(金) 15:13:41
2つの整数をa,bとする。

最小公倍数
・aとbが等しいか比較する。
・等しくない時aとbのどちらが大きいか比較する。
・小さい方は自分の値を自分に足す。(a += a)

上を繰り返す。

最大公約数
a,bの小さいほうで両方を割る。
どちらかが割り切れなかったら小さい方から1引いた値で両方を割る

上を繰り返す。
0090デフォルトの名無しさん2008/01/25(金) 15:14:18
0091デフォルトの名無しさん2008/01/25(金) 15:14:56
>>89
a += aじゃまずいな。
a,bはとっておいて、計算用の変数に足していかないと。
0092デフォルトの名無しさん2008/01/25(金) 16:27:43
>>86
#include <stdio.h>

int main(){
  int x,y,r,t;

  printf("x=");scanf("%d",&x);
  printf("y=");scanf("%d",&y);
  if(x<y){
    int z=x;
    x=y;
    y=z;
  }
  t=x*y;
CHECK:
  if(y==0){
    printf("%d,%d",x,t/x);
    goto END;
  }
  r=x;
MOD:
  r-=y;
  if(r>=y)goto MOD;
  x=y;
  y=r;
  goto CHECK;
END:
  return 0;
}
0093デフォルトの名無しさん2008/01/25(金) 16:45:23
nを与えて和Sを求めるプログラムで
S=1+(1+2)+(1+2+3)+-----+(1+2+3+---+n)
で1重ループでならできたんですが
2重ループでの作り方が分かりません。
低レベルですが教えて下さい。
0094デフォルトの名無しさん2008/01/25(金) 16:49:26
int i, j, s=0;

for(i=1; i<=n; i++) for(j=1; j<=i; j++) s += j;
0095デフォルトの名無しさん2008/01/25(金) 17:08:17
>>94
ありがとうございます。
0096デフォルトの名無しさん2008/01/25(金) 18:41:15
prime[ptr++]=2;
これのptr++ってどういう意味ですか?
ptrは[個数を記憶するもの]と分かるんですが
=2とできる意味も分からないです。
0097デフォルトの名無しさん2008/01/25(金) 18:43:46
primeに2を格納してptr++??
0098デフォルトの名無しさん2008/01/25(金) 18:45:12
>>96
インクリメント演算子知らんのか?
0099デフォルトの名無しさん2008/01/25(金) 18:48:16
知ってます☆
けど、i++とかなら分かるけど
prime[ptr++]=2
となると分かりません
0100デフォルトの名無しさん2008/01/25(金) 18:49:11
知ってはいても、理解してないってことか。
0101デフォルトの名無しさん2008/01/25(金) 18:50:01
>>99
prime[pt]=2;
ptr++;
まぁこういことだな
■ このスレッドは過去ログ倉庫に格納されています