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

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

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2006/12/02(土) 10:16:33
C言語の入門者向け解説スレです。
・C++言語はスレ違いです。
・分からない事をなるべく詳しく書いて下さい。
・ソースコードを晒すと答えやすくなるかもしれません。
・質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。

前スレ
C言語なら俺に聞け(入門篇) Part 4
http://pc8.2ch.net/test/read.cgi/tech/1162999861/l50
過去スレ
Part 1 http://pc8.2ch.net/test/read.cgi/tech/1146700389/
Part 2 http://pc8.2ch.net/test/read.cgi/tech/1153818463/
Part 3 http://pc8.2ch.net/test/read.cgi/tech/1160682950/

関連スレ
C/C++の宿題を片付けます 77代目
http://pc8.2ch.net/test/read.cgi/tech/1164079451/l50
くだすれC言語(初心者用)
http://pc8.2ch.net/test/read.cgi/tech/1153542424/l50
【ISO/ANSI/JIS】 C言語なら俺に聞け! Part 130
http://pc8.2ch.net/test/read.cgi/tech/1159613789/l50
【初心者歓迎】C/C++室 Ver.33【環境依存OK】
http://pc8.2ch.net/test/read.cgi/tech/1164376287/l50


0002デフォルトの名無しさん2006/12/02(土) 10:25:47
2げっとずざー
0003デフォルトの名無しさん2006/12/02(土) 13:06:06
ズサーc⌒っ・ω・)っ
0004ぴゅあ2006/12/02(土) 15:25:35
前スレ#987,#988
http://pc8.2ch.net/test/read.cgi/tech/1162999861/987-988

好みと言ってしまえば好みでもあるのだろうし
レスするまでのものでもないと思うけど
for (i = 0; i < 15; i++) {
 if (i > 0)
  fputc('\t',output2);
 fprintf(output2, "%d", bin[i]);
}
とかの方がやりたいことがスッキリ読めるような気もする…
0005デフォルトの名無しさん2006/12/02(土) 15:30:03
>>4
最後に改行打たないとだめらしいお
0006ぴゅあ2006/12/02(土) 15:51:52
(>>5より)
じゃあそれも追加しといて
forの中の話だけ挙げたので
0007デフォルトの名無しさん2006/12/02(土) 16:03:04
毎回ifで判定するのって無駄じゃない?
0008デフォルトの名無しさん2006/12/02(土) 16:24:59
数値を繰り返し入力し、合計、平均をその都度表示する
ただし、0を入力すると終了する
っていうプログラムを作りたいんですけど
0を入力すると終了ってとこはわかるのですが、
平均を出すときにどうやって今まで入力した回数を
指定するかがよくわかりません

#include<stdio.h>
int main(void){
int goukei=0;
int tokuten;
scanf("%d",&tokuten);
while(tokuten!=0){
goukei=goukei+tokuten;
printf("goukei=%d\n",goukei);
scanf("%d",&tokuten);
}
return 0;
}

ここからどうすればいいんでしょうか
よろしくお願いします
0009デフォルトの名無しさん2006/12/02(土) 16:30:44
#include<stdio.h>
int main(void)
{
  int goukei;
  int tokuten;
  int cnt; // ここ追加、カウンターを追加
  goukei = tokuten = cnt = 0;
  do {
    scanf("%d",&tokuten);
    if (!tokuten) break;
    goukei += tokuten; // 追加の場合これでおk
    cnt++;
    printf("goukei=%d, heikin = %d\n",goukei, goukei / cnt;);
  }
  return 0;
}
0010デフォルトの名無しさん2006/12/02(土) 16:35:33
>    printf("goukei=%d, heikin = %d\n",goukei, goukei / cnt;);
>  }
の部分修正、whileつけて
    printf("goukei=%d, heikin = %d\n",goukei, goukei / cnt;);
  }while (1);

またはdo〜whileの部分を
  scanf ("%d", &tokuten);
  for (cnt = 1; tokuten; cnt++)
  {
    goukei += tokuten;
    printf ("合計=%d, 平均=%d\n", goukei, goukei / cnt);
  }
でもいいと思うよ

数字を入力する部分を
  char str[64]; // 文字入力を数字に変える
  gets (str); // 文字入力を受け付ける
  tokuten = atoi (str); // ここで文字列をintに変える
としてもいいと思う
0011デフォルトの名無しさん2006/12/02(土) 16:36:49
>>9
ありがとうございます

それで、教えてもらってる身でこんな事言うのは
非常にあつかましいと思うのですが、
あんまり高度な事やっちゃうと先生に変な期待もたれそうで怖いので、
もし、もうちょっと簡単な方法ってありますでしょうか?
本当にすみません我侭言ってしまって・・・
0012デフォルトの名無しさん2006/12/02(土) 16:39:41
大丈夫。平均値を整数で出してるから。
あと、心理学の実験によると期待されているほうが成績がよくなるらしいぞ。
0013デフォルトの名無しさん2006/12/02(土) 16:40:00
>>10
すみません、リロードしてませんでした
これまた難しい方法なんですねorz
授業だとcntとか習ってないのでたぶんもっと簡単な方法でやるんだと思うんですが、
もしかしたら先生の意地の悪い宿題かもしれないです・・・
0014デフォルトの名無しさん2006/12/02(土) 16:43:15
>>11,13
スレ違い
 C/C++の宿題を片付けます 77代目
 http://pc8.2ch.net/test/read.cgi/tech/1164079451/


入力を文字列でして、数字に変える方法は便利、というかエラーになりにくい。

俺も良く分からんがバッファに関して優しいのかな。

表面上は些細な違いだが、内部の事を考えると高度な違いになるんで、
これやらなければ目をつけられる事無いでしょ

cntはcount(カウント)で良く略字として使われてる
なので、この部分を初心者っぽく"kaunto"とすればバレないぜ
0015デフォルトの名無しさん2006/12/02(土) 16:46:20
>>14
C/C++っていう言語のスレかと思ってましたorz
スレ違いすみませんでした・・・
0016ぴゅあ2006/12/02(土) 16:48:01
>>11
>あんまり高度な事やっちゃうと先生に変な期待もたれそうで怖いので
>>9(>>10の訂正付き)でいいんじゃないかと思いますよ
後は提出までにコードを理解しておくこと

1個穴があるだろうと思うけど

>scanf("%d",&tokuten);
の前で"tokuten = 0;"とかするのがよかったりするんじゃないのかなとか思ったりするけど
そこんところはそのまま穴にしておいてもいいんだろうけど(先生からの指摘を待つ?)
「そこは人から教わりました」(理解できてたなら)でもOKだろうと思いますよ
0017デフォルトの名無しさん2006/12/02(土) 16:51:53
>>16
そうですね・・教えて頂いた方法でやってみようと思います
とても助かりました
本当にありがとうございました
0018デフォルトの名無しさん2006/12/02(土) 16:53:34
cnt → kaisu
cnt++ → kaisu = kaisu + 1
ってすれば初心者っぽく見えるよ。
0019ぴゅあ2006/12/02(土) 17:01:43
>>17 (追記)
>数値を繰り返し入力し、合計、平均をその都度表示する
>ただし、0を入力すると終了する
という課題を満足させるなら
>>9(+>>10)のコードは最低必要になるだろうし
或いはそうでないなら"解りませんでした"になるのかも

>平均を出すときにどうやって今まで入力した回数を
>指定するかがよくわかりません
の"指定"とは、外から回数を与えたりするのではなく
"平均値を求めるために必要とする回数を得るにはどうすればいいのか"
と解釈しました
0020デフォルトの名無しさん2006/12/02(土) 17:02:09
>>16
ごめん、穴がどこだか俺じゃ分からない
訂正キボン
0021デフォルトの名無しさん2006/12/02(土) 17:10:23
>>8です

↓無事作る事ができました

#include<stdio.h>
int main(void){
int goukei=0,heikin=0;
int a,kaisu=0;
scanf("%d",&a);
while(a!=0){
goukei+=a;
printf("合計=%d\n",goukei);
kaisu++;
heikin=goukei/kaisu;
printf("平均=%d\n",heikin);
scanf("%d",&a);
}
return 0;
}

たくさんの助言ありがとうございました
本当に助かりました
0022デフォルトの名無しさん2006/12/02(土) 17:12:00
>>21
実に上手い
これほど初心者っぽくはなかなか作れまい
0023ぴゅあ2006/12/02(土) 17:15:14
>>20
2回目以降"scanf("%d",&tokuten);"に来たときのtokutenの値って
前回入力された値が入っているじゃないですか

たぶん…
そこでEnterキーだけ押したら前の値が入力されるかも?

・・・と思ったけど"%d"によってそうはならないみたいでした
なので一応>>16の後半は無視かも

ただ、(追求してみないと原因は判ってないけど)
適切な数値を入力→無効な文字(英字の文字列とか)
とするとループになってしまうようですけど
ここが対処できてしまったりするのは
宿題の答えとしては理解でき過ぎになるかも
0024ぴゅあ2006/12/02(土) 17:20:02
>>22
というか…

自身が示した>>8のコードに対して
>kaisu++;
>heikin=goukei/kaisu;
>printf("平均=%d\n",heikin);
が必要と解ったみたいなので
理解できたということだと思う
0025デフォルトの名無しさん2006/12/02(土) 17:20:07
>>23
あぁ、それそれ
直接的には覚えてなかったけどscanfよりgets&atoi使った方がいいってのはそういう事だったんだな
ループ懐かしいな
0026デフォルトの名無しさん2006/12/02(土) 17:23:40
#include<stdio.h>
int main(void)
{
 int goukei = 0,heikin;
 int a=1,kaisu;
 for(kaisu=1;a!=0;kaisu++)
 {
   printf("数値を入力してください。\n>");
   scanf("%d",&a);
   goukei+=a;
   heikin=goukei/kaisu;
   printf("合計=%d\t平均=%d\n",goukei,heikin);
 }
 return 0;
}
0027デフォルトの名無しさん2006/12/02(土) 17:31:34
任意の整数の約数(ただしその整数自体は含めない)の総和を表示するプログラムってどうやるんですか?
0028デフォルトの名無しさん2006/12/02(土) 17:35:40
1から順に余り求めて0なら、割った数を足す。整数自身のときはカウンタ回して飛ばす
0029デフォルトの名無しさん2006/12/02(土) 17:51:37
>26
それだと0のときも合計と平均出すことになるんだけど。
0030デフォルトの名無しさん2006/12/02(土) 17:54:47
#include<stdio.h>
int main(void)
{
 int goukei = 0,heikin;
 int a=0,kaisu;
 for(kaisu=1;;kaisu++)
 {
   printf("数値を入力してください。\n>");
   scanf("%d",&a);
   if(a==0) break;
   goukei+=a;
   heikin=goukei/kaisu;
   printf("合計=%d\t平均=%d\n",goukei,heikin);
 }
 return 0;
}
0031デフォルトの名無しさん2006/12/02(土) 17:57:24
>27
int i, n, sum=0;
for(i=0; i<n; i++) if(n%i==0) sum += i;
0032デフォルトの名無しさん2006/12/02(土) 17:58:12
for(i=0; → for(i=1;
0033デフォルトの名無しさん2006/12/02(土) 18:09:56
>>27
#include <stdio.h>
int add(int a, int b){return a+b;}
int mod(int a, int b){return a%b;}
int func(int n, int d){
if(!d)return 0;
return add(mod(n,d)?0:d,func(n,d-1));
}
int funct(int n){return func(n,n-1)}
int main(void)
{
return printf("%d\n", funct(atoi(gets(malloc(256)))));
}
0034デフォルトの名無しさん2006/12/02(土) 18:53:45
>>25>>26
うるおぼえだけど
int a;
do { scanf("%d",&a); } while( a != 0 );
として入力が 10G みたいになるとscanfは10だけ読んで終了する.
入力バッファに G だけ残るが次のscanfはバッファにはデータがあるけど読めないものだから 0 返して終了しちゃう(バッファもクリアされない)
結果延々ループになる

scanf の後に fflush 入れてバッファクリアすればいい
でも fflush って処理依存だったような気がするけど
0035342006/12/02(土) 18:54:36
まちがえた
>>23>>25ね
0036デフォルトの名無しさん2006/12/02(土) 19:03:09
fflushじゃなくてrewindだろ。
fflushは出力に対して使うもの。
0037デフォルトの名無しさん2006/12/02(土) 19:15:45
やりたいことは、stdioバッファに蓄積された(解析できない)データを
行末まで読み飛ばすことだろ。

それなら、
scanf("%*[^\n]");
でいい。
fflush()にしろrewind()にしろ、stdinに対して使った場合の挙動は
移植性が無い。
0038デフォルトの名無しさん2006/12/02(土) 19:21:09
うる覚えじゃなくてうろ覚えだっていうツッコミはナッシング?
0039デフォルトの名無しさん2006/12/02(土) 19:23:51
scanf・・・




┐(´ー`)┌
0040デフォルトの名無しさん2006/12/02(土) 19:29:50
freopen(stdin でOK
0041デフォルトの名無しさん2006/12/02(土) 19:42:29
ポインタはわざと意味不明なこと言ってるんですよね?
0042デフォルトの名無しさん2006/12/02(土) 19:43:29
2択の日本語クイズでやってたな
ナイナイの番組
0043デフォルトの名無しさん2006/12/02(土) 21:35:54
vprintf関数やvsprintf関数は、例えばこれらを中に含んだ関数を作って
出力先が同じ場合に毎回指定する手間を省いたり、独自の関数名を使うことで
出力先を分かりやすくして間違いを少なくするのに利用するんでしょうか?
0044デフォルトの名無しさん2006/12/02(土) 21:43:40
>>43
vprintfの存在意義を確認してるって事でおk?
0045432006/12/02(土) 21:48:47
>>44
あ、はいそうです
って良く考えなくてもvprintfは出力先標準出力に固定されてますね…
0046デフォルトの名無しさん2006/12/03(日) 02:23:52
>>43
本当に必要になるまで関数の存在意義は分からないもんさ
0047デフォルトの名無しさん2006/12/03(日) 02:27:48
「2つの整数 x と y の全ての公約数を求めて配列 d に格納する関数」
を作りたいのですが、
「2つの整数 x と y の全ての公約数を求める関数」が既にある場合、
その関数を配列dに格納する関数を新しく作るのと
関数を増やさずに作り変えて配列dに入れるのとどっちが楽ですかね?
0048デフォルトの名無しさん2006/12/03(日) 02:28:58
関数でsleepと言うのがあるらしいのですが、
本屋でいくつかC言語の書籍に目を通してもそれに関する記述も無く、
どういった働きなのか、どう使うのか、そもそもC言語で使用する関数なのかどうか
詳しい内容がわからず困っています、
sleepについてお願いします。
0049デフォルトの名無しさん2006/12/03(日) 02:39:51
>>47
1.「二つの整数 x と y の公約数全てを含めた”配列を返す関数”」を作るといいよ
2.既に安定した状態の関数を弄るよりは、それを使った方が可読性が上がる。
  より公約数を割り出す関数を利用する関数を作って配列を返すのがいい、と俺は思う。

ただ公約数って、全部求めちゃった方が楽だよな…
だから、コピって別の名前つけて弄っちゃってもいいと思うよ

>>48
システムコール
0050デフォルトの名無しさん2006/12/03(日) 03:44:11
すみません。
srand(time(NULL));
使ってて、今まではちゃんとした結果を出してくれたのですが、
今同じプログラムを作動してみると、50%ぐらいの割合で、
めちゃくちゃな結果を出します。
どうしたら良いでしょうか?
srand(time(NULL)); 使ったらやばい時間なのですか?
0051デフォルトの名無しさん2006/12/03(日) 03:49:01
>>50
一応キャストして(unsigned)使った方がいいけどそこはあんまり問題じゃないと思う
そんなに大きいソースじゃなければ該当のソースを貼ってみてくれ
0052デフォルトの名無しさん2006/12/03(日) 03:54:37
めちゃくちゃな結果が何を意味しているのかさっぱり見当がつかん。
疑似乱数の初期化なんだから乱数列はめちゃくちゃで当たり前だが。
0053デフォルトの名無しさん2006/12/03(日) 03:55:14
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

#include "janken.h"
#include "boardfunc.h"

extern int p_i,p_j;//直前にマークしたx,y座標

//○×ゲーム
main(){
int p_turn;//プレイヤーのターンの時は1
char p_get[10]; //プレイヤーの入力値
int r;//プレイヤーが揃ったか否かを判定結果

srand(time(NULL));

printf("【○×ゲーム】"\n);
do{p_turn = janken();} while(p_turn < 0);
if(p_turn){writeBoard();}

for(;; p_turn = !p_turn){
if(p_turn){ //プレイヤーターン
do{
printf("場所を指定して下さい(例:a2) > ");
scanf("%s",&p_get);
}
while(!writeMark(p_get));

0054デフォルトの名無しさん2006/12/03(日) 03:56:17
}
else{ //コンピュターターン
writeCompMark();
printf("コンピュターは・・・ %c%d\n",p_j+96,p_i);
}

writeBoard();
r = judge();
if(r != 0){break;}
}

printf("\n==========ゲーム終了=========\n);
if(r == -1){printf("\あいこですn");}
else{
if(p_turn{printf("プレイヤーの勝ち!\n");}
else{printf("プレイヤーの負け!\n");}
}

return 0;
}


0055デフォルトの名無しさん2006/12/03(日) 03:58:15
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
10-4.c:
エラー E2209 10-4.c 5: インクルードファイル 'janken.h' をオープンできない
エラー E2209 10-4.c 6: インクルードファイル 'boardfunc.h' をオープンできない
エラー E2206 10-4.c 18: 不正な文字 '\' (0x5c)(関数 main )
エラー E2121 10-4.c 18: 関数呼び出しに ) がない(関数 main )
警告 W8065 10-4.c 19: プロトタイプ宣言のない関数 'janken' の呼び出し(関数 main )

警告 W8065 10-4.c 20: プロトタイプ宣言のない関数 'writeBoard' の呼び出し(関数 ma
in )
警告 W8065 10-4.c 28: プロトタイプ宣言のない関数 'writeMark' の呼び出し(関数 mai
n )
警告 W8065 10-4.c 32: プロトタイプ宣言のない関数 'writeCompMark' の呼び出し(関数
main )
警告 W8065 10-4.c 36: プロトタイプ宣言のない関数 'writeBoard' の呼び出し(関数 ma
in )
警告 W8065 10-4.c 37: プロトタイプ宣言のない関数 'judge' の呼び出し(関数 main )
エラー E2380 10-4.c 41: 文字列または文字定数が閉じていない(関数 main )
エラー E2121 10-4.c 42: 関数呼び出しに ) がない(関数 main )
警告 W8070 10-4.c 49: 関数は値を返すべき(関数 main )
*** 6 errors in Compile ***

こうエラーが表示されてしまいます。
誤り箇所など、ご指摘お願い致します。
行数を見ても、何処がどう違っているか、わかりません。
0056デフォルトの名無しさん2006/12/03(日) 04:00:24
エラー E2209 10-4.c 5: インクルードファイル 'janken.h' をオープンできない
エラー E2209 10-4.c 6: インクルードファイル 'boardfunc.h' をオープンできない

janken.hとboardfunc.hが無いから、ちゃんと読めるように同じ階層に入れてあげて
005753-552006/12/03(日) 04:02:02
すみません、分割しているので
訂正箇所が
エラー E2206 10-4.c 18: 不正な文字 '\' (0x5c)(関数 main )
エラー E2121 10-4.c 18: 関数呼び出しに ) がない(関数 main )
エラー E2380 10-4.c 41: 文字列または文字定数が閉じていない(関数 main )
エラー E2121 10-4.c 42: 関数呼び出しに ) がない(関数 main )
警告 W8070 10-4.c 49: 関数は値を返すべき(関数 main )
*** 6 errors in Compile ***

だけになります。
005853-552006/12/03(日) 04:03:47
>>56
今のところ、#include "janken.h"
#include "boardfunc.h"

はまだ書いていません。
0059デフォルトの名無しさん2006/12/03(日) 04:04:41
>>58
そかそか、分かった、着眼点が違ったようでスマソ
>printf("【○×ゲーム】"\n);
""の外に\nを書いちゃだめよ
0060デフォルトの名無しさん2006/12/03(日) 04:07:42
C言語の少数に関して質問があります。

小数をバイナリ化した値 "0x40133333" (10進で2.3)
をunsigned intに代入して次のようにして、2.3と表示
されるのを期待しています。

#include<stdio.h>

int main(void){
unsigned int integ = 0x40133333;
printf("%f\n", (float)(integ) ) ;
}
としたのですが、結果はとんでもない値(1075000115.00000)に
なってしまいます。どうしてでしょう??
もともとはバイトオーダの変換をしていてうまくいかず調べ始めたのですが、
ここに行き着いてしまいました。。。orz
0061デフォルトの名無しさん2006/12/03(日) 04:09:25
>>60
printf("%f\n", (double)(integ) ) ;
006253-552006/12/03(日) 04:12:04
できました!ありがとうございました。
0063デフォルトの名無しさん2006/12/03(日) 04:12:22
>>51
137行ですが、宜しいですか?
>>52
2次元粒子のシミュレーションです。
10*10の箱に20個の粒子を少しでたらめに配置し、
時間が立った後で20個それぞれのスピードを計算する、というプログラムです。
最初は20個の粒子のスピードを1に設定してるのですが、
マクスウェルボルツマンによればそんなにスピードが速い粒子は無いはずです。
が、自分のプログラムは時たまとてつもでかいスピードの粒子が存在するのです。
0064デフォルトの名無しさん2006/12/03(日) 04:13:34
>>63
それはプログラムがバグっています。
0065デフォルトの名無しさん2006/12/03(日) 04:15:02
>>60
中々いい事してるね
浮動小数点の由来を調べてみるといいかも


詳しくは知らんし俺の推測からだけど
小数点の部分もfloatは格納してるから、
内部をそのまま写すと小数点の部分も整数として評価されるので、おかしくなる
0066デフォルトの名無しさん2006/12/03(日) 04:16:51
>>50と>>53-55は別人かよ…全然気づかなかった
0067デフォルトの名無しさん2006/12/03(日) 04:18:38
>>65に追加で丸め誤算が何故起こるかとかも調べるもっと賢くなれる
0068デフォルトの名無しさん2006/12/03(日) 04:22:44
>>60
printf("%f\n", *(float *)(&integ));

ちなみにdoubleは64ビット
0069デフォルトの名無しさん2006/12/03(日) 04:23:24
整数と少数の違いは置いとくとしても
(float)(integ)でどうして2.3が出ると思うのか?
integには整数しか入らないからキャストしても小数点以下は0しか出ない。
0070デフォルトの名無しさん2006/12/03(日) 04:28:19
>>68
なるほど、そんな手が
ってか普通に思いつかない俺があかんな
しかしこの用法が一体何に結びつくのだろう
0071デフォルトの名無しさん2006/12/03(日) 04:30:39
すみません、C言語に於けるマクロの意味を教えて下さい
機械語に変換される前に通るのと置き換えができると
入門書には書かれていますが、いまいちイメージが掴めません
ですので、何か他の物に喩えて、簡単にイメージが掴める様に
説明お願いします。
0072デフォルトの名無しさん2006/12/03(日) 04:41:57
>>71
ここに書いてあるけど;(セミコロン)を書いてはいけないもの
ttp://www.kouno.jp/home/c_faq/c10.html
だってさ

#includeや#define
VBSみたいに特に特殊な意味合いは無いと思う、マクロウィルス?とかみたいなね

ちなみにマクロで良く出てくる((a)?(b):(c))は三項演算という
0073デフォルトの名無しさん2006/12/03(日) 04:41:58
>>71
萌え画像ー>(脳内変換)ー>興奮
           ↑
         このへん
0074デフォルトの名無しさん2006/12/03(日) 04:43:03
>>71
変換される前に通る、って何?
通る=変換だと思うんだが
0075デフォルトの名無しさん2006/12/03(日) 04:45:24
>>74
お前のコンパイラ系は
プリプロセスで機械語に変換しているのか・・よかったな
0076デフォルトの名無しさん2006/12/03(日) 04:47:54
今の流れを満足させるページはこれか
マクロについても書いてある
ttp://mikata.curiocube.com/hello/ch19_comment.html
0077712006/12/03(日) 05:05:00
ありがとうございます、難しいですね…
マクロウィルス?とかも確かにマクロと付きますね。
なんとなーくはイメージを掴めました。

通るが変換ですた、すんまそ
0078ぴゅあ2006/12/03(日) 05:22:42
>>71
他のものに例えてみるのは考えるのが面倒なのでそのまま書きますけど

>>72が示したページにあるように「機械語に変換される前に」というより
大抵のコンパイラにはコンパイルの段階の前にプリプロセッサによる処理というものがあって
(概ね:プリプロセッサ→コンパイラ→アセンブラ→リンカ)
そのひとつのマクロ処理はソースコードから文字列(トークン)の置き換えを行うもの
(飽くまで文字列(トークン)を文字列のまま扱って置き換えする)
そうそう、エディタで言えば置換機能
その結果として出てきたソースコードがコンパイラに掛けられます

例えば(いい例書けるか自信ないけど)
#define ARRAY_SIZE (5*10)
int array[ARRAY_SIZE];
と書いておくと
int array[(5*10)];
と書いてあったものとしてコンパイラに掛けられる(これのことを"通す"と言っているのかな?)ことになります

>>72
#include,#define等はプリプロセッサディレクティブ
Cで言うところのマクロ処理については#defineディレクティブになるのでは?
これらのディレクティブ(擬似命令)を使って書いたものがマクロであるとかはまず言わないような気も…?
0079デフォルトの名無しさん2006/12/03(日) 05:25:21
質問者が例を言って去った後なのが悲壮感を誘う
感動した
0080ぴゅあ2006/12/03(日) 05:26:27
>>71
ついでにもうちょっと知ってみる材料として
「マクロ #define」辺りでググッてみるとか

取り敢えず最初の方に出てきたりした
http://wisdom.sakura.ne.jp/programming/c/c40.html
http://www.geocities.jp/ky_webid/c/039.html
辺りでも見てみるとかいいかも
0081712006/12/03(日) 05:33:49
>>78
ありがとうございます!
しかしながら本当に難しいです
特に例を書いて頂いた辺りが、もう一度頭を冷やしてから考え直しますノシ
0082ぴゅあ2006/12/03(日) 05:59:56
>>81
焦らずジックリやってみることですね

>>78に挙げた例とかは実際見てみるまでもなくそうなってるんですけど
例えばVC++なら(今持ってる最新はVC7で)プロパティページで
構成プロパティ→C/C++→プリプロセッサの"プリプロセスファイルの生成"で生成するようにすると
コンパイラに掛ける前のソースコードファイル(拡張子.iのテキストファイル)が得られるので本当にそうなるか見てみるとか
gccなら-Eオプションかな

#includeとか含まれていると見るのが大変になるので
まずは先の例だけ書いてみるとか
更に色々書き替えてみてどうなるかとか

もしかしたら実際にやってみたりする方が感触つかめたりするのかも?
0083デフォルトの名無しさん2006/12/03(日) 07:41:05
邪悪なCコードとか見るとマクロの異常さがよく解る
ただし間違っても自分が書くコードの参考にしないように
マジで
0084デフォルトの名無しさん2006/12/03(日) 08:45:03
>>63
srandがおかしいと言ってるんなら
srandを使用した最小限のプログラムを晒すべき
それでおかしくならないのなら、srand以外のバグだろ
0085デフォルトの名無しさん2006/12/03(日) 09:26:17
#include <stdio.h>
double carnell(double a,double b,double *c,double *d,double *e,double *f){
double bak1;

bak1 = a;
a += b;
*c = a;

a = bak1;
a -= b;
*d = a;

a = bak1;
a *= b;
*e = a;

a = bak1;
a /= b;
*f = a;
return 0;
}
0086852006/12/03(日) 09:26:49
int main(void){
double c,d,e,f;
double b[2];

c = d = e = f = 0;
printf("数値入力");
scanf("%lf",&b[0]);
printf("数値入力");
scanf("%lf",&b[1]);

carnell(b[0],b[1],&c,&d,&e,&f);
printf("和:%d\n",c);
printf("差:%d\n",d);
printf("積:%d\n",e);
printf("商:%d\n",f);
return 0;
}
0087852006/12/03(日) 09:28:10
上のはコンパイルはできるんですが
実行しても最後に出てくる数字が0ばっかなんです
初心者なんで良くわかりません
どこが悪いのか教えてください
0088デフォルトの名無しさん2006/12/03(日) 09:35:57
printfの%d
0089852006/12/03(日) 09:39:14
うはw�dクス!!
俺だめじゃんwwwww
0090デフォルトの名無しさん2006/12/03(日) 10:18:08
>>50
srand(time(NULL))は、rand()が返す乱数の種として、そのプログラムの実行時の時刻を使うということ。
(これをやらないと、プログラムを実行するたびに毎回同じ乱数列が生成される。)

君の環境が何かは知らないが、srandやrandにバグがあるとは思えない。
srandはその後のrandの結果に影響するだけ。randは0〜RAND_MAXの任意の値を返すだけ。
rand()が返す値が0〜RAND_MAXであることを確認できれば、
問題は君のプログラムの別の部分にあるはず。

これまで正しく動作していて、ソースを何もいじっていないのに急に動かなくなったなら、
これまでに動かしたときに生成された乱数の列が、たまたま上手く動く(ように見える)パターンだった
というだけだと思う。

ソースをさらしたとして、指摘できるのはC言語の使い方としての誤りだけだ。
そのシミュレーションのロジックが正しく実装できているかは判断しかねるから期待するな。
0091502006/12/03(日) 10:45:48
みんな、ありがとうございました。
やっぱり、プログラム事態おかしかったみたいです。部分、
   int i,j;
double dx,dy,r_ij,f_ij,fx[N],fy[N];
double x_new[N],y_new[N];
double t=0;
while(t<T_MAX){
t=t+dt;
と書いてあったのを
double t=0;
while(t<T_MAX){
t=t+dt;
int i,j;
double dx,dy,r_ij,f_ij,fx[N],fy[N];
double x_new[N],y_new[N];
と、ループの中で宣言したら書いたらオッケーでした。(でもなんでかわからん)
0092デフォルトの名無しさん2006/12/03(日) 10:53:00
>>91
srand(time(NULL));
がおかしいと思った時はsrandを用いた最小限のプログラムでテストするべき、
それで問題なければ他のところがおかしいとわかる

変数の宣言する場所で結果が変わるなら、
変数のスコープというのについて調べればいいと思うよ。
0093デフォルトの名無しさん2006/12/03(日) 11:02:07
>>91
思いつくのをあげてみると、
・Nがかなり大きな値なら、スタックがあふれているのかもしれない。
 大きな配列はローカル変数ではなく staticをつけて宣言するかmallocで確保すべき。
・原因は他のところにある。初期化していない領域を参照しているとか。
 スタックの配置が変わってたまたま正しい結果が返ってくるようになっただけ。

ちょっとだけESP発動。
10×10の配列の部分てどうやってる?
>>91の中には2次元配列とか、(double *)の配列がないから、
もしかしてdouble x_new[N],y_new[N]; 辺りが10×10のデータを格納するためのもの?
0094502006/12/03(日) 11:34:03
別スレからロダ借りてきました。正常に起動していると思われます。
vの分布が右にちょっと傾いた山型でピーク時のvが1ぐらいです。
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/3073.c
0095デフォルトの名無しさん2006/12/03(日) 12:08:36
>>94
>vの分布が右にちょっと傾いた山型でピーク時のvが1ぐらいです。
そんな説明で何をやっているのか分かるわけないだろう。
人にソースを見せるなら、せめて各関数の意味と変数の意味ぐらいコメントで書け。
お前はこんなソースを人から見せられて、何をやっているのか理解できるか?
質問をするなら、それを受け取った相手に何が伝わるかくらいの配慮はしろ。

で。
>for(i=1;i<=N;i++){
> fx[i]=0;
fx[N]で宣言したなら、f[0]〜f[N-1]のみが使える。
f[N]にはアクセスするな。
他の配列も同様。
0096502006/12/03(日) 12:51:17
ごめんなさい。

下のはコメント付けました。
でも日本語だと文字化けしちゃったので、英語です。
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/3075.c
0097デフォルトの名無しさん2006/12/03(日) 13:19:12
>>78
ちょっと難しく書きすぎてないか?
全然読む気が起きない
0098デフォルトの名無しさん2006/12/03(日) 13:20:29
>>96
>>95はシカトか
0099502006/12/03(日) 13:59:11
>>98
なんかただ小うるさいだけなんですよね。
もう答えてもらわなくていいです。
0100デフォルトの名無しさん2006/12/03(日) 14:15:41
60です。
68の方! 本当に有難うございました。
できましたよー!

ポインタの型変換ではうまくいくのに
どうして(float)(integ)では駄目なのかな。。
0101502006/12/03(日) 14:21:24
>>99は俺じゃ無いです。

>>99
修正中。。。
■ このスレッドは過去ログ倉庫に格納されています