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

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

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

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

過去スレ
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/
Part 4 http://pc8.2ch.net/test/read.cgi/tech/1162999861/
Part 5 http://pc8.2ch.net/test/read.cgi/tech/1165022193/

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

【C 関数検索 man on WWW】 http://www.linux.or.jp/JM/index.html
0002デフォルトの名無しさん2007/01/29(月) 19:30:37
>>1
乙様です。

早速ですが、↓マクロについて教えてもらえますか
#define ROUND_TO_INT(x) ((int) ((x)+(((x)>0)?0.5:-0.5)))

size = ROUND_TO_INT(sqrt(dx*dx + dy*dy));
のような使い方をするようなんですが、さっぱりです。
0003デフォルトの名無しさん2007/01/29(月) 20:15:31
>>2
それは x が 0 より大きければ 0.5 を足し、0より小さければ 0.5 を引く。
それから int 型にキャストする。

ということだ。
何が起こるかというと、四捨五入。

つまり、 x がたとえば 3.4 だったとすると 0.5 足されて 3.9になる。
それから int 型にキャストするので 3 になる。
3.5 だったら 0.5 足されて 4.0 になってそれから int 型にキャスト
するので 4 になる。
0004デフォルトの名無しさん2007/01/29(月) 20:19:13
>>3
回答感謝します。
四捨五入でしたか。マクロの見方もわかりました。
0005デフォルトの名無しさん2007/01/29(月) 20:44:41
ソース上で数値を扱う場合、
プログラムの軸構造を無惨に変更する(?)#defineは使わず、
enumを使うべきだと習いました。
無惨に変更するって、#defineはCソースでよく使われていると
思いますが、問題を抱えているんでしょうか?
0006デフォルトの名無しさん2007/01/29(月) 21:02:56
#define は危険って言っても、
適正な使い方をする分には問題ないし、
連続定数以外は #define した方がいいと思われ。
連続定数以外に enum 使うのは可読性が悪い気がする。
goto は絶対使っちゃダメ、っていうぐらい極端な思想だと思う。

C++ なら const 定数をその代わりとして使えるから、
#define は使わないんだけどね。
000752007/01/29(月) 21:31:04
>>6
ありがとうございます。
>#define は危険って言っても、
>適正な使い方をする分には問題ないし、
>連続定数以外は #define した方がいいと思われ。
わかりました。

>連続定数以外に enum 使うのは可読性が悪い気がする。
そうですね。

>goto は絶対使っちゃダメ、っていうぐらい極端な思想だと思う。
>
>C++ なら const 定数をその代わりとして使えるから、
>#define は使わないんだけどね。
はい。
0008デフォルトの名無しさん2007/01/30(火) 01:11:34
C言語でExcelの作成のデータベースファイルを読み込む場合、
ランダムで1行読み込ませるにはどういう方法をとればいいでしょうか

またランダムであっても出力する行に偏りを出すことは可能でしょうか
0009デフォルトの名無しさん2007/01/30(火) 01:26:15
>>8
いったん全データを取り出し、行数を数えてから
ランダムで行を取り出せばいいんじゃね

後半は何言ってるか分からんが、
偏らないランダムなんてランダムじゃないよ
0010デフォルトの名無しさん2007/01/30(火) 01:30:17
>>9
自分である程度狙った結果を出せるか、という意味です

例えば漢字のみの名前とひらがなのみの名前で構成されたデータベースで
漢字の名前が比較的出力されやすいように・・・といった感じです
0011デフォルトの名無しさん2007/01/30(火) 01:31:55
>>7
デバッガで追いかけっこをするときはenumを使っていた方が幸せになれるかもしれない。
0012デフォルトの名無しさん2007/01/30(火) 01:50:45
>>11
最近はマクロもインテリセンス効くけど、それじゃダメ?
0013デフォルトの名無しさん2007/01/30(火) 01:51:46
ああ、インテリセンスじゃないや。
いや、インテリセンスもだけど、
マウスカーソル置くと数値の出てくるアレ。
0014デフォルトの名無しさん2007/01/30(火) 12:29:34
プログラムの中で配列(要素数が大きい)を定義して、それが例えば200MBの領域だったとしたら、
メモリがそれ以下のPCでそのプログラムを実行することはできないのでしょうか?
0015デフォルトの名無しさん2007/01/30(火) 12:33:05
>>14
できる
極端にスペック足りないとできない
0016デフォルトの名無しさん2007/01/30(火) 13:44:02
>>14
仮想記憶という単語を調べれ
0017142007/01/30(火) 15:06:03
>>15
>>16
有難うございました。
0018デフォルトの名無しさん2007/01/30(火) 19:04:54
↓の関数の使い方がわかりません。

int addname(Nameval newname)
{
Nameval *nvp;

if (nvtab.nameval == NULL){/* 一番最初 */
nvtab.nameval = (Nameval *)malloc(NVINIT * sizeof(Nameval) );

if (nvtab.nameval == NULL)
return -1;
nvtab.max = NVINIT;
nvtab.nval = 0;
}else if ( nvtab.nval >= nvtab.max ) { /* 伸張 */
nvp = (Nameval *)realloc(nvtab.nameval,
(NVGROW*nvtab.max) * sizeof(Nameval) );

if( nvp == NULL )
return -1;
nvtab.max *= NVGROW;
nvtab.nameval = nvp;
}
nvtab.nameval[nvtab.nval] = newname;
return nvtab.nval++;

}
0019デフォルトの名無しさん2007/01/30(火) 19:06:15
構造体は、↓です。 

typedef struct Nameval Nameval;

struct Nameval
{
char *name;
int value;
};

struct NVtab{
int nval;/* 値の現在の個数 */
int max;/* 割り当て済みの値の個数 */
Nameval *nameval;/* 名前-値ペアの配列 */
} nvtab;

enum{NVINIT = 1, NVGROW = 2};
0020182007/01/30(火) 19:11:18
↓こういう風に使うと、コンパイルは通りますが、
 問題が発生したため、○○.exeを終了します、というエラーが出ます。
 どこがいけないのでしょうか?
よろしくお願いします。

void func_test()
{
Nameval newarray0 = { "tarou", 0x44 }, newarray1={ "shinzo", 0x88 };

if ( addname( newarray0 ) == -1 )
{
return;
}

if ( addname( newarray1 ) == -1 )
{
return;
}

cout << "\nnvtab.nameval[" << "0" << "].value" << nvtab.nameval[0].value << '\n';
cout << "\nnvtab.nameval[" << "0" << "].value" << nvtab.nameval[1].value << '\n';
}
※ 環境はVS C++ 2005 Expressです。
0021デフォルトの名無しさん2007/01/30(火) 19:40:46
ここC言語なんだけどなぁ

nvtabはどこにあるの?main の中?グローバル?
構造体NVtabのnamevalメンバはいつNULLで初期化?0埋め保障されてたっけ?

あと関係ないけど NVINIT を 列挙型で宣言ていうのはどーかと思うけど
0022デフォルトの名無しさん2007/01/30(火) 19:50:13
>>18
普通に動いた。

実際にエラーの出るソースコードでは、自動変数の寿命のこと考えてる?
0023デフォルトの名無しさん2007/01/30(火) 19:53:51
>>18
出せる情報は隠すな。
これはエラーが出るコードではないだろ?
0024182007/01/30(火) 20:00:59
すみません。説明不足でした。
ファイルをわけています。

//Sort_02_01.c
int addname(Nameval newname)
{
  //(18の内容)//
}

//SortData.h
typedef struct Nameval Nameval;

struct Nameval
{
  //(19の内容)//
};

struct NVtab{
  //(19の内容)//
} nvtab;

enum{NVINIT = 1, NVGROW = 2};

0025デフォルトの名無しさん2007/01/30(火) 20:01:45
>>18
どこでエラーになったかわからないなら
デバッグ手法を考え直したほうが後々の為
0026212007/01/30(火) 20:03:30
>>18-20 >>24
構造体NVtabのnamevalが最初にNULLでない場合不正なアドレスにアクセスする可能性あるのと
nvtabが下の関数から出た後に nvtab.nameval[nvtab.nval].name にアクセスするとダメだね

void func_test()
{
Nameval newarray0 = { "tarou", 0x44 }, newarray1={ "shinzo", 0x88 };
・・・・・・・
}
>>22さんも言ってるけどnewarray0とnewarray1を
関数 addname のnvtab.nameval[nvtab.nval] = newname でコピーしてるよね
でもnvtab.nameval[nvtab.nval].name は newarray0.name のアドレスをコピーするだけで文字列用のメモリは確保しない
Nameval.name の生きている時間はnewarray0と同じでnewarray0は関数func_testが終了すると消えちゃうから
nvtab.nameval[nvtab.nval].name のポインタも関数func_test以外では有効ではなくなる
関数func_test以外でnvtab.nameval[nvtab.nval].nameにアクセスすると不正処理で落ちるよ
0027182007/01/30(火) 20:07:55
//main.cpp

void func_test()
{
  //(20の内容)//
}

int main()
{
 func_test();
}

>>21
cppですが、C言語の文法しか使っていないので、
ここで質問させてもらいました。
0028デフォルトの名無しさん2007/01/30(火) 20:16:51
>>18
cout << "\nnvtab.nameval[" << "0" << "].value=" << nvtab.nameval[0].value << '\n';
cout << "\nnvtab.nameval[" << "1" << "].value=" << nvtab.nameval[1].value << '\n';
↓
cout << nvtab.nameval << endl;
//cout << "\nnvtab.nameval[" << "0" << "].value=" << nvtab.nameval[0].value << '\n';
//cout << "\nnvtab.nameval[" << "1" << "].value=" << nvtab.nameval[1].value << '\n';
にして実行してみて。

もし 0x00000000 が出力されたとすれば nvtab の実体が複数あるのが原因
0029212007/01/30(火) 20:27:48
>>27
cout ってC++じゃなかったっけ?まぁ細かいことはいいや

そうだね
ヘッダ内で
struct NVtab{ //(19の内容)// } nvtab;
の宣言してるから
各ソース //Sort_02_01.c と //main.cpp の両方に別々の  nvtab が存在してることになるね
0030182007/01/30(火) 20:35:27
>>28
>もし 0x00000000 が出力されたとすれば nvtab の実体が複数あるのが原因
0x00000000が出力されました。
自分、構造体がよく分かってないようですorz

nvtabは、関数func_test()とaddname()で
(それぞれincludeしているので)
2つ存在してしまっているということですか?

ってことはこの構造体の宣言をglobalですればOKですよね?

struct NVtab{
int nval;/* 値の現在の個数 */
int max;/* 割り当て済みの値の個数 */
Nameval *nameval;/* 名前-値ペアの配列 */
} nvtab;
0031212007/01/30(火) 20:37:34
あっ だからなんだ?ってかんじか

>>27
ソースを分けないでひとつのソースファイルにしてコンパイルするか
nvtabの実体はmainソースにおきヘッダでは型宣言のみで extern 宣言するとか
0032182007/01/30(火) 20:38:08

みなさん、回答ありがとうございました。
(私自身が、混乱していて申し訳ないです。)

これから修正してみようと思います。
0033212007/01/30(火) 20:40:30
リロード忘れた

>>30
>>nvtabは、関数func_test()とaddname()で (それぞれincludeしているので) 2つ存在してしまっているということですか?
その通りです

>ってことはこの構造体の宣言をglobalですればOKですよね?
今現在グローバルで宣言してますよ
→>>31

>>32
またのおこしをお待ちしております
0034182007/01/30(火) 21:25:02
できましたぁ。ありがとうございました!
0035デフォルトの名無しさん2007/01/30(火) 21:26:04
#defineによる定数と列挙型定数の、使い分けの指針みたいなものを教えてください。
0036デフォルトの名無しさん2007/01/30(火) 21:37:04
「バイナリファイルはテキストファイルよりもデータ効率がいい」と習ったんですが、下のコードを実行してできたファイルのサイズを
見てみるとテキスト18バイト、バイナリ20バイトになっています。バイナリのほうが効率がいいなら、サイズは小さくなるのではないでしょうか。なぜサイズにこのような違いがでるのか教えてください。よろしくお願いします。
#include<stdio.h>
#include<stdlib.h>
int main(void){
FILE *f,*g;
char line1[10] ="分からん";
char line2[10] ="助けて";
f = fopen("a.txt","w");
if(f==NULL){
printf("open error\n");
exit(1);
}
fprintf(f,"%s\n",line1);
fprintf(f,"%s\n",line2);
fclose(f);

g = fopen("a.b","wb");
if(g==NULL){
printf("open error\n");
exit(1);
}
fwrite(&line1,sizeof(line1),1,g);
fwrite(&line2,sizeof(line2),1,g);
fclose(g);
return(0);
}
0037デフォルトの名無しさん2007/01/30(火) 21:45:39
>>35
>#defineによる定数と列挙型定数の、使い分けの指針みたいなものを教えてください。

The Practice of Programming(ブライアン カーニハン)には、
「マジックナンバーは#defineでなく、enumを使おう」
と書いてありました。
ですので、私はdefineをあまり使いません。
0038212007/01/30(火) 21:46:17
>>35
指針?わかりません
私は、順序が必要かグループとして(関連性のある)くくりたい定数はenum、それ以外はdefine にしてる

>>36
文字列の場合はバイナリもテキストもほぼ一緒です
数値保存するさいはたとえば 4000 という数字を保存したい場合
テキストは4バイト、バイナリなら2バイトで済みます(パック10進数やゾーン10進数などはこの限りではありません)
0039212007/01/30(火) 22:00:35
>>35
あっそーそー
あとその定数の値そのものが意味のあるものの場合はdefineで、数値そのものには意味はなくあくまで識別することが目的なら enum とか
たとえば>>24さんのenum{NVINIT = 1, NVGROW = 2}; で説明させていただきますが(>>24さんゴメンナサイ)
これがenum{NVINIT = 2, NVGROW = 1}; になってた場合意味が変わってしまいますよね
こういうときは define にします
enum{left=1,top=2,right=3,bottom=4}
これは enum{left=4,top=3,right=2,bottom=1}
だったとしても意味は変わりませんよね
enum week{ sunday=1,monday,・・・} などもそうですね
(インデックスから曜日を求めるとか演算の対象とする場合は意味が変わってしまいますが、それは除いて)

あくまで、<私は>ですのでね、公式にどうするのかは知りませんよ
0040362007/01/30(火) 22:06:15
>>38
ありがとうございます。intだけを書き込んでみたら確かにバイナリのほうがサイズが小さくなりました。データ効率がよいといっても型によってはテキストよりもバイナリのファイルサイズのほうが小さいとは必ずしも言えないということですね。
0041352007/01/30(火) 22:16:22
>>37-39
ありがとうございます。
0042212007/01/30(火) 22:19:40
>>40
そうです

それと>>36のプログラムで2バイトの差が出てますね

これはテキストの場合 分からん(改行)助けて(改行)
fprintf(f,"%s\n",line1); ←これが文字列のみ出力し次に改行を出力します

バイナリの場合 分からん(NULL)(改行)助けて(NULL)(改行) になっているからです
( fwrite(&line1,sizeof(line1),1,g); はsizeof(line1),による書き込み文字数にNULL(0)も含まれているため、そのNULL(0)も書き込んでいるためです
このプログラムの場合NULL(0)を含まないようにすればバイナリとテキストは同じサイズになります
0043デフォルトの名無しさん2007/01/30(火) 22:24:03
>>39
まあ、普通はそういう使い分けは勧められないね。
0044212007/01/30(火) 22:30:11
>>43
やっぱダメ?
普通はどーする?
0045362007/01/30(火) 22:41:49
>>42
なるほど!何度もありがとうございました。
0046デフォルトの名無しさん2007/01/30(火) 22:50:29
>>44
プログラミング作法の41ページに書いてあるよ。
0047212007/01/30(火) 22:55:18
>>46
ありがとー読んでみます
0048デフォルトの名無しさん2007/01/30(火) 23:07:41
if(true || F()){
//この時、関数F()の実行は保障されるのか?
}
0049212007/01/30(火) 23:09:22
>>48
されません
0050デフォルトの名無しさん2007/01/30(火) 23:09:36
trueってなんじゃい?
if(1 || F()) {}
ならF()が実行されないことは保証される。
0051デフォルトの名無しさん2007/01/31(水) 00:36:13
30!のなんてどうやって求めればいいんだ?
オーバーフローっていうレベルじゃねぇーぞ!
0052デフォルトの名無しさん2007/01/31(水) 01:37:47
答えだけ教えてあげるね。

30!=265252859812191058636308480000000
0053デフォルトの名無しさん2007/01/31(水) 03:51:59
#include <stduo.h>

main(){
printf("5+5は%dです。\n",5+5);
printf("5−5は%dです。\n",5-5);
printf("5×5は%dです。\n",5*5);
printf("5÷5は%dです。\n",5/5);
printf("5÷3の余りは%dです。\n",5%d3);

return 0;
}

これで、何故これらは宣言をしなくても、かってに代入されるのでしょうか?
普通なら int a = 5; など宣言をするはずですが・・・。
0054デフォルトの名無しさん2007/01/31(水) 04:10:57
>>53
そのソースでは、
代入すべき変数はなさそうだけど、どこに代入するのん?
宣言すべき変数はなさそうだけど、何を宣言するのん?
それと、5%d3は5%3の間違い、stduo.hはstdio.hの間違いだよね?
0055デフォルトの名無しさん2007/01/31(水) 04:29:44
>>53
C++なら一時オブジェクトなどと説明されるのだろうが、
Cなら関数の引数には値を取る事が出来るので、計算式の
結果が値として渡されるという事でよいだろう。

&(5 + 5) などとやると当然エラーになる。
0056デフォルトの名無しさん2007/01/31(水) 04:43:43
レス、ありがとうごいます。

>>54
すみません、書き間違いでした
>>それと、5%d3は5%3の間違い、stduo.hはstdio.hの間違いだよね?

では、代入すべき変数や宣言がない時は、printf("5+5は%dです。\n",5+5);
で、かってに, 5+5 が代入されるのでしょうか?

>>55
何故、自動で計算結果が出るのでしょうか?
0057デフォルトの名無しさん2007/01/31(水) 04:52:36
>>56
いや、代入っていうのは普通、
変数として用意されたメモリ領域に値をコピーすることをいうのだと思うよ。
printf("..", 5+5);における5+5は代入と呼ばれる操作ではなく、
printfという関数へ与える実引数の値を計算する式だ。
0058デフォルトの名無しさん2007/01/31(水) 05:06:43
正確な説明でも何でもないけど、
代入という言葉は「変数=値」の形の時に使われて、
printf("5+5は%dです。\n",5+5)は関数呼び出しという別の操作。
関数呼び出しは、「関数名(値,値,...)」の形をしていて、
5+5というのは、その値を計算するための式、というのではどうかね?
5+5を計算した後の値は一般の変数ではなく、別のメモリ領域に置かれる。
0059デフォルトの名無しさん2007/01/31(水) 05:08:37
ひ〜難しい…
頭を冷やしてから考え直してきます、サンクスですた。
0060デフォルトの名無しさん2007/01/31(水) 07:47:15
ソース上の変数やリテラルはメモリのどこに配置されるか考えるといい
でもその式は実行時じゃなくてコンパイル時に計算される
0061デフォルトの名無しさん2007/01/31(水) 20:55:24
>>56
計算が自動なのはC言語の仕様だ。
0062デフォルトの名無しさん2007/01/31(水) 23:48:41
テキストファイル読み込んで、
ファイル内の指定した行を削除するにはどうしたらいい?
俺の頭の中では、
   fp = fopen("2ch.txt","w+");
   if(fp == NULL)
      printf("\aファイルをオープンできません。\n");
   else
   {
   /*ここで何かするのかなって思ってるんだけど*/
      fclose(fp);
   }
どうすりゃいいのか分かんなくて。そもそも"w+"でいいのか?
誰か助けてください。
0063デフォルトの名無しさん2007/01/31(水) 23:59:10
>>62
削除行を除いてテキストファイル再作成
0064デフォルトの名無しさん2007/02/01(木) 00:04:45
>>62
ファイルサイズを任意のサイズだけ小さくするような処理はできない
普通は一部分を除いたコピーを作る
0065デフォルトの名無しさん2007/02/01(木) 01:57:09
#include <stdio.h>

main(){
int a = 15, b = 0x11;

printf("10進数の%dは16進数では%X\n",a,a);
printf("16進数の%Xは10進数では%d\n",b,b);

return 0;
}

これで質問なのですが、このソースを実行すると
書式に合わせた結果が表示されますが
これも>>58->>57と同じ様な原理なのでしょうか?
かってに値が変わって表示されますが・・・。
0066デフォルトの名無しさん2007/02/01(木) 02:22:35
#include <stdio.h>

main(){
char c = 1;
char s[10] = "Hello!";

printf("long型 = %dバイト\n",sizeof(long));
printf("char型変数 = %dバイト\n",sizeof(c));
printf("文字列変数 = %dバイト\n",sizeof(s));

return 0;
 }

エラー E2206 samople2.c 12: 不正な文字 ' ' (0x8140)(関数 main )
警告 W8004 samople2.c 12: 's' に代入した値は使われていない(関数 main )
警告 W8004 samople2.c 12: 'c' に代入した値は使われていない(関数 main )
*** 1 errors in Compile ***

これの何処が悪いかわかりませんので、ご指摘お願いします。
0067デフォルトの名無しさん2007/02/01(木) 02:32:13
全角空白
0068デフォルトの名無しさん2007/02/01(木) 02:40:05
今までボーランドのコンパイラ使ってたんんですが
最近Visual C++に変えました。
VCの場合実行ファイルはどこに作成されるんでしょうか??
今まではexeファイルができてたんですが、見当たりません。
0069デフォルトの名無しさん2007/02/01(木) 02:50:44
>>66
×char c = 1;
○char c ='1';
0070デフォルトの名無しさん2007/02/01(木) 03:21:10
#include <stdio.h>

main()
{
double s;

for(s=1.0; s<=1.5; s+=0.1)
printf("s=%f\n", s);

}


これを実行するとs=1.50000が実行されません。
どうしてでしょうか?
教えてください。
0071デフォルトの名無しさん2007/02/01(木) 03:32:25
>>70
for(s=10; s<=15; s+=1)
printf("s=%lf\n", s/10);
0072デフォルトの名無しさん2007/02/01(木) 03:40:12
>>70
for(s=1.0; s<=1.5; s+=0.1) printf("s=%20.18lf\n", s);
にしてみると、本当は何をsに加えていたか分かるよ。
0073662007/02/01(木) 03:51:36
ありがとうございました。
0074デフォルトの名無しさん2007/02/01(木) 03:55:44
×%20.18lf
○%.20g
0075デフォルトの名無しさん2007/02/01(木) 04:10:22
丸め誤差
0076デフォルトの名無しさん2007/02/01(木) 04:13:56
×%.20g
○%.20a
0077デフォルトの名無しさん2007/02/03(土) 00:51:17
#include <stdio.h>

main(){
int i = 1;

for(1<4; i++)
printf("こんにちは%d\n",i);

return 0;
}

c:\source>bcc32 sample3.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
sample3.c:
警告 W8019 sample3.c 6: コードは効果を持たない(関数 main )
エラー E2378 sample3.c 6: For文に ; がない(関数 main )
警告 W8004 sample3.c 10: 'i' に代入した値は使われていない(関数 main )
*** 1 errors in Compile ***

こう表示されてしまいますが、
#include <stdio.h>

main(){
int i = 1;

for(i =1; 1<4; i++)
printf("こんにちは%d\n",i);

return 0;
}
これだと実行できるのは、何故でしょうか?i = 1と宣言を先にしていますが・・・
0078デフォルトの名無しさん2007/02/03(土) 00:53:18
for(; 1<4; i++)
0079デフォルトの名無しさん2007/02/03(土) 00:54:50
文法ミスだろ
0080デフォルトの名無しさん2007/02/03(土) 02:21:39
>>78->>79
ありがとうごいます。
あ〜ようするに省略の ; を付ければいいのでしょうか?

0081デフォルトの名無しさん2007/02/03(土) 02:26:51
#include <stdio.h>

main(){

while(a < 5){
printf("%d\n",a);
a == a + 1;
}

これだと、何故無限ループになってしまうのでしょうか?
本の解説に依れば、a == a + 1 は aを増やすところを
誤って書いた。これでは a の値は変わらないので
無限ループになると書いてあります。

これは == の等しいだからいけなく = ならいいのでしょうか(ループにならない)?
もしそうだとしたら、どうしてか解説をお願い致します。
0082772007/02/03(土) 02:30:43
#include <stdio.h>

main(){
int i = 0;

for(;0<4; i++)
printf("こんにちは%d\n",i);

return 0;
}


これで実行すると無限になってしまいます。
どのようにすれば無限にならないでしょうか?
0083デフォルトの名無しさん2007/02/03(土) 02:31:41
>>81
日本語でOK
==は関係演算子、=は代入演算子
a==a+1はaとa+1が等しいかどうかを判定して真偽値を返す
a=a+1はa+1の値をaに代入して、その値を返す
=と==は全くの別物だ
0084デフォルトの名無しさん2007/02/03(土) 02:33:00
>>82
for(;0>4;i++)
にする
0085デフォルトの名無しさん2007/02/03(土) 02:34:59
>>82
0<4
i<4だろ
そこは条件文だから
0<4なら一生trueだ
0086822007/02/03(土) 02:38:27
ぐはぁーわけわかめです、サンクスでした、よく考え直します
0087デフォルトの名無しさん2007/02/03(土) 02:46:09
>>86
for (A ; B ; C) D
は、A → B → D → C → B → D → C → B → D → C →...
とループする。ただし、Bの値で偽になった段階でループを抜ける。
0<4だといつまでたっても真だから無限にループする。
i<4ならループを回るたびにi++でiの値が1づつ増えるから、
いつかはi<4が偽になってループを終えることができる。
0088822007/02/03(土) 03:57:27
>>87
要約わかってきました、0<4は最初から既に、4は大きくて当然で
真と言う事ですね。ありがとうごいます。
0089デフォルトの名無しさん2007/02/03(土) 04:00:06
>>83
遅レス、もしわけありません。
>>a==a+1はaとa+1が等しいかどうかを判定して真偽値を返す
例えば等しくなければ偽と言うことでしょうか?

それで、>>a == a + 1; だと無限になってしまうかが
疑問です
0090822007/02/03(土) 04:06:02
#include <stdio.h>

main(){
int i = 0;

for(;0>4; i++)
printf("こんにちは%d\n",i);

return 0;
}

これを実行しても、
c:\source>bcc32 sample3.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
sample3.c:
警告 W8066 sample3.c 7: 実行されないコード(関数 main )
警告 W8004 sample3.c 4: 'i' に代入した値は使われていない(関数 main )
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

c:\source>sample3

c:\source>

と c:\source>に戻ってしまい、実行ができません。
0091デフォルトの名無しさん2007/02/03(土) 04:15:41
>>90
ちょっとは考えろ
0092デフォルトの名無しさん2007/02/03(土) 04:16:37
>>81
無限ループになる以前にそのコード、コンパイルを通らないだろ。
aの宣言と初期化がない。
もし、int a = 5;とかにすれば、無限ループなんかせずにすぐに終了する。
aの値がループを回るたびにどう変化するか、もしくは、どう変化しないかを追ってみろ。
0093デフォルトの名無しさん2007/02/03(土) 04:19:01
#include <stdio.h>

main(){
int i ;

for(i=0;i<4; i++)
printf("こんにちは%d\n",i);

return 0;
}

と書くことで
以下のようになりました

D:\lsic330c\BIN>lcc ..\baka.c
lld @link.i

D:\lsic330c\BIN>..\baka
こんにちは0
こんにちは1
こんにちは2
こんにちは3

D:\lsic330c\BIN>
0094デフォルトの名無しさん2007/02/03(土) 04:20:09
>>90
実行できてるじゃん。
コンパイル時の警告は無視するとして、
何の文句も言わずsample3.exeは異常終了することなく実行を終えてシェルに制御を移している。
>>87の説明をよく思い出して、0>4が何をやっているか考えろ。
0095デフォルトの名無しさん2007/02/03(土) 04:25:03
>>92
はい、そうしてみます。
0096822007/02/03(土) 04:48:31
>>93
このソースでやればできました・・・

>>94
考えれば考える程、自分の頭の中がループしてしまいます
後日出直してきます。
皆さん、サンクスでした!!!
0097ビル ゲーシ(^▽^) ◆lHG3Yzo0a6 2007/02/03(土) 05:03:53
>>96
ガンバレ!
ねぇねぇ、BCCじゃなく、マイクロソフトのVisualC++ 2005express使ってお
これFreeだし、BCCより良いから
0098デフォルトの名無しさん2007/02/03(土) 05:06:05
やめとけやめとけ、入れたらIP抜かれるぞ
0099デフォルトの名無しさん2007/02/03(土) 05:09:34
Cの学習用ならbccあたりで十分だ。
初心者のうちに下手にmicrosoftに手を出すと後から取り返しがつかないぞ。
0100デフォルトの名無しさん2007/02/03(土) 05:10:17
IPを抜かれると何が困るのか具体的に説明してくれ。
0101ビル ゲーシ(^▽^) ◆lHG3Yzo0a6 2007/02/03(土) 05:10:39
#include <windows.h>
int main()
{
MessageBox(0, TEXT("ビル ゲーシ(^▽^) ◆lHG3Yzo0a6"), TEXT("VISTA"), MB_OK);
main();
return 0
}
■ このスレッドは過去ログ倉庫に格納されています