printfで 0.1 0.2 ・ ・ ・ 9.9 10.0 10.1 10.2 みたいに右ぞろえで出力するにはどうすればいいですか?
右揃えなってないけど
投稿したらずれてしまいました 0.1 0.2 ・ ・ ・ 9.9 10.0 10.1 10.2
なってないじゃん
%桁数.桁数f
>>7 >>8 うまくいかないです
*0.1
*0.2
・
・
・
*9.9
10.0
10.1
10.2
こうしたいんです。*は空白とかんがえてください
10 :
デフォルトの名無しさん :2007/12/22(土) 14:12:45
幅指定してやればいい 右左のそろえを変えたいならマイナスつければいいし
>>9 どうやったんだよ
何で自分がやったやりかたを隠すんだ?
>>12 %ドットを含めた全体の桁数.小数点以下の桁数f
>>13 整数部分の桁数がわからない場合はどうすればいいですか?
*******1.12100912
******11.21890212
******12.12109121
*****212.21029211
***26575.12121111
みたいにしたいんですが
あらかじめ桁数大きくしておけば
>>15 * を使えば実行時に決定できる
数値はそのままで、空白を自分で追加してもいいし、どうにでなるでしょ。
>>前999 無理。 typedef は前処理(#ifdef とか #define とかの処理)が終了した後の コンパイル時に解析されるものであって、前処理ではその情報は使用できない。 bool を typedef するのと同時にマクロを別に定義するようにしておいて、 そのマクロが定義されているかどうかを #ifdef で判定するしかない。
すいません質問いいですか? 苦しんでのHPで書いてあったことなんですが・・・ 変数のところを勉強してるのですが そこに [ コンパイラの機能 ] 実は、このプログラムは多くのコンパイラでは動いてしまいます。 それは、C言語の拡張版である、C++(シープラプラ)では使えるからです。 また、近年決められたC言語の新規格であるC99でも使えます。 しかし、元々のC言語では使えないと覚えて下さい。 と書いてありましたが C言語のコンパイラでは変数は使えないと考えていいのでしょうか?
>>19 その一段前を読み直すんだ。
--
変数の宣言は、基本的に、関数の先頭でしか行うことが出来ません。
例えば、次のように変数を宣言することは出来ません。
--
>>21 ありがとうございます
ということはCでは変数の宣言を関数の先頭でしか行えない
しかしほかのは先頭じゃなくても行えるということでしょうか?
ん? bccで.cをコンパイルすると通らないぜそれ
>>22 概ねその通り。厳密にはブロックの先頭だが。
従って、
--
int main(void)
{
printf("Hello\n");
int value; /* 変数宣言の部分 */
return 0;
}
--
の変数宣言をどうしてもprintf()の後で行ないたいならこうすればいい。
--
int main(void)
{
printf("Hello\n");
{
int value; /* 変数宣言の部分 */
}
return 0;
}
--
>>23 bccは、その筆者にとっては「多くのコンパイラ」に含まれないのだろ。
つーか、そのサイトは結構難有りだと思うがな。
そのサイトのダメダメな一例。 -- fpos_t fsize = 0; fpos_t fsizeb = fseek(fp,0,SEEK_END); fgetpos(fp,&fsize); fseek(fp,fsizeb,SEEK_SET); -- この突っ込みだらけのコードは一体なんなんだか。
>>24 みたいにするとvalueってすぐ見えなくなるんじゃね?
>>24 そうゆう書き方もありなのか・・・
もう2週間経つがまだ変数の宣言までしか覚えてない
いつになればCが覚えられるのかな
>>27 日本語を覚えるのにどれだけ掛かったか、英語を覚えるのにどれだけ掛かったかを考えれば、
Cを覚えられるようになるのにどれだけ掛かるか判ろうものだ。
>>26 勿論int valueの宣言の後、そのブロックが閉じる前に使いたいだけ使えばいい。
>>27 自然言語と一緒で意味を考えながら書写すればいいよ。
音読するとご近所さんから奇人扱いされそうだけど
>>28-29 一応書きながらやっているから今までのことは覚えられているのだけれども・・・
文字列リテラルとか必要な言葉かどうか疑問に思ってくる
Cは覚えておいて損はないだろうから一応忘れないように
がんばっているんだがこれは無駄ではないよね?
知識は無駄ではないよ。知ってると知らないなら知ってるほうがよいに決まってる。 まあ、人間の脳なんて限界があるから、細かいことまで一生覚えてる必要はないよ。 それがどこに書いてあったかを覚えといて、必要なときにすぐに参照できるようにしておけばいい。 リテラルってのがソースコードに直に書いてある値のことだと知れば、 文字列リテラルだろうが整数リテラルだろうが、別に怖いことはないでしょ。 物の名前は他人に説明するときに絶対に必要だから、嫌でも覚えてしまうよ。
CってC++ってに比べて覚えること少なくね? 標準ライブラリの細かい使い方まで行くとまた別だが、 C自体の構文なんかは数日で覚えられるだろ
>>33 でもほら短時間で覚えると忘れちゃうじゃん
だからゆっくり覚えてるのSA!!
まだ変数のところだけどノートに26ページ書いてあるんだよ・・・
>>33 そりゃ、C++はCに++したものだからあたりまえ
Cから1しか増えてない割には結構な増強だな C+=2くらいじゃないのか
っ オペレーターオーバーローディング
くだらない質問なのですが CのDOS窓でprintfするときに、画面で ファイル ○を読み込みました 進行度 ○% 見たいのを表示してるのですが、1個ずつ改行されるので それを改行しないように画面更新するにはどうやればいいのですか? まったくやったこと無くて
Cを先に覚えるとC++はクラスが難関かもしれんが、速攻覚えられるな。 C++から始めると、Cは速攻覚えられるな。 つまりそういうことだ
>>41 これでだめ?
#include<stdio.h>
int main(void){
int i;
for(i = 0; i < 10; i++){
printf("%d", i);
fflush(stdout);
sleep(1);
printf("\r");
}
putchar('\n');
return 0;
}
// 俺漏れも書いてみたー。初めてWriteConsoleとか使ったけど、こんな感じで悪くないよね? #define STRICT #include <windows.h> #include <stdio.h> #define BUFFER_SIZE 64 int main(int argc, char *argv[]) { DWORD written = 0; BOOL alloced = AllocConsole(); HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE); char buffer[BUFFER_SIZE] = {0}; CONSOLE_SCREEN_BUFFER_INFO csbInfo = {0}; for (int i = 0; i <= 10; i++) { GetConsoleScreenBufferInfo(stdOut, &csbInfo); csbInfo.dwCursorPosition.X = 0; SetConsoleCursorPosition(stdOut, csbInfo.dwCursorPosition); int len = snprintf(buffer, BUFFER_SIZE - 1, "今 %d%% ですよ", i * 10); WriteConsole(stdOut, buffer, len, &written, NULL); Sleep(500); } if (alloced) FreeConsole(); }
キャラベースのプログラムで、プログレスバーの表示は\rを使うのが一般的? FORMATコマンドでFDフォーマットするときに出てくるようなやつ。もっと他の方法があるの?
エスケープシーケンスとかね
スケジューリングの勉強をしているのですが、 データフローグラフにはどのようなデータ構造が適していますか? また、リストスケジューリングの優先度リストに適したデータ構造についても 教えていただけないでしょうか?
戻り値のついて誰か詳しく教えてくれ・・・orz 本読んだんだがいまいちピンとこない・・・
ピンとこないときには、本読んだり人に話聞いたりするよりも、 自分でコード書いてコンパイル・実行するほうが理解できると思うよ。 そのコードはとりあえず本・Webのコピペでいいから。
戻り値がピンとこないってのが俺にはピンとこない。 はるかな高みからの質問かもシレンが。
C言語を触れたこともない者でも勉強できる お勧めの参考書教えてください
>>49 値を2倍する関数twiceがあったとする
例えば、printf("%d\n", twice(10)); のように使えば、20と表示されるとする
この、twice(10)の計算結果である20を、twice(10)の戻り値という
twice(15)の戻り値は30であるし、twice(-3)の戻り値は-6であろう
>>49 関数をジュースの自動販売機に例えると
お金が引数(実引数)でジュースが戻値(返値)
先生! お釣りが出てきません!
>>49 int f(int x) {
return 2 * x + 1;
}
int main() {
printf("%d\n", f(3) + 4);
return 0;
}
とした場合、
int main() {
int f3;
f3 = 2 * 3 + 1;
printf("%d\n", f3 + 4);
return 0;
}
みたいな感じで処理される。
実際には、関数を呼ぶとその関数の中に処理が移動して、
関数の中の処理が終了すると関数を呼んだ位置に戻ってくるんだけどね。
60 :
デフォルトの名無しさん :2007/12/24(月) 16:52:50
>>49 私も初心者ですが、、
自動販売機にお金とジュースの種類の情報を与えたら、
ジュースの実体が戻ってくる。
それが戻り値
で、
ジュールの種類やらお金が引数
と考えると分かり易い。
61 :
デフォルトの名無しさん :2007/12/24(月) 16:53:22
62 :
デフォルトの名無しさん :2007/12/24(月) 17:01:48
struct S1 *S1 ; /* プロセス管理テーブル */ S1 = /* プロセス管理テーブルOPEN */ (struct S1 *)Open_Kansumei(... ,... ,... ,...) ; こんな感じのCソースがあったんですが、 (struct S1 *)Open_Kansumei(); の部分の文法がよく分かりません。プロセス管理テーブルをオープンした結果を、 S1 構造体のアドレスの先頭に入れてるのは分かるんですが・・・。 関数名の前に (struct S1 *) が付いてる・・・?
FORTRANだと、戻り値があるのがFUNCTION(関数)で戻り値がないのがPROCEDURE(手続き) 数学でいう y=f(x)が関数
Cだと戻り値がないものも関数と呼んでいる
>>62 構造体へのポインタを返す関数なんじゃないの?
っていうか、入門書に載ってる短いサンプルでも適当に動かせばわかるだろ。。。
>>62 関数 Open_Kansumei の戻り値を struct S1 * 型にキャストしている
68 :
デフォルトの名無しさん :2007/12/24(月) 18:02:13
>>67 関数の戻り値をキャストするなら、
(struct S1 *)S1 = Open_Kansumei();
では駄目なんでしょうか?
それとも関数自体をキャスト・・・? S1 自体がアドレスだから、(struct S1 *)関数名
とすると、(struct *S1)関数名
と同じ意味になるのかな・・・よく分からなくなってきました・・・
>>68 型キャストの構文をもっぺん見直してみろ。
int x;
float y;
という2つの変数 x と y があるとき、y を int 型にキャストして x に代入するには
(int) x = y;
ではなく
x = (int) y;
と書くのが正しい。おk?
>>68 型の名前と変数名が一緒だからごっちゃになってないか?
struct S1 *p;
p = (struct S1 *)Open_Kansumei(...);
71 :
デフォルトの名無しさん :2007/12/24(月) 18:37:52
>>69 あ〜そうか〜そういえば!
関数の戻り値ってのは、=で受け取らないと扱えないと思ってたけど、
関数の中に関数を使ったりできますもんね。おk、おk!
ということは、「関数の戻り値をキャストして、さらに S1 に代入している」
ということなんですね。
この場合、 S1 にはアドレスが入るから、
(struct S1 *)関数名
にキャストした結果は、アドレスになる(struct S1 * 型というのはアドレス)
と考えていいんでしょうか?
72 :
デフォルトの名無しさん :2007/12/24(月) 19:02:48
>>70 あ・・!そういう意味なんですか?
と、、すると、
(struct S1 *)
struct S1 *
は同じ意味だから、
p = (struct S1 *)Open_Kansumei(...);
の右辺と左辺は同じ型が入るということになるんですね!
よく分かりますね!
73 :
デフォルトの名無しさん :2007/12/24(月) 19:14:34
ちなみに、その関数 Open_Kansumei の引数はこんな感じ↓になってます。 int Open_Kansumei( ... , ... , ... , ... ) { char *adataadd; /* データアドレス */ ...処理... return( (int)adataadd ); } アドレス値を int型にして引渡し、もらい先で *型に変換する、なんてこともできるんですね。
>>73 できるかもしれんが、行儀の良くない例だ
真似しないように
75 :
デフォルトの名無しさん :2007/12/24(月) 20:48:00
>>74 そうなんですね。読むだけにして、使わないようにします。
この場合、
return( adataadd );
...
p = Open_Kansumei(...);
とするのが普通なんでしょうか?これでも同じ意味になります?
76 :
デフォルトの名無しさん :2007/12/24(月) 20:50:06
なんで ? は、エスケープシーケンスで \? としなければいけないの? 何と区別がつかないのだ?
そもそもOpen_Kansumei関数の戻り値の型をstruct S1 *にしておく。
>>76 なんで ? を、エスケープシーケンスにしなければいけないの?
>>76 「シェルが展開しようとするから」って回答がお望み?
>>76 >>78 3文字表記(トライグラフ)のため。
3文字表記は、Cが多用する記号を使えない文字コードのための代替表記を与えるもの。
まあ過去の遺物と言っていい。
??=include <stdio.h>
int main(int argc, char *argv??(??))
??<
printf("%d??/n", argc);
??>
82 :
デフォルトの名無しさん :2007/12/24(月) 21:43:36
>>77 int Open_Kansumei( ... , ... , ... , ... )
{
struct S1 *adataadd; /* データアドレス */
...処理...
return( adataadd );
}
p = Open_Kansumei( ... , ... , ... , ... );
てな感じでしょうか。
この場合、
struct S1 *p;
をグローバルで宣言しないといけない訳ですね。
いや,グローバルかどうかは関係ない. struct S1 * Open_Kansumei( ... , ... , ... , ... ) { struct S1 *adataadd; /* データアドレス */ ...処理... return adataadd; } とするのがベター.
84 :
デフォルトの名無しさん :2007/12/24(月) 22:12:04
>>83 ああ、なるほど〜
関数の戻り値の型を変えるってのは、struct S1 * Open_Kansumei() の部分を
変えないと駄目ですよね。
あとは、Open_Kansumei()関数の定義側と、呼び出し側で、
struct S1 の中身が書いてある .h ファイルを include しとけばいいってことですね。
include が嫌だったから、 return( (int)adataadd ); ってしたのかもしれないな・・・
今ぷよぷよを作ってて、4つ以上繋がっているか上下左右をチェックする再帰処理で スタックオーバーフローになってしまうのですが 11*20程度のフィールドでありえるんでしょうか 僕のプログラムがおかしいだけなんでしょうか
スタックオーバーフローってメモリ不足だろ? MSDOSでやってるならわからんでもないけど、Winでそれが出るならプログラムがおかしいかと
>>85 メモリのオーバーフローかもしれないと思うなら、
試しにチェックする数を3とか2とか、もっと少ない再帰で終わるものにしてみるといい
それでもプログラムが落ちるなら、無限再帰とかに陥っている可能性が高い
89 :
87 :2007/12/24(月) 22:35:48
あれ、スタックオーバーフローってメモリ不足でいんだっけ? 用語分かんね
>>85 再帰だとありうるかも知れんが、まずは処理を見直したほうが良い。
再帰のネストが深すぎるかもしれない。
おかしくなさそうだったらmallocで。
>>86 スタックサイズはリンク時に決まる。
実メモリのサイズとは関係ない。
VisualC++の場合、デフォルトは1MBらしい。
91 :
デフォルトの名無しさん :2007/12/24(月) 22:42:14
動的メモリが動作中のプログラムと同じOS上で、デフラグをするとメモリの 内容が移動してしまったり、、、って事態は起こるんでしょうか? 他に、デフラグをするとおかしくなっちゃうような組み方ってどんなのがあります?
>>88 カウントが3900とかになってるので無限ループっぽいですw
ちなみに右方向限定とかならエラーは出ないです
ありがとうございました
>>91 デフラグ、ってHDDのデフラグだよね?
いくらなんでもそんなへぼいメモリ管理をしてない。
94 :
デフォルトの名無しさん :2007/12/24(月) 23:08:30
>>93 ですよね・・・。
デフラグでどうにかなっちゃうような実装があるとしたらC言語以外の何かなのか・・・。
とりあえず、C言語ではそういう実装はありえない、ってことでいいんですよね?
95 :
デフォルトの名無しさん :2007/12/24(月) 23:11:56
C でよく、int argc; とか、char *argv; なんて名前の変数をみかけるんですが、 どんな役割を持つ変数なんでしょうか?一般的に・・・。たいていコメントがないので・・。
97 :
デフォルトの名無しさん :2007/12/24(月) 23:17:25
>>94 C言語は関係なく、OSの実装次第。
デフラグでおかしくなるとしたら、
デフラグツールがおかしいか、OSがおかしいかのどっちか。
99 :
デフォルトの名無しさん :2007/12/24(月) 23:34:17
>>98 datファイルなんかを動的に持つってことは可能でしょうか?
で、また読み込みに行ったときに、デフラグされてると、どこにあるか分からなくなる、、とか。。
基本的にファイルはHDDに保存するもので、「動的」って概念すらないんですよね・・・?
あるいはファイル名を動的メモリに持つ・・・とか?う〜ん・・・
どう頑張っても、Cの実装次第で、デフラグされるとおかしくなるようなプログラムは作れない・・・ですよね?
OSのファイルシステムドライバを通さずにディスクを直に読み書きしてたりすると、 デフラグでおかしくなるようなことはあるだろう。
101 :
デフォルトの名無しさん :2007/12/24(月) 23:51:23
>>100 なるほど。。それかもしれないです。
OSのファイルシステムドライバを通さないと、実装がカンタンとか、
そういうメリットがあるんでしょうか?
>datファイルなんかを動的に持つってことは可能でしょうか? ファイルを動的に持つ、ってどういう意味? >で、また読み込みに行ったときに、デフラグされてると、どこにあるか分からなくなる、、とか。。 そうはならない。そのあたりはファイルシステムがどうにかする。 >どう頑張っても、Cの実装次第で、デフラグされるとおかしくなるようなプログラムは作れない・・・ですよね? CじゃなくてOSの実装だってば。 C言語的には、HDDのセクタを直接読み書きするような物だったら、 デフラグでおかしくなる可能性はある。 が、まともなOSならドライバじゃない限り HDDのセクタを読み書きできないようになってる。 HDDのセクタを直接読み書きせず、ファイルシステムを経由してアクセスするなら、 おかしくなることはない。
>>101 逆に実装が難しくなるので、特殊な用途にしか使わない。
データ復旧ツールとか。
104 :
デフォルトの名無しさん :2007/12/25(火) 00:08:09
>>102-103 う〜ん・・・そうですか。ありがとうございます。
ドライバやデータ復旧ツールを開発する訳でもないので、
私の聞き間違いか、言った人の勘違いかなんかでしょう・・・。
ありがとうございました。
>>101 それこそ自分でデフラグするソフトを作るのでもない限り不要だね
106 :
デフォルトの名無しさん :2007/12/25(火) 00:42:37
お初です。 getch関数の質問なんですが 文字入出力関数を作成したのですが2バイトキーを無視する処理で iKey = getch(); if ((0x00 == iKey) && (0xe0 == iKey)) { getch(); } というソースを書いたのですが、iKeyの型をintからcharにするとなぜかifの条件に引っかからなくなってしまうんですが、なぜなのでしょう??? 知恵をお貸しください。
△ char ○ unsigned char char が符号無しな環境なら char でも動くが。 0xe0 の型は int 型で、これは 224 という値に相当するけど、 char が符号つきだと、iKey = 0xe0 として iKey に入っている値はまあ大抵は -32 になる。
108 :
デフォルトの名無しさん :2007/12/25(火) 00:58:11
こんなソースがあるんですが、 int a; struct S1 { struct { int i; HANDLE h; }S2[100]; } ; ... S1->S2[a].i = 001519 ; /* 001519は時分秒 */ S2[100]とされているものに対して、S2[a] を入れることによってどうなるのかが よく分かりません。これは、構造体の配列・・・?
109 :
デフォルトの名無しさん :2007/12/25(火) 01:04:32
早速の返答ありがとうございます。 このことをC言語の初心者にも分かり易く説明してくださいと言われたらどう答えますか?
>>109 そのまま教えればいいだろ。
わからなかったら分かるまで考えてもらえばいい。
本気で話し出すと汎整数拡張の話になってしまうが、 まあ簡単に言うなら char が符号つきだと 0xe0 は値の範囲から外れちゃうから等しくなんないよ、と。
113 :
デフォルトの名無しさん :2007/12/25(火) 01:14:03
ちなみに説明するというのがメインの課題なので おしえてもらった通りに説明したいと思います。 ありがとうございました。
ビットシフト操作に関して、算術シフトと論理シフトの、 どっちを行うかは、規格できっちり決まっているものですか?
>>114 signed なら算術
unsigned なら論理
>>115 unsigned なら論理シフトだが、
signed の場合にどうするかは規格で決められていない。処理系定義。
117 :
115 :2007/12/25(火) 01:25:34
>>116 ぅぉ、マジカ。知らんかった…トンクス。
118 :
デフォルトの名無しさん :2007/12/25(火) 01:27:04
>>112 なるほど・・・。
int a = 5;
だとしたら、S2構造体の 5番目の変数 i にアクセスしてるってことなんですね。
S1->
となってるのは、なんでなんでしょうか?
S1-> なんてできるはずがないんだが。
× S2構造体の 5番目の変数 i ○ S1 のメンバである、無名の構造体の配列 S2 の 5 番目の要素の、メンバ i
121 :
デフォルトの名無しさん :2007/12/25(火) 01:32:23
>>119 そうなんですか?
至るところで、
S1->
をやってます。。そもそもなんで入れ子なんだろう・・・構造体要素1個なのに
至るところで入れ子やってます・・。
struct { struct { int i; HANDLE h; } S2[100]; } S1[1]; となってないか?
123 :
デフォルトの名無しさん :2007/12/25(火) 01:36:54
>>120 「S2」は「構造体の配列名」であって、「構造体名」ではないんですね。
構造体名は無名なんですね。
メンバ i
は、構造体配列 S2 の5番目の要素の無名構造体のメンバ i
って感じでしょうか。
まあ言葉で表現すると難しいが、とりあえず こいつのことだ ↓ S2[100] [i | h] [i | h] [i | h] [i | h] [i | h] [i | h] [i | h] ... [i | h] S2[0] S2[1] S2[2] S2[3] S2[4] S2[5] S2[6] ... S2[99]
125 :
デフォルトの名無しさん :2007/12/25(火) 01:41:56
>>122 あ、すみません!
S1->S2[a].i = 001519 ;
をやる前に、
struct S1 *S1 ;
となってました。
この場合、また型名と変数名が同じなので、
S1->
がどっちを指してるか分からないのですが・・・(n
>>125 単に構造体タグ名と変数名が同じというだけだな。
S1-> の S1 は変数名。
001519 ってのが凄く気になる。 こう書くと 8 進数になるけど 9 ってのが入ってて、 エラーになるはずだが。
128 :
デフォルトの名無しさん :2007/12/25(火) 01:49:53
>>124 どうもご丁寧にありがとうございます。
なるほど。分かり易いです。
>>126 struct S1 *p ;
p->
ってことですね。なんで分かるんですかぁぁ・・??
p->
だとすると、なんでわざわざポインタ型にして、入れ子の中の構造体に
アクセス??あああ訳が分からない・・・・結局 i には何が入っているの・・・
>ってことですね。なんで分かるんですかぁぁ・・?? 構造体タグ名を使って S1-> という風にはできないから S1 は何らかのポインタであるはずだ、ということになる。 C だと構造体タグ名と同名の変数を作る事はできるけど、普通は紛らわしいのでやらない。 >結局〜 例えば struct S1 hoge; struct S1 *S1 = &hoge; とした場合、S1->S2[a].i は hoge.S2[a].i と同じことになる。
130 :
デフォルトの名無しさん :2007/12/25(火) 01:59:49
>>127 すみません。001519 に入ってる値は、ビット演算子で時分秒をいろいろ
ゴチャゴチャやっていた値が入っていて、ビット演算子がよく分からなかったので、
>>105 の書き込み時間を適当に入れてみただけなんです。
晒してしまうと、
struct tm tagTime;
pstm = &tagTime;
nRunTime = /* 時分秒設定 */
(((((((pstm->tm_hour / 10) << 4) | (pstm->tm_hour % 10)) << 8) |
((pstm->tm_min / 10) << 4) | (pstm->tm_min % 10)) << 8) |
((pstm->tm_sec / 10) << 4) | (pstm->tm_sec)) << 8 ;
S1->S2[a].i = nRunTime ;
ってなことをやってます。
まあ、ちゃんとやってるのならいいのよ。
132 :
デフォルトの名無しさん :2007/12/25(火) 02:03:20
#include<stdio.h> int gcm(int a,int b); int gcm(int a,int b){ int amari; if( a < b ){ while(1){ amari = b % a; if( amari == 0 ){ return amari; break; }else{ a = b; b = amari; } } }else{ while(1){ amari = a % b; if( amari == 0 ){ return amari; break; }else{ b = a; a = amari; } } } }
133 :
デフォルトの名無しさん :2007/12/25(火) 02:04:01
int main(void){ int x,y; int ans; printf("*********最大公約数の計算をします********\n\n\n"); printf("1つ目の整数値を入力してください:"); scanf("%d",&x); printf("\n2つ目の整数値を入力してください:"); scanf("%d",&y); ans = gcm(x,y); printf( "\n\n\nGCM(%d %d) = %d", x, y, ans); return 0; }
134 :
デフォルトの名無しさん :2007/12/25(火) 02:06:00
>>132 >>133 ユークリッドの互助法のプログラムを書いてみたんですが、
二つの数値入力してエンターキー押したらコマンドプロンプトの画面がすぐ消えてしまいます。
自分ではこれであってると思うのですがどこがおかしいか見てもらえますか。
お願いします。
135 :
デフォルトの名無しさん :2007/12/25(火) 02:07:28
>>129 >S1->S2[a].i は hoge.S2[a].i と同じ
が難解すぎる・・・orz
>>129 を考えながら寝ることにします。
夜分遅くまでお付き合いいただき、大変ありがとうございました!
おやすみなさい。
>>134 Ctrl+F5 で実行すると消えない。
あるいは、最後にもう1つ入力をいれておくか。
まあ、まだバグがあるようだが、それは考えてくれ。
>>134 一瞬で終わる計算なんだからそれで正しいだろう
139 :
デフォルトの名無しさん :2007/12/25(火) 02:15:39
>>136 >>138 Ctrl+F5なら消えないんですかほむほむ。
return amariを return bに直したら正常に計算する事ができました。
ありがとうございます。
>>135 (*S1).S2[a].i と同じではどうだ。
141 :
デフォルトの名無しさん :2007/12/25(火) 09:48:22
失礼します。 現在、MSNメッセンジャーで受信したメッセージから特定のコマンドを抜き出して 別のアプリケーションへ送るというソフトを作ろうとしています。 そこで、まず、あらかじめアクティブにしておいたメッセンジャーで受信した文字列を 1秒間隔でCTRL+A CTRL+Cを利用して取り込む・・・という方法を調べているのですが分かりません。 どなたか答えていただける方がいればよろしくお願いいたします。
>>141 メッセンジャーでやったことはないけど
直接ウインドウテキスト取れないか?
144 :
デフォルトの名無しさん :2007/12/25(火) 10:02:25
>>142 SetWindowText()ってやつでしょうか?
>>143 あれ・・・ここじゃだめなんでしょうか?
146 :
デフォルトの名無しさん :2007/12/25(火) 10:17:47
148 :
デフォルトの名無しさん :2007/12/25(火) 10:42:28
149 :
デフォルトの名無しさん :2007/12/25(火) 11:57:03
初心者ですが。 データ型って意味あんすか?・・・ signed long intとか long intと同じじゃないすか? undigned型とかって使ったりすんでしょうかね?
>>149 long intはsigned long int の省略みたいな物だからまあ同じだろうね
unsignedは使うだろ
signedで桁数が足りなくて、負数を扱わない時とか
>>149 ・-(マイナス)の値がありえない変数のバグ防止
・char型については、signedを指定しないときの符号の有無は処理系依存
意味無いものなんて無い。必要に応じて使い分けるべし。
%lfで表示すると0.0000とかになるんですが、 eを使って表示させると6.111e-20とか、計算誤差の分が表示されてしまいます。 解決する方法はありますか?
>>152 どう表示させたいのかわからない。
%3.1e とか?
>>153 eを用いて表示させたいんですが、精度は小数点以下5桁ぐらいで、それいじょうはeの表示に反映させないようにしたいです
こんな感じか if (fabs(x) < 0.00001) { x = 0; } printf("%e", x);
>>155 0のときだけじゃなく、どんな数字にたいしても精度を切り捨てたいんです
157 :
デフォルトの名無しさん :2007/12/25(火) 15:50:41
いま、ポインタとファイルオープンまで学んだんだが。 あんたら何作ってる? 俺はアドレス帳など作ってみたんだが他にやりがいのある物はないか?
オセロとかテトリスとか簡単なゲームなんかどうかな
159 :
デフォルトの名無しさん :2007/12/25(火) 16:06:06
テトリスとか敷居高そうっすね。 物体が動くようにしたり
正数同士の除算の切捨て誤差を 四捨五入で求めたいのですが、 どういう風に書けばいいでしょうか。 今は下記のようにしています。 int n,m,d n = m / d; if( (m % d) > (d >> 1) ) n ++;
それのどこが切り捨て誤差?
163 :
デフォルトの名無しさん :2007/12/25(火) 17:26:47
そもそも整数演算で打ち切り誤差など発生しない。
>>160 うまくいきません。6.111e-20とかでてきます。
>>165 double型の変数の
小数点以下、例えば5桁だけを利用して表示したいんです。
0.000000002121なら0を表示したいです。
数がでかくなったらeを使ってすっきり表示したいです
167 :
デフォルトの名無しさん :2007/12/25(火) 17:42:13
#include<stdio.h> char pai[3][9] = { {'1','2','3','4','5','6','7','8','9'}, {'@','A','B','C','D','E','F','G','H'}, {'一','二','三','四','伍','六','七','八','九'}, }; int main (void){ printf("%c",pai[0][2]); return 0; } これで3という文字が表示されるはずなんですがうまくいきません。 どうなおせばいいのでしょうか。
>>166 こうか?
if(fabs(x)>=1000){
printf("%e", x);
}else{
printf("%f", x);
}
>>167 Warningいっぱい出なかった?
3はマルチバイト文字だから、'3' とやったら半分しか入らんぞ
>>166 二度手間だけど、丸めと表示の二段階で行なう。
void print(double foo)
{
char buf[20];
sprintf(buf, "%.5g", 1 + foo);
printf("%.5g", atof(buf) - 1);
}
171 :
デフォルトの名無しさん :2007/12/25(火) 17:50:40
>>166 自分の好きにフォーマットをコントロールしたいなら、
もうprintfのフォーマット機能に頼らず、
自分でフォーマットするプログラムを書いた方が早くないか?
いや、そんな気がする。どうだろう?
172 :
デフォルトの名無しさん :2007/12/25(火) 18:18:21
てす
173 :
デフォルトの名無しさん :2007/12/25(火) 18:27:50
>>169 3をいれるのにはどうやればいいんですか?
>>173 そりゃキミがどうしたいのかによって変わってくるが・・・
char pai2[3][9*2+1] = {
{"123456789"},
{"@ABCDEFGH"},
{"一二三四伍六七八九"},
};
printf("%c%c",pai2[0][2*2],pai2[0][2*2+1]);
これでも一応出るんで、あとは考えて。
>>167 ,173
●文字列にする方法
char pai ⇒ const char *pai
'3'など ⇒ "3"
printf() ⇒ printf("%s", ...
●ワイド文字にする方法
char pai ⇒ wchar_t pai
'3'など ⇒ L'3'
printf() ⇒ wprintf(L"%lc", ...
かなあ? いまいち自信なし。
>>167 char pai[3][9] = { {'1','2','3','4','5','6','7','8','9'},
{'@','A','B','C','D','E','F','G','H'},
{'一','二','三','四','伍','六','七','八','九'},
};
↑この時点でスタック壊してるな。
何が起こっても不思議ではない。
ワイド文字にしたほうがよい。
>●ワイド文字にする方法
>char pai ⇒ wchar_t pai
>'3'など ⇒ L'3'
>printf() ⇒ wprintf(L"%lc", ...
処理系がわからんが、VCなら L'3' じゃなくて_T('3')のほうがいい。
>>176 ワイドじゃないとダメだから _T にしたらあかんがな。
179 :
デフォルトの名無しさん :2007/12/25(火) 23:07:29
某サイトの問題をやってみました。 【問題】 文字列Aのm番目からn個分の文字列を配列Bにコピーする サブルーチンを作れ。 ただし、m,nの値が文字列Aの範囲を超えるような値が入力 されたら1を返し、正常にコピーできたら0を返す。 こんなプログラム組みました。 問題中のm,n,文字列A,Bの各オブジェクト名,サブルーチンの返値は 勝手に解釈して組んでます。(正常時TRUE(1),異常時FALSE(0))
180 :
デフォルトの名無しさん :2007/12/25(火) 23:08:45
#include <stdio.h> #include <string.h> #define STR_MAX 10 #define TRUE 1 #define FALSE 0 typedef unsigned short BOOL; BOOL BlockCopy( unsigned char*, unsigned char*, short, short ); // メイン関数 int main( void ) { unsigned char szSrcName[STR_MAX+1]; unsigned char szDstName[STR_MAX+1]; short nStartPos = 0; short nCopyLen = 0; printf( "Input Str : " ); scanf( "%10s", szSrcName ); printf( "Input StartPosition : " ); scanf( "%d", &nStartPos ); printf( "Input CopyLength : " ); scanf( "%d", &nCopyLen ); if( BlockCopy( szDstName, szSrcName, nStartPos, nCopyLen ) == FALSE ) { puts( "Error!!" ); return 1; } printf( "入力文字列 : %s\n", szSrcName ); printf( "コピー文字列 : %s\n", szDstName ); return 0; }
181 :
179,180 :2007/12/25(火) 23:09:25
// サブルーチン関数 BOOL BlockCopy( unsigned char* s1, unsigned char* s2, short m, short n ) { int i; short nLen = strlen( s2 ); if( nLen < m || nLen < (m+n) || nLen < n ) return FALSE; memcpy( s1, s2+m, sizeof(char)*n ); return TRUE; } 動作的には問題ないと思ってますがアドバイスお願いします。 また、この組み方はセンスないぞと思われる方は、よりよい プログラムの組み方を教授して頂ければ幸甚です。
Windows2003Server上でVMware Serverを使ってRHE3を動かしてます。 その上でlibjpeg.soを使ったjpeg圧縮ライブラリを作りましたが、 jpeg_create_compress()を実行した時点で以下のメッセージが出て先に進みません。 JPEG parameter struct mismatch: library thinks size is 372, caller expects 376 構造体のサイズが合っていないと言ってるのはわかるのですが、 libjpeg.soとjpeglib.hのVerは合わせてありますし、 同じ名前のファイルが複数存在しない事も確認済みです。 どなたか解決方法を知らないでしょうか?
>>181 ・無闇とshortを使うのはよくない。
・sizeof(char)が1であることを前提としている関数を使うのにsizeof(char)を掛けるのはおかしい。
・「文字列をコピーする」関数なのだから、ナルターミネートは保証するべき。
ってことで、判定部を除くとこれでいい。
sprintf(s1, "%.*s", n, s2 + m);
184 :
デフォルトの名無しさん :2007/12/25(火) 23:55:05
C言語でポートを選び、指定して 相手とファイルをやり取りするってプログラムを作りたいんだが。 どんな関数とか使うんだ?接続など
相手==
>>180 その手の文字列処理関数は、コード見ないとどの引数が入力でどれが出力か分からないから、
プロトタイプ宣言だけで分かるようにconst付けたり仮引数名を工夫したりするといい
BOOL BlockCopy(unsigned char* dst, const unsigned char* src, short, short );
>>182 .so と .h の不整合ではなくて、.so を作ったときのコンパイラ(構造体
のパディング)とそれを利用するプログラムのコンパイラ(構造体のパディ
ング)が違うんだろう。
>>182 #pragma pack(push,4)
#include"jpeglib.h"
#pragma pack(pop)
もしくはコンパイルオプションで指定
190 :
182 :2007/12/26(水) 10:42:05
>>189 #pragma指定を追加する事で無事にプログラムが流れました。
gdbで構造体を確認しましたが壊れている様子もありませんでした。
どうもありがとうございました。
printf("%.4s", s); の%.4sってどういう意味でしょうか?
>>191 最小幅と最大幅の指定のうち、最小幅を省略したもの
質問いいですか #include <stdio.h> int main(void) { printf("%d\n",10*2); return 0; } この場合関数の型名ってあんまり意味ってないんですよね? 変数宣言などするときに意味があったりするんですか?
もうちょっと何が聞きたいのかはっきりしてくれ。 関数ってどっちの関数?main?printf? 型名って何の型名?引数?戻り値?
>>194 質問の意味がよくわかんね
printfは可変長引数
floatとか使いたいとき明示的に
接尾子のfを付けたりする
main の戻り値に意義が見いだせないという事なのか、 それとも printf の戻り値を使ってないという事に関する疑問か。
うぉ・・・エスパーできん・・・
これは10*2に対して、一時変数に格納する意味なんて無いよね?っていうことでは
>>195 だって苦しむなんちゃらには
型名 関数名(引数){なんちゃら}
で関数って書いてあったんだもの><
>>199 そのとおりでございます
>>200 やっぱりわかんね。
int temp = 10 * 2;
printf("%d\n",temp);
と
printf("%d\n",10*2);
は、最適化されて同じバイナリが吐かれるよね?、ということを聞いてる?
あー printf にも戻り値は int型 って関数バイブルみたいな本に書いてあったな。 そういうことじゃ?
>>201 #include <stdio.h>
int main(void)
{
printf("%d\n",10*2);
return 0;
}
の場合intは文的には必要だが機能としてはまったく意味はない??が
#include <stdio.h>
int main(void)
{
printf("%d\n",(int)(1.05 * 360));
return 0;
}
のようにキャスト変換などするとintが使用されるっていうか
意味があるっていうか・・・・
そんな感じです
>>203 そもそも関数の型の意味を理解していないな。
int mainのintは戻り値(OSに正常終了か否か)をreturn 0 か1かで必要だからint mainなんだよ。
>>204 まだそこまでたどりついてません・・・
今苦しんでのキャスト変換のところなんで
もっと勉強すればわかることなんですね
>>203 関数の戻り値が分かってない?
これは何をしているかわかる?
int unko(int x) {
int z = x*2;
return z;
}
int main()
{
int temp = unko(100);
return 0;
}
キャスト変換はただその時の型を「一時的に強制的のその型にする」って理解すればいいと思うよ。 int main(void) { 〜〜〜 return 0; } は、関数の章で学ぶと思うから、 今は明示的に書かなければならないと思っておけばOK。 あまり先飛びすぎても混乱するだけだしね。
>>203 整数リテラル 10 はそれ自体としてintという型を持っている。
整数リテラル 2 もintで、int*intの結果はint型になることになっている。
ってそういうことじゃないのか。
>>205 そのサイトは地雷原だから、他で勉強することを強くお勧めする。
>>212 あー、間違いをそれと知らずに教わるにはいいかも。
どういうこっちゃ?
今時 C から始めるのは損だよ。 C++ の本でも最初のうちは C と似たようなもんだし、 その延長で C++ まで覚えてしまった方が絶対得だよ。
いきなりC++はどうだろうか。 C++はしょっぱなからクラス教えないっけ?
C++が仕様としてカバーしているCとしての意味での、C++ってことじゃない? まずCをやるんだけど、mallocとかFILE*とか、C++ではとって変わった部分を捨てて、 そのままC++のクラスなりnewなりをやれ、みたいなぁぁぁ
>>214 間違いがあるってことだろ。間違いかどうかは微妙だけど、こういう書き方されるともにょる。
>つまり、書き換える必要のある文字列は、一旦文字型配列に格納してから処理をするのが無難だと言えます。
# 無難も何も、文字列リテラルを書き換えるのは論外なわけで……
言葉が足りないんじゃないか 格納=コピーならいいけど、ポインタだけ格納してもね
#include<stdio.h> int main(void) { int i,d=97,c=65; char ca; scanf("%c",&ca); for(i=65;i=<90;i++){ if(ca=c){ ca=d; breke; } else{ i++,d++,c++; } } printf("ca = %c ",ca); return 0; } なんでこれがコンパイルできひんのじゃ!C言語死ねッ!!!!!
if(ca=c)がおかしい 比較じゃなく代入してる
ほんまや!!!!! すまんかった・・・・・
んでfor分の終了条件が=<なんて演算子はない。 <= だ。 ついでにbreak。brekeなんてない。
ていうかコンパイルエラー見れば原因わかるんだけど、コンパイラ何使ってるんだ???
ボーランド プロンプト読めない
ありがじゅう。 お気に入り追加した この恩は忘れるまで忘れない!
228 :
デフォルトの名無しさん :2007/12/27(木) 04:03:27
>>220 コンパイラタン(AA略)「なんでよ私一生懸命やってるじゃん!なんでそんなこと言うの!・・・ヒドイヨ・・・・・」
コンパイラタン「と、途中でそんなの挿入したら、(エラーが)で、出ちゃうじゃない・・・・・!!!」
その夜”ピ、ピ、”と言う不思議な音が深夜の闇の中木霊しつづけた・・・
コンパイラタン「だ、だめっ!そこに"Shift"しちゃダメェェェェェ!!!」
自分で色々検索して、何度も本を読み返したのですが判らないので質問です。 下記のソースでコンパイルは通るのですがIF文で条件外でも処理を実行してしまうようなのです。 どこが間違っているのか教えてください。お願いします。 #include <stdio.h> #include <ctype.h> main() { int i; int date[10]; for(i=0 ; i<10 ; i++) { scan: printf("%d個目のデータ:", i+1); fflush(stdin); scanf("%d", &date[i]); if(isdigit(date[i]) == 0) { printf("数値を入力してください。\n"); date[i] = 0; goto scan; } } printf("前から6個目のデータ:%d", date[5]); return 0; }
scanf("%d", &date[i]); 既にここで入力を数値として変換してしてるので scanfの戻り値を調べるといいよ。 isdigitは文字が('0'〜'9')かどうか判定する関数。 それとこの状況でわざわざコードを読みにくくするgotoを使用する意味はない。 whileとbreakで代用したほうがいい。
234 :
232 :2007/12/27(木) 08:27:31
>>233 ああ、そっか。%dだから受け取った時にすでに数値になってるんだ。なるほど。
じゃあこの場合文字を入れさせないようにするにはどういう風にしたら良いのでしょうか?
>whileとbreakで代用したほうがいい。
たしかにその通りです。気をつけます。
>>232 > main() {
> int i;
> int date[10];
>
> for(i=0 ; i<10 ; i++) {
> scan:
> printf("%d個目のデータ:", i+1);
> fflush(stdin);
入力ストリーム(stdin)のフラッシュは未定義
したこと無いけどたぶんフラッシュされない。
> scanf("%d", &date[i]);
> if(isdigit(date[i]) == 0) {
isdigitの引数は文字。'1'は文字。1は数値。ってな感じ。
> printf("数値を入力してください。\n");
> date[i] = 0;
> goto scan;
> }
> }
> printf("前から6個目のデータ:%d", date[5]);
> return 0;
> }
>
>>232 まず、直接関係ないが、
goto scan;
↑これは止めれ。こういうときはwhile文を使うのがセオリーだ。
isdigit()は「文字が数字かどうか」を判定する関数だよ。
scanf()で変換すると「数値」(int型)になるので、
scanf("%d", &date[i]);
if(isdigit(date[i]) == 0) {
これだとisdigit()は常に0を返すはず。
それに、scanf("%d", &date[i]); の場合、数字の入力を期待しているので、
それ以外の文字は入力されてもdate[i]に入らない。
>>210 main()
これでCマガジンに連載できるなんて…。・゚・(ノД`)・゚・。
休刊もやんぬるかな。
>>237 省略した場合はintって決まりなかった?
だから一応正しいんじゃない?
>>234 scanfの戻り値を利用する
scanfはスキャンに成功した数を返すから、
今回のケースで文字を入力されたら0が返る
>>232 >scanf("%d", &date[i]);
241 :
デフォルトの名無しさん :2007/12/27(木) 09:43:47
途中でエンター押しちゃったw
>>232 >scanf("%d", &date[i]);
こういう取り方は文字/数字チェックそのものに意味が無いのでやめ
普通はバッファの文字列変数を用意させて、そこに入力させる。
それをisdigit()に通してクリアしたら、その時点でdate[i]に代入するようにすればいい。
たぁすけてぇぇぇ! 結果がへんになる!!! #include<stdio.h> int main (void) { int a,c; float b,d; b=1,d=1; scanf("%d",c); for(a=1;a<=1000;a++){ b=b+d; if(b*b==c){ break; } if(b*b<=c) d=d*0.1; } printf(" %d の平方根は= %f ",c,b); return 0; }
>scanf("%d",c);
真に申し訳ございません。どうゆうこと?
あああああああああああああああ すいませんすいませんすいません! もうしませんもうしませんもうしません!
辞書検索の2分探索を下みたいに書いたんですけど、 ????のところ(該当しなかった場合)が思いつきません。 助けてくださいです… char a[20]; char b[20]; int hi,lo,i; 略 hi=i; i=i/2; lo=0; while(1){ if(strcmp(b,a) < 0){ hi=i; i=i-(hi-lo)/2; }else if(strcmp(b,a) > 0){ lo=i; i=i+(hi-lo)/2; }else if(strcmp(b,a) == 0){ printf("あった"); break; }else if( ???? ){ printf("そんなものなかった"); break; } }
>>246 そこは if (lo > hi) を入れたいんだと思うが、
突っ込みどころが多すぎるからもうちょっと練り直して来い。
せっかくなので1つ突っ込んでくだしあ
if文の比較で最初の3通りのどれかに必ず含まれるから最後のelseは 絶対通過しない、まあelse外せばいいけど。 で、1ループでstrcmpは1回呼べばいいべ。 あと文字列が終わったのをチェックしないとね。 略の部分を略さないでテスト用に値設定したやつさらしてみてね。
あ、ほんとだ。 ちょとまってください。
#include <stdio.h> int main(){ int i,j; for(i=1;i<=9;++i) printf("%2d ",i); printf("\n--------------------------\n"); for(i=1;i<=9;++i){ for(j=1;j<=9;++j) printf("%2d ",i*j); printf("\n"); } return 0; for文の練習で書いた上の九九を表示するプログラムをwhile文だけで書けないかなぁと思って
>>251 の続き
#include <stdio.h>
int main(){
int i=1;
while(i<=9){
printf("%2d ",i);
i++;
}
printf("\n--------------------------\n");
i=1;
int j=1;
while(i<=9){
while(j<=9){
printf("%2d ",i*j);
j++;
}
printf("\n");
i++;
}
return 0;
}
このように書いてみたのですが1の段以降改行だけでプログラムが終了してしまいます
どうやったら上手く動かせるでしょうか
>>252 jの値がどういう風に変化するか追ってみよう。
>>252 while (j<=9) のループ抜けたらj を1に戻さないと。
あーjが9のままだから次以降のループはスキップされちゃうのか ヒントありがとうございました
せっかくレスくれたのに放置ですみません。 またあとで伺いにきます。 かしこ
それでいいよ
いいのかよw
ダメ出しすれば著者を超えた気分になれるよね
あんたは小石を跨いでも小石を超えた気分になれるのか?
aho
>>257 そのサイトで勉強すると、>19や>205みたいなことを書くようなお馬鹿になっちゃうよ。
266 :
デフォルトの名無しさん :2007/12/27(木) 19:03:50
>>257 参考になるけど、やっぱり本がいいよ。
独習Cとか、やさしいCね。
どうなろうと後で矯正するからいいよ。
まあ初心者はどのサイトから始めてもいいと思うけど、 そこに留まらずいくつかのサイトを回った方がいいよ そして宿題スレで宿題を解く ついでに簡単なデータ構造、アルゴリズムも学ぶ こんな感じで基礎はおk
269 :
デフォルトの名無しさん :2007/12/27(木) 19:09:25
他のサイトを見るたびに、こんなやり方があったのか! ってなって悲しくなるぞ。
他のサイトを見るたびに、こんなやり方があったのか! ってなって嬉しくなるぞ.
特定のサイトにいついたことはないなあ 適当に検索して、 その日見つけたサイトをぱらぱらと読む サイト規模にもよるけど1日ありゃ十二分に読み終われるとこばっかだし
273 :
デフォルトの名無しさん :2007/12/27(木) 20:10:38
WisdumSoftでC言語の基礎文法を覚えて (例文の内容にアニメ好きがかもしだされているが) Programing Placeでデータ構造とかその他の 知識を学ぶ。 で理解できない所(ポインタとかかな)を重点的に 載せてる本でさらに学ぶ。 あとは、経験値をつけていくだけだ。
274 :
273 :2007/12/27(木) 20:11:47
間違えたWisdomSoftだ
変数宣言と代入ってつなげられるんですか?
苦しんでわけわかめ 違うサイトで勉強するわ お勧め教えてくだしあ
猫でも解るって、ぶっちゃけどう? 携帯からサーセソw
>>275 int i;
i = 0;
を指してるなら可能だし
int i=0;
なら
>>276 の言うとおり「初期化」という。
初期化と代入はどう違うんですか?
初期値を指定するのが初期化。 初期化と代入ではできることが違う場合がある。 配列は一気に全要素を初期化できるけど、 一気に全要素に代入することはできず、 1要素ずつしか代入できない、とか。
const int x; x = 1; //Error //代入できNEeeee!!! const int x = 1; //OK //Yeah! 初期化最高!!
>>280 ぜんぜん違う。初期化される前の値が何であるかは神のみぞ知る。
以下の二つのコードで、 仮に最適化されないとするなら、 生成される機械語コードは同じですか? それとも違う? (1) int array[2] = {1,2}; (2) int array[2]; array[0] = 1; array[1] = 2;
コンパイラ次第
286 :
284 :2007/12/27(木) 21:41:47
すいません、ちょっと質問が悪いかも 初期化と代入は内部的に全く異なる処理をやっているんですか? それともただ確保後に代入してるだけですか?内部的に。
コンパイラ次第
手元の環境で機械語コード生成してみればいいじゃん
rep movsd 使って初期化してるかもしれないし、 mov で初期化してるかもしれないし。 そのあたりはコンパイラ次第としか言いようが無い。
>>284 >仮に最適化されないとするなら、
これが殆ど意味がないのでなんとも言えない。
ってかマシン語レベルでの差なんて最適化どうこう言う前にコードが変われば変わる可能性はある。
空行(セミコロンのみの行)に対してNOPを吐くか消されるかだってコンパイラしだい。
予想でいいのならいくらでも応えられるけどな。
>>284 のコードなら最適化関係なく同じコードが吐かれるかもね。
293 :
デフォルトの名無しさん :2007/12/27(木) 23:55:28
そんな事、気にしてたら禿げるぞ
これ以上禿げたら腋毛が無くなる びっくりするほどなくなる
機械語レベルを気にする必要があるくらい禿てたら手段くらい知ってるだろ
代入と初期化の違いは配列やれば判るよ 配列の初期化はOKだけど配列全体の代入はNG なんでえ〜?ってのはポインタやると判る
Java厨です。 プロトタイプ宣言ってなんですか? C言語ってなんで関数を使う前に宣言しとく必要があるんですか? 昔ながらの慣習みたいなものですか? 宣言無くてもコンパイル通るなら、 コンパイラの手抜きと違うんですか? 関数宣言がないときと宣言も定義もないときと ちゃんとコンパイラは違うエラー出しますよね?
適度に手抜きしてくれないとコンパイルに時間がかかってしょうがないじゃないか
分割コンパイルしないなら無くても良いんじゃない?
C始めて3日くらいです fopenとfcloseの使い方がようやく分かって、ポインタについては良くわかりません(変数の代わりなのかな?くらい そこであるテキストファイルを開いて、その中にある文字列(英数字)からある文字列(setofなど)を探したいです 最終的にはある文字列が見つかる→その後ろ〜〜バイト(もしくは〜〜行)をコピーして、別のファイルにペースト というところまでやりたいのですが 検索しようとしている時点で詰まっています。ソースコードは以下です #include <stdio.h> #include <conio.h> #include <string.h> #define BUFFER_SIZE 200 main(){ char buffer[BUFFER_SIZE],name[BUFFER_SIZE]; FILE *fp; printf_s("test.txtを開こうとしました\n\n\n\n"); fp = fopen("test.txt", "r"); printf_s("検索文字列を代入してください\n"); scanf_s("%s",&name); printf_s("%sを検索しています\n",name); if ( !fp ){ printf("ファイルオープンエラー\n"); return 0; } while( fgets(buffer, BUFFER_SIZE, fp) ){ if(!strcmp(name,buffer)){ printf_s("%sが見つかりました!\n",name); break; } } fclose(fp); }
以上のソースに対して、テキストファイルを用意します 『aaxaa ←改行 bbxb ←改行 cxc【EOF】』 すると、cxcを入力しても反応してくれず、strcmpのところでcxc\nに変更すると、ifの見つかりました文が出ます コレに対する問題点としては 1.改行まできっちり一致しなければ見つからないことになる 2.bbxbで完全一致であるが、bxbでも部分一致で見つかったことにしたい しかし、今では1行読み込みのために不可能(BUFFER_SIZEを実数にしても無理) というところです 〜〜の関数使ったほうがいいよ、とか、こういうルーチンで考えるとできるよ、っていうのがあればお願いします わかりにくい質問で申し訳ありませんが、宜しくお願いします
>>302 ありがとうございます。今色々なページを見てきたのですが…
返り値としてポインタとして返すんですね。ポインタと見た瞬間に顔が引きつったのですが…
void TestStrStr(void)
{
char *s1 = "abcdef";
char *s2 = "de";
char *cp;
cp = StrStr(s1, s2);
printf("'%s'の中に現れる'%s'という文字列は%d文字目にある.\n", s1, s2, cp - s1 + 1);
}
このようなソースを見つけました。printfの一番後ろにあるcp-s1+1はおそらく何文字目にあるか指定してくれてるようなのですが
ポインタ同士を引き算しているこのような場合、実数として計算をしているのでしょうか?
>>303 メモリアドレスを計算している。s1が100番地に格納されているとすると、メモリ上は
100 101 102 103 104 105 106 (メモリアドレス)
a b c d e f \0
のようなイメージ。
strstr()は、見つかった部分のポインタを返すから、"de"を見つけたならアドレス103を返し、それをcpに代入している。
printf()の最後の引数はcp - s1 + 1、つまり103 - 100 + 1で4を返す。
>>304 なるほど。だからポインタは便利だって言われてるんですね…メモリ上の一番基礎になる数字を返すから…
ありがとうございます
もうちょっとポインタのこと勉強してからやってみます。とりあえず今日は寝ます
ありがとうございました
>>305 すまん、ちゃんと質問読んでなかったw
ポインタは「アドレスという数字」を格納する変数。
アドレスと聞くと拒否反応が出るかもしれないが、メモリ上の位置を表す何の変哲も無いただの数字。
ただし、四則演算のうち可能なのは加算減算だけで乗除は出来ない。やっても意味のある数字が得られないから。
正しくはインクリメント、デクリメントだけど、これについての詳細はググってくれ。
ポインタやる時はメモリマップ作って見ると良いよ スタック、データ、コードのそれぞれのセグメントがどんな配置か判っているとポインタの理解が早くなる
>>306 ちょっとだけ語弊がありそうなので補足。
・ポインタ+整数 → n 要素だけすすめたポインタを算出
・ポインタ−整数 → n 要素前のポインタを算出
これは可能。ただし配列とか malloc で用意してある範囲を逸脱しないように注意。
・ポインタ−ポインタ → 2つの要素の差を整数で算出
なんだけど、この場合2つのポインタは同じ範囲を指すもの
(304みたいに同じ文字列内の違う位置を指すように)
でないといけないから注意。
309 :
デフォルトの名無しさん :2007/12/28(金) 08:31:18
アドレスは「符号なし整数には似ているけど、全く違う種類のデータ」だと考えた方がいい。
整数なら四則演算が定義できるが、アドレスの場合は
>>308 の言う通り。
そしてインクレメント/デクレメントなんかは「アドレスと整数の混合演算」だと思えばいい。
C言語ではデータの種類によって専用の型を用意するから、整数はintやlong、アドレスは
ポインタを使うと思っておけばいい。
インクレメント に一致する日本語のページ 約 1,940 件中 1 - 10 件目 (0.20 秒) もしかして: インクリメント
312 :
デフォルトの名無しさん :2007/12/28(金) 12:52:57
まったく… K&Rに何と書いてあるか読んでから出直して来い。
英語で書いてあるな
英語のカタカナ表記を議論することほど無意味なものはない。 ただ、そのあたりを議論したくてしょうがない馬鹿よけ対策として、 市民権のある表現を使うに越したことはない。
D→デー T→テー と発音するベテラン技術者に食って掛かる新米社員を思い出したw
>>299 相互再帰する必要がある時はないと困る。
>C言語(シー言語)は、1972年にAT&Tベル研究所のデニス・リッチー (Dennis M. Ritchie) が主体となって作ったプログラミング言語である。 1972当時のマシンでJava並みのコンパイラやアプリなんて起動すらしねぇw
おまえは何を
テキストエディタ(メモ帳)で、ソースファイルを作ったのですが、 どこのファイルに保存すればいいのか、全く分かりません どなたか宜しくお願いします
自分で決めた場所に自分でフォルダ作って保存しとけ
.| .| ∩___∩ | | ノ\ ,_ ヽ .| / ●゛ ● | .J | ∪ ( _●_) ミ 彡、 |∪| | / ∩ノ ⊃ ヽ ( \ / _ノ | | \ " / | | \ / ̄ ̄ ̄ /  ̄ ̄ ̄ ̄
マイドキュメントとかに置くとスペースがどーたらではまるから c:\homeとかc:\srcとかってディレクトリを作ってそこに置け。 コマンドプロンプトを起動したら cd /d c:\home と打ってそこに移動してコンパイルしろ。
なんか、自分の手違いがあるらしく、「:や¥は、ファイル名には使えません」 と出てしまいます・・・ どういうことなのでしょうか・・
プログラム以前の問題。 Windows のことをもうちょっと勉強しる。
:や¥はファイル名に使えるがなんて冗談は置いといて
>>322 のはディレクトリ(フォルダ)名
Windowsキー+Rでcmdを起動 以下を入力 mkdir c:\home cd /d c:\home explorer /n,/e,c:\home notepad hello.c gcc hello.c && a.exe
327 :
デフォルトの名無しさん :2007/12/29(土) 17:11:14
beginthreadexに複数の値を渡すコードがわからないのですが、 教えて下さい。
何日くらいでマスターできますか?
>>329 何を?C?
あんたの今のCの習熟度、他言語について、PCに関する一般知識がどの程度のものか
>>330 Cですね
今日はじめた。他言語まったくしらない。PC知識まぁまぁ。
1000日くらいがんばれ
どの程度を「マスター」と言うのか分からんが、 一通りどんな感じなのか知るのに2ヶ月、 それなりに使えだすのに半年、 十分使えるまでには1〜2年くらいじゃね。
がんばるよ
C言語の「マスター」と言うと、 ・ANSI前(K&R?)の仕様とC89、C99の規格に精通している ・代表的なコンパイラのオプションと処理系定義の仕様が概ね分かる ・上記コンパイラの最適化の仕様がある程度分かる(要アセンブラ?) 代表的なコンパイラ:gcc、VC、BCCぐらい?組込みだとその他もか 辺りだと思うんだがどーか。
Linuxカーネルをビルドできたらスーパーハカーです
コンパイラマスターだな
とりあえず正月つぎ込んで入門書読破すりゃマスターしたってことでいいよ。
341 :
323 :2007/12/29(土) 18:55:56
なんとか意味を理解したつもりで、プログラムの実行段階まで来たのですが #include <stodio.h> int main() { printf("Hello World!\n"); return 0; } のようなソースファイルを実行したらエラーがでました・・・ どこがまずいのでしょうか
stodio.h エラーメッセージ嫁
stodio.h
344 :
323 :2007/12/29(土) 19:03:08
>>342 どうもすみません
なんとか成功しました! やはり実践しなければ分かりませんね
このすっとこどっこいアイオー
>>341 ごめん、僕も極最近始めたものだけど、stodioには吹いたw
一緒に頑張ろう!
studio とかはたまに見かけるな。
348 :
デフォルトの名無しさん :2007/12/29(土) 19:56:49
stdioも見るな
cstdioも見る。
みんなどのくらいの年齢でC言語始めるんだろうか もしかして今の商業高校とかでは教えられているのか?
>>351 商業の基本は情報処理だが、
俺のとこじゃ国家試験の勉強が中心
だが、商業でVBをやるところもあったし、JAVAをやるところもある。
>>353 元の関数仕様が void* だから
渡す側が lpPARAM をvoid*にいれて
とりだす側がキャストで戻してる
355 :
デフォルトの名無しさん :2007/12/30(日) 00:05:56
C言語ってポインタとか使うメリットあんの?って感じだけど 難しいから使わなくても大丈夫かな?
>>355 ポインタのメリットをすぐに理解する必要はないが,必要になったときにすぐに(少し調べて)使える程度に覚えとけ
358 :
デフォルトの名無しさん :2007/12/30(日) 00:17:59
ok いま独習Cでポインタやってるんだが、まぁある程度理解してるんだが 少し、上に行くと難しいんだよな。 char *bokki ="ちんこが立つ"; printf(bokki); って場所やってるぜ、こういうのってプロでも使うのか?
>>255 使うメリットが無い内は使わなくていいと思うよ
便利だから使うのであって、かつC言語をやっていればそのうち「これはポインタを使った方が楽だ」って状況が出てくる
その時に使えばいいだけの話
まあC++ならまだしも、C言語だと関数との配列の受け渡しとかで
すぐにポインタが必要な状況になるよ
>>355 同じアドレスを共有したいときがあるのさ
夫婦だって別々のベッドじゃいやだろ?
>>358 まぁリテラル文字列はstaticでconstで領域もconstしちゃうけど
362 :
デフォルトの名無しさん :2007/12/30(日) 00:22:19
Cは難しいなポインタが もしかして359と360はバリバリ使えるんすか?
>>358 const char * str = "俺童貞";
printf("%s", str);
まあdefineの代わりにconstポインタを使うことはあるかもね
defineの代わりとしては
const char* const str = "ヤリてー";
の方がいいかね
364 :
デフォルトの名無しさん :2007/12/30(日) 00:25:40
すごいっすねみなさん この頭の良さを駆使して、みなさんが作ったプログラムはどんなのありますか? 実用的で使えそうなやつっすよタブを消したり入力した文字をソートしてなんたらしたり
>>358 表示したい文字列に%があると見落とすかもよw
宇宙に浮かんでるアレの制御プログラム、を作るための支援ツールとか監視システムとか
367 :
デフォルトの名無しさん :2007/12/30(日) 00:29:31
ちなみに私が作ったのは 1,暗号化 2,解読 3,Quit というやつでシーザー暗号に似た奴ですね。 まだまだへたれですよ
文字列のポインタは文字列の実装上使わざるを得ないのでメリットが分かりにくいと思う
369 :
デフォルトの名無しさん :2007/12/30(日) 00:30:44
>>366 本気で言ってるんすか?
知人の凄い人でもATMなのに人工衛星とかの制御プログラムとか次元が違いすぎる
最近、どっかの団体のコーディングルールとか見ると、ポインタの演算禁止とか、 ポインタのポインタらしい使いかたはしないって流れになってきてるな。 じゃPascalでも使ってればいいのにって気がするけど。
371 :
デフォルトの名無しさん :2007/12/30(日) 00:32:54
ポインタがどうでも良くなってきたんで。 早くファイル操作などの場所をやりたいんですが、ページを飛ばすと複雑な気持ちになるので ポインタのページと関数のページを仕方なくやりますか
>>369 よく嫁
支援ツールだ
つまりだたの社内ツール
実用的なのは作ったこと無いな、所詮娯楽用品止まり。
私の書いたコードなら、世に出回っているフラッシュメモリのシェアの多くを生み出す装置の検査に使われているぜw
まぁ日曜プログラマならそれでいいんじゃね? 自分の腕を仕事に活かしたいと思ったら、それはそれで地獄をみることになるし
376 :
デフォルトの名無しさん :2007/12/30(日) 00:35:54
>>372 でもすごいっすよ
C言語を始める時期が悪かったですかね
ガキの頃に手をつけとけば良かったと後悔しますよ
Cをマスターしたら次はperlかjavaやろうかと思ってるんすよ
377 :
374 :2007/12/30(日) 00:36:39
もっと身近なところでは、某駅ビルの駐車券発行機に使われているとか(ぉぃ
去年一年くらいCの仕事をやって、医療関係のシステムだったけど、ありえないくらいコードの質が 低かったから、そのシステムを導入してる病院には行かないことにしてる。怖い。
>>376 始めるのに早いも遅いもない
逆にガキのころはガキのころにすべき勉強なり体験なりをしなくちゃいけない
Cなんてただの道具にすぎんのですよ、偉い人にはそれがわからんのです
380 :
デフォルトの名無しさん :2007/12/30(日) 00:41:44
>>374 まじすか?
凄過ぎますよ、是非そういう人に基礎から教えてもらいたいんですが
まぁ無理なんでしょう、自力でやらないと意味がないし
そういうコードを書くにはCを学んでいたときに1日どのくらい書いてましたか?
あとは1日3個適当にプログラムを作るとかそういう目標とかってありましたか?
>>2373 私もそんな感じっすよ
暗号化できたーやーいって(自己満)すよね
>>375 プログラマーになったら大変そうすよね
それで食ってくのは難しいすよね
プログラミングの仕事は中国やらインド勢力に取られていくし、 自動生成の流れが盛んになってきているから、 プログラミングの仕事はどんどん減っていくだろうね 現に、カードにパンチしていた時代はコーディングが開発工程の8割を占めていたのに、今では2割程度
382 :
374 :2007/12/30(日) 00:46:50
そう言えば某社のFAXに……あれはアセンブラだったな。 某社の検査装置に使われているのは……basicか。 てな具合にいろんな時期にいろんなことをやっていたから「Cを学んでいた(だけの)とき」なんてないよ。
娯楽用品って言っても仕事なんだけどな (´・ω・`)
384 :
デフォルトの名無しさん :2007/12/30(日) 00:48:11
>>381 今の日本は開発よりかも指示とかプロジェクトの提案とかそんな感じすかね?
たしかにインドとか中国はすごいっすよね。
ロシアは凄いらしいですがどうなんでしょう。
生まれる場所を間違えたな・・・
385 :
374 :2007/12/30(日) 00:48:52
>>381 あー確かに、カードパンチの時代は「完全なる机上コーディング」をしたものを「パンチするだけ」だったな。
# 流石に学校で体験しただけだが
NHKのワーキングプアの番組でやってたな。 アメリカで銀行のシステムをやって年収1000万のIT技術者が、インドに仕事とられてファーストフードの店でアルバイト。
別にインドや中国が凄いってわけじゃなくて、単価が安いからそっちに簡単な仕事まわしてるだけだよ 難しい仕事は単価の高い日本で集中的にやる
388 :
デフォルトの名無しさん :2007/12/30(日) 00:53:59
やっぱ裕福な国は、それ以上求める物が無くて開発するレベルが低いんですか? 日曜プログラマが良いかな、本職は他ので。 パソコン詳しいねすごいねおっちゃんって言われればそれでいいかな
>>387 これからはインド人や中国人の10倍の価値のある技術がないときびしいだろうね。
>>388 日本を舐めすぎw
おまい、マスコミに変に影響されてるな
プログラミング力のあるなし以前に、視野の狭さが心配だよ
コーディングっていうのは単純作業なんだよ、単純作業
町工場で働く工員と同じ
指示されたものを淡々と作るだけ
じゃあ、それ以前に何をどう作るか、ってのを考えなきゃいけないよね
それを考えるのが日本の仕事
もちろん、今後すぐにプログラミングの仕事が無くなるわけじゃない
やっぱり言語や文化の壁があって、オフショア開発の管理って難しいくて、
リスクを極力避けるために、
現状は、仕様変更の激しい部分とか、重要な部分ってのは日本でコーディングしてる
C/C++でポインタを使わないプログラミングが想像できない
>>380 1日3個も作れるならそいつは天才か、作ったものがゴミ箱行きのカスか
とりあえずLinux上の適当なコマンドのソースでも読んでろ
UNIXコマンドのソースは俺も読んだなあ。
おまいはいいよ
ライブラリの○○.aっていうファイルから 収録してある関数名を取り出すことって可能ですかね? あったら教えてください
>>391 C++ならiteratorは別とすればポインタつかわないこと多くね?
Java厨です。 Include文とかヘッダファイルの自動生成って出来ないもの?
条件にもよるが不可能では無い 頑張って作ってみれば?
#define DATA "data" と、例えば定義してexeを作ったときバイナリエディタでみても"data"を文字列として見つけられません これはどういう形で格納されていのでしようか?
402 :
デフォルトの名無しさん :2007/12/30(日) 08:26:04
たとえば、 #define SRAM_A (volatile unsigned char *)0x200000 こんなのもポインタを使っているといっていいですか? SRAM.Hの中身は、こんなのだらけなんですけど。
>>401 DATAを作っていなければコンパイラはobjに"data"を出力しない。
当然、出力されるEXEにも存在しない。
>>402 それだと「アドレス」と言いたくなるけど、まぁポインタだね。
>>402 組み込みなら普通は #pragma で section 名指定して、
リンカーで配置する。処理系によって違うけど
似たようなコードがあるはず。
絶対アドレスにポインタ使う必要なし。
趣味でGBAやったときも402みたいなことばかりやったな。
こんなマクロ定義してたな俺。 #define Acc08(Adr) (*(volatile unsigned char *)Adr) #define Acc16(Adr) (*(volatile unsigned short *)Adr) #define Acc32(Adr) (*(volatile unsigned int *)Adr)
DOS 時代も VRAM 使う時にそういう事してたな。
>>401 そもそも使ってなければプリプロセッサはコンパイラに"data"を出力しない
void *myMalloc(int size) { void *p; p = malloc(sizeof(double) * size); if (p == NULL) ...エラー処理; return p; } と言うような関数を作ったのですが、 これに、double **a の奴と、 double *b に a = (double **)myMalloc(size); b = (double *)myMalloc(size); と、つなぎ合わせる事をするのですが、 特にこれで問題は起こらないものでしょうか?
a = (double **)myMalloc(size); のあとは、for文回して a[i] = (double *)myMalloc(size); と言うふうに、2次元配列を作る予定なんですが・・・
413 :
デフォルトの名無しさん :2007/12/30(日) 21:51:23
すみません、質問させてください。 テキストファイルを作ると同時にそのファイルから文字を読み込んで出力する・・というのをやりたいのですが、なぜか開こうとしてもすぐ画面が消えます。なにがいけないんでしょうか? 別に読み込むだけでもいいのでアドバイスお願いします。コンパイラは「Bloodshed Deb-C++」です。
改行が多すぎると言われたのでいくつかに分けて書きます。 #include <stdio.h> #include <stdlib.h> void kaku(int,int*,char*); int main(int argc, char *argv[]) { int ten=0; char kekka[]="NG"; kaku(1,NULL,NULL); kaku(2,&ten,kekka); kaku(3,NULL,NULL);
FILE *fp; char data[256]; fp=fopen("test,txt","r"); fscanf(fp,"%s",data); fclose(fp); printf("%s\n",data); system("PAUSE"); return 0; } void kaku(int fg,int *ten,char *kekka) { static FILE*f; switch(fg){ case 1: f=fopen("test.txt","w"); break; case 2: fprintf(f,"%d点,",*ten); fprintf(f,"%s\n",kekka); break; case 3: fclose(f); break; } } です。長々とすみません
>>412 pointer to pointerを作るなら
a = (double**)malloc(size*sizeof(double*));
じゃないの?
まあ、メモリは余分に確保されてるからコーディング間違えなければちゃんと動くだろうけど。
>>413 意味が分からない
417 :
416 :2007/12/30(日) 22:01:23
>>416 printf("%d\n", sizeof(double));
printf("%d\n", sizeof(double *));
で確認した所、 double型が8で、double *型が4でした。
ポインタだと値が違うんですね。 始めて知りましたorz
通りで動かなかったのかと・・・
ありがとうございました。 頑張ってみます
>>413-415 13行目はtest,txtじゃなくてtest.txtだろう。
fopenしたならfpがNULLかどうか必ず確認すべきだ。
system("PAUSE")というのは俺の環境にはなかったから外したら多分期待通り動いた。
>>418 ついでにcharとchar *、shortとshort *とかもsizeofして見比べて見ると良いよ
ポインタがちょっと見えて来る
テキストファイルからある文字列を検索し、ヒットした文字列の直後にある数値を抜き出すコードを考えています 例えば X= 630.20 Y= 220.20 Z= 33.25 A= 30.25 のような感じです。このうちプログラム内で定数として用いたいのが630.20や220.20、33.25に30.25です まず1行目をfgets()でポインタ*fpに読み込んで、"X="をstrstr()で探します その辺りまでしかぱっと思いつきません ここから630.20を読み込もうと思うと、どのような方法があるでしょうか 宜しくお願いします
scanf
>>423 ありがとうございます
ですが、scanfはキーボードから入力したデータを読み込む奴ですよね?
テキストファイルに書いてあるものを読み込みたいのですが…
425 :
デフォルトの名無しさん :2007/12/31(月) 02:15:45
isdigit() 一文字ずつで調べて配列に格納して、atof() とか トークンがスペースなら、そこまで読み込むようにして、 atof() とか トークンをもう少し考えなおすのがいいかも、セミコロン、カンマとかにする。 strtokn()とかあった気がするが、それは調べてくれ。
>>425 変なこと教えるなよ。
atofは数字以外に当たったら解析を終了するから、
> 一文字ずつで調べて
とかは不必要だろ。
>>425 ありがとうございます。isdigitでチェックして配列に格納が簡単そうですね
strtokn()もありますけど、元ファイルを変換する(というより、別ファイルを作ってそこに数値同士をカンマ等で区切るようにする?)ので、あまり使いたくないところです
最悪、strtokn()で別ファイルを一時ファイルとして作成してやるという方法がありますが…
ちょっと考えてみます。ありがとうございました
>>426 fscanfにそんな機能があったのですか、もう一回調べてきます
ありがとうございました
>>428 scanfはfscanfのラッパー関数みたいなもん。
scanf内でfscanfをstdinに対して処理している。
scanfでもstdinをfreopenすればファイルからの入力にできる。
普通strtol(), strtod()
#include<stdio.h> int main () { int a,b,c,i,f,d[50]; scanf("%d %d",&a,b); switch(a*b){ case 0: return 0; defalt: c=a/b; printf("%d",c); /*19*/ break; } i=1; while(i<=50){ c=a%b; d[i]=c/b; c=c%b; printf("%d",d[i]); if(d[i]==0) f++; else f=0; if(f>=2) break; i++; } return 0; } スミマセン!なんでコレダメなのデスカ?オシエテクダサイ!!!
>>431 scanf("%d %d",&a,&b);
反射神経が書いてるので違うかもシレン。
>>431 defalt:
↑これがだめだ。
ラベルとして認識しているはず。
default: な。
>>431 ちょっとずれるが、
switch(a*b){
case 0:
↑0かどうか判断したいだけなら、if文を使うべきだ。
switchにする必要なし。
スミマセンちなみにエラーの内容ハ”Ifに(がナイ”デス。 修正しまシタがダメデス。 書き方ノドンクササとかよりそっち教えてホシイデス。
>>435 もう一回、ifの入ってるバージョンのソース見せてくれたらなにかコメントできるかも
>>431 >d[50];
>i=1;
>while(i<=50){
これも駄目だな
437 このトウリデス ナオラネエ!ウガァァァァァ
440 :
デフォルトの名無しさん :2007/12/31(月) 17:09:50
#include <stdio.h> void test(int i); itn main(void) { test(0); return 0; } void test(int i) { if(i<10){ test(i+1); printf("%d",i); } } 再帰なんですが これ難しくて理解できないんすよ。 みなさん詳しく説明してくださいお願いします。
test関数は引数が10未満ならもう一度test関数を引数+1の値を使って呼び出したあと引数を出力する。 出力は「9876543210」ってなるだけかな? 10を3とかにして流れをゆっくり追って行けばわかるよ。
itnってなんだろうってのは置いといて、 test(0)は0+1でtest(1)を呼ぶ test(1)は1+1でtest(2)を呼ぶ 最終的にtest(9)が9+1でtest(10)を呼ぶが、i<10じゃなくなるので何もしない その後printfで9が印字され、8が印字され・・・最初の0が印字されて終了と 処理が戻っていく感じだな
443 :
440 :2007/12/31(月) 18:03:00
何が難しいのかさっぱり理解できない
445 :
440 :2007/12/31(月) 18:11:48
何故、0123456789じゃなくて 逆になるのかが、難しい
>>443 感覚的に理解できないだけだと思うけど、
デバッガでステップ実行して追っていけばわかると思うよ。
ちなみに、再帰はめったに使わない。
11年ぐらい仕事でCプログラミングやってるが、
再帰を使ったのは1,2回。
>>445 printfを実行するのはtestを実行した後だから
ディレクトリの走査とかそれに類似したものは再帰使うなぁ
定番というか
デバッグ中に無限に再帰してスタック食いつぶしてデバッガがフリーズするのも良い思い出。
449 :
440 :2007/12/31(月) 18:56:37
再帰なんて深く理解しなくていいすか? 適当にながしちまえば?
じゃあこれでどうだ int sum(int n) { int ret; printf("enter sum(%d)\n", n); if(n == 1) ret = 1; else ret = n + sum(n - 1); printf("leave sum(%d)=%d\n", n, ret); return ret; } int main() { printf("sum(5)=%d\n", sum(5)); // print 1+2+3+4+5 return 0; } enter sum(5) enter sum(4) enter sum(3) enter sum(2) enter sum(1) leave sum(1)=1 leave sum(2)=3 leave sum(3)=6 leave sum(4)=10 leave sum(5)=15 sum(5)=15
>>449 何を目的で勉強してるかによるんじゃないかな
単位のためとかであれば流しちゃっていいと思う
滅多に使わないけど、再帰は階層構造を簡単に処理するには非常に便利、 この程度の基本テクニックにねを上げてるようじゃ、先は暗いよ。 諦めずに理解するべし。
453 :
440 :2007/12/31(月) 19:11:11
>>452 理解してみます
再帰はソートっぽいんすね
>>451 >>452 とか
他の人たちは
socketとかネットワークプログラムとかもへっちゃらすか?
「へっちゃら」の意味合いによる ネットワーク関連のバグの修正とかは泣きそうになる
スタックはLIFO
456 :
440 :2007/12/31(月) 22:31:02
test(0); printf("%d",i); tesxt(i+1); の逆の再帰だと理解できます 先にprintfで0を表示してそのあとにtest0+1をして 1になってprintfで1を表示して それを10まで繰り返すんですが 上の440のやり方だと なぜtest(i+1);したあとprintfをやっているのに 9が最初にくるかがさっぱりなんですが より詳しく教えてくれる人はいませんすか?
>>456 再帰呼び出しが終わったらどこに戻るか考えてみそ。
長いのでi<2でやると test(0)→test(1)→test(2)→2は何もしないのでそのまま終了 test(1)に戻る、printf("%d",1)、test(0)に戻る→printf("%d",0) return 0;に戻る
10まであると面倒だからif(i<10)のところがif(i<2)だったものとする。 test(i+1)の所に順次、関数の中身を展開していくと、 if(0<2){ if(1<2){ if(2<2){ test(2+1); // ここは実行されない。 printf("%d",2); // ここは実行されない。 } printf("%d",1); } printf("%d",0); } になる。で、10が表示される。これ見たら分かる?
>>456 たぶん他の人と被ると思うけどw
test(0) が呼ばれるじゃん?
→ i<10 なので、test(1) が呼ばれるじゃん?
→ i<10 なので、test(2) が呼ばれるじゃん?
: 中略するじゃん?
→ i<10 なので、test(9) が呼ばれるじゃん?
→ i<10 なので、test(10) が呼ばれるじゃん?
→ i<10 が成立しないので、何もせずに test(10)を抜けるじゃん?
→ printf("%d", 9) で 9 が出力されるじゃん? そんでtest(9)を抜けるじゃん?
:
→ printf("%d", 2) で 2 が出力されるじゃん? そんでtest(2)を抜けるじゃん?
→ printf("%d", 1) で 1 が出力されるじゃん? そんでtest(1)を抜けるじゃん?
printf("%d", 0) で 0 が出力されるじゃん? そんでtest(0)を抜けるじゃん?
main() 終了じゃん?
さあ、何が出力されたかな?っと。
3人もかぶるとはめずらしい
462 :
460 :2007/12/31(月) 22:47:32
ほら被ったあw
おまえら大晦日なのに暇人だな いや大晦日だから暇なのか
初詣に出かけるまでの時間、暇で暇で仕方ない
休みなんて、コーディングくらいしかやること無いしね
466 :
440 :2007/12/31(月) 22:57:43
おお!わかりやすいです。 ですが何故、繰り上がってる時にprintfが有効にならないのかが不思議です i<10 test(0); test(1)に繰り上がる時は test(i+1)とprintf("%d",i);をやるはずなんですが 何故printfが飛ばされてるんですか?
test(i+1)が終わらないとprintfに進めないじゃないか。
わかってないのにわかりやすいとはこれいかに 飛ばされてるんじゃなくて、test(i+1)で止まってると思えばいい で、test(i+1)の処理が終わったら戻ってくる。
469 :
440 :2007/12/31(月) 23:02:55
test(i+1);で10になるまでループしてると考えれば良いんですか? それで10になったら 987654321と戻ると?
>>440 test は、9 から i までを出力する関数。
引数が 10 未満の時は、まず test(i + 1); とすることで 9 から i + 1 までを出力してから、その次に i を出力してるっしょ?
そういうわけで、9 から i までが出力される。
んで、10 以上の数を渡すと、if に引っかかって何も出力されない。
だまされた気分になっても気にしない。
test(10)は何も表示しない。 test(9)はtest(9+1)を実行してから9を表示する。つまり、9を表示する。 test(8)はtest(8+1)を実行してから8を表示する。つまり、98を表示する。 test(7)はtest(7+1)を実行してから7を表示する。つまり、987を表示する。 …中略… test(1)はtest(1+1)を実行してから1を表示する。つまり、987654321を表示する。 test(0)はtest(0+1)を実行してから0を表示する。つまり、9876543210を表示する。
再帰関数を展開して1つ1つ理解しようとしても混乱するだけだよ。 例えば 9 から i までを出力する関数 hoge があるとするだろ? それを使って test を実装しようとすると、一番簡単なのは hoge をそのまま呼ぶだけだけど、 それじゃ面白くないので 9 から i + 1 までを hoge に出力させて、 それから i だけを test 内で出力するという風にしてみよう。 そうすると void test(int i) { if(i < 10) { hoge(i + 1); printf("%d", i); } } となるわけよ。これは分かるっしょ? んで、この test っつー関数は 9 から i までを出力する関数になったわけだから、 hoge としてこの test が使えることになる。 というわけで、 void test(int i) { if(i < 10) { test(i + 1); printf("%d", i); } } としても同じ結果が得られるって寸法だ。
>>459 とほとんど一緒だけど
int main(void)
{
/* test(0)開始 */
if(0<2){
/* test(1)開始 */
if(1<2){
/* test(2)開始 */
if(2<2){
/* ここは実行されない */
}
/* test(2)終了*/
printf("%d",1);
}
/* test(1)終了*/
printf("%d",0);
}
/* test(0)終了*/
return 0;
}
_beginthreadexでウィンドウハンドルを渡したいんですが、 どうすればいいですかね?
スレ違い
第3引数から渡すれ
477 :
440 :2007/12/31(月) 23:21:05
なんとか理解しました
>>460 さんのが分かりやすかったです
まだ完全理解したという訳ではないので勉強してみます
回答してくれた皆様ありがとうございました。
おそらくスタックがどんな感じなのかわかっていないかな? iがスタック上に積まれる他に関数呼び出しによる復帰情報(ここだとtest()関数な)がスタック上に積まれるんよ 復帰情報は関数が何処に戻れば良いかを示すリターンアドレスが格納されている ここではまだ実行されていないprintf()の直前 つまりイメージとしては 復帰←0←復帰←1←復帰←3←復帰…8→復帰←9←復帰 と積まれる(push) でループから抜けると 今度は 復帰情報→0→復帰→1→復帰→3→復帰…8→復帰→9→復帰 と逆に飛び出してくる(pop) つまりLIFO(Last In First Out)な訳 良くコインの入れ物として説明されている有名アレ
ああなんか色々間違ってるなゴメン 正しくは push時 main復帰←0←復帰←1←復帰←2←復帰…8←復帰←9←復帰 pop時 main復帰→0→復帰→1→復帰→2→復帰…8→復帰→9→復帰
スタック云々言って理解できるなら、 再帰ぐらいで悩まないと思う…。
うぬ、そうか、、、スタック説明しないと無理か 大変だな えーっとスタックはローカル変数を格納する為のメモリ領域で・・・ ってスレ違いだなこりゃ スマン調べてくれとしか言いようが無い 頑張ってくれ
同じ関数だから混乱する。 引数が関数名だと思ってたどってみ test(1)は test1(1)だと
年越し勉強会になっててワロタ
printf("あけおめ");
puts("ことよろ");
scanf("%d", &otoshidama);
^D
!#include <stadio.h> int mein() { fprint("間違えを見つけた数×100000円お都市玉をもらえます"); } return 0; あけましておめでとうございます
600000GET
600000円が最高金額か ダンヒルの最高値福袋2個分かよw
Max \700,0000- ?
\700,000-
\nが無いのを間違いと見るなら800000円かな?
>>474 4番目のvoid *arglistを使って渡すべし。
函数の()の中にvoidとかを書かないのは間違い?
函数の()って何だよ。 もうちょっと人に伝わる言葉で表現しろよ。
さーせん。 「mein()」の()の事
mein って何だよ
こっちのセリフです><
main
>>497 それだけじゃ、宣言か定義か呼び出しかすら分からないわけだが・
別に何の間違いでもないだろ
( ) 内に何も書かなかった場合 ○ プロトタイプ宣言 引数がどうなっているか不明であることを表す。 その後具体的な引数を指定した宣言や定義が現れない限り、 この関数を呼び出す時、実引数は可変長引数の時と同じように扱われる。 ○ 関数定義 規格上は void であると見なされることになっている。 ただし、上記に書いた通りの動作を起こすコンパイラもある。 ○ 関数呼び出し そもそも ( ) 内に void と書いて呼んではならない。
505 :
440 :2008/01/01(火) 16:48:42
また質問っす #include <stdio.h> #include <string.h> int ko(char *p); int main(void) { char str[80]; gets(str); printf("%d\n",ko(str)); return 0; } int ko(char *p) { int a; a=0; while(*p){ a++; p++; } return a; } なんですが while(*p)なんですが str[80]に入力した文字をどのように繰り返してるんでしょうか? while(*p)だと全然理解ができません 入力した文字列の\0(ヌル文字まで繰り返すんでしょうか?)
while(*p != '\0') { } と同じ。
507 :
440 :2008/01/01(火) 17:00:23
ありがとうございます *pとかよくわかりずらくて参考書にそんなようなこと書いてなくて 次はforでやってみようかと思います
>>505 ・C言語では偽が0、真が0以外
・whileは条件が真(つまり0以外)の間、ループを続ける
・C言語の文字列(char配列)はヌルターミネートといって最後にヌル文字('\0')が入っている
・ヌル文字の文字コードは0
・*は間接参照演算子
つまり
>入力した文字列の\0(ヌル文字)まで繰り返す
で正しい。
ヌル文字ではなかったらaをインクリメントし、ついでにpを進める、ということを繰り返す
まあ(半角)文字数を調べる関数だね
509 :
440 :2008/01/01(火) 17:06:50
>>508 あ!だからヌル文字で終わるんですね
ヌル文字=0って事を・・・
文字列とかが入るとややこしくなるんで
これを使えば特定の文字の数を数える関数とかへっちゃらっすね
でも、ちゃんと '\0' と比較した方が読みやすいから比較しようぜ
そうだね。 こんな読みにくいコード書いても、読みやすいコードに比べて実行速度が速くなる訳じゃないもんね。
512 :
440 :2008/01/01(火) 17:42:21
実行速度ってどうなんすか? 僕が作るプログラムではそこまでイライラするほどかからないんすが
全く変わらん。
#include <stdio.h> int main(void) { while(1) { printf("おまいら\n"); printf("あけましておめでとう!\n"); } return 0; }
515 :
440 :2008/01/01(火) 19:18:16
ネットワークプログラム作りたいんすよね どんな過程でネットワーク系に入りますか? まずC言語の文法など覚えてたらすぐネットワーク系のプログラムとかやりますかね?
ネットワークプログラムは結構めんどくさい。文法覚えただけでは苦戦する。 でも、目的を持って難題に立ち向かうのが上達の秘訣だとおもう。 コードを書いていれば、何が必要かだんだんとわかってくる。 すぐに作れなくてもあきらめないことが重要だよ。
#if #else if #end if の使い方がわかりません! どういうときに使うんですか!
以下の★1と★2のやり方で結果が同じになるのはどうしてなんでしょうか? 有識者の方ご教授をお願いします。 #include<stdio.h> void * func(void *p){ printf("□■□func開始□■□\n"); printf("pのアドレス = %p\n",p); printf("p = %d\n",(int)p); (int)p += 100; printf("p = %d\n",(int)p); printf("□■□func開始□■□\n"); return NULL; } int main(void){ int number = 30; printf("numberのアドレス = %p\n",&number); func((void *)number);★1 return 0; }
#include<stdio.h> void * func(int *p){ printf("□■□func開始□■□\n"); printf("pのアドレス = %p\n",p); printf("p = %d\n",*p); *p += 100; printf("p = %d\n",*p); printf("□■□func開始□■□\n"); return NULL; } int main(void){ int number = 30; printf("numberのアドレス = %p\n",&number); func(&number);★2 return 0; }
>>517 #define VER 2
#if VER < 2
//古いコード
#else
//新しいコード
#endif
みたいにソースを丸ごと切り替えるときに使ったりする
慣れると便利。
521 :
440 :2008/01/01(火) 19:59:01
>>514 それは、おまいら あけましておめでとうを無限ループですね?
while(1)なので
>>522 *(int*)p += 100;
とすると、同じ結果が出るね。
>>517 デバッグ時にコードを一時的に無効化したり有効化するのに便利だね。
/* */とは違って、入れ子にできるから楽
#if 0
hoge();
hoge2();
#endif
>>523 ほんとに
func((void *)number);★1
こうなのか?
>>520 >>524 ありがとうございます!
ということは int VER みたいなフラグを作っておいて使うんですね!
#if 0
とか参考にしてたソースに出てきてわからなかったです
ありがとうございました!
>>528 >int VER みたいなフラグ
駄目です、それじゃ使えません
>>523 *(int*)p
それは参照先がアレじゃないか?
>>518 そのこぴぺされたコードで、コンパイルして実行できるか、もう一度確認してみてくれないか?
ちなみにWindows?もしかしてDOS?
534 :
440 :2008/01/01(火) 21:01:52
viみたいなエディタ作るには 1人じゃ無理すかね?
>>532 プリプロセッサと呼ばれる機能なのだ。
#defineはマクロで、文字列の置き換え
#define VAR 2
と書くと、今後ソースのVARは2という文字に置き換えられる。
#ifは条件付コンパイル。式が0でなければ有効となる。
#if VAR>1
と書くと、以下と同意になる。
#if 2>1
となって、式の結果は、1なので、有効となる。
viみたいなエディタなら無理じゃない
537 :
440 :2008/01/01(火) 21:05:24
画面上に色とかつけたりしてるのは、あれはC言語でやってるんすかね? viで色とかが使えるすがスキームなど色文字を表示することは可?
>>537 DOSなら、エスケープシーケンスじゃないか?
WindowsならコンソールAPI
540 :
440 :2008/01/01(火) 21:15:29
Linuxじゃ無理すか? たしかにwindowsだと猫でもわかるC言語に書いてありましたが
猫か…
>>540 linux
エスケープシーケンス使えるよ
printf("\033[31mhogehoge\n");
って感じで
VT100か
>440 ちょっとは自分の頭を使って集中して物を考えたり調べも伸したりする習慣をつけろよ
545 :
440 :2008/01/01(火) 21:47:36
>>542 すげーっすね!
できましたよ
エスケープシーケンスで調べてきます
>>544 以後気をつけます
>>546 これを実行してみてほしい
#include<stdio.h>
int main(void){
long num=1234;
*((char*)&num)+=65536+256;
printf("%ld\n", num);
*((short*)&num)+=65536+256;
printf("%ld\n", num);
return 0;
}
キャストしたものは左辺値じゃないけど、* をつけたから左辺値で通るんだよ。
#include <stdio.h> #include <malloc.h> main(togo,toog) int togo; char *toog[]; {char *ogto, tgoo[80];FILE *ogot; int oogt=0, ootg, otog=79, ottg=1;if ( togo== ottg) goto gogo; goto goog; ggot: if ( fgets( tgoo, otog, ogot)) goto gtgo; goto gott; gtot: exit(); ogtg: ++oogt; goto ogoo; togg: if ( ootg > 0) goto oggt; goto ggot; ogog: if ( !ogot) goto gogo; goto ggto; gtto: printf( "%d goto \'s\n", oogt); goto gtot; oggt: if ( !memcmp( ogto, "goto", 4)) goto otgg; goto gooo; gogo: exit( ottg); tggo: ootg= strlen(tgoo); goto tgog; oogo: --ootg; goto togg; gooo: ++ogto; goto oogo; gott: fclose( ogot); goto gtto; otgg: ogto= ogto +3; goto ogtg; tgog: ootg-=4;goto togg; gtgo: ogto= tgoo; goto tggo; ogoo: ootg-=3;goto gooo; goog: ogot= fopen( toog[ ottg], "r"); goto ogog; ggto: ogto= tgoo; goto ggot;} これは何ですか?
たしかIOCCCのプログラム。別に何ってわけじゃない。
頭が物故割れた
#include <stdio.h> #include <string.h> int main(int argc, char *argv[]) { char *position, line[80]; FILE *fp; int counter=0, num, maxbuf=79; if ( argc == 1) {return 1;} fp= fopen(argv[ 1], "r"); if ( !fp) {return 1;} position= line; while ( fgets( line, maxbuf, fp)) { position= line; num= strlen(line); num-=4; while (( num > 0) && ( !memcmp( position, "goto", 4))) { position= position +3; ++counter; num-=3; ++position; --num; } } fclose( fp); printf( "%d goto \'s\n", counter); return 0; } たぶんこういうこと
まちがえた、・・・まぁいいか・・・
554 :
デフォルトの名無しさん :2008/01/05(土) 01:12:12
Javaを半年ほどやってCを最近始めた素人です。 同じソースファイル内でも関数の定義位置が違うだけで、 コンパイラが、関数宣言ないよー。という警告をするのが、 いまいち慣れないのですが。 static宣言な、ファイル内スコープの関数なんかでも、 プロトタイプ宣言ってきちんとしたほうが良いのでしょうか。 手元にあるC言語入門だと、main関数を最後のほうに、 定型的な計算用の関数等を、頭のほうにもってきて、 プロトタイプ宣言を書かないようしているのですが、 皆様はどういった書き方をしておられるのでしょうか・・・。
>>554 基本的に、ソースファイルの書き方は一貫性が大事だと思っている。
だから、一貫性を持って読みやすければそれでOKだ。
556 :
デフォルトの名無しさん :2008/01/05(土) 01:29:27
>>554 おぃ… どのportでaccessしろと云うのだ?
557 :
デフォルトの名無しさん :2008/01/05(土) 01:51:07
558 :
デフォルトの名無しさん :2008/01/05(土) 02:09:33
方向音痴な初心者です 因みに… '/usr/share/doc/man1/或.zg 個人の計算では恐らく'/usr/share/doc* 全てを読み込む様に為っていた筈…
559 :
デフォルトの名無しさん :2008/01/05(土) 02:20:37
最後の状態… 1・再起動がBIOSに到達せず再起動… 2・停止がBIOSに到達せず停止の筈が再起動… 3・RANを切らないと停止せず…
560 :
デフォルトの名無しさん :2008/01/05(土) 02:25:06
斯様に考えてもfile内に.pngを埋め込むのは無理と考えerror_fileを削除の末… 此の顛末…
次の質問をどうぞ
562 :
557 :2008/01/05(土) 02:42:49
564 :
557 :2008/01/05(土) 03:49:11
>>563 Spcially sorry, sir.
>>554 > 手元にあるC言語入門だと、main関数を最後のほうに、
> 定型的な計算用の関数等を、頭のほうにもってきて、
> プロトタイプ宣言を書かないようしているのですが、
> 皆様はどういった書き方をしておられるのでしょうか・・・。
基本的に読むときのことを考えて書く。
文章は上から下へ向かって読む。
だからプロトタイプ宣言も書いてmainの下に呼び出す関数を書く。
よく見るif (0 == a) みたいなやり方(=を書き間違えるミスを防ぐやつね)
もバッドノウハウだと思う。
>>565 最後の2行は同意するが、関数をボトムアップで書くのは臨機応変でありだと思う。
>>565 > よく見るif (0 == a) みたいなやり方(=を書き間違えるミスを防ぐやつね)
> もバッドノウハウだと思う。
なんで?
他にいい方法ある?
はい、次の質問どうぞ〜
>>565 >基本的に読むときのことを考えて書く。
>文章は上から下へ向かって読む。
>だからプロトタイプ宣言も書いてmainの下に呼び出す関数を書く。
うーん・・・微妙。
結局main関数がファイルの一番上に来るわけでもないし、
mainを最初に持ってきたからって可読性は上がらないと思う。
コード全体で一貫性があればケースバイケースどころか
趣味の範疇じゃない?
>>567 最近のコンパイラなら警告を出すはずだし、lintもある。
それに、
if (a = b)
は防げない。
-Wall で出る警告をすべて潰すか、lintを使う習慣をつけたほうが良い。
Cに慣れると関数がボトムアップに並んでないと不自然に見えてくる。
>>569 おれは
>>565 に同意。
main関数を一番下に持ってくるのは、プロトタイプ宣言がなかった頃の
古い習慣を引きずってるだけだったはず。
>結局main関数がファイルの一番上に来るわけでもないし、
これはその通りだけど、プロトタイプ宣言を長々と書くことは少ないし、
たとえ長くなっても関数ブロックがどこから始まるかはすぐわかるので、
main関数が上にあるはうが見つけやすい。
あと、呼び出す関数の引数などを見たいとき、
プロトタイプ宣言が一箇所にまとまっているほうが見やすいと思う。
まあ、これはコーディングスタイルだから、強くは主張しないけど。
>>573 プロトタイプ宣言のなかった頃という実例を提示してくれ。
宣言がなかったら外部の関数は一切まともに呼べないと思うのだが。
> mainがどうとか 最近はフリーのでもエディタが強いからなぁ。 気にならなくなったし気にしなくなった。
10個の配列に入っている数それぞれが 全て異なるってどういう風に書けばいいんでしょうか?
int array[10]; for (int ic = 0; ic < sizeof(array) / sizeof(* array); ++ic) array[ic] = ic;
578 :
576 :2008/01/05(土) 13:45:39
追記すいません。 10個の配列には既に数字が入っていて 条件式でかくならどうすればいいですかね?
ループでまわすか45個条件式書くか、好きなほうにしろよw
無駄に再帰 int unique(int array, int n){ int i; if(n <= 1)return 1; for(i=1; i<n; ++i) if(array[0] == array[i]) return 0; return unique(array+1, n-1); }
要素数intを再帰するのはちょっと勇気がいる。「スタックはもう0よ」に気をつけて。
要素10個の配列を想定した再帰でスタックの心配とかw
>>581 そこで最近覚えた末尾再帰の最適化ですよ。
"入っている数"があまり大きくない数字(例えば0〜9999とか)なら、 配列(例なら10000要素)を用意して重複チェックするという手もある 10回ループすればわかる
ソート済み配列なら楽なんだがな
586 :
576 :2008/01/05(土) 16:39:31
>>584 ので
わかった気がします。
ありがとうございました
587 :
584 :2008/01/05(土) 17:50:36
あぁ 577 にもヒントが 見落としていたよorz
mainなんて最後に読むから下にあったほうが邪魔にならなくていいな
mainから読まないと理解できない俺はorz コメント豊富ならいいが、 そうでなければ順を追わないと分かりづらい……
どうせ上から下に綺麗に順に追って読めるわけじゃないから、どこにmainがあってもいいや
591 :
554 :2008/01/06(日) 01:04:01
レス有難う御座いました。
結論としては
>>555 なのでしょうが。
自分はIDE使っていて、
>>573 さんの様なスタイルがやりやすそうです。
コンソールでUnixプログラムとかを書ける様な方だと
また意見も変わってくるんでしょうかね…。
>>571 とかも参考になります。
皆様ご意見有難う御座いました。
すいません、超初心者なんですが判らなくなったので教えていただけませんか? 今アクセスカウンタを作ろうと思って、まずは簡単に動く物をテストで作ってみ ようかと思ってるのですが、思った動作をしてくれません・・ ipアドレスをゲットして、そのipアドレスから連続でアクセスがあった場合カウンタ が回らないようにしたいです。超初心者の自分なりに書いてみたのですが、同じipから のアクセスでもカウンタが回ってしまいます。ソースは #include <stdio.h> #include <unistd.h> #include <stdlib.h> main() { long i; FILE * fp; char *test,*ip,*count="count.dat",*addr="addr.dat"; test = getenv("REMOTE_ADDR"); fp = fopen(addr,"r+"); fgets(ip,30,fp); if(ip==test){ printf("test"); fclose(fp); }
593 :
592 :2008/01/06(日) 04:11:42
else { fprintf(fp,test); fclose(fp); fp=fopen(count,"r+"); rewind(fp); fscanf(fp,"%6ld",&i); i++; rewind(fp); printf("Content-type: text/plain\n\n\0"); fprintf(fp,"%06ld",i); printf("%06ld",i); fclose(fp); } } こんな感じです。多分どっか物凄く適当な事をしてる部分があると思うのですが 自分ではぜんぜんそれがどこか判りません・・・ 誰か教えてください・・・
594 :
592 :2008/01/06(日) 04:13:28
あー15行目の printf("test"); はif文に入ったかどうかチェックする為に書いた物で意味はありません。
基礎からやった方が良いと思うけど、とりあえず。 ・ipは只の未初期化のポインタ ・文字列の比較は==ではしない
>>592 char* ip; で
fgets(ip,30,fp); は臭う
if(ip==test) ポインタ比較してどうする
文字列比較は strcmp (string.h)
全部読んでないが、ここら辺。
597 :
592 :2008/01/06(日) 04:35:19
>>595-596 こんな時間なのに即レスありがとうございます。
もう少しポインタの勉強してきます・・・
ポインタの前に配列を
599 :
592 :2008/01/06(日) 04:56:42
あぅあぅ・・ 眠いせいか全く頭まわらず、未だ解決の糸口が掴めません・・今日はもう寝ます。 もしよかったら592の鳥頭でも判るcの初心者向け解説サイトなんかあったら教えていただけますか?orz よく寝て頭冴えてる時にもう1度チャレンジします。
>>592 char *test,ip[128],*count="count.dat",*addr="addr.dat"; にして
if(ip==test){ は
#include <string.h> を追加して if(strcmp(ip, test) == 0)だな
あと、printf("Content-type: text/plain\n\n\0"); の最後の\0は要らない
サイトより、しっかりした一冊を読んだほうが為になると思う
602 :
592 :2008/01/06(日) 05:55:21
眠い目こすりながら"もうちょい・・もうちょい・・"ってやってたら出来ました! 600さん601さんありがとうです。ほぼ601さんの書き込み通りで出来ました。 else の後に rewind(fp); が無かったのでaddr.datが追加書き込みで上手く働かなかったのだけ なんとか自力で見つけて修正しました。ホント有難うです!
まだやんの
>>603 まさか、その「古いスタイル」という奴は宣言ではないとでも?
昔はいきなり呼べたような。 そのためmath.hをインクルードしてないと引数がintになったりしてたような
今でもいきなり呼べるよ
608 :
603 :2008/01/06(日) 12:59:23
>>605 ごめん、間違えた。
#ifdef __STDC__
extern int func(int arg1, char *arg2);
#else
extern int func() /* これが古いスタイル */
#endif
こうだった。
610 :
603 :2008/01/06(日) 15:20:15
まだやってたのか。
>>605 とりあえず「プロトタイプ宣言」では無いと思う。
>>606-607 >引数がintになったりしてたような
戻り値とちゃうか?
んで、暗黙の戻り値の型はC99でダメにならなかったっけ?
>>611 古い仕様やANSI非準拠の環境ならプロトタイプ宣言なくても関数呼び出しが可能。
戻り値は省略された場合intとみなす(これは確か規格)
引数はそこに関数呼び出しがあるならプロトタイプ宣言がなくとも予測できる。
int func();// ←プロトタイプ宣言
int a = func( 5, "hoge" );
と書かれていればfuncの引数が予測できる。
予測も何も、そのままスタックに積んで取り出すだけでしょ あってる限り問題は出ない
コール規則が複数あるような場合に嵌るだろ
プロトタイプを人間が確認してるようなもんだな
まぁ、math.hをインクルードせずにprintf("%g\n", log(1))してみたまえ。いいもんだ。
%gってなんすか?教えてくだしあ
printfでぐぐれ
manコマンドしか見てなかったよ
ごめんうそ
普通に、man printfしても出てくるでしょうが。
プロトタイプ宣言。 200〜300行程度のプログラムならなんとでもなるね。 問題は複数の Cファイルに分割しなければいけない時。 ファイル数が多くなり、extern 関数呼び出しが多くなった時 プロトタイプ宣言が有る場合と無い場合とではバグ出現回数が 大幅に違ってくる。 プロトタイプ宣言する事を癖にした方が良いよ。
ますます話が迷走を深めてまいりました
>ファイル数が多くなり、extern 関数呼び出しが多くなった時 >プロトタイプ宣言が有る場合と無い場合とではバグ出現回数が >大幅に違ってくる。 ソースキボン
>>625 プロトタイプ宣言がない場合、関数の引数の数と型を合わせるのはプログラマの責任になる。コンパイラはチェックしない。
ファイル間の膨大な数の関数と呼び出しで、それを完璧にやれる人はまずいない。
627 :
623 :2008/01/07(月) 00:38:00
>>625 ソースなんてないよ。 実体験。
まだ経験してないのであれば...幸せなのか天才なのか、はたまた...
ソースが無いのにどうやって体験したんだとか勘違いした俺はどうすれば
>>628 俺も一瞬思ったw
>>627 昔はソース書いてからコンパイラに吐かせてプロトタイプ作ったりもしたが
今はIDEもあるし、ほぼ同時に作るべ、
複数人でやるならソースとヘッダの提供は不可欠だしな
627と628の言うソースは違うものを指していると思われ。
野暮だな
そんなことは628もわかってんのにな
633 :
U :2008/01/07(月) 17:58:56
質問です・・ if (a < (int)(a * 10) % 10){ a = (int)a+1; } (注:aはdouble型です) 上記のような文がプログラム中にあったとき、aを7.1なら8のように小数の切り上げをしたいんですがこれでなっていることになるのでしょうか? 小数の切り上げの方法を知っていたら教えてほしいです(標準関数を用いない方法で)。
その前に標準関数を使って行けない理由を聞かせてもらおうか。
条件がはっきりしないけど、0.9足して切捨てとか
636 :
633 :2008/01/07(月) 18:22:42
>>634 学校の課題なので使ってはいけないという制限があるんです。
>>635 回答ありがとうございます。
ですがすみません7.1の他にも小数があるのでそれ以外にも対応出来るようにしたいんです。
637 :
633 :2008/01/07(月) 19:05:00
if文の不等号を逆にしたら出力したい結果が無事でました!! とても答えづらい質問ですみませんでした。
は?
解決したと思ってるんならそれでいいだろ。 詮索することはあるまい。
「宿題の回答」としてはベストな回答だと思うよ。
アホだろ
(n + d) / d; だめ?
だめ
適当に貼ってみる #include<stdio.h> #include<stdlib.h> int main(int argc, char *argv[]){ double value=100.001; long result; if(argc>=2) value=atof(argv[1]); result=value; /* この行と */ if(value>result) result++; /* この行 */ printf("%ld\n", result); return 0; }
645 :
デフォルトの名無しさん :2008/01/08(火) 00:57:40
101 287 345 391 348 287 391 371 388 39 388 88 404 150 428 404 387 145 299 404 197 320 397 141 342 428 429 206 36 214 412 88 176 214 346 210 406 308 250 26 112 370 328 328 284 こんな感じのデータファイル(data.txtの一部です)を2次元配列にいれるにはどうプログラミングすればいいですか? 改行とかスペースをどう考慮していけばいいかさっぱりです
647 :
デフォルトの名無しさん :2008/01/08(火) 01:10:12
>>645 for(i = 0; !feof(fp); i++){
do{
fscanf(fp,"%d",&date[i][j++]);
}while(fgetc(fp) != '\n');
}
649 :
デフォルトの名無しさん :2008/01/08(火) 01:28:52
いやfscanfも普通に改行コード読み飛ばすし
650 :
デフォルトの名無しさん :2008/01/08(火) 02:15:50
今年からやさしいCを買ってはじめたんだけどscanfがでてきてからいっきに面白くなってきやがったぜ!
653 :
デフォルトの名無しさん :2008/01/08(火) 03:36:40
ほとんど利用しない命令
654 :
デフォルトの名無しさん :2008/01/08(火) 03:46:36
>>652 面白くなってきたのか!!
良いことだ!!
ただ油断するなよ。
scanfの仕様をもう一度確かめるんだ!!
不具合が多くて嫌になるぜ!!
>>653 ほとんど使わないのかよ!
>>653 printfとかだとなんか字がでてくるだけでつまらなかったけど
scanfだとキーボード側から入力できて面白くなってきたぜ
しかし練習問題やったら、doubleなのに変換仕様を%fにしてたり
変数の前に&入れてなかったりとミス多発\(^o^)/
質問スレなのにすいません
>>655 scanfは正しい入力をしているならまだいいが、ひとたび間違った入力が来ると簡単にバグの原因になる。
整数(%d)を欲しいところで文字列なんて打っちゃった日にはもう・・・
まぁ外に出すようなものじゃなければ気にしなくてもいいけどね。
慣れてきたらそこらへんも勉強してみるといいと思うよ。
!feof(fp) だろ。それじゃ4バイトも無駄になる。
とりあえず、入力と出力ができるようになってからいろいろ試せるんだし scanfから入るのもいいんじゃない?そのうち使わなくなるだけで
>>658 どこでどんな4バイトが無駄になるんですか?
>>656 それは返り値でなんとかなるだろ
いやscanfで値取得がだめなのはもちろんなんだがな、オーバーフローは検知不可能できないし
そもそも
>>658 は誰宛なんだよwww
>>661 >オーバーフローは検知不可能できないし
検知できるんですか? できないんですか?
そもそも、その「オーバーフロー」とはなんのことですか?
知らない言葉が出てきたら自分で調べる癖つけないといつまでたっても上達せんよ
>>662 オーバーフローとは
風呂にお湯を張るとき、止めるのを忘れたときに起こる奴
エウレカ!エウレカ!
666 :
662 :2008/01/08(火) 14:57:16
>>663 「オーバーフロー」の意味は判るのですが、整数値の入力でどんなオーバーフローが起きるのかと思いまして。
intの最大値は(4バイトの場合)2147483647でこれ以上大きい数値は格納できない。 longもunsignd intもcharもそれぞれに最大・最小値があるから、それを超える値を入力されると困る。
char *foo[] = {"C/C++", "は", "市ね"}; のような文字列の配列があった場合に、この配列の長さ(上の例では3)を 取得するにはどのようにすればできるでしょうか? length のような関数があるのではないかと思うのですが、、、
sizeof(foo)/sizeof(*foo)
670 :
662 :2008/01/08(火) 15:49:00
>>667 なるほど。で、それは検知不可能なんですね?
では検知できる入力関数はあるのでしょうか。
或いは、桁数制限してしまえばオーバフローは回避できますよね。
getsとかで数字を文字列として読み込んで、atoiとかで文字列を数字に変換する、とか。 文字列としてならいくらでも大きい数値を入れられるし、atoiはオーバーフローを検知してくれる。
んだ。今度はバッファオーバーフローだな。
scanfでも桁数制限できるだろ
>>650 if(!num) はif(num == 0)と
if(num) はif(num != 0)と同じ意味
while(!feof(fp))はfeofの返り値が0になるまでって意味
ごめん feofの返り値が0の間
>>671 果てしなく無意味なオーバーフロー対策だなwwwwwwwww
プロンプトで入力待ちするプログラムなんて練習のときくらいしか使わんからなんでもいいべ リダイレクト前提のやつはこの限りでもないが。
for(i=0; i < 10; i++){ printf("%d %d\n",x++,x); } だと表示される値は2つとも一緒なのに printf("%d %d\n",x,x++); に変えるとなぜ左側のほうが大きくなるのでしょうか? 後ろに++を付けているのだから右側が大きくなるべきだと思うのですが
なんだべきって
>>680 それ未定義動作
まあ理由としては、引数は後ろからスタックに積むから後ろの式を先に評価するケースが多いからだろうな。
>>681 「べき」って使いませんか?
「大きくならなければならないと思うのですが」というニュアンスです。
>>682 素早い回答有り難うございます。
681は日本語を勉強するべきだろう。
SEになりたくて、IT企業に就職しても、 途中で挫折する人がいて退職する人も多々いると聞きます。 そう言われてる箇所は、だいたいどういう箇所なのか 具体的に教えてくれませんか?
人間関係
UNIX Cシェルのmakefileで、 外部の環境変数が設定してあるファイルを makefileの中から読み込むことって出来ますか? 出来るなら方法を教えてください。
さすがにそれはシェルスクリプトのスレかmakeのスレで聞いた方がよくね
>>689 ありがとうです
makeスレがないですね
シェルはあまり関係なさそうだし・・
うーん。どこがいいんだろ・・
691 :
688 :2008/01/08(火) 20:38:44
それっぽいスレ見つけました そちらで聞いてみます。どうもありがとうでした。
fopenの書き込みモードで第1引数(?)にC:\save.txtのように入れたのですが、指定したフォルダを探してもファイルがありませんでした。 エラーは出なかったのでおかしいと思って、読み込みモードで同じフォルダを指定すると読み込むことができました。 あれ?と思いそのフォルダを開いてみたのですが、ファイルは見当たりませんでした。 これはどういうことなんでしょうか?
え?ファイルが無いのに読み込めたの?
>>693 ありがとうございます!
ファイルを保存できました。
>>694 そうなんです
これはなぜだったんでしょうか?
>>695 書き込みモードで起動したときにファイルを作成したと思う。
>>692 別のフォルダでsave.txtというファイルをまず作ってくれ
それをお前さんが指定したフォルダにコピーできるか試してみてくれ
あと使っているOS教えてくれ
見えないというのはGUIを使っているということでいいのか?
>>697 コピーできました。
OSはWindowsXPです。
GUIです。
D:\save.txtで書き込むとちゃんとファイルが出来ました。
指定したフォルダはCの中にあり、その奥に既にsave.txtがあったのが問題だったのでしょうか?
勝手に探してくれたということだと思うのですが。
上のほうでfeof()で終了判定してるやつがいるけど、どこの素人だよ。 fscanf()がEOFを返したときに終了するのが普通。
>>698 何も解決にならないでこんなこというのもなんだが
画面に絵とかファイル名とかが表示されてないだけで実際はファイルが生成される現象かな
Windows使ってる友人から以前聞いたことある
ブラウザからテキストの内容を見ることできると言っていたかな
力になれなくてすまん
feof()の仕様って欠陥だろ。 なんでこんな使いどころのない関数があるんだよって感じ。
エラー時に、ファイル終端に到達したのか エラーが発生したのかチェックするために使うんじゃね。
バイナリファイルはfeofで、特に他では使うなとか聞いたな
読み込みエラーが発生して、ずっとエラーから復帰できなかったら、 永遠にファイル終端に達しないから、エラーチェックしないと feof は危険。 しかし、そのエラーチェックでファイル終端も分かるから・・・。
feofが単独で存在するのは読まずにチェックすることがあるからで、 読んでるのなら使うことはないな。
まあ、読まないとEOFフラグセットされないわけだが
0バイトのファイルを開いた直後の状態でもEOFではないでしょうか?
ではない
別に読むのがライブラリで自分が読まないケースだってあるんだよ
>645 は1行あたりのデータ数がまちまちなんだが、そもそも >2次元配列にいれる っていうルールはどんなんだ?
連投嫌われる? 聞きたい事いいいいっぱいあるです・・・。
重要度の高い順に少しずつ質問すればいいと思うよ。
715 :
713 :2008/01/10(木) 02:57:50
じゃぁひとつだけ>< ソケット通信用のIOを得たときや、 open などのシステムコールを使って ファイルディスクリプタを得た時など、 これらのリソースが正数型で返されますが、 この返り値は単なる確保したIOリソース用の 管理用番号みたいなモノと考えて良いのでしょうか? また、もしそうならば、同一の正数値を指定さえすれば、 同じリソースに対して操作が可能なのでしょうか?
>>715 open()の度に更新されるから、無理。勿論、close()しない限りは変わらないが。
# 例外は、stdin, stdout, stderr, stdaux相当のディスクリプタ。
>>716 さん
レスありがとうございます!
>open()の度に更新されるから、無理。
これに関してはもちろんわかっています。
ただ、返り値自体がどの範囲でどういった形で、
有効なのかが解らなかったもので…。
(IOを得るのにポインタとかで操作しないのかなー?と思ったのです。)
同じプロセス上から同じ値で参照した場合。
という意味で書きました。解りにくくてすみません…。
でも
>勿論、close()しない限りは変わらないが。
ということは715は合ってると考えていいですよね?
># 例外は、stdin, stdout, stderr, stdaux相当のディスクリプタ。
参考になります!
訂正です。 誤:ということは715は合ってると考えていいですよね? 正:ということはclose()しない限りは715は合ってると考えていいですよね? 結果的に連投になってしまいましたすみません><
>>718 同じプロセス上でopenしたままの記述子なら同じ。
というかそうじゃないと全てのIOが出来ない。
char array[256]; と宣言したら sizeof(array); で256が返ると思います。でも、 void print_arraysize(char *array) { printf("%d",sizeof(array)); } というようにするとポインタのサイズが返ります。 呼び出される関数側から配列のサイズを知る方法はありますか?
>>720 Cでは無理です。諦めて、その関数にサイズも渡すしかありません。
>>720 構造体の中に配列入れて構造体を引数にすれば、関数に配列を渡せる。
ただ、関数を呼ぶときに構造体の中身の全コピーが作られるので、激しく無駄。
配列の要素数を1つ多めに作っておいて、そこに目印となる値を入れておいて、
関数側で数えるという手もある。
けど結局はfunction( array , sizeof(array) )のようにして呼び出す
関数を作るのが一番かと。
723 :
デフォルトの名無しさん :2008/01/10(木) 13:52:06
自然数n = 10, r = 0, 1, . . . , 10 に対してnCr を出力するプログラムを教えてください。もしくはそれが載ってるサイトを教えてくださいm(__)m
くだらない質問なのですが Cで static int hoge; int static hoge; の違いって、前者が大域変数になって 後者が関数内で静的な、値を保持しつづける関数になるってことですか?
違う。 staticのような修飾子と型名は順不同というだけ。
>static int hoge; >int static hoge; その2つは一緒 >前者が大域変数になって >後者が関数内で静的な それは宣言する場所で変わる 関数の外で宣言すれば大域 関数の中で宣言すれば関数内のみ
関数内でも大域にならない?
寿命はそうだがスコープは地が宇部
なんで意味合いの違うものに両方staticなんて割り当てたんだろうな。 ファイルローカルはexternに対してinternalとかにすりゃよかったのに。
C++では無名名前空間で対処したな。
>>725 ですが
ちょいとまだ把握できてないです
void main(){
int hoge[400000];だとアウトで
static int hoge[400000]; だと領域が確保できて
…
}
教えてくれた人が「static使うと、たくさん取れるよ」と言ってくれたので調べたのですが
どうもそういうことが見当たらなくて「静的な」とか。
上のような使い方は間違ってますか
それは、static つけないとスタック領域を使うし、 スタック領域は他と比べるとかなり小さいから。 まあ恒久的なプログラムじゃなくて、一時的な使い捨てプログラムのときはそうやることもある。
つまり、staticつけると 大域変数と同じところのメモリ領域を使うということですか。
そゆこと
了解しました!
>>733 メモリ制限厳しい組込みとかだと普通にやるよ。
まぁでもソコまでだと、外部変数のバッファを使いまわしてチューニングする方が多いかも。
そんなんやりたく無いんだけどね・・・ハードコスト削減には勝てんわ。
音声出力のソースを作っています。 以下のソースで、ファイルは出力されるのですが、音声が出てきません。 どこを修正すればよいか教えていただけませんか? #include <stdio.h> #include <stdlib.h> #include <math.h> #define SIZE 22050*5 #define OFFSET 23 int main(int argc,char *argv[]) { FILE *fp; short int inbuf[SIZE]; short int outbuf[SIZE]; int i,f,f0,amp,PI; f = 440; f0 = 11050; amp = 5000; if((fp = fopen("test-sound-16-22.wav", "rb")) == NULL ) { printf("ファイルオープンエラー\n"); exit(EXIT_FAILURE); }
続き fread(inbuf, sizeof(short int), SIZE, fp); fclose(fp); for (i=OFFSET; i<200; i++) printf("%d, ",inbuf[i]); printf("\n"); for (i=0; i<OFFSET; i++) outbuf[i]=inbuf[i]; for (i=0; i<(SIZE-OFFSET); i++){ outbuf[i+OFFSET] = amp * sin(2*PI*i*(f/f0)); } for (i=(SIZE-OFFSET); i<SIZE; i++) outbuf[i]=0; if((fp = fopen("testfile2.wav", "wb")) == NULL ) { printf("ファイルオープンエラー\n"); exit(EXIT_FAILURE); } fwrite(outbuf, sizeof(short int), SIZE, fp); fclose(fp); return 0; }
>>738 音声を出力するところがどこにもないじゃん。
出力された音声はどんなふうになってる? あとsin()の中intになってないか?
音声→音声ファイルね
>>738 PIの初期化してないじゃん。ちゃんとデバッグしてんの?
そーだ、それも書くの忘れてたw
745 :
738 :2008/01/12(土) 13:29:36
これとほぼ同様のソースで、2倍の周波数(以下のソース)で出力するものは、 きちんと出力されて、音声も出ています。 正弦波の合成はなぜか出来ない・・・ >> 740 音声ファイルを出力するところがないとは?音声ファイルは出力されていますが・・・ >> 741 出力された音声ファイルは何も発音がありません。 ファイルのサイズはきちんとあるので、データは自体は出力されていると思うのですが・・・ for (i=0; i<(SIZE-OFFSET)/2; i++) { outbuf[i+OFFSET]=inbuf[i*2+OFFSET]; } for (i=(SIZE-OFFSET)/2; i<SIZE; i++) outbuf[i]=0;
math.hにPIが定義してあるのかとおもったが、そうでもないな
とりあえずPIの定義と、sin()の2を2.0にしてみ
何も言わずにコピペだとマルチうぜーとか言われそうなもんだけど、ここの住人は優しいんだな
>>745 デバッガで変数の値見ながら実行すればすぐに分かりそうなもんだけど。
750 :
738 :2008/01/12(土) 14:09:29
解決できました。皆さんありがとうございます。
構造体で 氏名 年齢 住所 が入る変数を宣言しその構造体の配列を10人分用意しループで順番に入力してもらい氏名、住所、年齢に 空ENTERが入るとループを終了するということをしたいのですが。 全ての項目に空ENTERが入力されるとループを終了するという所をどのように書けばいいのかわかりません。 教えて下さい。
>>751 空ENTERが入力されたかどうか判別するプログラムは作れるのか?
>>751 氏名をfgets関数で入力し、strlen関数で氏名の文字数を求め、それがゼロだったら終了
fgetsってファイル関連の関数じゃないの? 文字入力として使えるの?
えー
printf()とかputs()とかscanf()とか全部廃止して、f****()に統一すりゃいいのに。 ストリームの概念が理解しやすくなる。
f***()とか全部廃止してopen/close/read/writeにすれば良いのに。 ディスクリプタの概念が理解しやすくなる。
もう開く/閉じる/書く/読むでいいよ。
それなんてinterface?
LISP だと以下のようにして定義できるが (defun 開く (file-name mode &optional perm) ...) (defun 閉じる (file-desc) ...) (defun 書く (file-desc buff buff-size) ...) (defun 読む (file-desc buff buff-size) ...) まぁ, スレ違いだわな
スレ違いに値しますが、どなたかtabキー送り幅の設定方法を教えて下さい 8マスから4マスに変えたいです
>>762 環境による。また、アプリケーションの設定にもよる。
スレ違いすぎるwww エディタによる、いやそもそもエディタの話なのかも知らんが
それは表示する側の問題だろ。Cの範疇じゃ無理。 使ってるOSと端末くらい書け。
766 :
デフォルトの名無しさん :2008/01/14(月) 00:21:01
教えてください int main(void) { char *c1; { char *c2; c1 = StoA(1000); c2 = StoA(2000); printf("c1 : %d\n", c1); printf("c2 : %d\n", c2); } return 0; } このプログラムを実行すると、 なぜかc1の値がc2の値と同じになってしまします。 なぜなのか教えてください。
767 :
デフォルトの名無しさん :2008/01/14(月) 00:22:24
***追記*** ちなみにStoA関数は数値を文字列に変換する関数です。
StoAって何だよ
StoAの中身書いてないわろた
どうみてもStoAが悪いだろw
どうみてもStoAが悪い。 あと >printf("c1 : %d\n", c1); >printf("c2 : %d\n", c2); %sちゃうのか? で、同じ数値になるってところからサイコメトリーすると、 グローバル変数かローカル変数辺りの配列のポインタを返してると見た。 コール時にバッファ渡すか、StoAでmallocしてmainでfreeするかしたまい。 StoAを作るのが目的でないならsprintfかitoaでも使え。(個人的にはsprintf) 最後に、C言語で数値を文字列に変換する関数は「ItoA」か「ItoS」な。 StoAだと何してんだか訳分からん。
772 :
デフォルトの名無しさん :2008/01/14(月) 00:42:07
すんません%sでした"汗 StoAはshort型からアスキーコードに変換する関数です。 int main(void) { char *c; c = StoA(123); printf("%s\n", c); return 0; } だと正常に動きます。
773 :
デフォルトの名無しさん :2008/01/14(月) 00:44:08
mainの中にあたらしいブロックを作ってその中で*c1をつかうのがなんかしらダメなんじゃないかなと思うんですが。 作るのが目的ではなくてなぜこうなるのか説明するのが目的なのでよろしくおねがいします。
いいからStoAの内容書けよ
>>772 んなこた良いからさっさとStoAのソースを貼れwww
StoAのソースコードは守秘義務の関係上公の場に貼ることは出来ません。 無茶な要求をしないでください。もう少し常識をわきまえて。
じゃあ分かりません帰ってください
説明するのが目的なのか、説明してもらうのが目的なのかはっきりして欲しいな
779 :
デフォルトの名無しさん :2008/01/14(月) 00:51:35
>>776 その通りです。
ありがとうございます。
>>778 説明するのが目的なので分かりやすく説明してもらえると光栄です。
とりあえず、StoAのソースを貼る気がないのなら終了で。
>>779 c1 = StoA(1000);
c2 = StoA(2000);
printf("c1 : %s\n", c1);
printf("c2 : %s\n", c2);
↑で同じ値が出るんだろ?多分両方2000か?
c1 = StoA(1000);
printf("c1 : %s\n", c1);
c2 = StoA(2000);
printf("c2 : %s\n", c2);
これで同じになるか試してみ。
違う値になるようなら、多分StoAがstatic変数かグローバル変数のバッファ使ってる。
printf("%p, %p\n", c1, c2);
で同じ値が出てくるはず。
そうじゃなきゃ、自分でデバッグしてくれ。
ソース無しじゃお手上げ。
782 :
デフォルトの名無しさん :2008/01/14(月) 01:14:31
正直いいますと今手元にソースが無いのでかけませんが、覚えてる範囲で流れを書きます。 処理@ 引数の桁数を調べる (引数が12345ならiDigに10000を入れておく) 処理A pStrにcStrのアドレスを入れて 数値を文字コードに変換して*pStrに格納。 処理B結果をかえす。 ちなみにcStrはstatic変数です。 わかりにくくてすいません"汗
StoAがわかったら説明してやんよ
そら二回目の呼び出しで cStr の内容を上書きしてるから 同じのが表示されるの当たり前でんがな。 バッファをローカルで持って、引数で渡すといいよ。
ある時間,たとえば10時20分50秒になったらAの動作を行うというプログラムはどう作れば良いですか ひとつの方法としてtimeを使って,現在の時間を取得し続け時間になれば動作する方法 これだとずっと時間を取得し続けるので,良くないような気がするので・・・ ちなみに環境はFedora,gccです.
cron に投げれば
sleep(指定時間-現在の時刻) すりゃいいだろ。 ま、ふつーにcron使えと。
本人の振りしてあおるのもうやめろよwwwみんな耐性ついてるんだしwwwww
>>786 ありがとうございます.ちょっと調べましたがcronは使えそうです.
あとは,外部から動作する時間の変更が行われるので,それが出来るか調べて見ます.
自分のプログラムだけで実現できると一番良いですが・・・
sleepの方法も考えましたが,時間の変更を行うことがあるので実現しにくいと思いやめました やはりcronを使わないとしたらこの2つですかね
コンソールアプリケーションの画面を何も表示されていない真っ黒の画面に 戻したいんですが方法を教えてください。
792 :
785 :2008/01/14(月) 02:04:17
cron調べましたが使えそうです ありがとうございました
OSに依存する
>>791 winだったら、system("CLS");
>>791 win以外ではエスケープシーケンスとか
clearコマンドが使える場合もあるけど、鼬害。
sysytem("cls")だとちらつきがひどいんですが ちらつかないようにって可能なんでしょうか。 もし可能であるならばどうやればいいのでしょうか。
ちらつきって コンソールでゲームでもつくってんのか?
エスケープシーケンスなりCursesなりコンソールAPIなり好きなの使っとけ 細かい制御が必要なら環境かけっつうの
ちょっとしたゲームをつくっています。 環境はWinです。 同じ文字列が右から左に移動していき左端にきた文字は消えていくというのをしてるのですが おもったようにちらつきを消すことができまちぇん。。
>>801 消さずに上書き。
変化の無い部分は書き換えない。
う、うわがき・・・ 上書きってどう書けばいいのかわかりません。。。。 ちょっとした例示してもらえませんか?
消したい文字列と同じ座標にスペースか何かで上書きするとか
//
>>801 #include <stdio.h>
#include <string.h>
void func(int width, const char * str)
{
int len = strlen(str);
for (int ic = 0; ic <= len; ++ic) {
printf("\r%*.*s", width, ic, str);
fflush(stdout);
sleep(1);
}
for (int ic = 0; ic < width; ++ic) {
printf("\r%*s%*s", width - 1 - ic,
ic < width - len ? str : str + ic + 1 - width + len,
ic + 1, "");
fflush(stdout);
sleep(1);
}
}
int main()
{
func(20, "abcde");
return 0;
}
int main(int argc, char **argv){ FILE *fp; int i, j, a, b; short int image[HEIFGT][WIDTH]; 上のプログラムを一行ずつ何をしてるんですか? a = atoi(*argv[1]); b = atoi(*argv[2]);
807 :
806 :2008/01/14(月) 12:42:21
あと下の a = atoi(*argv[1]); b = atoi(*argv[2]); も教えてください
Windowsでもcurses使えるんだっけか?
>>807 プログラムの起動時に渡されたコマンドラインの引数を、数値に変換してるんだけど、それだとバグっていて動かないね。
806の日本語がバグっとる
変換前:This 変換後:hisTay 変換前:is 変換後:siay 以下のコードで上のように出力して欲しいのですが上手くいきません 何故でしょうか? int main() { int i; char s[256] = "This is a pen", *word; word = strtok(s, " "); printLatinWord(word); word = strtok(NULL, " "); // wordに"ay"が入る。何で? printLatinWord(word); return 0; } void printLatinWord(char *word) { char *alp; /* 通俗ラテン語風に変換して出力 ※先頭の文字を末尾に移し、その後ろにayを付加する。 */ printf("変換前 : %s\n", word); strncpy(alp, word, 1); alp[1] = '\0'; strcat(word, alp); strcat(word, "ay"); printf("変換後 : %s\n", &word[1]);\ }
>>812 char *alp;
ポインタにぶちこむな
char alp[1000];
的な感じにしないと
>>812 strtokは、与えた文字列(この場合s)の中を書き換えながら、そこを指すポインタを直接返す。
たとえば、"This is a pen" を与えると、strtokは最初
"This\0is a pen"
↑
ここを返す。文字列は\0で終わる決まりなので、"This"が得られる。2回目は
"This\0is\0a pen"
↑
ここを返す。"is"が得られる。3回目は
"This\0is\0a\0pen"
↑
ここを返す。"a"が得られる。
こういう動作なので、帰ってきた文字列に直接strcatで追加すると、
後ろの文字列(=次に返される文字列)が書き換わってしまう。
つまり、そのprintLatinWordを実行すると、sの中は
"ThisTay\0a pen"
のように書き換わり、次にstrtokが返すはずだった "is" は "ay" になってしまう。
815 :
812 :2008/01/14(月) 16:42:27
>>813 なんとなく*alpになってしまいました
まだ違いが良く分かってないので頑張って勉強します
>>814 wordを書き換えるとsも変わってしまうんですね。なるほど
丁寧にどうもです
*wordをword[256]に、word = strtok(s, " ");をstrcpy(word, strtok(s, " "))に直して上手くいきました
大学の課題で一部分からない点があるので、よろしければヒントをお願いします。 #include<stdio.h> #define MAX 10 int inputnum(int num[]){ int i; for(i=0;i<MAX;i++){ scanf("%d",num[i]); } return num[]; } int main (void){・・・・・・と続くのですが、 上記のサブ?ルーチンに表記の間違いがある場合、修正せよという問題です。 ですが配列の返し方など全て自習ということでここで止まってます…。 構文にエラーがあるというところまで分かっているのですが、 どうすえればいいか分かりません。ご教授願います。 orz
817 :
816 :2008/01/14(月) 16:56:30
For文が見にくくなってしまいすいません…。 よろしくお願いします。
void inputnum(int num[]) { int i; for(i=0; i<MAX; i++) scanf("%d", num + i); }
>>816 return 0;とでもしておけ
返さなくても渡された中身は書き換わってる
なんでかはポインタについて勉強せんと・・
scanf("%d", &num[i]); もでした
821 :
816 :2008/01/14(月) 17:17:55
int inputnum(int num[], size_t num_size) { int i; for(i=0; i<num_size; i++) if(scanf("%d", &num[i]) != 1) return 0; return 1; }
823 :
816 :2008/01/14(月) 17:58:20
>>822 すみません、「size_t num_size」とは何でしょうか?
また戻り値がどこの変数へ戻るのか分かりません…。
また1つ分からない事があるのでどなたかご教授お願いします orz
サイズを指定せずに配列を作る事は可能でしょうか?
int num[];
//これでは要素が無いためサイズが0であるのでできないということまで
分かりましたがそれ以上で詰まっています。
よろしくお願いします。
>>823 size_tは型。たぶんunsigned intと同じである環境が多いのかな?
要は自然数用型とか思っとけばとりあえずOK。(サイズにマイナスはないからね)
戻り値がどこに入るかは呼び出し側次第。
int func( void )という関数があったとして
main内で「int a = func( );」 としてればfunc内の戻り値がa内に入る。
>>823 サイズを指定しない配列は無理
malloc系を使えば好きな大きさで確保したり、大きさ変えたりはできるけど
char s[] = "もけあ"; とかはできるけどそれは宣言のときだけね
827 :
816 :2008/01/14(月) 18:32:46
>>824 詳しくありがとうございます。
int inputnum(int num[], size_t num_size)
メインルーチンの方で上の2つの変数の値を指定すればいいということですね。
>>825-826 明確にありがとうございます。
入力する回数を予め決めるか、
要素次第ということですね。大変参考になりました。
皆さんありがとうございました。
int func(int num){ return !(num%2); } 上記の関数でnumが奇数の場合と偶数の場合の戻り値はそれぞれどうなりますか? 有識者の方宜しくお願いします。
タメセカス
算数じゃん。
>>828 何がわからんのだ?%演算子か?!演算子か?
関数や戻り値がわかってるのならどっちかだろうな。
num = 2;
num % 2 == 0;
!0 == 1
num = 1;
num % 2 == 1;
!1 == 0;
こんなもんでわかるだろ。
ってか
>>829 で良かったかな。
自己顕示欲・・・
833 :
816 :2008/01/14(月) 21:14:46
すみません。また1つ疑問ができてしまいましたのでご教授お願いします… orz 配列inputのサイズ変数MAXをサブルーチンで決定したいのですが、 int MAX; void sub(int MAX){ scanf("%d",&MAX); } int main(void){ input[MAX]; ・ ・ ・ } とした時に、「sub(MAX);」をどこで定義すればいいのでしょうか? それともルーチンではできないでしょうか? よろしくお願いします orz
(^ん^)?
とりあえずC言語における「定義」の意味を調べなおした方が
日本語でおk MAXの値はどこでも変えられるけど? MAX = 4;とか好きにすれば? それとも配列のサイズ変えたいの?
837 :
816 :2008/01/14(月) 21:19:52
>>833 訂正です、すみません。
void sub(int MAX){
scanf("%d",&MAX);
}
int main(void){
int MAX, input[MAX];
・
・
・
}
838 :
816 :2008/01/14(月) 21:22:24
>>835 すみません、定義ではなく呼び出しでした。ご指摘ありがとうございます。
>>836 サイズを入力で指定したいのですが、そのプログラムはサブルーチンで記すことが条件です。
>>833 若干エスパー。
丸写しはどーかと思うけど、こういうことか?
void sub(int *MAX){
scanf("%d",&MAX);
}
int main(void){
int MAX;
int *input;
sub(&MAX);
/* int input_NG[MAX] <- これはムリ。配列の宣言では定数しか使えない */
input = malloc(MAX * sizeof(int));
・
・
・
free(input);
}
840 :
816 :2008/01/14(月) 21:37:44
>>839 ご回答ありがとうございます。
分かりづらくなってしまい申し訳ございません。
int MAX = 10;
int main(void){
int main[MAX];
・
・
・
このように、最初から数値を指定するのではなく、
MAXの値をscanf等の入力で毎回変更することはできませんか?
またできる場合、それをサブルーチンでまとめられますか?
イメージはこんな感じになります。
scanf("%d",&MAX);
int input[MAX];
何度もすみませんがよろしくお願いします。
>>840 一応そのイメージで839を書いたんだけど・・・。
要はmallocを使いたくない(or知らないので分からない)ってこと?
どうしても配列ってことであれば、おそらく分からないだろうけど
C89ならムリ。C99なら出来る。
つまりコンパイラによる。
例えば俺が知ってるうちではVCでは出来ない。gccは最近のであれば出来る。
842 :
816 :2008/01/14(月) 21:53:33
>>839 /* int input_NG[MAX] <- これはムリ。配列の宣言では定数しか使えない */
すみませんようやく意味が分かりました。
本当に詳しくありがとうございました。
843 :
816 :2008/01/14(月) 22:01:13
>>841 #include <stdlib.h>とセットでちらっとだけ見た事があるので
調べて分かれば使えると思いますが、分からないということでお願いします。
別のプログラムで指定した値をファイルに出力し、当プログラムで読み込むというような方法はあるのでしょうか?
>>843 とりあえずfopen辺りでファイルの入出力ができるよ(他にもあるけど)
それも分からないの?
845 :
816 :2008/01/14(月) 22:17:29
>>844 そこは以前にある程度習っているので復習すればできると思います。
ありがとうございます。
>>843 >調べて分かれば使えると思いますが、分からないということでお願いします。
お願いされてもwww
とりあえず十分に大きい固定サイズの配列を用意するか、
mallocを調べるのが良いと思うよ。
847 :
816 :2008/01/14(月) 22:34:59
>>846 >お願いw
すみません余計でした^^;
>固定サイズ
とても参考になりました。
0〜固定サイズまでで値を指定することならできそうです。
ありがとうございました。
時間があればmallocを扱えるようにしたいと思います。
質問。 ハッシュ法について勉強してるんだけど、格納されたデータ(学籍番号と氏名)を読み取る際に、学籍番号の数(生徒数)を読み取る部分的なプログラムが分かりません。 どういう構文使えばいいでしょうか? 読み込みはこんな感じです↓ /* データファイルの読み込み */ if ((fp=fopen("DATA","r"))==NULL){ printf("File \'DATA\' is not found !\n"); } while ( fscanf(fp, "%d %s", &data_zipcode, data_address) > 0 ) { printf("%d : %s\n", data_zipcode, data_address); /* データの格納 */ if ( StoreData(data_zipcode, data_address) == 0 ) { printf("Hash Table is full !\n"); } } fclose(fp);
>>848 ファイル内のデータの総数を知りたいなら、一回空読みすればよかろ。
つーか、それってハッシュ法と関連するのか?
>>849 ハッシュするための下準備。んで、出来ました。ありがとうございました。
if ((fp=fopen("DATA","r"))==NULL){ printf("File \'DATA\' is not found !\n"); } いっつも思うんだけどさ、これって何したいの? ファイルオープン失敗したまま処理続けるなよ
852 :
N :2008/01/15(火) 20:07:27
ナップザック問題を解説付きで教えてください。
>>851 その箇所だけならなんとも言えんだろーがw
#include <stdio.h> #include <stdlib.h> #define MAX_LINE 128 int main(void); int main(void) { char buf[MAX_LINE]; int n; printf("降水確率を入力してください。\n"); gets(buf); n = atoi(buf); ptintf("降水確率は %d %% です。\n", n); if (n >= 50){ printf("傘を忘れずにね。\n"); } else { printf("傘はいりません。\n"); } printf("いってらっしゃい。\n"); return(0); } /*これ↑のどこが悪いのか教えてください*/
gets(),ptintf,return(0);
ていうかなんでmain関数にもプロトタイプ宣言してんの?
>>852 ググった方が早いと思うよ。
検索ワードはナップザック・ナップサック・動的計画法とかで
アプレット使った図解解説ページがあったと思う。
C言語の質問というよりアルゴリズム全般、数学の方が分野としては近いと思う。
mainクソワロタwwwwwwwwwwwwwwww
>>854 >/*これ↑のどこが悪いのか教えてください*/
降水確率が40%でも傘を持たせない根性。
グレゴリウス暦の定義を利用して入力された日は何曜日か計算するにはどうしたらいいでしょうか?
>>860 適当な起算日からの日数を計算して7で割ったあまりを得よ。
typedef struct{ int data[100]; } test; int func(const test *x); int main{ test data; ... //省略 for(i=0; i<10000; ++i){ int temp; temp = ...; //省略。dataの要素を使ったなんかやたら複雑な計算 func(&data); printf("%d", temp); } return 0; } ちゃんとしたコンパイラなら、 funcの引数がconstポインタだからループ中でdataの値は変更されない、と解釈して 毎回やたら複雑な計算をするようなことはしないように最適化してくれますよね?
ちゃんとしたコンパイラがあればね。
ないんですか? たとえばVCとかgccではどうですか。
自分で確かめろ
いやgccもVCも持っていなくて…… アセンブラも読めないし
なら入手して確かめればいいじゃん。
constなんかキャストすればいくらでも外せるからな・・・最適化してしまうわけにはいかんような気がする
>>864 そんな保証はどこにも無いから素直にループの外に出しておけ。
自分の為だけなら好きにすりゃいいけど、他人が読むなら言いようの無い不安感
(このコードを書いた奴はまともな人間知性を持っているのか・・・他にも問題ありそうだな・・・)
を煽るだけだからやめておけ。
ループの中で毎回計算しないものを、ループに入れる神経がわからない。
>(このコードを書いた奴はまともな人間知性を持っているのか・・・他にも問題ありそうだな・・・) あるあるw
874 :
864 :2008/01/16(水) 20:11:05
要するに最適化してくれないということですね? ありがとうございます。 それと、「const*って最適化に使われているのかな」という疑問が唐突に湧いてきたので質問したものでして、 別にこのコードを実際に使うわけでもないのでいろいろとご安心ください。
一度計算した結果はまた同じになることが保証されてるのは関数型言語だけだからな。 Cは最悪裏でサブスレッドがなんかやってるかもしれないし最適化には限界がある。
>>874 const*自体は最適化のヒントに使われているよ。
ただ、>864のケースでは使ってないと思うけど。
txtファイルの中にある100を探し出してカウントするプログラムを書かないといけないのですが 100を見つけるたびに一つカウントしていくプログラムを組む場合どのような事をすればいいのでしょうか
char *sの中から100を検索するコードを書け それを一行に複数あっても見つかるように拡張しろ それを複数行に対応させろ いじょ
十分に大きな配列を用意 txtファイルを読み込む strstrでNULLがでるまで検索 検索した回数を数えればおk
ありがとうございます やってみます
でかい配列なんてイヤだっていうならこんな方法もある。 char buf[4] = {0}; int ch, cnt = 0; while((ch=fgetc(fp)) { buf[0] = buf[1]; buf[1] = buf[2]; buf[2] = ch; if(atoi(buf)==100) cnt++; }
while((ch=fgetc(fp))!=EOF)だった。
>>884 僕には「100」が含まれているように見えますが・・・?
buf[3]が常に'\0'であることに気付いてないのでしょう。
int filename; scanf("%d",&filename); fopen("filename.txt","w"); キーボードから任意のファイル名でファイル作りたいんだけど うまくいかないです。お願いします。
char filename[32]; scanf("%s", filename); fopen(filename, "w");
なぜintでいけると思ったんだよw
int fileNo; scanf("%d", & fileNo); char fileName[100]; sprintf(fileName, "file-%d.txt", fileNo);
894 :
884 :2008/01/17(木) 18:43:09
これがフルボッコというものかwww
エスパー解釈して数値が並んでいるテキストから
特定の数値の個数をカウントするんだと思ったんだが違うのか?
>>878 テキストに含まれる "100" という文字列の数を数えたかったの?
っていうかそんな問題ならfscanf()で数値を読めばいいだけで悩むこともないと思うが。
除算法を使ったハッシュ関数ってどうすればいいの? 一文字読み込むごとに割って余りを出してその余りを足していけばいいのかな? で最後まで読み込み終わったらまた割って余りを出すという感じか? 全く見当違いのことを書いていたらすまん。
>>898 それだ。
文章を読み込ませてハッシュ値を出したいんだが、
>>897 のような感じでいいのかな?
精度を気にしないならそれでいい
ありがとう。 一応考え方は間違っていないようで安心した。
>>861-863 ありがとうございます
とりあえず前年度までの総日数と現在の総日数を出せたたのですが
そこからどうしたらいいのでしょうか?
for文とか使うんですか?
1月と2月の計算に注意な
まず基準となる日の曜日がわかってないとだめだよw
だからそんなことしなくてもmktime()で教えてもらえばいいだろ。
それで最初の質問の用件、「グレゴリウス暦の定義を利用」したことになるのか?
>>902 1582年10月15日が金曜日だから、そこからの日数を7で割れば何曜日かわかるでしょ。
>>907 Cの標準関数がグレゴリウス暦の定義を利用していないとでも?
>>909 たとえそうでも、元の質問者の意図通りじゃないだろう
標準関数は1970年以降しか扱えない時点で グレゴリウス暦の定義を利用しているともしていないともいえない。
912 :
902 :2008/01/18(金) 20:21:50
とりあえずこんな感じの問題です 西暦1年1月は月曜日 1年は通常365日、閏年は366日 4で割り切れる年は閏年 400で割り切れる年は閏年 100で割り切れる年は閏年ではない 変数名関数名を作成 goto文は使用しない 関数途中でのreturnプログラム途中のexitはしない 外部関数は使用しない
>西暦1年1月は月曜日 意味不明。
西暦1年とかまで考えようとしたら、 途中暦を正すために何日かすっとばしたのも考慮に入れるのけ?
>>913 そうなんですか?
問題にはそう書いてあるのですが・・・
>>914 ありがとうございます
そっちでやってみます
>>918 おかげさまで解決できました。どうもありがとうございました。
920 :
デフォルトの名無しさん :2008/01/20(日) 18:03:14
C#厨です。C始めました。 #define A 1 #define B 2 int main(){ int i = A + B; int j = A + B; int hoge[i][j]; } で 新規テキスト ドキュメント.c 新規テキスト ドキュメント.c(7) : error C2057: 定数式が必要です。 新規テキスト ドキュメント.c(7) : error C2466: サイズが 0 の配列を割り当てまたは 宣言しようとしました。 新規テキスト ドキュメント.c(7) : error C2057: 定数式が必要です。 新規テキスト ドキュメント.c(7) : error C2466: サイズが 0 の配列を割り当てまたは 宣言しようとしました。 新規テキスト ドキュメント.c(7) : error C2087: 'hoge' : 添字がありません。 新規テキスト ドキュメント.c(7) : error C2133: 'hoge' : サイズが不明です。 です。どうしたらいいでしょうか?
C言語は変数を用いて配列の宣言はできひんのよ
1. C++コンパイラの力を借りる。 拡張子cppにして、こういう風に書く const int i = A + B; const int j = A + B; int hoge[i][j]; 2. プリプロセッサの力を借りる。 #define i (A + B) #define j (A + B) 本当に実行時まで変数の値がわからない時の話はまた今度。 お前の見ている本やWebサイトを読み進めていれば、その内出てくるだろうし。
923 :
デフォルトの名無しさん :2008/01/20(日) 18:17:55
>>921 なぬぅ!なんて使えない糞言語!
ユーザーの入力.etcによって必要なだけ配列を確保するにはどしたらいいん?
ポインタはいいとして(C#にもあるし)、プロトタイプ宣言とか、変数の宣言はブロックの先頭とか、
面倒な決まりが多いぜ…orz
その例で無理矢理実現するなら。 #define A 1 #define B 2 #define i (A+B) #define j (A+B) int main(){ int hoge[i][j]; }
C++ の std::vector 使った方が
まさに高級言語により生まれたゆとり世代。
929 :
デフォルトの名無しさん :2008/01/20(日) 18:22:06
>>922 いあ、C#で書いた迷路の生成プログラムを移植してて、
コマンドライン引数で指定した迷路のサイズによって
2次元配列のサイズを変えたいのね。
コンパイラはVC++EEのコマンドライン使ってるのでC++のコードもおkだけど
出来ればCの範囲でやりたいでふ。
malloc 一択。 演算子のオーバーロードとかないから、 何かアクセス関数作っとけ。
932 :
925 :2008/01/20(日) 18:23:14
(´・ω・`)
あらかじめ最大サイズを決めておくという手もなくはない。 エレガントではないが。
gccで-std=c99使えばいいよ。 後の規格改定で、変数宣言の位置の縛りもなくなったし、 配列の要素数に変数が使えるようにもなった。 が、しかし、需要がなくてVisual C++は対応していない。
935 :
920 :2008/01/20(日) 18:33:38
>>935 フリーを忘れないようには
どうするといいかってのを
考えながらくむのも
おもしろいもんだよ
>>935 プログラムが終了すればおk
C#のunsafeとほぼ一緒だと思うけど
938 :
920 :2008/01/20(日) 19:09:27
>>936 {書いたら直ぐに
}書いて、その間にコードを書くみたいに
麻呂したら直ぐにフリーして間にコード書いちゃ駄目?
>>937 よかた。ちゃっちゃいプログラムなら大事にはならなさそうね。
いやいやいやいや、 終了すれば大丈夫だからって 放置する癖は付けない方がいいぞ
940 :
920 :2008/01/20(日) 19:22:43
>>939 それはだいぢょぶ。
ただ、びくびくしながら書いてたら上達しにくい気がするから心配だっただけ。
もひとつ質問していいかな。
int main(){
int hoge[10][10];
hoge[10][10] = 100;
poke(hoge);
return 0;
}
int poke(int *moge){
return *moge[10][10];
}
って平気?一次元だと出来たんだけど。
試してもいいかなぁ?
mallocを麻呂って書くヤツはカス。
>>935 大丈夫。VC++みたいなのが世の中の多数派。使う人間、誰もいないし。
たとえ解放し忘れても、プログラムが終了すればWindowsが丸ごと解放する。
あと、マネージドなプログラムで何やってもプログラムが落ちるだけというなら、
アンマネージドなCのプログラムだって、
何やってもプログラムが落っこちるだけで済むと言える。
9xのWindowsでもない限り。
>>940 そもそもhoge[10][10]の参照はまずくないか
mallocってなんて読むの? えむあろっく かと思ってるんだけど
>>944 宗教論争みたいになっちゃうけど人間関係に問題が起きない範囲で好きに読めばいいと思う。
俺は普段はまろっくって読んでる
ネイティブはマロックって言うらしい ソースは俺
まろっくって読んでるけど個人でやってるから口に出した事ないな プログラマだと口に出して言うことあるのか?
動的確保!って叫んでる
普段はC++だから口に出して言ったことは無いな
ちゃーだと最近のクソ芸人のギャグまでひっかかる
>>940 平気じゃない。
2次元配列を1次元配列にマップしたときのインデックスを計算汁。
int hoge[10][10]; 配列の最後は hoge[9][9]; よってオタワ
int poke(int (*moge)[10]){ return moge[9][9]; } こういうのならいいんでしょうか・・?
int poke(int moge[][]){ } って感じにできなかったっけか?
957 :
920 :2008/01/20(日) 23:16:34
>>952 でけた。THX
でも、こんなの読めないよ…。
hoge[2番目の長さ * 1番目の添え字 + 2番目の添え字]
が
hoge[1番目の添え字][2番目の添え字]
と同じだなんて気付きようがないぬ
もっと可読性が高い書き方はないかにょ…。
>>955 最低でも int poke(int moge[][N]) の N が必要
962 :
デフォルトの名無しさん :2008/01/21(月) 00:49:55
マルチ乙としかいいようがないな
ざっと見てみたけど自意識過剰サイトでわろた しかもテキストごときに8000円とか誰もひっかからんだろwww
在学中に情報系の国家試験である、基本情報処理技術者、ソフトウエア開発を取得 極普通じゃねーかwwwww
ばかじゃねーの 8800円あったら専門書買うわーバーカ
構造体の初期化で教えてください。 (1) struct Type x = {.var = NULL}; (2) struct Type *x; x = (struct Type *) malloc(sizeof(struct Type)); x->var = NULL; (3) struct Type *x; x->var = NULL; とあって、(1), (2) だと問題ないのですが、 (3) だと segmentation fault になってしまいます。 どういう理屈からでしょうか? また、構造体を 「*変数名」で宣言したときは、最初に値を設定するときに、 必ず malloc をしてからでないといけないのでしょうか? よろしくお願いします。
ポインタってのはどこかの実態をポイントしてなきゃアクセスできるわけがねぇ
xはその構造体の型へのポインタだから
>>967 ポインタがなんなのかまったく理解できてない
struct Type *x;
で用意されるのは構造体struct Type がどこにあるかを表す変数だけ
構造体の本体はない
mallocでそれを用意してやってる
long と long int は何が違うんでしょうか
いっしょです
タイプ数
音声を出力するにはどうすればいいのかな?
環境書け
センサーがあるのでそれで感知をした時に 音声を出力するプログラムを作るにはどうすればいいですか?
センサーの入力を監視する部分と、音声を出力する部分を作ればいける
音声の出力する部分を作るには どうすればどのようなプログラミングを作ればいいですか?
Cの標準機能じゃ無理だからOSとかコンパイラとかを書かないと答えようがない
センサーって、組み込み? それなら、周辺回路によるけどどこかのポートをパタパタ。
>>978 window.hをインクルードしてBeep関数使えば鳴らせるよ
985 :
デフォルトの名無しさん :2008/01/23(水) 01:32:38
初歩の初歩の質問で恐縮なんですが fgetc(fp)とすると、その次のfgetc(fp)では次の1バイトが取得されます。 これを、何度取得しても同じバイトが取得されるようにできないでしょうか? 具体的には、 char c1; char c2; FILE *fp; ...ファイルオープン... c1 = fgetc(fp); fseek(fp, -1, SEEK_CUR); c2 = fgetc(fp); とすると、c1とc2に同じ文字が代入されると思うのですが、fseekを使わなくても、 c1 = fgetc_noFoward(fp); c2 = fgetc_noFoward(fp); として、c1とc2に同じ文字が代入されるようにしたいです。 fseekを使うか、 c1 = fgetc(fp); ungetc(c1, fp); c2 = fgetc(fp); とungetcを使うしかないでしょうか?? ファイルの中の位置を変えない文字取得関数ってないのかな。。。
>>985 c1 = fgetc(fp);
c2 = c1;
>>985 fseek()やungetc()を入れたって、ソースが1行増えるだけで何の不都合
もないと思うんだが。行が増えるのが嫌だったら関数化すればいいのだし。
あらかじめファイルの中身をメモリに置いておけば、いくらでも読み直
せるよ。
>>985 意図が読めない。
int fgetc_noFoward(FILE *fp)
{
int i;
i = fgetc(fp);
fseek(fp, -1, SEEK_CUR);
return i;
}
989 :
985 :2008/01/23(水) 02:48:00
後ろ向きにファイルを検索したいんです。 というのは、まず --- int result = 0; while((c = fgetc(fp)) != EOF) { if (c == 'h') { result = 1; break; } return result; --- とすると、ファイルに'h'が含まれるかどうか前向きに1文字づつ判定していけます。しかしここで、 'h'が見付かったあと、逆の方向へ後向きに1文字づつ、別の文字'H'が含まれるかも判定したいのです。 --- int result2 = 0; fseek(fp, -1, SEEK_CUR); //nakusitai if (result) { for (i=0; i<100; i++) { //'h'の前100文字に限り後向きに検索 fseek(fp, -1, SEEK_CUR); //nakusitai c = fgetc(fp); //1文字分進んでしまう if (c == 'H') { result2 = 1; break; } fseek(fp, -1, SEEK_CUR); //nakusitai } } --- 単純にファイルに'H'が含まれてるだけでなく、'h'の何文字の前に'H'が含まれているかを判定しようとしています。 とここまで書いてなんですが、 >あらかじめファイルの中身をメモリに置いておけば、いくらでも読み直せる ですよね。大きめの配列容易して、まずファイル内容読み込んで、処理すれば解決しそう。ありがとう
>>989 なるほど。
それはストリームに対して行う処理じゃないね。
ファイルを全部読み込みたくないのなら、
例えば、こういう風にも出来る。
#define N 100
char buf[N+1], *p;
---
int result2 = 0;
fseek(fp, -(1+N), SEEK_CUR); //nakusitai
if (result) {
fgets(buf, N, fp);
if (p = strrchr(buf, 'H')) {
// (N - (p - buf)) == 'h'からの文字数
result2 = 1;
break;
}
}
---
991 :
デフォルトの名無しさん :2008/01/23(水) 13:16:03
__0__1__2__3__4__5__6__7__8__9 __1__1__2__3__4__5__6__7__8__9 __2__2__4__6__8_10_12_14_16_18 __3__3__6__9_12_15_18_21_24_27 __4__4__8_12_16_20_24_28_32_36 __5__5_10_15_20_25_30_35_40_45 __6__6_12_18_24_30_36_42_48_54 __7__7_14_21_28_35_42_49_56_63 __8__8_16_24_32_40_48_56_64_72 __9__9_18_27_36_45_54_63_72_81 (_は空白です) #include<stdio.h> int main() { int i,j; for(i=1;i<=9;i++){ for(j=0;j<=9;j++){ printf("%3d",i*j); } printf("\n"); } return 0; } としたのですが、できませんでした。 どこを直したらいいですか?教えてください。(for文で)
>>991 そりゃ横着しすぎだろ。
ラベル部分と中身を単純に一緒に出力することは無理だがね。
まぁ、こんなもんかな。
--
#include<stdio.h>
int main()
{
int i,j;
printf(" 0 1 2 3 4 5 6 7 8 9\n");
for(i=1;i<=9;i++){
printf("%3d", i);
for(j=1;j<=9;j++){
printf("%3d",i*j);
}
printf("\n");
}
return 0;
}
--
最初のラベルをループにするのは課題にしておこうw
どうでもいいことだが、もうひとつ気になる点がある "%3d" じゃなくて " %2d" の方がイイ!
んじゃ、敢えて二重ループ一つだけで。 #include<stdio.h> int main() { int i,j; for(i=0;i<=9;i++){ for(j=0;j<=9;j++){ int num; if (i == 0) { num = j; } else if (j == 0) { num = i; } else { num = i * j; } printf("%3d", num); } printf("\n"); } return 0; }
995 :
994 :2008/01/23(水) 13:31:07
一部訂正。 ×二重ループ一つだけ ○ラベルと中身を分けずに # よく見たら、>992もループ構造は二重ループ一つだけだったのね……_/ ̄|○
996 :
デフォルトの名無しさん :2008/01/23(水) 14:06:39
>>992 ,993,994
ありがとうございました。解決できました。
997 :
デフォルトの名無しさん :2008/01/23(水) 19:08:24
こんにちは。 じつはC++ 6.0のプロダクトIDを忘れてしまったのですが、どうすればよいでしょうか?
CD ケースか何かに書いてるだろ。
/.:´ ̄`¨`ヽ、
/.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:ヽ
/.:.:.∧\ヽ.:.:)__、.:.:.'、
/.:.:.:ム__ゝ、\チt‐ij.:.:.:.:.ゝ、
ノ.:.:.:.j,ィ fハ ,`´ゞ-' レ-.:.:.:.辷__
∠ィ'j .:人 `¨ r‐、 ムソ__ニ=-
/ハ.:.f ゙ゝ t-ヲ ,イ.:.:_≧
', `ミ`ーr-y '// `,
ゝミ/7/,ィ'´/ |
,仆、//」/ ヽ j
/`ー'.. `ヽ.| ヽ{
/().. /.. .. /|| 〉 あなたに次スレが訪れますように!
|.. .. i.. .. i´.:.:.:j.| !
|.. .. l.. .. l.:.:.:.:i.:| |
j.. .. i.. .. |.:.:.:.:|/| |
ノ.. .. .. rニロニ〈 | |
,ゝr_ニ'イ ハ 〉::ハ| |
〈/|」 i| ∨i .. ..j:: '| |
// .. |::.. .. |:.. .. |::.:| |
/ f .. .|:: .. . |::.. .. .|::| ム
C言語なら俺に聞け(入門篇) Part 24
http://pc11.2ch.net/test/read.cgi/tech/1201083176/
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。