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

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

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさんNGNG?DIA(320721)
C言語の*入門者*向け解説スレッドです。
初心者、初級者の方は他の質問スレのほうが良いかもしれません。

教えて欲しいのではなく宿題を丸投げしたいだけなら
↓宿題スレ↓へ行ってください。
C/C++の宿題片付けます 130代目
http://pc12.2ch.net/test/read.cgi/tech/1250204272/

・C++言語はスレ違いです。
・分からない事をなるべく詳しく書いて下さい。
・ソースコードを晒すと答えやすくなるかもしれません。
  # 抜粋/整形厳禁、コンパイラに渡したソースをそのまま貼ること
  # サイズが大きい場合は宿題スレのアップローダ等を利用してください
・開発環境や動作環境も晒すと答えが早いかもしれません。
・質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。

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

過去スレ
http://makimo.to:8000/cgi-bin/search/search.cgi?q=%82b%8C%BE%8C%EA%82%C8%82%E7%89%B4%82%C9%95%B7%82%AF&andor=AND&sf=0&H=&view=table&D=tech&shw=5000
0153デフォルトの名無しさん2009/09/21(月) 11:18:17
>>152
環境による。速度や効率については実際に試すのが吉。
0154デフォルトの名無しさん2009/09/21(月) 12:10:25
>>152
1行目はmemcmp(キャラ配列の3バイト, 指定した文字列, strlen(指定した文字列))と読めるのだけど、
なんでmemcpy()が出てきたりstrstr()が出てきたりするのか判らん。
0155デフォルトの名無しさん2009/09/21(月) 12:19:07
一行目のその読みが違ってる可能性もあるわけだ。
0156デフォルトの名無しさん2009/09/21(月) 14:15:19
strstrは分かるでしょう
memcpyは3バイト以降をバッファにコピーして、それとあとでstrcmpなりmemcmpするんでしょう。もしくはtypo
0157デフォルトの名無しさん2009/09/21(月) 15:45:50
strstr()で3バイト分の検査がどの程度の時間かかるのか見積もりがわからないけど
気にしたら負けレベル
0158デフォルトの名無しさん2009/09/21(月) 16:25:35
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, int showCmd)
{
printf("test");
return 0;
}

bcc
コンパイルエラーになるんだけど
サンプル引用したものなのに
0159デフォルトの名無しさん2009/09/21(月) 16:37:11
>>158
#include <stdio.h>
を追加したら
0160デフォルトの名無しさん2009/09/21(月) 16:39:00
>>158
エラーメッセージくらい貼れよ
0161デフォルトの名無しさん2009/09/21(月) 16:50:03
環境によってはそれでコンパイルできるからなあ
0162デフォルトの名無しさん2009/09/21(月) 16:52:03
コマンドまたはファイル名が違います.
0163デフォルトの名無しさん2009/09/21(月) 16:53:47
-W
0164デフォルトの名無しさん2009/09/21(月) 16:58:38
パラメータ’hInst’は一度も使用されてないだとか
WinMainの引数全部に同じエラーが出る
あと外部シンボル’_main’が未解決 だって
0165デフォルトの名無しさん2009/09/21(月) 17:04:18
-Werrが付いてるんだ。殊勝な心がけだね
0166デフォルトの名無しさん2009/09/21(月) 17:33:15
>>164
上のはエラーじゃなくてウォーニンだろ。
下のはコンパイルエラーじゃなくてリンクエラーだ。
0167デフォルトの名無しさん2009/09/21(月) 17:45:37
それでどうやって解決するの?
0168デフォルトの名無しさん2009/09/21(月) 17:48:47
>>163 で既に答え出てるだろ。
0169デフォルトの名無しさん2009/09/21(月) 17:59:16
-Wって何のかわからん
これだけじゃ検索ヒットしない
0170デフォルトの名無しさん2009/09/21(月) 18:02:11
>>169
コンパイラのマニュアルをどうぞ
っても-Wだけだとまた困りそうだけど
0171デフォルトの名無しさん2009/09/21(月) 18:04:16
bcc32 [リターン]
0172デフォルトの名無しさん2009/09/21(月) 18:13:06
まったくもう、なぜ>>1に目を通さないかね?
>C言語の*入門者*向け解説スレッドです。
>初心者、初級者の方は他の質問スレのほうが良いかもしれません。
0173デフォルトの名無しさん2009/09/21(月) 18:29:05
ああやっとできた
回答者サンクス
>>172 スマソ
0174デフォルトの名無しさん2009/09/21(月) 19:35:10
>リターン
0175デフォルトの名無しさん2009/09/21(月) 21:42:34
-WだとWを検索対象から外す意味だぞ
0176デフォルトの名無しさん2009/09/21(月) 22:02:26
-w
0177デフォルトの名無しさん2009/09/21(月) 23:17:28
くだらない質問なんですが,
Sleep(0.9)って可能でしょうか?
0178デフォルトの名無しさん2009/09/21(月) 23:25:50
sleep(0.9)だったらコンパイラがエラーか警告吐くとおもうけど
Sleep(0.9)だとわからないなぁ
0179デフォルトの名無しさん2009/09/21(月) 23:36:52
その Sleep ってのが Win32API のことなら、引数は整数型だから、
その表記は単に
Sleep(0);
と見なされるだけだろ。
で、
Sleep(0) ってのは何も問題ないよ。
割り当てられた残り CPU 時間を打ち切ってシステムに制御を返すはず。
0180デフォルトの名無しさん2009/09/21(月) 23:40:41
Sleep を時間待ちに使おうとしてるなら止めたほうがいいよ。
精度は低いし、そもそも設定するのは休止する最低限の時間であって
戻ってくる時間を指定できるわけじゃない。
0181デフォルトの名無しさん2009/09/21(月) 23:44:29
じゃぁどうすればいい?
0182デフォルトの名無しさん2009/09/21(月) 23:46:37
DWORD t = GetTickCount();
while (GetTickCount() - t < 1000);
01831772009/09/21(月) 23:47:18
やはり0となるのですね.すっきりしました,ありがとうございます.
0184デフォルトの名無しさん2009/09/21(月) 23:49:30
>>182
それビジーループにならない?
0185デフォルトの名無しさん2009/09/21(月) 23:57:56
何か問題でも?
0186デフォルトの名無しさん2009/09/22(火) 00:05:54
>>182 だったらsleepのほうがいい。
0187デフォルトの名無しさん2009/09/22(火) 00:06:40
>>185
エコに反する、勿体ない。
0188デフォルトの名無しさん2009/09/22(火) 00:12:08
具体的に
0189デフォルトの名無しさん2009/09/22(火) 00:14:44
sleep(n)でn秒以上止まることは保障されてるけれど
n+1秒以内に復帰するとかって保障されてる?
必要だったら>>182もしょうがないと思うが
0190デフォルトの名無しさん2009/09/22(火) 00:24:20
>>182にしたって、他のタスクが忙しくて実行が止まってるかもしれないんで保証されないのは同じだし。
0191デフォルトの名無しさん2009/09/22(火) 00:29:26
作業用PCのHDD逝ったあああああああああああ
0192デフォルトの名無しさん2009/09/22(火) 00:32:52
1発のwaitを正確に行うのは難しいが、
複数回の平均なら容易く制御できる。
t = GetTickCount();
while(1) {
 何らかの処理;
 t += 900;
 Sleep(t - GetTickCount());
}
0193デフォルトの名無しさん2009/09/22(火) 01:27:08
まず1ミリ秒のsleep()が平均(もしくは最悪)の待ち時間 hを計算しておく
xミリ秒停止するなら,x-hミリ秒(もしくはx-2hミリ秒)程度のsleep()を入れて,そこから先はビジーループ

ってのをやったけど,実時間性を保障するシステムより耐性のあるシステムを作ったほうが安全

※といっても hは保障できる値ではないのでリアルタイム処理なんかはあきらめるしかない
0194デフォルトの名無しさん2009/09/22(火) 01:39:18
情報オリンピックの問題なんですが、
退勤時間 − 出勤時間で勤務時間を求めるプログラムです
一応出来たのですが、変数使いすぎだし、効率悪いような気がしてなりません。。。
もっと簡単に纏めれるやり方ってありますか?

#include<stdio.h>
int main(){
int a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;
while(a =! 000){
scanf("%d %d %d %d %d %d",&a,&b,&c,&d,&e,&f);
scanf("%d %d %d %d %d %d",&g,&h,&i,&j,&k,&l);
scanf("%d %d %d %d %d %d",&m,&n,&o,&p,&q,&r);
if(f - c < 0){
f = f + 60;
e--;
}
if(e - b < 0){
e = e + 60;
d--;
}
if(l - i < 0){
l = l + 60;
k--;
}
if(k - h < 0){
k = k + 60;
j--;
}}
0195デフォルトの名無しさん2009/09/22(火) 01:40:38

if(r - o < 0){
r = r + 60;
q--;
}
if(q - n < 0){
q = q + 60;
p--;
}
printf("%d %d %d\n",d - a,e - b,f - c);
printf("%d %d %d\n",j - g,k - h,l - i);
printf("%d %d %d\n",p - m,q - n,r - o);
}
}
0196デフォルトの名無しさん2009/09/22(火) 01:41:33
>>194
データ構造と処理構造見直せ
おもにtime_tでdifftimeしたり
0197デフォルトの名無しさん2009/09/22(火) 06:18:21
文章をコピーする関数で

void copy(char *to,const char *from)
{
while(*to++ = *from++)
;
}

だと「不正な代入」と警告が出てしまう
プログラム自体は動くがこの書き方だとまずい?
0198デフォルトの名無しさん2009/09/22(火) 06:36:10
別に問題ないけど、気になるんだったら
while((*to++ = *from++))
とすると警告出さなくなるかもしれない。
01991972009/09/22(火) 06:47:06
>>198の通りにやっても警告が出てしまう・・・
本に書いてある通りの書き方だから多分大丈夫だと思うし深く考えなくていいかな
0200デフォルトの名無しさん2009/09/22(火) 06:49:30
つ
memcpy
0201デフォルトの名無しさん2009/09/22(火) 06:50:39
なんでマニアックな書き方すんだ _?
0202デフォルトの名無しさん2009/09/22(火) 07:03:40
マニアックでも何でもねーよ
K&R本にも「このような書き方はマスターすべきである」と書いてあるし
0203デフォルトの名無しさん2009/09/22(火) 07:20:17
memcpyつかったほうが速いし、その本みたことないが
不必要な場面でも使えとは書いてないだろ。 
0204デフォルトの名無しさん2009/09/22(火) 07:23:47
なんでmemcpyが出てくるんだ?
速いからったってstrcpyと比較しなきゃフェアじゃないだろ
0205デフォルトの名無しさん2009/09/22(火) 07:36:21
>>199
なら while((*to++ = *from++) != 0)
ってすればいい。
0206デフォルトの名無しさん2009/09/22(火) 07:37:25
>>203
もしかして、「K&R」の名前も知らないの?

ここはC言語のスレだよね?
0207デフォルトの名無しさん2009/09/22(火) 07:48:32
K&R至上主義の方がちょくちょく現れるが、今の時代に合わせて変えていくことも大事だよ。
この記法についてはidiomとして十分浸透しているものだから別にあれこれ言うつもりはないし、
すんなり読めるようになっておくべきだとも思う。
けれど、K&Rが絶対であるという考えは(そのように言ってはいないのかもしれないが)
やめておいた方がいいよ。
K&RのHello Worldは今ではタブーなコードであるし。
0208デフォルトの名無しさん2009/09/22(火) 07:49:39
Ken TompsonとDennis Ritchieはこの世界じゃ神様だもんな
知らないモグリが回答なんてするはずないよね
0209デフォルトの名無しさん2009/09/22(火) 07:53:17
俺としてはRMSも入れてあげたい、っていうか、釣りだよね
02102092009/09/22(火) 07:55:40
Knuth先生とRMSにするか。
0211デフォルトの名無しさん2009/09/22(火) 08:05:44
別にK&Rを読めとか崇拝しろとか言っているわけじゃない。
もちろん、盲信すべきでもない。

が、K&Rの名前も知らない
つまり、まともに知識を得ようとすれば必ず知っているはずの名前を知らない
という事実が問題。
他の言語でも大抵最初に扱われる、「Hello worldの由来」としても。

この点は、K&Rの知名度よりはだいぶ劣るが
C FAQについても言える。
何かについて詳しく知ろうと調べていけば、普通はこの存在を知ることになるし
Cでまともなコードを書こうとしている人なら、存在自体は知っていなければおかしい。
そして、鵜呑みにする必要は無いが、どんなことが書いてあるか等は目を通しておくべき。
0212デフォルトの名無しさん2009/09/22(火) 08:06:39
■質問です。

↓のような txt ファイルを読み込んで
hoge = {67, 12, -23, 34, -45};
という配列を作りたいのですが、どのようにすれば良いでしょうか?

*** txt ファイル********
67
12 -23
34 -45
*********************

今のところ、とりあえず fgetc で取得した文字(数字や符号)を
文字型配列に入れてみたのですが、
整数への戻し方がわからない状況です。

◆例:-23 の場合

文字型配列 buf を作って buf = {-, 2, 3} と格納したが、
これを整数の -23 へ戻す方法がわからない……。
buf = {1, 2} ならば、10 * buf[0] + buf[1] で 12 が取得できるのだが……。

以上、よろしくお願いします。
0213デフォルトの名無しさん2009/09/22(火) 08:21:30
>>210
Knuth先生はC言語に直接関わってないだろ。
RMSもフリーのコンパイラ作ったっていう関わり方だし、
Cに関してはKernighan/Ritchieは別格。
0214デフォルトの名無しさん2009/09/22(火) 08:23:17
ケントンプソン出てきた時点でこの業界の偉人でK&Rを組み立てる流れになったんじゃなかったのかよ
0215デフォルトの名無しさん2009/09/22(火) 08:25:48
>>212 コード読むのも勉強になればと思って書いてみた。
寝起きだからバグってたらごめん。
真面目に処理するときは自前コードじゃなくてscanf()で整数変数にぶちこむかatoi()等を使う。
int myatoi(char *str)
{
int retv = 0;
int sign = 1;

while (*str) {
if (*str == '-') {
sign = -1;
} else if ((*str >= '0') && (*str <= '9')) {
retv = retv * 10 + *str - '0';
} else {
// break; //error
}
str++;
}
return sign * retv;
}

>>208はsageじゃなくてbokeなんだ。すまない。
02162092009/09/22(火) 08:27:28
すまない。ほんとうにすまなかった。
ラリーウォールじゃLだしなんかインパクトに欠けるし(失礼)とかそっちで精一杯だったorz
0217デフォルトの名無しさん2009/09/22(火) 08:31:35
>>212
定石的なやり方は
fgetsで一行文の文字列読み込んで、それをsscanfで変換。
0218デフォルトの名無しさん2009/09/22(火) 08:48:09
>>216
K&R論争なんてやりたくないしとりあえずボケちゃえと思ったんだ。
乗っかってくれた209さんには感謝してるよー
0219デフォルトの名無しさん2009/09/22(火) 09:09:59
>>215,217
こんな早朝からありがとうございました!
↓のコードで成功しました。※スペースは、掲示板の都合上、全角スペースを用いています。

>>217 の方がよりコードを簡略化できたので、>>217 の方法を使わせていただきました。

#include <stdio.h>
#define LINEMAX 15
#define WORDMAX 6

int main(void) {
  char txtbuf[LINEMAX];
  FILE *fp = fopen("in.txt", "r");
  
  int idx = 0;
  int wordbuf[WORDMAX];
  
  while( fgets(txtbuf, sizeof txtbuf, fp) != NULL) {
    sscanf(txtbuf, "%d ",&wordbuf[idx]);
    printf("%d", wordbuf[idx]);
    idx ++ ;
  }
  
  fclose(fp);
  return 0;
}
02202192009/09/22(火) 09:26:14
あれ。ちょっとまだバグがあるので、これから修正します
0221デフォルトの名無しさん2009/09/22(火) 09:57:06
サイズを求める手間を足しても、memcpyの方が198のやり方より速いの?
0222デフォルトの名無しさん2009/09/22(火) 10:00:33
2009にもなってまだこんなネタで盛り上がれるなんて
よほどやることがないんだな
02232192009/09/22(火) 10:44:58
入力 txt ファイルの -23 と -45 の情報が取得できていないバグを取りました。
#include <stdio.h>
#define TXTMAX 300

int main(void) {
  char txtbuf[TXTMAX];
  FILE *fp = fopen("in.txt", "r");
  
  int idx = 0;
  int wordbuf[TXTMAX];
  
  int toshisu = fgets(txtbuf, sizeof txtbuf, fp);
  printf("都市数は %s \n", toshisu);
  
  while( fgets(txtbuf, sizeof txtbuf, fp) != NULL) {
    sscanf(txtbuf, "%d %d", &wordbuf[idx], &wordbuf[idx + 1]);
    printf("txtbuf の情報を表示します。\n");
    printf("%s", txtbuf);
    printf("txtbuf の情報終わり。\n");
    printf("wordbuf[%d] = %d \n", idx, wordbuf[idx]);
    printf("wordbuf[%d] = %d \n", idx + 1, wordbuf[idx + 1]);
    printf("\n");
    idx = idx + 2 ;
  }
  
  fclose(fp);
  return 0;
}
0224デフォルトの名無しさん2009/09/22(火) 10:45:38
*** txt ファイル********
67
12 -23
34 -45
*********************

■実行結果
都市数は 67

txtbuf の情報を表示します。
12 -23
txtbuf の情報終わり。
wordbuf[0] = 12
wordbuf[1] = -23

txtbuf の情報を表示します。
34 -45
txtbuf の情報終わり。
wordbuf[2] = 34
wordbuf[3] = -45
0225デフォルトの名無しさん2009/09/22(火) 11:38:06
char *m  = (char*)malloc (sizeof(char)*256);
m[258] = '1';
free(m);

明らかに確保してない領域に書き込んでいるのですが
実行してもエラーが出ません、なぜでしょうか?
0226デフォルトの名無しさん2009/09/22(火) 11:39:52
エラーを出力することが規定されていないから
0227デフォルトの名無しさん2009/09/22(火) 11:41:35
そういう言語だから。
OSが保護していない領域は書き換えられまくり。
0228デフォルトの名無しさん2009/09/22(火) 11:42:07
なんだよ都市数ってwなんかの宿題か?
0229デフォルトの名無しさん2009/09/22(火) 12:34:24
>>228
そうですね。課題は巡回セールスマン問題で、
ありがたいことにネットにプログラムはあったんですが、
細かい仕様は当然違うので、その調整をしてました。

プログラミングなんて1年以上前に3ヶ月程やっただけなので、
本当に気が重かったのですが、このスレのおかげで何とか提出できそうです
0230デフォルトの名無しさん2009/09/22(火) 13:04:50
K&R(第2版)を読めば>>225みたいなのがどうして一見正常に機能するのか
その理由もある程度推測できるようになる(mallocの実装例が載っているので)。
0231デフォルトの名無しさん2009/09/22(火) 13:33:59
mallocでユーザがヒープ領域管理できるのなかったっけ
0232デフォルトの名無しさん2009/09/22(火) 16:47:22
#include <stdio.h>

int main(void){
float i,j;
i = 1/3;
printf("%f\n",i);
j = i*3;
printf("%f\n",j);
return 0;
}
のプログラムを実行してみたんですけど、i,jの値ともにゼロになってしまうんですけど
これはどういうことなんですかね?
0233デフォルトの名無しさん2009/09/22(火) 16:49:02
>>232
> i = 1/3;

i = 1.0/3;
0234デフォルトの名無しさん2009/09/22(火) 16:49:21
1/3は整数で完結してるから0になる
1.f/3
1.0/3
にしろ
0235デフォルトの名無しさん2009/09/22(火) 16:51:17
すみません!!
わかりました。ありがとうございます。
0236デフォルトの名無しさん2009/09/22(火) 22:50:39
>>207
>K&RのHello Worldは今ではタブーなコードであるし。
フレーム抜きで詳説希望
0237デフォルトの名無しさん2009/09/22(火) 23:11:49
どうせ「第二版」というものを開いた事も無いような奴が寝言言ってるだけだろ
0238デフォルトの名無しさん2009/09/22(火) 23:19:42
タブーなんていう曖昧な表現をするあたり、何か問題があるにしても
個人的な思い込みに反してるだけだろうしな
0239デフォルトの名無しさん2009/09/22(火) 23:31:39
return がないとかそういう話かね。
0240デフォルトの名無しさん2009/09/23(水) 00:06:28
main(argc,argv)
int argc;
char **argv
{
printf(""Hello world!);
}
0241デフォルトの名無しさん2009/09/23(水) 00:19:02
笑っちゃうね、もう少し勉強してからきてね
0242デフォルトの名無しさん2009/09/23(水) 00:29:53
>>240
それはK&R1。
0243デフォルトの名無しさん2009/09/23(水) 00:32:23
http://www.ioi-jp.org/joi/2008/2009-yo-prob_and_sol/2009-yo-t3/2009-yo-t3.html
こういう問題って頭の中だけで考えますか?
それとも一回紙に大体書き出してからやりますか?
0244デフォルトの名無しさん2009/09/23(水) 00:36:10
適当にコーディングしながら考える。
0245デフォルトの名無しさん2009/09/23(水) 00:36:59
>>240
ああそれはうざい。

というかprintf(""Hello world!);は革新的すぎるぜ
0246デフォルトの名無しさん2009/09/23(水) 00:39:27
>>244
そうなんですか。

>>244さんなら、これをどうプログラミングしますか?
0247デフォルトの名無しさん2009/09/23(水) 00:40:35
>>243
その問題なら、いきなりコーディングできるのでは?
0248デフォルトの名無しさん2009/09/23(水) 00:41:14
古い本だとmain( )やvoid main( )で表記してるのがあるけど、
まだ統一された規格が無かった頃のコードなの?
0249デフォルトの名無しさん2009/09/23(水) 00:41:26
>>247
簡単ですかねー・・・?
まだ経験が浅いので、作ってみたらgdgdになってました(´・ω・`)
0250デフォルトの名無しさん2009/09/23(水) 00:44:37
組み込みの世界は無限ループするからvoid main()が一般的ってほんと?
02512472009/09/23(水) 00:49:23
>>249
自分ならまず、ゲーム部分のシミュレータ作って(返り値が個数)、
入力データ N 個の一箇所を別の色に変えたデータを作る部分を
作って、全体制御と一番小さい数値を返す部分を作って、
終わり
0252デフォルトの名無しさん2009/09/23(水) 00:53:55
>>248
void main() は明らかに間違い。
■ このスレッドは過去ログ倉庫に格納されています