>>前スレ994 たとえば、次のようなコードを書いたとしよう。 a = b = 1 + c; これをコンパイルして実行したとして、コンピュータの中でどういうことがおきるか。 コンピュータは、まず「1」を評価する。 この「評価する」というのは、「1」を整数の1であると認識して、 その整数値1をコンピュータが持っている小さな机の上に乗せることを意味する。 次に、「c」を評価する。 今度は、変数cの中に入っている値(仮に整数の2だったとしよう)を取り出して、 その値(仮に2)をさっきの1と一緒に机の上に並べる。 そして、今度は「1 + c」を評価する。 これは、いま並べて置いた整数値1と2を足して3という数を作り、 「1 + c」という式の値として、改めて机の上に置くことを意味する。 さらに、「b = 1 + c」を評価する。 ここで「1 + c」は3であることがわかっており、それは机の上にある。 そして「=」は代入するという演算子なので、変数bに整数値3を代入(コピー)する。 ここで、机の上の値3はなくなったわけではない。 この値は、「b = 1 + c」という式の値としてまだ残っている。 最後に、「a = b = 1 + c」が評価される。 上で書いたとおり、「b = 1 + c」は3として評価されているから、 変数bに値を代入したのと同様に変数aに3を代入する。 値3は、「a = b = 1 + c」の値として再度机の上に残されるが、 「;」が現れて「この文で行う作業は終わりです」ということになるので、 ここで残った値3は捨てられ、次のコードへと作業が移る。
つづき 同様に、以下の文の意味を考えてみる。 return N[i]; まず、「N」が評価される。 これは関数に渡されたポインタ変数の値で、たぶん配列の先頭を指していて、 そのポインタの値(配列のメモリ上での場所、番地、アドレス)が取り出される。 次に「i」が評価される。 これはもちろん、そのとき変数iに入っていた値が取り出される。 そして「N[i]」が評価される。 []演算子は、ポインタの指している場所から整数値ぶん先の領域を参照するという意味なので、 コンピュータはN(の指している配列)のi番目の要素(変数)を見つけて、 その値を取り出し、「N[i]」の値として机の上に置く。 最後に 「return N[i]」が実行される。 returnは続く式の値を返すというキーワードであるから、その式の値、 ここでは「N[i]」の値、つまり今机の上に置かれている値が、 関数を呼び出した先に返される。 おわかりいただけただろうか。
>>2 ,3
ある程度わかるようになってから
そういう文みると
あーわかりやすね
って思うのだけれど
プログラミング始めたうちは言ってることが電波杉てわからないんだよね
「評価する」「式の値」「副作用」というキーワードを理解していただける手っ取りはやい方法はないものでしょうか? printf("%d\n", 1 == 1); はどうですか?
コンパイルして実行したとして・・・という感じではないなあ。 実際には CPU の仕様とか最適化とかが影響してくるわけだし。 C の文法を理解する方法としてはそれで全く問題ないんだが。
評価する=計算する・実行する 式の値=計算結果 副作用=状態変化
関数型言語教えた方がはやい気がしてきたな
評価っていう概念は初心者には敷居が高いと思う 前スレ見るに、 return N[i]; で 配列Nのi番目という、N と i の2つの情報が返る と思ってるように見える。 そうじゃないよと。その配列の値ひとつ(数値なら数値ひとつ)が返ると。 って説明がわかりやすいかと
11 :
983,994 :2008/11/15(土) 14:09:14
>>984 前スレ
大学で聞いた.
>>988 前スレ
勘違いしていない.
大学で
>>983 と習ったんだよ.もしかしてうちの准教授がおかしいのか?
>>990 前スレ
今GCC使ってるんだが,コンパイラによって挙動が異なるはずだから,
C90だのなんだのって話をしたんだ.
準拠してるコンパイラならどれ使っても大丈夫なのかが知りたいんだ.
もし環境依存の事実を覚えてしまうと今後面倒なことになるから.
>>993 前スレ
>>常に確実であることが保障されている。
そうだったのか.
12 :
983,994 :2008/11/15(土) 14:17:40
>>2 ,3
なるほど.よくわかった.
小さな机ってのは,多分アキュムレータのことだよな?
アセンブラの方を思い出して想像してみるとよくわかった.
大学で
関数のreturnにはstaticな変数を用いろって話だったんだ.
理由は前スレ
>>983 で書いてる通り.
それであんな質問をしたんだが,return文は引数と同じで値渡しでOK?
さっきから皆ポインタがどうとかって言ってるけど,それはこういうことだよな?
char *func4(char *a,*b) {
static char s[50];
sprintf(s,"%s%s",a,b);
return s;
}
例なのでバッファオーバーランの話はなしで.
もし.sをstaticで宣言してなかったら,
sのアドレスは正しく返るけど,返したアドレスが指すところはいつ書き換えられてもおかしくない.
ということだよな?
return文が値渡しってのは,みんなどこで知ったんだ?
仕様書とかに書いてある?
あまりに当たり前すぎて仕様書に書いてあるかどうかなんて気にした事なかったな
14 :
983,994 :2008/11/15(土) 14:21:35
>>10 つまり値渡しってことだよな?
どうも大学で変な知識を植え付けられたらしい.
困った大学だOrz
仕様書にはちゃんと書いてある。 俺が知ったのはKnRでだが。 まあ、ほとんどの解説本にも書いてるだろう。
関数に渡す引数と、関数が返す戻り値をごっちゃにするなって。 値渡しだなんだのは前者の話だろう。 なんだって後者の話で出てくるんだ。
17 :
デフォルトの名無しさん :2008/11/15(土) 14:28:30
マイナスの実数を扱う変数型ってなんで無いんですか?
float, double
C言語で言う構造体とC++のクラスって似たようなもん?
ある側面で見ると似てるね。 ずいぶん拡張された構造体として扱えば最初は楽なんじゃない
21 :
デフォルトの名無しさん :2008/11/15(土) 14:41:32
>>18 float は 10^−45 〜 10^38 ってかいてあったんですが・・・
符号ビットもあるよ
>>11 >もしかしてうちの准教授がおかしいのか?
いわれることが正しければ、そういうことになりますね。か な り お か し い。
浮動小数点を実装するに当たって符号ビットをもうけなければならないという制限ってあるのかな。 ないなら別にそういう処理系があってもいいんだろうし、そういうふうに 書いてあったとしてもおかしくはないだろうね。 普通は符号ビットあるとおもうんだけどさ。
浮動小数点のビット表現の標準規格があるから 大体の処理系はそれに準拠してる。 IEEEなんたらでぐぐれ
>>25 IEEEなんたら の検索結果 約 17,800 件中 1 - 10 件目 (0.27 秒)
なんたらじゃわからんwww
IEEE754だな
>>12 >小さな机ってのは,多分アキュムレータのことだよな?
>アセンブラの方を思い出して想像してみるとよくわかった.
早合点するやつはそれ以上学べないぞ。
小さな机はレジスタとか、あるいはスタックもありうるな。
アキュームレータはねえよ
28 :
デフォルトの名無しさん :2008/11/15(土) 16:35:25
>>24 ISO/IEC9899:1999(E) 5.2.4.2.2 Characteristics of floating types <float.h>
によれば、浮動小数点型は負数が表現できなければならないことになっているが、
符号ビットという実装を義務づけている記述は見あたらない。脚注 16 もそう読める。
>>27 いや、load/store を指示可能な(外部からレジスタと同等に扱うことのできる)アーキュムレータ、というのもありまして。
>>16 そりゃ、関数呼び出しで参照渡しの返り値が可能な言語処理系もありますし。
>>28 なるほど。C99ではそうなっているということですよね。
ありがとうございました。
32 :
デフォルトの名無しさん :2008/11/15(土) 17:37:54
33 :
デフォルトの名無しさん :2008/11/15(土) 17:46:29
>>12 仮引数もそう書けと習ったのか?
返却値の話もろくに聞いていなかっただけだろ
malloc による文字列操作に至っては授業を欠席していたようだな
適性ある奴と同じ行動とってるとひでえ目にあうぞ
34 :
デフォルトの名無しさん :2008/11/15(土) 18:16:16
ちょっとトンチンカンな質問かもしれませんが int n=0; ong t; while(n!=100){ time(&t); printf("%f\n",t); n=n+1; } とやるとtの値として100個とも全く同じ値が出てくるのですが これはプログラムを走らせてる最中全く時間が経過してないということなんでしょうか・・・?
35 :
12 :2008/11/15(土) 18:16:49
>>15 昨日調べようとおもって,図書館いったら誰かが借りてて見れなかったんだ.
今度本屋で立ち読みしてくるよ.
>>16 >>32 返すときも,値渡しなのかどうかって話.
>>16 のいうとおり,話がごっちゃになってきてるが,俺はCの返り値が参照渡しなのか,値渡しなのかがわからなかったからこういう質問をしてしまったんだ.
ここがCのスレだからCの返り値について質問してるんだ.
>>27 アセンブラの授業だと,スタックに入ってるデータをアキュムレータに入れないと足し算も出来なかったんだがなぁ.どうしてもアキュムレータに入れないといけないのかを聞いたら,出来る事は出来るが,遅いって言われた.
36 :
34 :2008/11/15(土) 18:16:58
すみません ong は long の間違いです
37 :
12 :2008/11/15(土) 18:18:11
>>33 授業は全部出てるしちゃんと聞いてる.
今回のreturnについては変だったから准教授にも聞いたんだ.
そしたら
double normalize(double th) {
while(th > PI) { th -= PID; }
while(th <= -PI) { th += PID; }
return th;
}
はだめで,
double normalize(double th) {
static double out;
while(th > PI) { th -= PID; }
while(th <= -PI) { th += PID; }
out=th;
return out;
}
としろって話だったんだ.
> 引数 th が関数に渡されるときに関数内部では別の変数が用意されて,その変数
> にコピーされます.この関数内の変数は当然 static ではないはずですので,
> return によって正しく返却されることは保証されないと思います.ですから,
> やはり static 変数を別に用意してください.
> なお,数式の評価値も正しく返却されるのか不安なので,私は static 変数に代
> 入してから return しています.たとえ仕様上は保証されていてもバグがあるか
> も知れないので,こうすれば安心です.
とのことだった.
仮引数の書き方はとくに指示されてはいないし,malloc による文字列操作どころかmallocはまだ名前以外出てきた事がない.
仮引数の書き方に適切なものがあるなら是非教えてくれ.
38 :
デフォルトの名無しさん :2008/11/15(土) 18:19:59
>>34 実行速度が速いから,1秒たつまでに終わっちゃうんだと思うよ.
100とするところを,1000000くらいにして試してみると,少しは変わるかも.
>>37 教授がなんか勘違いしてんだろうね。
仮引数の件
char *func4(char *a,*b) {
↓
char *func4(char *a, char *b) {
40 :
34 :2008/11/15(土) 18:25:07
>>38 なるほどほんとだ。
ありがとうございます。
>>37 その準教授なり教授なりの返答はあまりにも稚拙だな。
あなたはstatic変数にしないと不安で仕方ないかもしれませんが、
私はそのようなことで不安になることもありませんし、メモリを浪費したくもありません。
とでも言っておけば?
追記。 仕様で保証されているものをバグだ何だと騒ぎ立てるんだったら staticにすれば大丈夫なんていうのも保証はないし、 そもそもnormalizeにthが壊れずに渡されるかどうかも心配すべき。 ちょっとどうかしてるよ。
43 :
12 :2008/11/15(土) 18:34:50
>>39 ですよね……
名古屋大出てるのにOrz
仮引数.
なるほど.次からちゃんと分けて書くようにするよ.
でもなんでそう書く方がよろしいんだ??
さっき,GNU libcを落としてきて,ソース漁ってみた.
printf.cのソースで,
int
__printf (const char *format, ...)
{
va_list arg;
int done;
va_start (arg, format);
done = vfprintf (stdout, format, arg);
va_end (arg);
return done;
}
ってなってたよ.次からいちいちstaticにするのはやめておくことにする.
44 :
デフォルトの名無しさん :2008/11/15(土) 18:42:23
printfで%lfで表示すると同じなのに、比較すると(if分で!=de)異なると なってしまいます。片方は計算で得た5.0000、もう片方は5をdouble型に 入れたものです。 この二つをどうにかして同じ値として扱いたいんですが何かいい方法はないでしょうか?
45 :
デフォルトの名無しさん :2008/11/15(土) 18:44:20
日本語がおかしくてすみません 簡単に言うとif文の条件として二つの変数を比較するときだけ 小数点5桁とか4桁だけで比較したいんですがどうしたらいいでしょうか?
>>44 浮動小数点では単純に==で比較すると誤差で涙目になる。
適当に許容する誤差を決めて
#define EPS 1e-5
if(fabs(a-b) < EPS){//aとbが等しいなら
}
みたいにやるのを薦める
47 :
33 :2008/11/15(土) 18:50:37
>>37 それは失礼した
しかし痛い教授にあたったものだな、ご愁傷様
試験のときも教授と同じ間違え方をしないと減点されかねないから気をつけてな
48 :
デフォルトの名無しさん :2008/11/15(土) 18:50:50
ありがとうござます!!
49 :
デフォルトの名無しさん :2008/11/15(土) 19:00:53
>>35 一つ言っておこう
授業で習うことなんて8割方嘘だ
初心者向けにかなり誤魔化しが入っとるけん、
全部鵜呑みにせんと、概要だけふーんと聞いておけばいいよ
なぜ伊予弁
51 :
34 :2008/11/15(土) 19:15:30
すみませんもうひとつ質問なのですが、 たとえばゲームとかを作る時、キャラクターを動かす部分のプログラムは、 「今xに表示しているキャラ画像を、○○秒後にx+10に表示する」 みたいになると思うのですが、 そもそもこの部分の処理に○○秒以上かかっちゃっう場合はどうするんですか?
教授なんて名大を出ててもそんなものか。。。 かったるくて日進月歩に合わせられないんだろうな。 法科、会計、情報系は教授もリアルタイムに日進月歩しないと駄目じゃね? 古いままだと実態に合わなく使い物にならなくなるから。
>>51 タイマー割り込みの手法を使って、差分を計算してキャラを動かす。
キャラが増えて負荷が高くなったら、一部を間引いて処理する工夫を入れるか
タイマー間隔を延ばして処理する工夫を入れる。
55 :
12 :2008/11/15(土) 19:25:23
>>47 俺は授業よりも,Cの本の方を重点的にやってるから,
今回の返り値の謎に気がついたからよかったけど,他の連中に返り値がどうのとかいうと,
「返り血」と思われてしまうよww
困ったもんだ.准教授といえども,間違うってことか.
そう言えば,scanfのフォーマットで[]とか*とかもしらなかったもんな.
そんなもんなのかな?
>>49 准教授の授業3割,本4割,libcとかのGNUのソース2割,どっかのサイト1割くらいで参考にしてるから,
それは大丈夫だと思いたい.
質問の結論は返り値は値渡し.
みんなありがと.ずっと変なソース書き続けるとこだったよ.
聞いてみてよかった.
>>37 誰か指摘してたが、関数内で不用意に性的変数を
参照するのは避けるべき
なぜなら再入可能でなくなるから
つまりマルチスレッドで同時にその関数を使用すると不具合が起こる
要はマルチスレッドプログラミングも
したことない助教授は明らかに素人なので
気をつけろってことさ
人員不足で担当させられてるだけの門外漢だったりして
なんという痛み分けw
59 :
34 :2008/11/15(土) 19:40:46
>>52 なるほど・・・
>>54 なんかよくわかりませんがいろいろ解決法があるのですね。
調べてみます。
60 :
デフォルトの名無しさん :2008/11/15(土) 19:40:48
>>55 つかさーアセンブラやってんなら返り血を
渡すコードがどうなってるか見てみるといいぜ
返す型でも変わるし
61 :
デフォルトの名無しさん :2008/11/15(土) 19:51:26
しかしこの返り値クンは、なんやかんやと言い訳ばかりでむかつくなw 後から伸びないタイプだわw
管理職タイプ
関数ポインタってどういう時に使うんですか?><
65 :
デフォルトの名無しさん :2008/11/15(土) 20:36:50
場合分けが必要で呼び出し元で処理を共有したい時とか?
wikiでデリゲートを調べたのですがちんぷんかんぷうでした・・・
switch (kannsuu) { case hoge1: hoge1(); case hoge2: hoge2(); } な感じでしょうか
69 :
デフォルトの名無しさん :2008/11/15(土) 21:03:40
>>67 「ちんぷんかんぷう」に心動かされたので真面目に答えてみる。
関数ポインタの利点は、
1種類のイベントに対して、挙動が違うという場合に用いると良い。
ボタンAを「押した」ときは処理A'を実行し、
ボタンBを「押した」ときは処理B'を実行したい。
てなプログラムを書くときに便利なのです。
ボタンAもBもボタンという挙動をするプログラムなわけだけど、
それぞれのボタンを「押した」という1種類のイベントに対して
処理を変えなければならんでしょ。
そういうときに、関数ポインタを使う。
そもそも、WindowsのGUI部分は関数ポインタの雨あられで実装されてると
思うと良い。
なんとなくデリゲートがわかった気がします int event(string)[10]; event[0] = int kansuu1(string s) {return 1}; event[1] = int kansuu2(string s) {return 1}; event[2] = int kansuu3(string s) {return 1}; event[3] = int kansuu4(string s) {return 1}; event[0](); event[1](); event[2](); event[3](); ということですね
・・・・俺、
>>69 だけど、酒飲みながら書くと、日本語おかしいな。
反省してもう寝る。おやすみ。
>>69 ということは、
>>70 で、
event[0]に処理A'、event[1]に処理B'を入れておいて、
A=0, B=1にして、event[X]()で実行すればいいんですね!
74 :
12 :2008/11/15(土) 22:16:01
>>60 アセンブラは,そんな詳しいところまで教えてもらってないぜ.
>>61 解釈はいいわけでもなんでもいいんだけど,
事実だから俺にはどうしようもない.
習ってないものは習ってないし,
staticを使えと教えられたものは俺にはどうしようもない.
>>63 しばらくROMって見る事にするよ.
75 :
デフォルトの名無しさん :2008/11/15(土) 22:22:58
>>74 > アセンブラは,そんな詳しいところまで教えてもらってないぜ.
アセンブラもその教授かw
いちばん肝心なことなのに
76 :
12 :2008/11/15(土) 22:30:37
>>75 アセンブラは違う人だけど,あの人は非常勤だw
>習ってないものは習ってないし, >staticを使えと教えられたものは俺にはどうしようもない. うむ、こういう所が伸びない奴の特徴だなw 伸びる奴は自分で自発的に調べる。 習ってないなんて言い訳はしない。
今の学生は昔で言う生徒ですから
ゆとりは使う人がインプットしないと何もできません
22:32:04〜22:34:04 僅か2分の間に一気に批判が集中したな。
まぁまぁ。 疑問を持ってこのスレにくるだけマシだよ 態度は気に食わないが
82 :
デフォルトの名無しさん :2008/11/15(土) 22:46:42
mingw の crt2.oってどのパッケージにはいってますか?
84 :
12 :2008/11/15(土) 23:18:58
誤爆しました
85 :
12 :2008/11/15(土) 23:34:39
>>77 必要があれば調べるよ.だけども,returnのについては初歩的過ぎるのか適当な情報がなかったんだよ.
俺の検索能力で見つかったなら聞いていないよ.
>>79 俺はゆとり第1期生さ.すまん.
おっしゃるとおりだ.
>>82 俺は俺の大学をもう少し信じてみるよ.
>>84 おまえ誰だよw
staticにして返すなんてのは初めて見た。 その教授よっぽど変な環境でプラグラミングしてたんだろうか。
>>12 は専攻は何系なんだろう。
まさか情報系じゃないよなw
おれは、本人
>>12 の勘違いだとおもう。
文字列のポインターの戻り値の場合、文字列はstaticで定義するを
戻り値はstaticでになったんだと思う。
大学名が知りたい それがだめなら地域と偏差値だけでも
まぁ全てはこのゆとりを経由した情報だからな。 鵜呑みにはできんな。
>>85 「呼び出し規約 返り値」で検索すれば情報が出てくるぜ
Cとアセンブラを学ぶなら呼び出し規約は必須だから
>准教授の授業3割,本4割,libcとかのGNUのソース2割,どっかのサイト1割くらいで参考にしてるから,
>>12 のレベルではGNUのソースはまだ早いなw
>>88 一応
>>37 を見ると教授がおかしいように見える。
が、
>>74 辺りから
>>12 を見る目が変わってしまったことは否めない。
今後の学び方次第でどちらにも転がる分岐点にいるって感じかな。
気をつけてね。
>>93 >37の准教授の語ったというその台詞をよく読むと、この准教授と名乗っている馬鹿が自己矛盾に気付いていないことが判る。
仮にも准教授と名乗るだけの知恵のある馬鹿がそこまで間が抜けていると考える道理がないので、台詞が間違って伝えられたと結論付けたい。
伝言ゲームがゲームとして成立していることから判る通り、人間は意外に他人の台詞を曲解しているものなんだよね。
doubleがスタックにつまれるコンパイラがあったとか?
>>95 doubleを値渡しできないはるか昔の時代のことか・・・・・・
いやよく知らんけど
>>95 その辺はCPUとOSの仕様もからむな
x86は浮動小数点スタックに積んで返してるし
>>95 の言うスタックではないが
仮に、70年代のコンパイラで育ったからその旧弊に縛られているとしよう。 問題は、その年齢で准教授と言うことだな。
いやリタイアするまで准教授のままの奴なんてごまんといるよ
lsi-c 80とかで苦労したんじゃないの?
そんなCコンパイラは過去に存在しない
LSI C-80ってまだ売ってるんだ。
>>64 ん、qsort() とかで必要でしょうね。
>>89 偏差値ってなんですか?なんの役に立つのですか?まさかそれでプログラミング能力がわかるとでも?
あなたの偏差値がしりたいものです。
ゆとり君まだ居たのね。
いや、別人だろw
質問です 例えば以下のような場合、xは5でいいのでしょうか? int x = 1, i = 0; x += ( i += 2, i % 3 );
110 :
108 :2008/11/16(日) 11:46:41
>>109 違うのですか?
x += が二回実行され、2と1が足されると思ったのですが
111 :
108 :2008/11/16(日) 11:52:15
あ、失礼しました 2と2が足されて6ですね
void line(hword Xa, hword Ya, hword Xb, hword Yb, hword color) { hword x, y; int j = Ya; int e = 0; for(x = Xa; x < Xb; x++) { draw_point(x, j, color); e = e + (Yb-Ya); if((Xb-Xa)< e) { e = e - (Xb - Xa); j = j + 1; } } } このメソッドがどのように動いて斜線を引いているか分かり易く教えていただけないでしょうか? draw_pointメソッドは指定された(x,j)座標にcolorで指定した色のドットを表示するメソッドです。 斜線の範囲は(Xa, Ya)から(Xb, Yb)です。
>>114 どのようにもなにも、適当な位置を決めて自分で机上トレースしてみれや。
>>115 >114のどこがCじゃないと?
Cじゃない確証がないならこのスレで扱えばいいじゃない。
>>114 どの辺が判らない? 全部判らないなんてのは無しにしてよ。
>>115 eの型が hwordじゃなくてintなのが気持ち悪い
yを使ってないのが気持ち悪い
あと、水平寄りの斜め線しか引けない気がする
121 :
デフォルトの名無しさん :2008/11/16(日) 12:39:58
動的に確保した構造体を自作関数へ渡す時、何故全て二重ポインタにしないのですか?
つーか二重ポインタって何?
124 :
114 :2008/11/16(日) 12:43:26
>>119 まず1ループ目でeが点から点の高さになりますよね。
そのあと現在値にドットを打って移動して行って、横の長さが段々増えていきますよね。
そこまでは理解できるんですが、それでeが横の長さより大きくなった場合のif文からが理解できません。
机の上で書いてみたりしてるんですが、どうもイメージがわかないので、何故斜線になっていくのかが分かりません。
>>124 ブレゼンハムのアルゴリズムかな?
ググればでてくると思う。
>>122 構造体へのアドレスが違うのでスッキリしないのですが、
>>124 そこまで判っているならこのスレ的にはヒントキーワードを出せば事が足りそうだね。
つ[ブレゼンハム]
>>126 言いたいことがよく判らんから、具体例を提示してくれ。
129 :
デフォルトの名無しさん :2008/11/16(日) 13:13:05
typedef struct { char *a; }TEST; int main(void) { TEST *test = malloc tes(test); } void tes(TEST *tes) { tesはtest構造体を指さないのでスッキリしない }
指しますが何か。
>>129 おまえ、コードが断片過ぎだし用語が滅茶苦茶だし、勉強しなおして来いよ。
アドレスが違う訳だが、指してる事になるの?
どうせポインタのアドレス表示して 違うとか騒いでるだけだろ
>>108 x+=が二回実行されるわけではない。
i%3の値が一回だけx+=で加算されるため、xは3になる。
カンマ演算子でググればわかる。
構造体の実体はmalloc()が取ってきたメモリに置かれてるから、ポインタに入ってるアドレスが構造体のアドレス。 ポインタ自身のアドレスは、構造体とは違う。
>>137 どうやって確認したのかきちんと提示しないからこんな馬鹿げたことになる。
いいから大人しく>133
142 :
デフォルトの名無しさん :2008/11/16(日) 13:24:43
>>140 >ポインタ自身のアドレスは、構造体とは違う。
これはtes関数の引数のポインタ?
143 :
デフォルトの名無しさん :2008/11/16(日) 13:26:13
>>141 printf("%p"&p); //main
printf("%p"&tes); //test
>>143 断片を提示するな。ポインタ変数の値とポインタ変数のアドレスを区別しろ。ポインタとは何かを考えろ。
要は、>133
struct Hoge h; struct Hoge* ph = &h; void func(struct Hoge* arg) { } func(ph); //ph と arg は同じ(hを指してる) // &arg と &ph は別
>>129 main関数内のtestと、tes関数内のtesは同じだろ。
だから、構造体は渡すことができている。
main関数内の&testと、tes関数内の&tesが異なるのは当然。
mainに p なんてないし、test って関数もないし、わけわかめ
149 :
デフォルトの名無しさん :2008/11/16(日) 13:36:01
129:デフォルトの名無しさん :2008/11/16(日) 13:13:05
typedef struct {
char *a;
}TEST;
int main(void)
{
TEST *p = malloc
tes(p);
}
void tes(TEST *tes)
{
}
コードを間違えた
>>146 mallocの戻り値を格納するTEST構造体型のポインタ自身のアドレスが
関数testに渡されているだけであって、関数testの*tesが実態を指し示しているとは考えられない
150 :
デフォルトの名無しさん :2008/11/16(日) 13:40:02
2次元配列のポインタを実現したいのですが、 (文字列のn×n表を作る方法は木構造やハッシュ表でよく分からないので・・・) #include <stdio.h> typedef struct node { char *item; }; int main(void) { int i; char n[100]; struct node *a[100][100]; for (i=0; i<3; i++) { fgets(n, 100, stdin); sscanf(n, "%s", a[i][0]->item); } printf("%s\n", a[1][0]->item); } どのようにすれば文字列をポインタへ設定できるのか何卒ご教授願います。
>ポインタ自身のアドレスが関数testに渡されている
ダウト。
だから
>>133
>>150 あんたの欲しいものは、ポインタの配列の配列じゃないのか?
そのためには、各文字列を収容する空間が別途必要になるが、>150ではそれを一つで済まそうとしているから巧くいかない。
itemのサイズが見込めるなら、ポインタにしないで(取り敢えず)配列にしてしまってはどうか。
154 :
デフォルトの名無しさん :2008/11/16(日) 13:54:34
ポインタpとtesのアドレスが違うのにどうしてポインタtesが構造体を指し示していると言えるのか、 上記が違うのにtes->strとp->strのアドレスが同じなのは何故か、 この二つを教えて下さい
155 :
デフォルトの名無しさん :2008/11/16(日) 13:58:59
間違えた ポインタpとtesのアドレスが違うのにどうしてポインタtesが構造体を指し示していると言えるのか、 ポインタpとtesのアドレスが違うのにtes->strとp->strのアドレスが同じなのは何故か、 test関数の引数*tesを**tesにした場合の違いは何なのか この二つを教えて下さい
ここでこんなに説明されても理解できてないんだから、ちょっと引き篭もって勉強してこいよ。
158 :
デフォルトの名無しさん :2008/11/16(日) 14:02:21
それをさっきから説明してるんだろ・・
160 :
デフォルトの名無しさん :2008/11/16(日) 14:05:41
void func(int i, int * pi) { printf("%d, %p\n%p, %p\n", i, & i, pi, & pi); } int main() { int i = 1; int * pi = & i; printf("%d, %p\n%p, %p\n", i, & i, pi, & pi); return 0; } これで理解できなきゃ死ねば?
おっと、func()の呼び出しが抜けたぜ。ついでにグローバル変数も追加しておこう。 int gi; int * gpi; void func(int i, int * pi) { printf("%d, %p\n%p, %p\n", i, & i, pi, & pi); } int main() { int i = 1; int * pi = & i; printf("%d, %p\n%p, %p\n", i, & i, pi, & pi); func(i, pi); gi = i; gpi = pi; printf("%d, %p\n%p, %p\n", gi, & gi, gpi, & gpi); return 0; }
typedef struct { char *a; }TEST; int main(void) { TEST *p = malloc tes(p); } void tes(TEST *tes) { rrr: } じゃぁこれで説明すると 仮に1番地におかれたp に mallocによって200番地に確保されたメモリを入ったとするだろ そうするとp は1番地に置かれていて 200が入ってるわけだ で、tesに渡すと ポインタp は2 番地に置かれたとして中身は 200になるわけだよ (*p)も(*tes)も ポインタの中身である200 、その番地にあるデータへの参照になるわけだよ
165 :
150 :2008/11/16(日) 14:10:18
#include <stdio.h> #include <stdlib.h> struct node { char *item; }; int main(void) { int i; char n[100]; struct node *a[100]; a = (struct node*)malloc(sizeof(*a)); /* エラー:左辺値が必要 */ for (i=0; i<3; i++) { fgets(n, 100, stdin); sscanf(n, "%s", a[i]->item); } printf("%s\n", a[1]->item); } まずはこのようなポインタの配列を実現したいのですが、どのように領域を確保すればよいのでしょうか?
× で、tesに渡すと ポインタp ○ で、tesに渡すと ポインタtes だた
c 多次元配列 動的確保 あたりでぐぐったほうが ここでちょろっと説明してもらうよりわかりやすいかもしれない
ホント、他人の話をよく読まない香具師が多いな。
>>165 >165にだけピンポイントで答えるぞ。
for (unsigned ic = 0; ic < sizeof(a) / sizeof(* a); ++ic)
a[ic] = malloc(sizeof(* a);
>>155 ポインタがオブジェクトを指し示しているということの意味を理解しているか。
ポインタがオブジェクトを指すことができるのは、ポインタ変数の値がオブジェクトの位置を保持しているからである。
問題になるのはポインタ変数の値であって、ポインタ変数の位置ではない。
複数の(つまり、位置の異なる)ポインタ変数であっても、同じ値を持っているなら、それらは同じオブジェクトを指している。
関数の仮引数をポインタとして宣言したとき、関数に渡されるものは実引数に指定されたポインタの値のコピーである。
だから関数の中と外で同じオブジェクトを参照することができる。
>>155 int test = 10;
int *a = &test;
int *b = &test;
// a と b は同じ test をさしているが、&a != &b
関数やら構造体やらの前に、これだけの話じゃないの
171 :
150 :2008/11/16(日) 14:33:49
>168 for (unsigned ic = 0; ic < sizeof(a) / sizeof(* a); ++ic) a[ic] = (struct node*)malloc(sizeof(*a)); or (i=0; i<3; i++) { fgets(n, 100, stdin); sscanf(n, "%s", a[i]->item); } for (i=0; i<3; i++) { printf("%s\n", a[i]->item); } malloc以下をこのようにしてコンパイルできるようにはなったのですが、 a[0]->item 〜 a[2]->item の区別がなく更新されてしまういます。 a[0].item のように*を使うことはできないのでしょうか?
#include <stdio.h> #include <stdlib.h> #include <string.h> #define BUFLEN 100 #define NODELEN 100 #define READLEN 3 struct node {char *item;}; int main(void) { int i, slen; char n[BUFLEN]; struct node **a; a = malloc(sizeof(struct node*) * NODELEN); for (i=0; i<READLEN; i++) { fgets(n, sizeof(n), stdin); slen = strlen(n); if(n[slen-1]=='\n'){n[slen-1] = '\0';slen--;} struct node *p = malloc(sizeof(struct node) + slen + 1); p->item = (char*)(p + 1); strcpy(p->item, n); a[i] = p; } for(i=0; i<READLEN; i++) printf("%s\n", a[i]->item); return 0; }
>>171 何がしたいのか不明
3行とって、3行出力なのか?
174 :
12 :2008/11/16(日) 14:51:43
>>87 工学部情報工学科 一回生だw
>>88 だとすると,
>>37 のメールの返信をどう解釈するんだ?同じ学科の友達も,staticにするものだと思ってるぞ.
>>89 大学は偏差値が60の国公立.地域は近畿.
>>91 調べてみる.情報サンクス.
>>92 早いのはわかってる.俺が参考に出来るのは,returnする変数にstaticがついていないだとか,ソースの書き方だとか.
アルゴリズムだとかはまだぜんぜんわからない.けど,見ないよりは見た方が良いと思ってる.少しでも人が書いたソースにも慣れていきたいと思うし.
>>93 忠告ありがと.もっと謙虚に学ぼうと思う.
>>94 >>37 はメールの本文.
returnについての質問に対する返信の部分だ.伝言ゲームじゃねぇ.
でも俺の勘違いならその方がいい.返値が値渡しってことは皆のおかげでわかったし,
これからもこの准教授に世話になるから.学生の質問にも丁寧に答えてくれるから,俺はこの准教授好きなんだ.
>>98 准教授は50年代中頃の生まれだよ.まだ50代.
というわけで,そろそろ場違いも甚だしいのでROMに戻ります.
>>37 仕様上保証されてもバグがあるかもしれないからstatic?
意味がわからん
そんな事気にしてたら何も書けないだろ
パラノイアか?
具体的にコンパイラにバグがあって
それを避けるためのworkaroundだというなら分かるけど
ゆとりキター!!
for文に関して for(;;)とはどのようにループするのでしょうか?
>>177 無限ループの慣用表現
while(1)と同じ
既出かもしれないけど。
>>37 は明らかに教授の間違い。
引数 th が値渡しでコピーされるのと同様に、
戻り値も値渡しになっているので、戻り値を返すときにもコピーが発生する。
だから関数内でstatic にしようが、ローカル変数にしようがどちらでも関係ない。
一般に、staticな変数を関数内で利用すると、マルチスレッドでの実行時などにトラブルが起こる可能性がある。
逆に言えば、マルチスレッドで利用する可能性が無い関数なら、使っても別にかまわない。
無限ループです
181 :
デフォルトの名無しさん :2008/11/16(日) 15:03:53
>>177 質問の意図がよくわからん
永久ループという以上の説明がいるのか?
>>174 一年坊主か。じゃあ忠告しておく。
大学は高校までと違って
教 員 は 教 育 の プ ロ で は な い 。
研究が本業だからな。自分の研究分野以外は素人だ。
そのうち卒業研究とかすると思うけど、自分で多くの調査実験を
行ったうえで、指導教官と意見が食い違ったら、自分が正しいと思え。
と、うちの指導教官が言ってた。
たまにおかしなこというけど、今でもその言葉は正しいんじゃないかと思う。
教授に捨てメルアドでこのスレの内容を送ってやれ。
質問です main(){ int kekka = 0; unsigned char soeji[] = { 4, 3, 2, 1 }; unsigned int deta[] = { 0, 100, 200, 300, 400 }; kekka = deta[(soeji[3])]; } この deta[(soeji[3])] という表記は使っても大丈夫でしょうか?(kekkaに100が入ってる?) また添え字になるならsoeji[]はunsigned charよりunsigned intの方が 処理速度的にはよいのでしょうか? よろしくお願いします。
186 :
デフォルトの名無しさん :2008/11/16(日) 15:23:12
char buf<:124:>; <::>これ何
188 :
デフォルトの名無しさん :2008/11/16(日) 15:27:06
>>185 何を問題視しているのか判らない。
soeji[3]は問題ないし、deta[1]も問題ない以上、deta[soeji[3]]も全く問題ない。
unsigned charは演算の際にどうしてもintに拡張される。従って、unsigned intにしておいた方が無難。
但し、どうせ大差ない。
どこでみたんだよ
>>185 添字には整数値が使えるので問題ない
int型あるいはunsigned int型の方が、CPUが扱うビット数と等しいので、一般的には早くなる。
しかし、char型であっても、コンパイル時にint型に格上げされるので、結局変わらないと考えるべき。
>>186 またM$の拡張表記だろ。
>>171 >168は、そこにあるように文字列のケアはしていない。文字列については、>152。
193 :
デフォルトの名無しさん :2008/11/16(日) 15:31:12
>>190 VCでコンパイル出来る理由が分からないからどのスレで聞けばいいか教えて
>>185 deta[(soeji[3])] の表記自体は問題ないが、そのプログラムだとべつにdeta[soeji[3]] でもいい。
char と int でどちらが速いかは処理系依存だけど、
現在のPC用の処理系では int のほうが有利か、まったく同じかのどちらか。
少なくとも、 char のほうが速いということはない。
> <::>これ何 ↓の幼虫 <ヽ`∀´> ウェーハッハ
>>193 VS C++ 2008 で試したが、コンパイルとおらないぞ。
char buf<:124:>;
digraphオプションをONにしろ。
<: == [ :> == ]
そういやそんなのあったな 一応標準だわ
(<: = [)) ↑チンパンジーとかゴリラの顔文字にみえる
>>176 あなたのほうがゆとりと呼ぶのにふさわしい。
>>12 は筋の通った言い分をもっており媚びずに素直で好感を持ちました。
>>12 icot の先生はまだおられますか?
∧__∧
ミ ・ω・ミ∧∧
/⌒ ,つ⌒ヽ ) ←
>>202 =
>>12 (___ ( __)
"''"" "'゙''` '゙ ゙゚' ''' '' ''' ゚` ゙ ゚ ゙''`
204 :
185 :2008/11/16(日) 16:57:41
205 :
デフォルトの名無しさん :2008/11/16(日) 17:02:50
仕様書(JISX3010)のreturnに関係がありそうなところ読んでみたけど,値渡しかどうかはわかんなかった.
でも,ISOの仕様書にもJISの仕様書にも,return文に用いる変数をstaticにしてるものは見つからなかった.
関数内で配列を宣言してそのアドレスを返す場合を除いて.
>>179 マルチスレッドがどうのって言ってる人が何人かいるけど,
staticってマルチスレッドどんあ悪さを?
>>183 忠告ありがたく受け取っておきます.
そう思っていればなんか食い違ってもそっかぁと思えるし.
でも,正しいものを選定するのが大変そうだ…
個人的には,高校も小学校までと違って,教師は教育のプロではないと思う.
>>184 すぐにばれるwwreturnについて質問したやつなんて,多分学科で俺一人に違いないw
>>202 icotが何かわかりません><
ほぼ同時に関数を実行しようとすると値がおかしくなる可能性がある
「static マルチスレッド」でぐぐればいくらでもでてくるだろう それでも理解できないならわからないところを質問すればいい
208 :
デフォルトの名無しさん :2008/11/16(日) 17:11:32
>>207 いっぱい出てきた.ごめん軽はずみに聞くべきじゃなかった.
しかしこれは…准教授はほんとにマルチスレッドでプログラミングしたことないのかな…
209 :
さかみ :2008/11/16(日) 17:14:44
ギタン砲乙www ヤリ無双普通に面白かった
なんという誤爆
>>205 関数内に書かれたstatic変数は、実行時にプロセス内で唯一無二の変数として存在。
マルチスレッドな実行環境でその関数が多重並列に呼ばれる場合は弊害をもたらす。
シングルスレッドな実行環境でも、リエントラント問題を考慮しなければいけない。
staticの挙動の学習用に限ってなら使って構わないよ
>>205 そもそも返却値に値渡しなんて概念はない。
返却値をどう使うかを考えてみればすぐわかるぜ。
さらにいうと、厳密には引数にも値渡ししかないしな。
その自称准教授流に再帰階乗関数書いて見た。 これについて意見聞いてみたいな int kaijo(int n) { static int ret; ret = n; if (n > 1) { ret *= kaijo(n-); } else { ret = 1; } return ret; }
DWORD thID; を int thID にすれば?
>>215 もしかして 64ビット環境?
とりあえずキャストすればいいんじゃないかな
_beginthreadex(NULL, 0, mythread, NULL, 0, (unsigned int *)&thID);
>>213 正確にいえばそうなりますね。C に参照渡しはない。
だから、
>>30 でいったとおり、他の言語、特にpascal なども念頭におくと意思疎通が図りやすいのでは、と考えたしだいです。
>>217 64bit環境って何ですか?
とりあえずそれで解決できました。
ありです。
CreateThreadと_beginthreadexは微妙に引数・戻り値の型が違うから困りもの。 215のコードはCだと警告が出るだろうけどコンパイルできるはず。
>>218 人の話聞いてねーなてめー
C言語で関数からの返却値をどう扱うかを考えれば
値渡しだとか参照渡しだとかそもそも関係ないってことだよ
C言語の返却値が値渡しってのも間違いだ
じゃ、何渡し?
はぁ?なにいってんの?
そもそも関数の内側からの視点で考えるからわかりづらい。 HOGE()って関数があって、それを呼び出すって言うことは HOGE()を評価するってこと。 評価=evaluateだから、値を得るって言ったほうが本質に近いな。
その議論で、static変数の問題は解決するんだろうか? 解決するにはどこへ議論を運べばいいんだろうか?
ResumeThreadと SetEventって何が違うんですか?
んで、C言語では評価されたものをどう使うかってとこに行くのさ。 例えば、a = HOGE(); を考える。 aに代入する時点でどのみちコピーが発生するので、 HOGEでの返却値がテンポラリ変数であろうが、static変数で あろうがどっちでもいいのさ。
めでたしめでたし。
構文は、 return 式; だから、値しか返しようがない。 式がたまたま変数一個からなっていても特別扱いはされない。
>>228 スレ違い。
Win32API質問箱にでも行ってみたら?
>>228 なにがちがうんですかってほど似てないだろ。
234 :
デフォルトの名無しさん :2008/11/16(日) 20:23:27
関数へ渡す引数が多くてややこしい場合 引数をポインタ配列にして渡せば、見やすくなると思ったんですが こういう方法は一般的ではあるんでしょうか?
ありますよ?
構造体に纏める方が幾分まし。
構造体もやってみようとしたんですが 関数の中でコードがややこしくなったんで(私の不勉強でいい方法があるのかも知れませんが) ポインタ配列で渡そうかと思った次第です どうもありがとうございます。
with文を使うと簡潔になる。
241 :
205 :2008/11/16(日) 20:46:36
>>211 ググったらもっと難しいのがいっぱい出てきたけど,
その例はわかりやすいなぁ.ありがとう.
>>214 これおもしろいな.
でもこのままじゃ何入れても1しか返さないじゃ…
int kaijo2(int n)
{
static int ret;
if () {
ret = n * kaijo2(n-1);
} else {
ret = 1;
}
return ret;
}
これでどうだろう.
242 :
205 :2008/11/16(日) 20:50:05
>>213 引数が値渡ししかないってのはわかる.アドレスを引数にもってくるときも,アドレスの値を渡してるわけだし.返却値が値渡しかどうかって話になったのは,俺が引数を比較対象に持ってきたからだすまん.
准教授は授業で,
関数が終了したら関数内の自動変数は解放される.だから,返値に用いる変数にはstaticをつけないと,戻った時点で値が変わってる可能性がある.だから,返値に用いる変数にはstaticをつけろってことだった.
今回,俺がstaticをつける事に疑問を抱いて,同じ学科の友人との話題にしたんだ.
准教授の説明の意味を,呼び出し元に戻るときに関数が終了するから,戻った時点でその変数の中身が保証されない.
だから,代入する時点で保証されないっていうことだと考えた.もし,引数の場合と同じように値がコピーされるなら,staticをつけないといけない意味がわからない.
int func(void) {
int n;
n=50;
return n;
}
int main(void) {
int a;
a = func();
}
とすると,
内部的には,return文は式のアドレスを取得するという意味で,
a = func();のfunc()はそのアドレスの指す内容に置き換えられるという感じなんだろうと解釈したんだ.
そうすれば,staticが必要な意味が現れてくる.
だから,return N[i];が正しく返されるのかを質問したりしたんだ.return文で評価した値をどうやって呼び出し元に持ってくるのかがわかってればこんな質問はしなかった.
return N[i];に至っては,N[*(&i)]てな感じになって呼び出し元にもっていくのだと思ってた.
>>229 a = HOGE();で,HOGE()が評価されたときに,HOGE()の実行結果の値をどうやって,呼び出し元にもってくるのかが問題です.だから値渡しなのかどうかって話になったんです.
>>242 >a = HOGE();で,HOGE()が評価されたときに,HOGE()の実行結果の値をどうやって,
>呼び出し元にもってくるのかが問題です.だから値渡しなのかどうかって話になったんです.
どうやって呼び出しに持ってくるかは処理系依存。
C言語の仕様として決まってないし、決めても仕様がない
ゆとり君が気にしてることは、ある意味正常な好奇心だわな。 その答えを手にするにはC言語のコードがどういう風に アセンブリコードに落とされるかを調べないといけない。 C言語のレイヤーでは答えはでないよ
戻り値の実装はどうでもいいんだよ 大抵はスタックに積むんだろうけど
適当に EAX レジスタとかいってみる
俺の環境(PCとPSP)だとサイズが収まれば 返値はレジスタに入ッてるな。
おまいら、結論はstatic変数にするな、准教授はC言語素人、ってことでFA なんだから蒸し返すなよ
249 :
デフォルトの名無しさん :2008/11/16(日) 21:21:54
>>235 配列で渡す(つまり、ポインタで渡す)ならわかるが、
ポインタ配列で渡すのはまったく一般的ではない。
>>242 >a = HOGE();で,HOGE()が評価されたときに,HOGE()の実行結果の値をどうやって,
>呼び出し元にもってくるのかが問題です.だから値渡しなのかどうかって話になったんです.
関数 HOGE() は、自身が return xxx; で呼び元に戻る時、戻り値xxxの値をレジスタ(例えばEAX)
などに入れて戻ります。 そして呼び元の a = HOGE(); に戻った時点での右辺の評価とは、その
レジスタ(EAX)の値を評価するということです。つまりxxxの値ですね。
あと、C言語の関数インターフェースレベルでは値渡しとか参照渡しの概念は無いよ。
プログラマの手によって、ポインタやアドレス演算子を使った参照ライクなコーディングも
可能ですよ、という仕組みが盛り込まれているだけなのです。
C言語の仕様によって、ポインタとアドレス演算子という便利素材が用意されているだけです。
スレチ承知なんだけど function func_name() { func_name = 0; } a = func_name(); という感じで、関数名に値を入れることで右辺値とする言語があったように思うんだけど、 なんだっけ?記憶が薄い辺りで探るとvbかpascalかその辺だと思うが。。
JavaScript?
学びて思わざればすなわちくらし、思いて学ばざればすなわちあやうし 知識がないのにあーだーこーだ理屈を捏ね回すのはよくない。 同様に、教科書読んだだけでC言語マスターしますた、なんてのもよくない。 バランス、大事。
>>256 ん、同意します。でも、個人的にはコードを書いた量を信頼します。どなたかの真似をすれば
「書いたコード量は裏切らない」
>>253 昔のbasicだな
>>254 関数ポインタの話と誤解して無いか?
関数名に代入すると返り値になるとこじゃないかな
バランス厨氏ね
みんな新弟子前
>>259 そう。関数名に代入すると返り値に、のところ。
basic由来なのね。ありがとう。自分が最近使ってる言語では
やらないから思い出せずむずむずしてたんだw
ちがうだろww昔のbasicに関数なんてねーよw VB.NETでは使えるな
知識に見合った技術が無いといけない アマチュアとプロで言えば 知識の量 アマチュア>プロ 技術の量 プロ>アマチュア になる
Cでcgiを作ったことのある人はいますか?
はい。
269 :
デフォルトの名無しさん :2008/11/16(日) 23:42:45
{ } の対応が、どう見ても、何度見直しても合ってるのに、コンパイルが通らなくて、 } を一個消すとコンパイルが通る・・・。 こういうことってあり得るんでしょうか?原因は何でしょうか?
たぶん}が一個多かったんじゃないかな?
実は一つコメントになっていたとか、条件コンパイルの対象になっていたとか、なんかあるんでしょ。
"が開きっぱなしとか
273 :
デフォルトの名無しさん :2008/11/16(日) 23:54:12
ノーマークなトライグラフ発動したとか? ??> が文中の何処かにある?
275 :
デフォルトの名無しさん :2008/11/16(日) 23:58:05
ちなみに、while文の入れ子はできないってルールはありますか? それから、while文の中からreturnはできないってルールとか。。
>>275 ないよ。
正確には入れ子の深さ制限はあるかもしれないが
気にするようなレベルじゃない
278 :
デフォルトの名無しさん :2008/11/17(月) 00:06:48
>>275 お作法にルールで反論してもかみ合わないよ
279 :
デフォルトの名無しさん :2008/11/17(月) 00:10:22
>>274 ??>
というのは、??は任意の2文字ということ??中途半端に、>や)の片方だけを
使ってる部分はあるかもしれません。
けど、
}
だけの1行をコメントアウトすると、コンパイルが通り、きちんと動作するのが不可解で・・・。
>>276->277
ありがとうございます。
入れ子は2重なので深くはないですよね。
int main()
{
while( ){
if( ){
while( ){
}
}else if( ){
}
if( ){
}
}
}
のような感じで非常に長いので、あまりよろしくないプログラムであることは
間違いないのですが。上手い書き方がよく分からず・・・。
この場合、関数分けして短くすべきなんでしょうか・・・?
トライグラフというキーワードも一緒にもらえてるんだからそれで調べるぐらいの気概が欲しい
281 :
デフォルトの名無しさん :2008/11/17(月) 00:13:06
>>279 そのくらいの関数は普通ですけど。
あと、長いから分けるというのは感心しない。機能で分けてください。
>>279 > ??は任意の2文字ということ?
違う
文字通り ??> の組み合わせ。 プリプロセッサが ??> を } に置き換える
>>279 正味のところやりたいことによると思うが、各ifの条件文はwhileでのループ内容に依存してるかどうかとか、
関数化したら短くなった!の前に見直したらすっきりした!という結果になることはあるよね。
これぐらいで可読性を失うとかどんなエディタだよ
if や while の条件式部分が長く、そこに傾注しちゃって 肝心の { を開いてないオチに1票 (K&R スタイル記述でたまにやっちまうZE
エディタの機能で可読性が上がったという方は#regionでガベッジにふたをするタイプかなぁ。 そうじゃないといいんだけど。
292 :
デフォルトの名無しさん :2008/11/17(月) 00:29:21
>>290 windowsでいうところのメモ帳のようなエディタといえばよろしいでしょうか
>>269 思い込みは止めろ。ソースは嘘を付かない。
コメントになっていることはよくある。特にエディタに強調表示がないときには。
って、VIMかぁ、とりあえず:set showmatchしとけ
どこかにアップロードしたら、確かめてあげるよ。
295 :
289 :2008/11/17(月) 00:35:44
ここでemacserが颯爽と登場。 ヘッダファイルに{が多いのかもな
297 :
デフォルトの名無しさん :2008/11/17(月) 00:37:29
>>280 すみません。今調べてみたら、「??に続けて特定の文字を記述することで、ISO/IEC 646にない文字を表現する。」
とかなんとか出てきました。よく分からずにいたら、
>>283 でようやく意味が分かりました。
知りもしなかったので、それは使ってないですね。教えてくださって、ありがとうございます。
>>282 、
>>284 機能ごとに分けるとすると、既に機能では関数化されてるので、長く書くしかないですね。。
>>285 viエディタです。
印刷してマーカー引いて見直してもよかったんですが、時間がなくて・・。
>>297 viなのかvimなのかにもよるが、最近ならたぶん、
いずれかのカッコの上にカーソルを置いて%で対応カッコにジャンプしてくれるよ。
きゅーえっくす
>>297 プリプロ終了段階で止めて
ソースチェックしてみたら?
301 :
269 ◆omke6ataOI :2008/11/17(月) 00:47:48
すみません。キャップつけます。
>>289 は別の方です。私は vi 使ってます。
>>298 そうです。その%で括弧に飛んでるんですが、どう見てもあってるんですよ。
%で飛べば、コメントも関係なく飛んでくれるはずなので、コメントアウト
されてる可能性が一番高いかもしれません。
皆様、ありがとうございました。
インクルードファイルだと思うけどなぁ
整形ツールに通してみれば良いんじゃないかと
304 :
269 ◆omke6ataOI :2008/11/17(月) 00:52:59
>>300 そんなことできるんですか?どうやるんですか?
>>304 コンパイラのオプションとかで。
コンパイル環境は?
どうでもいいがHDDのドライバ書きそうな酉だな
>>301 vimと仮定して書くが、
ggVG=
とやって再インデントを行ってみては。
手癖がでてしまった。 gg=G のほうが楽か。コマンドモードで。
>>304 vi ってことはgccっぽいな。
-E オプションでコンパイルだ
質問です 10この配列の中から値が100の配列の添え字を戻り値とする関数は、 配列の添え字が戻り値ということで、unsigned int型とした方がいいのでしょうか? main(){ int ret; /* unsigned intとするべき? */ ret = read_soeji(); } unsigned int read_soeji(){ int i; /* unsigned intとするべき? */ for( i=0 ; i<10 ; i++) { if( array[i] == 100 ) { return( i ); } } } よろしくお願いします。
見つからないときの処理が入ってないぞ。
>>309 規格書をみていないのでアレなんですが、
実は
a[-5]
もアリで、コンパイル自体は無難にとおってしまいます。
ということで、普通の int 型でいいのでは、と思います。
>>309 それ、明示的にreturnされないパスがあるぞ。
それはそうと、read_soeji()の返り血をintにして、
値が100のが見つからない場合は負数を返して
エラーを判別できるようにするのが一般的
>>309 私ならint型にしておく。
添字は、int型の整数値ならよいから。
もうひとつ、見付からなかったときに、-1とか返せた方が便利だから。
>>309 つかさーアセンブラやってんなら返り血を
渡すコードがどうなってるか見てみるといいぜ
返す型でも変わるし
>>1 のテンプレにこれ追加
Cのレイヤーでは答えられない質問があります。
なのでその場合、回答者は質問に合ったスレッドへ誘導してください。
夜も遅いのにみなさん即レスありがとうございます。 修正してみました。 int read_soeji(){ int i; int ret = -1; /* 配列に100がない時retは-1 */ for( i=0 ; i<10 ; i++) { if( array[i] == 100 ) { ret = i; break; } } return( ret ); } こんな感じでどうでしょうか。
>>319 10返しちゃうよそれ。
int read_soeji(){
int i;
int ret; /* 配列に100がない時retは-1 */
for( i=0 ; i<10 ; i++)
{
if( array[i] == 100 )
{
return i;
}
}
return -1;
}
こんなんでいいよ
returnに括弧つけるのよく見るけど何で? i=(1); と書くのと同じようなもんだと思ってるんだけど、違う?
括弧つけると関数っぽく見えて何となく統一感があるからなだけ
>>322 returnが関数だと勘違いをしている人もいる。
そういう人は括弧をつける。昔のオレw
ifやwhileとかの制御系キーワードには括弧がつくので、 returnの後ろにも括弧があると統一感が出る・・・・ような気がするが、どっちでもいい
モテようとして、括弧つけちゃっている人がいるんですよぉ〜 なぁ〜〜にぃ〜〜!?やっちまったな! 男は黙ってぇ〜↓
括弧つけるとコンパイル時にエラーが検出されないと何度言ったら…
昔はつける必要があった
昔はなぁ、たった1倍とでも無駄にはできんかったとばい。 < と <= と、イコール1文字でも省略できる条件があるなら、そうしたとばい。
1倍とじゃなくて、1バイトねw 改行も叱り。中括弧の位置とか。
むしろ1行何円というバイトの給与形式だったので必死に延ばしてたぜ
>>326 男は黙って exit
男は黙って exit
C言語における神様のパズルとは何か いくつか提示せよ
軍曹殿、それは命令ですか?
335 :
デフォルトの名無しさん :2008/11/17(月) 18:00:08
Red Hat Linux 9でC言語を初めよと思い簡単なプログラムを作成したけど gcc test.ccと実行すると -bash: gcc: command not foundになってしまう。 何故なの??
>>335 なんで、そんな大昔のOSを使ってるの?
>>335 非標準的なインストールをして、gccがインストールされていないのでは?
パッケージをインストールして適切にパスを通せば使えるはずですよ。
それはいいけど、拡張子".cc"はCじゃありませんよ。
>>335 シェルで
which gcc
をやってちゃんとあるか確認せよ。
確かRedHat9はデフォルト設定でプログラミング環境が入らなかった。
システム設定
アプリケーションの追加と削除
エディタ
開発ツール
のチェックボックスをチェックしてインストールせよ。
windows2000+VC6です。 beepを5秒位鳴らしたいのですが、非同期で鳴らす方法はありますでしょうか? スレッドを使わずに済ませたいのです。
342 :
デフォルトの名無しさん :2008/11/17(月) 21:19:05
スレッドを使いたくないのに非同期とな
>>341 スレッド使わなきゃそもそ(ry
マルチプロセスならおk?
>>341 非同期と同期を勘違いしてるとしてマジレス
1.時刻取得->t1
2.ビープならす
3.時刻取得->t2
4.t2-t1が5秒以下なら2へ
5.酋長
×酋長 ○終了
>>342-344 いや、5秒間鳴らしたいのですが、その間も処理をしたいのです。
PlaySoundとかのクラスが非同期をサポートしてた気がしたので、
beepにもないかなぁと思ったわけです。
MessageBeep?
350 :
デフォルトの名無しさん :2008/11/17(月) 22:15:23
Cしかできない物理科なんですけど就職先ってありますかね?
353 :
デフォルトの名無しさん :2008/11/17(月) 22:25:16
>>351 というような質問をしていることが最大のネックになるだろう
続きマ板でやれ
354 :
341 :2008/11/17(月) 22:25:37
>>347 MessageBeepを試してみました。
これってコンパネで設定されたWAVファイルが再生されるので、指定時間鳴らす事ができないようです。
>>348 何でって言われるとちょっと困りますが、5秒間メッセージに応答しないのは問題なのです。
355 :
341 :2008/11/17(月) 22:27:20
>>350 標準のCじゃなくてもよかったんですが、win32APIを使うとなるとC++になるって事でしょうか?
とりあえず、C++にして紹介されたスレで聞いてみます。
356 :
デフォルトの名無しさん :2008/11/17(月) 22:30:14
>>355 Win32API は C++ じゃなく C だよ
win32APIはCで使えるぞ
358 :
356 :2008/11/17(月) 22:34:13
>>357 正確にはそうだな
実際アセンブラで書いたことあるし
359 :
341 :2008/11/17(月) 22:35:48
>>356-357 了解です。CのままWin32Apiのスレで聞いてみます。つか、もう書きこみした。
あそこのスレはおかしな流れになってるので、レスが付くが微妙ですが・・・。
だめだああああ どうあがいてもファイルの分割コンパイルができない。 グローバル変数を使いたくて、ヘッダファイルに宣言書いて、重複定義の話とかインクルードガードとか externとか調べて一応理解もしてるつもりが、ずーーと無理だ。 絶対に既に定義されているとか言われちまう。ちくしょー
まあなんだ、ソースうpしてみなって
ifdef使いなよ
>>360 グローバル変数を使おうとする時点で間違っている。
ヘッダで変数宣言してるからじゃ?ヘッダに書くとインクルードしたファイル全部にその変数が宣言される。
まぁ、宣言だけなら問題ないな。問題は、定義をばら撒いてしまうことだ。
ヘッダーには extern 付きで宣言 分割ソースのうち、何処かのファイルの1箇所だけで extern 無しで宣言(+初期化) a.h extern int globalA; b.c #include "a.h" int globalA = 0; /* 初期化もついでに */ c.c #include "a.h" ...... globalA を参照・変更したーり
b.c では #include する必要なし
もう壊れかけで書きなぐっただけなのに色々教えてくれてありがとう 既になにが何やら分からんし疲れたのでまた今度ちゃんと質問しに来るよ。
おおう そうであった b.c は include 不要だね (組み込み型だし 構造体とかだと、結局 include するはめになるだろうけど
ポインタのメリットは? ややこしいだけで便利な感じが全くしないからイメージが掴めない 一応使い方は分かるけど全部数字渡せばいいんでないのかな?
>>371 双方向リスト構造を自分で実装してみれば
ありがたみがわかるよ
それで済むレベルならそれでいいと思うよ
qsort の立場が無くなる
realloc=re + allocのreはどの英単語が省略されたのですか?
接頭辞でぐぐれ
>>376 英語で普通によく使われる接頭辞 re- じゃないでしょうか?
>>376 省略っていうか、そういうもんなんじゃないの?
int array[10] = { 20, 30, 40, 100, 100, 50, 60, 100, 90, -1 }; この配列から100を削除し、前詰にする(空いたら最後に-1を追加)プログラムですが、 こんな感じでいいでしょうか? int i,j; while( (array[i] != -1) && (i<10) ) { if( array[i] == 100 ) { for( j=i ; j<10-1 ; j++ ) { array[j] = array[j+1]; } array[10] = -1; break; } else { i++; } } 2個連続で100が続いた場合、for文では2つ目を飛ばしてしまいそうですが、 for文でも方法がありましたら教えて頂けるとありがたいです。
while( (array[i] != -1) && (i<10) ) ↓ for(; (array[i] != -1) && (i<10); )
array[10]にアクセスするな
配列サイズで終わるのか、-1で終わるのかどっちかにしろ。 仕様が曖昧になって無駄に複雑になる。
元のプログラムがあちこち怪しいから書き換えてみたけど…… -- for(int i = 0; array[i] != -1 && i < sizeof(array) / sizeof(* array); ++i) { if (array[i] == 100) { for (int j = i; j < sizeof(array) / sizeof(* array) - 1; ++j) { array[j] = array[j + 1]; } array[sizeof(array) / sizeof(* array) - 1] = -1; --i; } } -- ちゃんと考えていないから合ってなかったらゴメン。
void reduce100(int array[]){ int *p, *q; for(p = array; *p != 100; p++) if(*p == -1) return; q = p + 1; while(*q != -1){ if(*q == 100){ q++; continue;} *p++ = *q++; } *p = -1; }
>>376 re-freshとかre-turnとかre-unionとか
void reduce100(int array[]){ int *p, *q; for(p = array; *p != 100; p++) if(*p == -1) return; for(q = p + 1; *q != -1; q++) if(*q != 100) *p++ = *q; *p = *q; }
遅い時間にみなさんありがとうございます。 forで書くとやっぱりわかり辛いので、指摘頂いたのを修正しまして int i,j; while( (array[i] != -1) && (i<10) ) { if( array[i] == 100 ) { for( j=i ; j<10-1 ; j++ ) { array[j] = array[j+1]; } array[10-1] = -1; break; } else { i++; } } これでどうでしょうか。
20 30 40 100 50 60 100 90 -1 -1 だな。
てか、i 初期化してねーぞ。
ごめんなさい、これでどうでしょうか int i=0; int j; while( (array[i] != -1) && (i<10) ) { if( array[i] == 100 ) { for( j=i ; j<10-1 ; j++ ) { array[j] = array[j+1]; } array[10-1] = -1; } else { i++; } }
>>391 i==10のときにarray[10]を読んでしまうのはまずいので、
&&の左右を入れ替えるべし。
while( (i<10) && (array[i] != -1) ) {
あとはいいと思う。
俺はもう頭が弱ってしまっているので 作業配列を用意して、そこに元の配列をコピーして、 作業配列を読みながら100以外を詰めていくようにしてしまうな
>>380 クソースだというのは内緒でおじゃる
#include <stdio.h>
#define DEL 100
#define END -1
int main(void) {
int array[10] = { 20, 30, 40, 100, 100, 50, 60, 100, 90, -1 };
int i,j,array_sz=sizeof(array)/sizeof(array[0]);
for(i=0,j=0; i<array_sz; i++) {
if(array[i]==DEL) j++;
else array[i-j]=array[i];
}
for(i=array_sz-j; i<array_sz; i++) array[i]=END;
for(i=0; i<array_sz; i++) printf("%d ",array[i]);
return 0;
}
ありがとうございます。 心置きなく寝れます。
そうか、安らかに眠れ・・・
色々やってもうだめだと思ったら 大文字と小文字違ってやんの・・・俺の3時間かえせーーー
___ ,r' `ヽ、 ,i" ゙; !.(●) (●),! ゝ_ _,r'' / ;;;;;; ・・ ;;;;) それは報告しなくてもいいです。 / (_ | f\ トェェェイノ  ̄`丶. | | ヽ__ノー─-- 、_ ) . | | / / | | ,' / / ノ | ,' / / | / _ノ / ,ノ 〈 ( 〈 ヽ.__ \ ヽ._> \__)
シグナルハンドラを使うメリットを教えて下さい。
float同士計算してて 表現できる範囲こえると何が表れるの? 1231e-39をこえると、完全に0になるわけ?
1231e-99を超えるっていうのかそれ。 確かに精度を割り込んだら0になるけど。
floatで小数点の計算をしてて、でた結果をlogとるときに nanがでるケースがあるとおもうんだけど、 どういうケース?log(0)=nanなんだけど
負数でも入れたんじゃね
確率計算だから負はないんです。 0で表現できなくなったからnanになったと考えるしかないかな
本当はぴったり0になるはずのところ誤差でマイナスになったとか
そんなくだらないことより日本終了のお知らせですよおまいら
409 :
デフォルトの名無しさん :2008/11/18(火) 15:35:50
#include <stdio.h> #include <stdlib.h> #include <string.h> struct node { char *item; }; int main(void) { int i; char n[100]; struct node **a, *b; a = malloc(sizeof(*a)); for (i=0; i<3; i++) { fgets(n, 100, stdin); b = malloc(sizeof(*b)); b->item = (char*)(b+1); strcpy(b->item, n); a[i] = b; } for (i=0; i<3; i++) printf("%s\n", a[i]->item); } このポインタの配列a[i]->itemを、2次元配列a[i][j]->itemとして実現したいのですがどうすればよろしいでしょうか? a[i][j]->item = b; としてもうまくいかないので・・・
そりゃ a が struct node** なら a[i] は struct node* だし、てことは a[i][j] は struct node なんだから a[i][j].item でええやん。
>>409 その前に色々バグを直した方がいいんじゃないか
二次元配列の動的確保をしたいならこれで我慢しなさい foo **bar; bar = malloc(sizeof(foo *) * A); for(i = 0; i < A; i++) bar[i] = malloc(sizeof(foo) * B); bar[a][b] = hoge; for(i = 0; i < A; i++) free(bar[i]); free(bar);
413 :
409 :2008/11/18(火) 16:05:56
>>411 一応動く程度には作ってみたのですが、どこを直せばよいでしょうか?
なんで自分で考えないの?
分からないグズは黙ってろ
ポインタの解釈がおかしいからでは?
>>413 strcpyでコピーしてる先はどこで確保してんの?
b+1がどこを指すかわかってる?
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 10 #define N 3 struct node { char item; }; int main(void) { int i, j, k; char n[MAX]; struct node **a; a = (struct node **)malloc(sizeof(a) * N); for (i = 0; i < N; i++) { a[i] = (struct node *)malloc(sizeof(*a) * MAX); gets(n); for (j = 0; j < (int)strlen(n); j++) a[i][j].item = n[j]; for (k = j; k < MAX; k++) a[i][k].item = '\0'; } for (i = 0; i < N; i++) { for (j = 0; j < MAX; j++) printf("%c", a[i][j].item); putchar('\n'); free(a[i]); } free(a); return 0; }
419 :
409 :2008/11/18(火) 17:11:05
>>418 for (i=0; i<3; i++) {
for (j=0; j<3; j++) {
gets(n);
すみません、i*j入力してi*j出力する意味で2次元配列と書いたつもりだったのですが・・・
>>419 お前の目はフシアナか
for (i = 0; i < N; i++)
for (j = 0; j < (int)strlen(n); j++)
421 :
デフォルトの名無しさん :2008/11/18(火) 17:26:05
/* aを入力した場合「正解です」と表示し、そうでない場合「不正解です」と表示し、 aが入力されるまで繰り返すプログラム*/ #include <stdio.h> int main(void); int main(void) { char moji; while(1){ printf("aを入力して下さい。\n"); scanf("%c",&moji); if( moji=='a' ){ printf("正解です\n"); break; } else{ printf("不正解です\n"); } } return (0); } 実行結果 aを入力して下さい。 s 不正解です aを入力して下さい。 不正解です aを入力して下さい。 こうなってしまいます。 どうしたらいいんでしょうか?
いいんじゃない?どうでも
423 :
409 :2008/11/18(火) 17:27:19
>>420 jをそのように使うのではなく、iと同じように行列で入力したいという意味なんです(3*3入力のように)
>>421 改行文字を入力しているのに、それを読み飛ばしていないから。
425 :
421 :2008/11/18(火) 18:10:05
改行文字の意味は分かりますが、 読み飛ばしていないからと言うのはどういう意味なのでしょうか?
入力された改行文字は、次回のscanf()で収容されるのです。
scanfの次にこれ入れてみては。 printf("(%#2x)\n", moji);
428 :
421 :2008/11/18(火) 18:19:44
どのようにして読み飛ばせばいいのでしょうか? 例をあげて頂ければありがたいです。 何度もすいません。
>>423 という事は i や j を数値で入力するという意味ですか?
ご呈示のソースでは行が横方向に繋がった文字列として
書かれていますのでどっちみちその書き方では[i][j]のように
アクセスする事はできません。
>>421 scanf("%c ", & moji)
431 :
421 :2008/11/18(火) 18:28:37
ダメです、変わりません。 どうしたら・・・
getchar()
ダミーでscanfの前にscanf("%*");するとか
434 :
421 :2008/11/18(火) 18:40:27
getchar()でも結果は同じorz
435 :
421 :2008/11/18(火) 18:46:22
433さんありがとうございます。 無事できました!!
>>423 こういう事?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 10
#define N 3
struct node {
char *item;
};
int main(void)
{
int i, j;
char n[MAX];
struct node **a;
a = (struct node **)malloc(sizeof(a) * N);
for (i = 0; i < N; i++) {
a[i] = (struct node *)malloc(sizeof(*a) * N);
for (j = 0; j < N; j++) {
a[i][j].item = (char *)malloc(sizeof(char) * MAX);
gets(n);
strcpy(a[i][j].item, n);
}
}
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++)
printf("%12s", a[i][j].item);
putchar('\n');
free(a[i]);
}
free(a);
return 0;
}
あ、free(a[i][j].item); 忘れてたわ 付け加えといて
438 :
409 :2008/11/18(火) 21:27:51
>>436-437 どうも分かりやすいスマートなプログラムをありがとうございます(o*。_。)oペコリ
ポインタの考え方もとても参考になりました。
>>438 gets()じゃ危険でfgets()を使いたいのなら行末に'\n'が入るから
取り除かないと表示が変になるよ
0〜30までの乱数(小数5ケタ)を発生させる方法を教えてください
メルセンヌツイスタでおk
0〜10までの乱数を割り算を使わずに表示するメソッドを作成したいのですが、どのようにすればよいでしょうか?
0-10がでるまで頑張って返す
>>443 C言語のプログラムファイルを元にプログラムを作成して、それを変換して使うのですが、変換後の媒体では割り算が使用できないためです。
自分で割り算の処理を作ればいいじゃない。
>>445 それはその「変換後の媒体」について聞くべき場所で聞くことじゃないのか
448 :
デフォルトの名無しさん :2008/11/18(火) 23:28:10
>>445 乱数の種を配列で作っておき、それをローテーションして使うとか?
十進文字列にして一の位を取り出す
450 :
デフォルトの名無しさん :2008/11/18(火) 23:30:39
>>445 ハードウエアで乱数を作る方法をもしかして知っているか?
10より小さくなるまで10で減算を繰り返せば10で割った余りが求められるよ!
もう下位4ビットだけ使えば
お前ら何を言っているんだ。 >442は「表示する」メソッドが欲しいんだぞ。 乱数生成はきっと既にあるに違いない。
じゃ割り算いらねぇじゃんよ
strcpy("hogepiyohogera","AAAA"); って、BCCでコンパイルエラーにならないんですが、大丈夫でしょうか? char *strcpy(char *s1, const char *s2); 第二引数の方はいいとして、第一引数は"hogepiyohogera"(const char *ですよね??)をchar *に変換しているようで、全く大丈夫な気がしないんですが…。
Cでは慣習的に(互換性のためにも)文字列リテラルをchar *にそのまま渡せる。 結果どうなろうとそんなの関係ねぇ。
BCCのコンパイラオプションに -d (重複文字列をマージする)ってのが
あるからこれをONにしてコンパイルして
>>455 みたいのを試すと
同一文字が全部書き換わってワロス
なるほど。無茶が残ってるんですね。 あと、 char sz[42]; strcpy(sz,"HOGE"); *(sz+2)='C'; が問題ないのは分かりますが、 char *sz; sz="HOGE"; *(sz+2)='c'; って大丈夫なんでしょうか? これまたconstなところを書き換えようとしているように見えるのですが、BCCは何らモンクを言いません・・・。
>>458 一応規格では unspecified(不定の動作)になる
BCCでは問題ないようだがコンパイラによっては本当にread onlyの
領域に文字列がマップされてコアダンプ起こすことがある
460 :
デフォルトの名無しさん :2008/11/19(水) 00:12:32
なるほど。 あのコードを走らせてマシンから火が吹いても俺のせいなわけですね。 どうもありがとうございます。
#include <stdio.h> int main() { char *a = "abc", *b = "abc", *c = "abc"; *(a + 1) = 'd'; printf("%s %s %s\n", a, b, c); return 0; } bcc32.exe -d test.c test adc adc adc
ISO9899:1999§6.4.5.6 It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined. 悪い未定義(undefined)と書かれていた
そうなるとK&R第2版P128に「結果が不定となるので注意がいる」 というのは誤訳かはたまたC89に限った事なのか
fscanfでファイルから値を読み込みたいんですが、 FILE *fp = fopen("data.dat","r"); float x,y; if(!fp) return 1; while(fscanf(fp,"%f %f",&x,&y) != EOF) printf("%f %f\n",x,y); fclose(fp); これはどこかのサイトに載ってたのをほぼそのまま借りたのですが、 これだとdataファイルの中身の値、例えば0.123・・・などの整数値が0の場合printfを使ったとき 1,23・・・のように初めて0ではない数が現れるとその数値が整数部になってしまいます。 これをそのまま0.123・・と印字できるようにしたいのですが、御教授お願いします。 値がマイナスの場合はそのまま印字されてました。 ファイル内の値はただの数でなく0.12345E+00のようになっていてE以前の数値の部分だけ読み込んで印字できるようにしたいです。 上のプログラムでは一応不要な部分は消えてました。
>>465 %f であれば実数表現(0.123) になりませんか?
%e であれば浮動小数点表現(1.23e-01) になりますが、これを非正規化?のままで出力する(0.123e-00) のは、
printf() ではわかりません。
そのプログラムをそのまま実行したら 0.123450 0.123450 となったが、これじゃいかんの?
468 :
デフォルトの名無しさん :2008/11/19(水) 00:52:36
>>464 あの本はコンセプトを綴った本で、明確な定義を求めてはいけない
一行に数値が4つ並んでるんですよ。 0.588235E-01 0.300000E+01 -0.299827E+01 0.1500000E+01 とりあえずこの1行だけををファイルに書いて、プログラムを走らせたら結果は 0.058823 3.000000 -2.998270 1.500000 ってなりました・・・マイナスの奴もずれてましたw
0.123e1をscanf("%f")で読んでprintf("%f")したら1.230000と出る、って話じゃないかな?
指数表記での仮数部をとりたいなら、文字列として読んでいらない所を捨てるしかないかな。
>>465 "0.12345E+00"はE+00まで含んで一つの数値の書き方(これを指数表記という)なんだけど、
大丈夫ですよね?
>>470 恥ずかしながら今初めて知りました・・・
ってことはE+〜、E−〜の部分がちゃんと計算されて桁が繰り下がったり、上がったりしてた
ということですか・・
レス下さった方々有難う御座いました、かなり恥ずかしいです
ファイルを取り込み、それを構造体として格納し、 numの大小によってそれらを入れ換えるプログラムを書きたいのですが、 どうやってもセグメントエラーになってしまいます。 同じ型で二つの構造体変数を宣言していて、 ひとつの構造体変数同士の入れ換え(例 a[1]=a[2];)は問題なく動いているようなのですが、 別々の変数で入れ換えを行っているとき(例 b=a[1];)でエラーが返されているようです。 どうすれば正しく動くようになりますでしょうか?
#include <stdio.h> struct data{ char a[21]; char b[21]; int num; }s[21],t; main() { FILE *fp; int count,i,j; fp=fopen("test.dat","r"); for(i=0; ; i++){ if((fscanf(fp,"%s %s %d",s[i].a, s[i].b, s[i].num))==EOF){ break; } else count++; } fclose(fp); for(i=0; i<count; i++){ t=s[i]; for(j=i+1;j<count;j++){ if(t.num<s[j].num){ t=s[j]; s[j]=s[i]; s[i]=t;} } } for(i=0; i<count; i++){ printf("%s %s %d\n",s[i].a, s[i].b, s[i].num); } return 0; }
474 :
デフォルトの名無しさん :2008/11/19(水) 18:44:29
コンパイラBorland C++ Compiler 5.5を使ってコマンドプロンプトでコンパイルしたいのですが "インクルードファイル`stdio.h`をオープンできない"って表示されてコンパイル出来ないのですが なにが原因なんでしょうか?教えてください
コンパイラ初期設定はしたんだろうな?
476 :
デフォルトの名無しさん :2008/11/19(水) 18:47:34
しょ、初期設定とはなんでしょうか?
ヒント:bcc cfg
>>472 そもそも
>>473 のコード動くのか?
count を0に初期化することと、s[i].numは&s[i].numじゃないのか?
480 :
デフォルトの名無しさん :2008/11/19(水) 18:51:00
あ、それはあります。 置く場所が間違っているのでしょうか・・・ bcc55に入れてあるのですが。
481 :
476,480 :2008/11/19(水) 18:56:14
ググったら解決しました^^ ありがとうございました
すいません 人のふりするのは止めてもらえませんか
当人はググっってみたの?
484 :
デフォルトの名無しさん :2008/11/19(水) 19:10:04
GCCの件です。
>>336 2003年から放置状態でした。
>>337 ダウンロード済みのやつを買ったので不明です。拡張子はcですか?
>>340 which gcc を実行したところ no gcc でした。
インストールしてみます。
485 :
481 :2008/11/19(水) 19:13:59
すみません・・・当人です・・・ まじで、ググったら解決しました。
ファイルからの読み込みを構造体の各配列に格納したいのですが、上手くいきません。 #include <stdio.h> typedef struct Student{ char number[4]; char name[8]; } Student; int main(){ char fname[32]; int i=0,j; FILE *fp; Student sdt[8]; printf("filename:"); scanf("%s",fname); scanf("%*c"); fp=fopen(fname,"r"); if(fp==NULL){ printf("error\n"); break; } while(){ fgets(sdt[i].number,3,fp); for(j=0;sdt[j].number!='\n';j++); sdt.number[j]='\0'; fgets(sdt[i].name,7,fp); for(j=0;sdt[j].name!='\n';j++); sdt.name[j]='\0'; i++; } return 0; } ファイルには、構造体の配列に対応するデータが1行ずつ書き込まれています。 例:(「」の内) 「101 太郎 102 次郎 … 」 ファイルの最後は改行され、最終行は何も無い状態です。 とりあえず1行ずつ読み込めばいいのかと思い作ってみましたが、ループ部の条件で躓きました。 どなたかご教示お願いします。
まず、windows環境ならファイルを"rt"で開くこと 次に、fgetsの仕様をよく読みなおすこと
つ−かコンパイルでエラーするのでは
>>486 iカウンタを使うならwhileよりforのほうがわかりやすいし、初期化忘れ対策にもなる
fgetsは最大で指定した文字数-1文字まで読み込む関数
3と指定したら2文字しか読み込まない
3桁の数字の行は\nを含めて4バイトになるから
終端ヌル文字を加えてバッファは5以上ないといけない
\nをはじくのはいいが、必ずあると決めてかかるのは危険
ない場合にも処理できるようにすること
あと、本当は行の長さが長すぎた場合の処理も必要
終了条件は二つ
・用意したバッファが満杯になる
・正しく読めるデータがない
それから配列の添字の使い方があちこち間違ってる
>>478 countはコピペミスで、ご指摘の通りcount=0になっています。
&については、つけなければコンパイルを通り、つけると不適切な代入としてエラーが返されます。
創価学会は詐欺集団です。 池田大作という名前はウソで、本当は朝鮮人です。 創価は日本人から金をしぼりとる朝鮮企業です。 俺が見たのは2つの封筒で、片方には2枚プリントが入っていて もう片方は1枚プリントが入っていて、両方あわせて約4万円です。 朝鮮人には無料で配られますが、日本人は4万円で買わされます。 仏壇も朝鮮人なら無料で貸してくれます。 日本人は3000万円以上の仏壇を買わされます。 引越しも朝鮮人なら無料です。 (いつも仏壇をちょっと運ぶだけでたくさん金をもらってるから) 今から創価学会に入る人は本当にバカです。 そのバカな人のおかげで印刷所・引越し業の人が生活できる。 悲しいけどこれが現実なのよね。
493 :
デフォルトの名無しさん :2008/11/19(水) 20:32:51
>>340 エディタ、開発ツールのインストールの途中にインストールDISK1ディスク
を挿入して下さいと表示されましたがうちの自宅サーバにはCD-ROMドライブが付属していないので困っています。
一応、RedHatLinux9のCD-ROMの内容はPCに保存されているようです。
どうすればいいのかがわかりません。
TeraTermProから操作しています。
宜しくお願いします。
>>493 rpmはもってるってこと?
なら
rpm -ivh /path/to/gcc.rpm
>>493 CDドライブぐらい買った方がいいんじゃないの?
496 :
486 :2008/11/19(水) 21:46:01
ご回答ありがとうございます。理解できた範囲で修正してみました。 #include <stdio.h> #include <stdlib.h> typedef struct Student{ char number[8]; char name[16]; } Student; int main(){ char fname[32]; int i=0,j; FILE *fp; Student sdt[8]; printf("filename:"); scanf("%s",fname); scanf("%*c"); fp=fopen(fname,"rt"); if(fp==NULL){ printf("error\n"); exit(0); } for(i=0;i<8;i++){ fgets(sdt[i].number,4,fp); for(j=0;sdt[i].number[j]!='\n';j++); sdt[i].number[j]='\0'; fgets(sdt[i].name,8,fp); for(j=0;sdt[i].name[j]!='\n';j++); sdt[i].name[j]='\0'; } return 0; } 改行コードはあるものとしてお願いします。 読み込むデータが無い場合の条件の表現がわかりません。 fgetcとEOFを上手く使うのでしょうか。
板違い
>>496 だからfgetsの仕様をちゃんと読めって
500 :
496 :2008/11/19(水) 21:56:22
>>498 申し訳ありません。おっしゃっていることが理解できないのですが。
fgets()を使用するとアクセス位置が次の行に移ると認識しているのですが、誤解でしょうか。
これ以外には思い当たる節がありません。
>>500 たぶん、かなりの初心者なんだと思うけど
4文字読むとか8文字読むために fgets は、普通、使わない。
fgets は1行丸ごと読むために使う。
char buf[1024]; // 十分なサイズ
fgets(buf, sizeof(buf), fp);
とかしておいて、そのあと読んだデータを加工するのが、普通の使い方。
strcpy(sdt[i].number, buf);
for(j=0; sdt[i].number[i] ; j++)
if(sdt[i].number[j] == '\n' ) sdt[i].number[j] = '\0';
だれかscanf()は使うなってアドバイスしてやればいいのに。
scanfマジオススメ。
>>501 そういう風にするなら
char *p;とでも宣言しといて
char buf[1024];
fgets(buf, sizeof(buf), fp);
if(p = strrchr(buf,'\n'))
*p = '\0';
てしたほうがすっきりするかな
>>500 fgets()はファイルエンドに達したときにヌルポインタを返す
これを使って終了条件を設定する
>>504 strrchr()じゃなくてstrchr()でいいよ。どうせ改行文字は高高一つしかないからね。
組み込み系とかは抜きにしてイマドキの環境でヒープとスタック領域が 衝突するなんて起こりえる? メモリのアロケーションはOSとコンパイラとどちらに依存しているのかえ
508 :
486 :2008/11/20(木) 00:19:34
なんとか形になりました。 助言ありがとうございました。
>>507 今時のなら起こりえない、間に衝突を塞ぐ的なものがある
>>509 ssとdsは違う、とおもっていていいのでしょうか?
MMUがあるからな
>>511 それは windowsも?linux も?
windows って ss=ds ではなかったでしょうか?
isspace()はどのように実装されているのですか?
>>513 実際どうなってるかは知らないけど、その手のは大体テーブル使ってるらしいよ、主に速度面の理由から
>>512 今時、セレクタ(セグメントレジスタの値)は関係ない。
Win32の場合、EXEファイルに使用するスタックの量を指定しておき、
実行開始時、それだけのアドレス空間が予約されるようになっている。
アドレス空間を予約してしまえば、ほかの用途(ヒープなど)で手を出すことは不可能。
しかも、指定された量を超えてスタックを使おうとすれば、スタックオーバーフローとして例外処理される。
516 :
デフォルトの名無しさん :2008/11/20(木) 03:32:02
int isspace(int c) { if((c >= 0x09 && c <= 0x0d )|| c == ' ') return 1; else return 0; }
locale対応の必要性もなかったっけ?
誰もがうなる1行ハックコードを教えてください。僕が感動したらあなたの勝ちです
format c:
C言語はschemeみたいにステップ実行、つまり順番にどのような作業が行われているかを 1ステップごとに見ることはできないのですかね? ビルドはできても正常な値を出せないときはプログラムを地道に調べていくしかないのでしょうか? どこまで正解で、どこから自分の考えた値を出せていないのかを知りたいのですが… 初心者丸出しな質問ですいません。
>>520 それはデバッガの話であって
Cだからとかそういう話では無かろうよ。
環境は何?
えーと、デバッガというものがあってね。
ファイルが開いてるか開いてないか状態を調べる関数とかってありますか?
>>523 fopen/openしたら?オープン済だったらエラーになるだろ。
つか、それ以前にオープンしたかどうかはプログラムで把握していないといけない。
>>524 実行環境依存じゃね?
マルチプロセスOSで 同一のファイルを 両方とも read で開くのはOK とか
昔々ひとつのファイルをread と write で開いて中身消滅させたことがあるな
>>524 排他処理してたらエラーにならないわけで(ファイルが閉じるまで待つようにしていれば)、それ以外の方法を知りたいのです
OSによって違うんだから環境依存
>>527 複数のプロセスで同じファイルにアクセスするってこと?
アクセスはreadのみ?writeのみ?readとwrite?
>>529 テキストファイルを、他のプロセスから開かれてないかチェックしたいのです
>>530 そのプロセスというのが自分の身内ならそこに問い合わせろ
関係ないプログラムなら環境依存
だーかーら OS依存だってば 自プロセスが read で開いている間に 別プロセスが read で開く/write で開く とどーなるか? 自プロセスが write で開いている間に 別プロセスが read で開く/write で開く とどーなるか? 別プロセスが read で開いているファイルに対して 自プロセスが read/write で開くとどーなるか? 別プロセスが write で開いているファイルに対して 自プロセスが read/write で開くとどーなるか? C言語のレベルでは上記の振る舞いに対し どうあるべきかの規定は無い
環境ごとのスレで聞け WindowsならWIN32APIのスレ
WindowsとかLinuxとかそれぞれがそれぞれの流儀を持っている領域。 C言語の標準規格の枠組みでは方法がないということ。
そもそもCにはプロセスという概念すらない
言語仕様はそうだろ。でも標準関数まで枠を広げたらプロセスの概念はあるだろ。
かなり基本的なことかつ、情報量が少ないかもしれませんがよろしくお願いします。 今Cで卒論をやってまして、フィッシャー識別器を作ってます。 ソース等は明かせませんが、2つのクラスのサンプルを読み込み、 再代入法で誤識別率を求めるパターン認識系のプログラムです。 入力パターン数を変動できるようにしていまして、 最小な誤識別率を出すパターンの組み合わせを最良優先探索法で導いています。 入力パターン数が9以下の時は動作自体に問題はないのですが、 10以上になると計算用のdouble型配列tmp[]の中身にNaNが入ってしまうことがあります。 自分の考察としては、Cで利用できる記憶領域の許容量をオーバーしたため、 他に記憶しようとした値がtmpのアドレスに上書きされてしまったのではと考えているのですが、 そのようなことはあり得るんでしょうか。 また、情報が少なくて申し訳ないのですが、あり得ないなら他にどのような理由が考えられるでしょうか・・ よろしくお願いします。
十中八九、計算式が間違っているだけだと思う。
541 :
539 :2008/11/20(木) 14:43:22
連投すみません、開発環境は以下になります。 WindowsXPSP3 エディタ:C言語を始めよう + コンパイラ:Borland C++ また、友達とペアプログラミングしており、その友達の環境は WindowsXPSP2 Visual C++ です。 両方ともC++のコンパイラですが、C++は知らないことと、 ソースはCのつもりで書いたため、こちらで質問させていただきました。 よろしくお願いします。
542 :
539 :2008/11/20(木) 14:47:26
>>540 さっそくのお返事ありがとうございます。
計算式ですか‥
入力パターン数9の時も10の時も、作業自体は変わらなく、
いうなればループの数が増えているだけなのですが、
9の時はうまく動作しているので問題ないかと考えていました。
もう一度じっくり見直しつつこちらをのぞかせていただきます、
ありがとうございます。
計算式があっていても、計算結果によってはNaNがはいることがある。 浮動小数点のフォーマットでは表現しきれない数値など
544 :
539 :2008/11/20(木) 14:55:21
>>543 お返事ありがとうございます。
そのようなことがあるのですか、それかもしれません。
そこで扱う値はとても小さく、ほぼ0と言ってもいいようなものなので・・
ありがとうございます、すぐにその方向で進めてみます。
業務連絡でスレの私物化は自重!
546 :
デフォルトの名無しさん :2008/11/20(木) 15:23:49
条件式にbit演算が使われている場合の真偽判定について教えてください. 例えば以下のようなソースは,どのように真偽判定が行われるのでしょうか? char dat=0xaa; int i; for(i=0;i<8;i++){ if(dat & 0x80){ ; ; ; }else{ ; ; ; } dat<<=1; } よろしくお願いします.
547 :
デフォルトの名無しさん :2008/11/20(木) 15:25:37
条件式にbit演算が使われている場合の真偽判定について教えてください. 例えば以下のようなソースは,どのように真偽判定が行われるのでしょうか? char dat=0xaa; int i; for(i=0;i<8;i++){ if(dat & 0x80){ ; }else{ ; } dat<<=1; } よろしくお願いします.
if(dat & 0x80) ↓ if((dat & 0x80) != 0)
549 :
デフォルトの名無しさん :2008/11/20(木) 15:33:11
548さん 見ている雑誌(トランジスタ技術2006年6月号)のソースコードには if(dat & 0x80) と書かれていましたが?
if((dat & 0x80) != 0)と同じ意味ということ。 Cでは、条件式において0以外ならすべて真として扱われる。
>>490 遅くなり申し訳ありません。
パソコンが壊れて動かなくなってしまい、復旧作業をしていました・・・。
"&"は下のtempに関する "=" の時につけていました。
また、t.numとs[i].numはどちらもint型の値なので、片方に"&"をつけると
ポインタと整数の比較というエラーが返されてしまいます。
552 :
デフォルトの名無しさん :2008/11/20(木) 15:42:29
550さん なるほど!ありがとうございました
fgets(buf,10,stdin); で標準入力に「test」と入力すると、 bufには必ず"test\n"と格納されているのでしょうか? それとも、Windows環境では"test\r\n"となるのでしょうか?
テキストモードでオープンしているなら前者 stdinがテキストモードのままなら\n
内部では必ず\nになるのですか。ありがとうございました。
内部? 前者って「必ず」にはかからん、すまん。 \r\n → \n の変換があるのがテキストモード
stdinがテキストモードならCRLFがLFに変換されてbufには"test\n"が格納され、 そうでなければそのままbufには"test\r\n"が格納される、 ということでいいのでしょうか?
キーボードでリターンキー入れた場合はそうだね。 試しに、_setmode(fileno(stdin), O_BINARY); と比べてみるのもいいかも。
EOFも
562 :
デフォルトの名無しさん :2008/11/20(木) 20:55:52
メイン関数の型がvoidだとどうなるのでしょうか? またint型との違いはなんでちゅか?
563 :
デフォルトの名無しさん :2008/11/20(木) 20:57:01
www 訂正です。 なんでちゅか→なんですか
戻り値の型が void なのは規格違反。 プログラム終了後に異常動作が起こっても文句は言えない。
いやいや、開始前からおかしなことになっても文句言えないだろ。
そもそもコンパイルエラーになっても文句は言えないな。
どうしてexit関数があるのかと
深い所で終了するため。
>>564 規格違反ではないだろ。void main'void)でコンパイラは通るわけだし。
>>569 さんざん引用されておりますが、規約違反なのでは?
個人的には規約云々をもちだすまでもなく、スタートアップコードが int の返り値を仮定している以上、void main() と書いてはいけないと
思います。スタックに返り値を載せる言語処理系ならば、呼び出し側と呼び出され側で仮定する返り値の型が異なるとアウトです。
>>570 ではなんで、void main(void)がコンパイルエラーにならないんでしょうか?
>>571 規格違反でもコンパイル通るし、動く記法なんざ他にもいくらでもあるだろ
Cじゃ 動く= 規格に沿ってる とは限んないんだよ
double main(void) これはコンパイラ通りますか?
>>571 gcc だとデフォで警告になるし、コンパイルオプションによってはエラーになる。
>>574 そりゃ警告をエラーにするオプションあるんだから後半は無意味だろwwww
void main(void) は古い形式であるということですか? つまり、昔はOKだったもので、移植性のために保持されたものであるということですか?
>>575 -ansi -pedantic-errors でエラーになる。
別に -Werror なんか不要。
>>576 そんなものが正式な形式になったことは今までにない。
void main(void)と書いてある参考書は窓から投げ捨てろ
正確には void main(void) は規格違反ではない。 int main(int, char**) と int main(void) と それらと等価な定義を必ずサポートしなくてはならないだけであって、 それ以外の定義をコンパイラが独自にサポートしていても良いことになっている(処理系定義)。 もしそのコンパイラが void main(void) を独自にサポートしていると明言しているのであれば、 void main(void) が使えるからといってそのコンパイラが規格を違反しているわけではない。 移植性は無いがな。
581 :
デフォルトの名無しさん :2008/11/20(木) 22:13:30
>>564 なかなか巧みな話術だが未定義という用語が使えないわけか
582 :
デフォルトの名無しさん :2008/11/20(木) 22:14:23
レビューん時に、上司がメインでexitするなら、voidでいいっていうから、今voidのが動いてるんですけどw 何か気になって、いろいろ調べて、ここに質問なげたわけなんだけど。。。 大丈夫かな
そのコンパイラで大丈夫なら大丈夫なんじゃね。 移植性は無いがな。
>>582 みんな脅してるだけでほんとに、おかしな動作することないから気にするな
でも、別に無理に exit してまで void にする必要も無いよな・・・
587 :
デフォルトの名無しさん :2008/11/20(木) 22:18:39
次回からしれっとintにしとこう というか、移植性を考えてexitはstdlibのマクロ使えっても言ってたな なんか矛盾してきたかこれ
mainでのexitとreturnってなんか違うの? mainの戻り値となる点で同じだと思ってた
exit がマクロな処理系があるのか。
592 :
デフォルトの名無しさん :2008/11/20(木) 22:25:32
>>589 EXIT_FAILERとかだろ
あ〜スペルがわからんw
やっぱり一緒だよね。 その上司的に、EXIT_SUCCESSマクロをつかえという話をしているのであれば、やっぱりvoid mainはダメじゃないだろうか
>>592 ああ、戻り値マクロのことか。
EXIT_SUCCESS と EXIT_FAILURE だな。
>>584 たまたま自分の目の届く範囲で問題が起きないからといって
間違いを放置しておくのはよくない
少なくとも、voidと書くことは規格が保障していないと「知っている」のは絶対必要
知っててvoidと宣言するのは個人個人の問題だから好きにすればいい(他人に迷惑をかけない限り
重ねて言うが、void main(void) はその処理系で使用可と定義されていれば規格違反ではない。 ただ、移植性を気にするのであれば避けた方が良い。
むしろ、どうしてそこまでvoid…と宣言したがる人間がいるのかが気になる intのほうが文字数少なくすらあるのに
return 書くのが面倒なんだろw C99 なら書かなくても良いが・・・。
600 :
デフォルトの名無しさん :2008/11/20(木) 22:33:43
明日grepしてみるか void mainとかあるとは思えんが
for(){ for(){ if() break; } } このbreakでは中のfor文からぬけて1番外のforはまだ継続されますか?
実行環境なくて座学で勉強してるのかぁ。 大変だね。
継続されるけど 試せば分かるだろ
>>600 初めて書いたhello worldが発掘されるよ
>>601 breakは常にループ(またはswitch)を一つだけ抜ける
606 :
デフォルトの名無しさん :2008/11/20(木) 23:40:56
if(no % i == 0) この行で左辺値が必要とかでエラーが出るのですがなんでですか? 教科書丸写しなんですが・・・
== じゃなくて = になってんじゃねーの?
if ((no % i) == 0) これはどう?
609 :
デフォルトの名無しさん :2008/11/21(金) 00:11:09
>>494 RedHatLinux9のCD-ROM8枚組が/cdに納められているようです。
ディレクトリやファイルの内容です。
ap cd.txt doc inst1 inst2 inst3 rpm.txt src1 src2 src3
インストールの仕方がわかりません。
宜しくです。
>>495 こういうときのためにかっておいた方が良いようですね。
>>499 isoファイルが落とせると言うことですが英語がわかりませんでした。
わかりしだい落としてみます。
>>609 分かりました、がんばって英語を読んでください
>>611 そもそも void main(void) という記述が現れないが、
規格的には処理系が定義していればおk。
5.1.2.2.1 プログラム開始処理 プログラム開始処理において呼び出される関数の名前は main とする。 処理系は、この関数に対して関数原型を宣言しない。 この関数は、次の4種類の方法のいずれかで定義しなければならない。 - 返却値の型 int を持ち仮引数を持たない関数 int main(void) { /* ... */ } - 二つの仮引数をもつ関数(仮引数は、これらが宣言された関数に対して局所的であるため、 どのような名前を使用してもよいが、ここでは argc 及び argv とする。) int main(int argc, char * argv[]) { /* ... */ } - 上に揚げた二つの方法のいずれかと等価な方法(9) - 上に揚げた三つの方法のいずれでもない処理系定義の方法 ---------------------------------------------------------------- (9) したがって、int は、int として定義された型定義名で置き換えることができるし、 argv の型は、char ** argv と書くこともできる。 最後の処理系定義おkの項目があるから、 処理系が void main(void) を使っていいと定義していれば問題ない。
int main にしとくべき。 void mainが許せないバカよけ対策として。 この手の話でなんレス潰れたか・・・・・
元凶は処理系がvoid mainを許しているわけでもないのに 問題が起きないからってvoidは正しいんだと勘違いしてるバカのほうだろ
return 0; っていちいち書くのがめんどい。
>>615 問題が発生するような処理系では、
コンパイラがチェックをかけて通さなくするんじゃない?
618 :
デフォルトの名無しさん :2008/11/21(金) 02:07:23
Cのソースで、これはすごいって思ったテクニックを教えてください。
>>617 標準外で処理系による定義もないってことはそれは未定義
チェックされる保障なんてありません
>>612 その「規格的には処理系が定義していればおk」というのは
ISO/IEC 9899:1999のどこに書いてありますか?
622 :
デフォルトの名無しさん :2008/11/21(金) 02:15:39
問題が発生するとかしないとか、そんな個別の問題を言っても仕方ないんですよ 前置きなくCの話をするときは、それは当然標準Cの話であって、 規格に反しているなら「それは間違いです」としか言いようがないんです
規格に反しているなら「それは規格に反しています」としか言いようがない の間違いでは?
C++ JIS X3014:2003より引用
> 処理系は,関数 main をあらかじめ定義しておいてはならない。その返却値の型は,int とする。
> これを除いて,関数 main の型は,処理系定義とする。処理系は,次に示すどちらの形での関数
> main の定義も受理できなければならない。
> int main(void) { /* ... */ }
> int main(int argc, char* argv[]) { /* ... */ }
C++ならば、void mainは規格違反。
Cは
>>613 からvoid mainは規格違反ではない。(JIS X3010:2003)
追加
C99(JIS X3010:2003)以前のANSI−Cでは
>>613 の
- 上に揚げた三つの方法のいずれでもない処理系定義の方法
がなかったので、void mainは規格外
628 :
デフォルトの名無しさん :2008/11/21(金) 04:09:28
int main (void){ int a,b; a = 5,b = 10; printf("a = %d b = %d \n",a,b); swap(&a,&b); printf("a = %d b = %d \n",a,b); return 0; } void swap(int *sa,int *sb){ int *tmp; *tmp = *sa; *sa = *sb; *sb = *tmp; } void swap(int *sa,int *sb){ int tmp; tmp = *sa; *sa = *sb; *sb = tmp; } swap関数は上下どちらでも結果は同じですが、プログラムとしてどちらの方がいいとかはあるのでしょうか?
>>609 何度聞かれても答えは同じなんだが。。。
rpm -ivh /path/to/gcc.rpm
最近はrpmファイルダブルクリックでインストールできたりすんのかな。よくわかんね。
>>628 上はだめ。
下がいいとかじゃなく、上はだめ。
>>628 上は問題外
絶対にやるな
確保してない領域を使うな
ああ、俺もついに結婚する日が。。。
>>631 が女なら。
>>626 >これを除いて,関数 main の型は,処理系定義とする。
だから、処理系が void main を定義してれば大丈夫だろw
このプログラムを簡略化するにはどういった手法がありますか? struct cell{ int value; struct cell *next; }; int main(void){ struct cell *head,*temp,*new; int x; new=(struct cell *)malloc(sizeof(struct cell)); head = new; temp = new; scanf("%d",&x); head->value = x; for(;;){ scanf("%d", &x); if(x==0) break; new=(struct cell *)malloc(sizeof(struct cell)); new->value = x; temp->next = new; temp = new; } temp->next = NULL; new = head; while(new!=NULL){ printf("%2d",new->value); new = new->next; }
>>634 ・高高int一個のデータのためにリスト構造は無駄なので、メモリ戦略を見直す。
# vectorのような倍倍戦略でもいいし、そこは適当に。
・scanf()は基本的に融通が利かず危険だから避ける。
・main()はコマンドライン(コマンドインタプリタ)とのI/F関数だから、作業を詰め込まない。
new は C++ の予約語。 将来C++に移植することがあるかもしれないので、Cでも避けておく。
>>553 仰る通りで、&の場所を変えたらきちんと動作しました。
ありがとうございました。
638 :
デフォルトの名無しさん :2008/11/21(金) 15:33:50
void MakeBMNextTable(wchar_t *p, int *next) { int n, k; n = (int)wcslen(p); for(k = 0; k < 65536; k++) next[k] = n; for(k = 0; k < n - 1; k++) next[p[k]] = n - k - 1; }
639 :
デフォルトの名無しさん :2008/11/21(金) 15:35:12
int BMSearch(wchar_t *buf, wchar_t *str) { static int next[65536]; int buf_len = (int)wcslen(buf); int str_len = (int)wcslen(str); int i = 0, j = 0; MakeBMNextTable(str, next); i = str_len - 1; while(i < buf_len) { j = str_len - 1; while(str[j] == buf[i]) { if (j == 0) return i; --i, --j; } if (next[i] > str_len - j) i += next[buf[i]]; else i += str_len - j; } return -1; } BM法のアルゴリズムなのですが、BMSearch関数の検索速度を上げるためにはどのような改善をすればいいでしょうか?
640 :
634 :2008/11/21(金) 16:18:34
641 :
デフォルトの名無しさん :2008/11/21(金) 16:30:36
double data[5][20]={0.0} こう宣言すれば100個の要素はすべて0.0になりますか?
なります
変数Aと変数Bが10^n (nは任意に決める) 倍以上違うっていう条件式はどう書きますか?
fabs(log10(A) - log10(B)) >= n
答えてる後に言うのもなんだがC言語の質問じゃないな
646 :
デフォルトの名無しさん :2008/11/21(金) 18:00:19
>>647 フヒヒwwwwwwサーセンwwwwwww
649 :
デフォルトの名無しさん :2008/11/21(金) 18:29:09
Printf関数が存在する言語は何ですか?
652 :
デフォルトの名無しさん :2008/11/21(金) 19:41:10
[1] 授業単元:プログラミング2 [2] 問題文(含コード&リンク):以下に示す条件を満たしたFile Aの内容をFile Bへコピーするプログラムを作成せよ. コマンドライン引数を用いプログラムの実行時に,コピー元とコピー先のファイル名が指定できること. strcmpを使いコピー元のファイル名とコピー先のファイル名が同じかどうかを判定し,同じ場合には,strcatを使いコピー先のファイル名をファイル名1と変更する処理を書け. 例) 「file」を「file1」とかにする.単にファイル名に1を加えるだけ. [3] 環境 [3.1] OS:Linux [3.2] gcc [3.3] 言語:C [4] 期限:2008年11月25日まで
654 :
デフォルトの名無しさん :2008/11/21(金) 19:50:37
[1] 授業単元:プログラミング演習 [2] 問題文(含コード&リンク):名前,年齢,身長,体重,性別(M:男性,F:女性)についてのデータファイルを使って以下のことを行なうプログラムを作成せよ. † コマンドライン引数を導入し,データファイルと出力ファイル,実行モードを指定せよ. 使い方> ./a.out 入力ファイル名 出力ファイル名 モード 使い方> ./a.out personal_data.txt result.txt 1 実行モードとして,下記三つのモードを用意せよ 1. 男性のデータのみをファイルに書き込む 2. 女性のデータのみをファイルに書き込む 3. 全員のデータをファイルに書き込む ※ 書き込む場合は,名前,身長,体重,年齢の順とする. データファイルから,全員分のデータを読み込む.ただし,データの終わりを判定して,読み込みを終了すること. 全員分のデータを標準出力に出力する. データファイル 名前 年齢 身長 体重 性別 A 18 175.8 62.3 M B 23 154.2 49.5 F C 28 180.1 75.2 F D 32 169.5 59.8 M E 35 158.4 54.3 F F 40 175.8 80.9 M [3] 環境 [3.1] OS:Linux [3.2] gcc [3.3] 言語:C [4] 期限:2008年11月24日まで [5] strtok・atof・fputsは習っていません。 よろしくおねがいします。
>>654 おい糞餓鬼
中学以上は義務じゃねぇんだ、勉強する気が無いならやめろ
習ってないならググれ、書籍買って学べ
いや、勉強しないで死んでくれたほうがいい気がする
658 :
デフォルトの名無しさん :2008/11/21(金) 20:27:23
二つ質問があります。 1. quarter int 型 (1 byte) という整数型を作るにはどうしたらよいでしょうか。 short int 型 (2 byte) のさらに半分です。 2. その変数が「int 型だ」などと記憶しているのはどこの領域でしょうか。 ふと思いついてしまって、不思議で気になってしまってしょうがありません。
正直初心者はパソコンの性能考えずに、おもいっきり領域とってプログラムかくべきだと思う。 パソコンがばぐるようなプログラムは初心者レベルではないから。 しかし演習のTAやってて、何のボケだよ的なプログラムみたw
一次元配列を二次元配列にいれてくれと注文したら for(i=0;i<maxA;i++){ for(j=0;j<maxB;j++){ data2[maxA][maxB]=dnum[i]; } } とかかいて実行しだしたw
>>660 1)charを使え。
2)コンパイラが管理している。プログラムの中に組み込まれているわけではない。
>>663 ありがとうございます
2番の質問は、
コンパイルが終了してプログラムを実行させた時、メモリのどの領域でどうやって管理しているのだろう、
のようなことです。
>>660 1. 「quarter int」な型は存在しないし、作ることもできない
(Cではそもそもchar以外の整数型のサイズはきっちり決まっているわけではない)
1バイトの整数型が必要ならcharを使うこと
2. そんな領域はない
「型」とは言語とコンパイラがメモリ領域を扱うときの約束ごとであって、
生成された実行ファイルや、その実行時メモリ空間の問題ではない
なんのボケだよwww
>>660 C99なら stdint.hを読んでください。
int8_tとかね。使うの面倒だけど。
無理矢理char型で代用する手もあるが、必ずしも8bitでないので、お薦めしない。
>>664 型というのは、メモリの「大きさ」と「用途」を抽象化したもので、
プログラマが書いてコンパイラが読み取るまでの間しか意味がない。
実際にメモリをどう操作するかという命令はコンパイラが作り出す(コンパイルする)。
charだって、1バイトは1バイトだけど、サイズが決まってるわけじゃないしな。
charが8bitでない処理系があるというのは、 トリビアとして知ってれば十分。
1バイトが1オクテットじゃない処理系なんて今でもある?
ファイルのMD5を取得する関数はありませんか?
>>672 探せばあるだろうけど、標準関数にはない。
>>673 標準じゃなくてもかまわないので教えてください
md5のソース見てみな。亜留是。
後、Cでも正規表現が使えるようになるライブラリとか無いですか?
OpenSSL とか
>>676 標準の regex.h
他には PCRE など
ほそく。md5のソースは、md5を計算する部分が ライブラリとして分離されている。
682 :
デフォルトの名無しさん :2008/11/22(土) 02:13:48
Cプログラムをプリコンパイルした後、コンパイルした際にできる「.obj」ファイルを、ひとかたまりのライブラリファイルにすることは可能でしょうか? 「aaaaa.pc」 →prec→ 「aaaaa.c」 →cl→ 「aaaaa.obj」作成 「bbbbb.pc」 →prec→ 「bbbbb.c」 →cl→ 「bbbbb.obj」作成 「ccccc.pc」 →prec→ 「ccccc.c」 →cl→ 「ccccc.obj」作成 aaaaa.obj,bbbbb.obj,ccccc.obj から libraryファイル作成 もともとUNIX上でコンパイルした「.o」ファイルより「library.a」ファイルを作成し、COBOLプログラム(呼び出し元)のコンパイル時にリンクさせておりました。 それをWINDOWSで行いたいと思っております。 コンパイルはBATファイルを作成(Oracleインストール時にあった、pcmake.batをカスタマイズ)して、「prec」コマンドでプリコンパイルして、VisualStadioのC++をコマンドライン「cl -c(リンクなし)」でコンパイルして、最終的に中間ファイル「.obj」を作成しております。 ご説明が分かりにくくて申し訳ございませんが、具体的な方法・ご指摘がございましたら、宜しくお願い致します。
>>682 プロジェクトの新規作成時に「Win32 Static Library」を選択すればlibを作成する為のプロジェクトが出来上がります。
超初歩で申し訳ないのだが プログラミングを学ぶべくvisual Studio C++ 2008をインストールして C言語は何処を操作すれば作成可能になるの?初歩でスマソ
ファイル→新規作成→プロジェクト プロジェクトの種類: Win32→Win32コンソールアプリケーション
>>684 メニューで「プロジェクトの新規作成」を選択して「コンソールアプリケーション」を選択。
main関数がでてくるから、そこにprintf("Hello world");の行を追加して、「ビルド」。
エラーがなければ「実行」。
じゃないか?VCはちょっとまえのものしか知らないけど、こんなかんじ?
プロジェクトを作らないと話にならないことはたしか。
返答どうもありがとう!
>>685 の通りにWin32コンソールアプリケーションを実行したら
.cppの拡張子のファイルができたよ!
おかげで「ビルド」できました
>>686 もサンクス!
たびたびで申し訳ない 確かに「ビルド」はできたのだがエラーが発生してしまった #include<stdio.h> int main(void); int main(void) { printf("Hello,world.\n"); return(0); } と入力したのだが原因が入力ミスと思えないのと .cppファイルを作成したときにstdafx.cppというファイルも同時にできたのだけど これって何? 長文スマソ
VS2003で申し訳ないが、 ・コンソールアプリケーションプロジェクトを作る時に、オプションで空のプロジェクトにチェックを入れる ・プロジェクトを右クリック、新規項目の追加でCPPファイルを選択し、ファイル名はhoge.cと拡張子込みで指定する ・プロジェクトを右クリック、プロパティ、C/C++の詳細、コンパイル言語の選択でCコードとしてコンパイルを選択 こんなかんじでどう。
あと、エラーの内容を貼らないとわからない。 しいていうなら、mainのプロトタイプ宣言はいらない
>>688 Standard Afxというやつですね。できますねえ。おまじないだと思って無視してかまいません。
ビルドは出来ますか?
返答レスありがと 最初の項目のオプションで空のプロジェクトにチェックを入れたところ ソース・ヘッダー・リソースどのファイルにもCPPファイルが作成されていなかったよ 自分でCファイル作って起こしてみたんだがやっぱりビルドは失敗だった。 わざわざ返答してくれたのにすまんね
最初から勉強するならstdafxとかじゃまだろうと思って空のプロジェクトにしてもらったわけだけれど。 もう一回聞くけど、エラーの内容が分からないと解決しづらい。 ソースのフォルダにCファイルはできてる? コンパイルエラーが出る?
Win32コンソールアプリケーション(空のプロジェクトはチェック無し)から作成し // bjk.cpp : コンソール アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { return 0; } にhellow worldの奴を入力すると 1>------ ビルド開始: プロジェクト: bjk, 構成: Debug Win32 ------ 1>コンパイルしています... 1>bjk.cpp 1>c:\program files\microsoft visual studio 9.0\visualcpp2008_samples\bjk\bjk\bjk.cpp(19) : error C2084: 関数 'int wmain(int,_TCHAR *[])' は既に本体を持っています。 1> c:\program files\microsoft visual studio 9.0\visualcpp2008_samples\bjk\bjk\bjk.cpp(7) : 'wmain' の前の定義を確認してください 1>ビルドログは "file://c:\Program Files\Microsoft Visual Studio 9.0\VisualCpp2008_Samples\bjk\bjk\Debug\BuildLog.htm" に保存されました。 1>bjk - エラー 1、警告 0 ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ========== となった 逆にhellow worldの奴だけだと 1>------ ビルド開始: プロジェクト: bjk, 構成: Debug Win32 ------ 1>コンパイルしています... 1>bjk.cpp 1>c:\program files\microsoft visual studio 9.0\visualcpp2008_samples\bjk\bjk\bjk.cpp(10) : fatal error C1010: プリコンパイル ヘッダーを検索中に不明な EOF が見つかりました。'#include "stdafx.h"' をソースに追加しましたか? 1>ビルドログは "file://c:\Program Files\Microsoft Visual Studio 9.0\VisualCpp2008_Samples\bjk\bjk\Debug\BuildLog.htm" に保存されました。 1>bjk - エラー 1、警告 0 ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========となった
ちなみに return(0); とかいてるけど、この空白は書き込むために全角空白にした? ソースファイルの字下げに全角空白は使えないよ
>>693 Win32コンソールアプリケーション
空のプロジェクトに
チェック→あり .cppファイルが作成されない
なし .cppファイルは作成される
(もちCファイルそのままは作成されない)
空のプロジェクトにチェックなしでも
>>694 の症状です。はい。
int _tmain(int argc, _TCHAR* argv[]) { return 0; } int main(void) { ... } と書いたということ? 後者はプロジェクトの設定で「プリコンパイル済みヘッダーを使用しない」と設定しないとだめかな。 2008だと使用するがデフォになってるのかな。
>>697 >>697 に書いてもらった文はデフォです
今から「プリコンパイル済みヘッダーを使用しない」を探してみます。
(VS2003参考)プロジェクトのプロパティ→C/C++→プリコンパイル済みヘッダー
>>697 で言われた通りチェック外してみると
1>------ ビルド開始: プロジェクト: asdsasda, 構成: Debug Win32 ------
1>コンパイルしています...
1>スキップ中... (関連する変更は検出されませんでした)
1>asdsasda.cpp
1>ビルドログは "file://c:\Program Files\Microsoft Visual Studio 9.0\VisualCpp2008_Samples\asdsasda\asdsasda\Debug\BuildLog.htm" に保存されました。
1>asdsasda - エラー 0、警告 0
========== ビルド: 1 正常終了、0 失敗、0 更新不要、0 スキップ ==========
となり成功です!この後コンパイルもして上と同じ文になったのですが
実行ファイルがフォルダの中にみあたりません。
>>700 Cで開発するなら拡張子はCにして、「Cコードとしてコンパイルする」にしといた方がいいよ。
実行ファイルはDebugフォルダの中にでもできてるんじゃないかな
あー、んで、実行ファイルをダブルクリックしたら一瞬黒いのが出て終わりましたっていう展開になりそうなので、 コマンドプロンプト開いて、そのフォルダに移動して実行するといいです。 ファイル名を指定して実行 cmd と入力 cd "Program Files\Microsoft Visual Studio 9.0\VisualCpp2008_Samples\asdsasda\asdsasda\Debug" asdsasda.exe
cd "c:\Program Files\Microsoft Visual Studio 9.0\VisualCpp2008_Samples\asdsasda\asdsasda\Debug" か。
すいません
>>700 の修正です
コンパイルして.exeファイルは作成されたのですが
一瞬開いて瞬く間に閉じるような状態なのですがどうして直に閉じてしまうのでしょうか?
又これまで問題にお付き合いいただきありがとうございました!
ありがちな出来事だからねw ともあれ、プログラミング言語Cで実行ファイルを作ることに成功した訳だね。 おめでとう! すばらしいソフトを作れるようになることを願ってるよー
>>702 の言うとおりにコマンドプロントを開いてみて
C:\Documents and Settings\[myドキュメント名]>cd"略"のcdより前は無視してOkですか?
絶対パス指定するなら今どの場所にいようが関係ないから無視していいよ
今までお付き合いありがとう! ただコマンドプロントに上のように入力してみたところ ファイル名、ディレクトリ名、またはボリューム ラベル構文が間違っています。 と出てきたのだけど、このコマンドプロントは入力後Enter押すとそのファイルが実行される ものなの?
>>703 をコピペしてもだめかね。
cd と "〜〜" の間に空白入れてないとかじゃ?
そういう意味じゃあ、 "C:\Program Files\Microsoft Visual Studio 9.0\VisualCpp2008_Samples\asdsasda\asdsasda\Debug\asdsasda.exe" と入力してEnterを押してみるのも悪くないかもしれない。 ダブルクォーテーション("←これね)も必要だよ
>>709 int a;
printf("Hello world\n");
printf("Hit ENTER to exit ");
a = getchar(); /*入力待ち*/
return 0;
こうすると、returnする前に入力待ちになるから、
コマンドプロンプトに表示された内容は確認できる。
それやるとscanf使ってすぐに終了するようになってしまったのですけど何でですか! と、なる未来が見える
今日はみんな優しいな
ただcdと””の間にスペースがなかっただけっだた(スマソ) そのかわり入力した文が\asdsasda\asdsasda\Debugだと C:\Documents and Settings\[myドキュメント名]と 入れ替わっただけで実行ファイルは即消えます。 他には \asdsasda\asdsasda\Debug\asdsasda.exeは指定されたパスが見つかりません。 \asdsasda\Debug\asdsasda.exeはディレクトリが無効でした。になりました。
"...\asdsasda.exe"まで含める場合はcd要らない
C:\Documents and Settings\[myドキュメント名]> とだけ表示されている黒い画面で "C:\Program Files\Microsoft Visual Studio 9.0\VisualCpp2008_Samples\asdsasda\asdsasda\Debug\asdsasda.exe" と入力して、Enterを押すとどうなるの? Enterを押す直前の画面は、 C:\Documents and Settings\[myドキュメント名]>"C:\Program Files\Microsoft Visual Studio 9.0\VisualCpp2008_Samples\asdsasda\asdsasda\Debug\asdsasda.exe" こんな感じになるよ
そろそろ実行されてもいい頃のように思うが、はたしてw
>>718 Hellow,world.
やっ、やったどー!できた!
いやホンッッッットみんなありがと、おかげさまでできました!
みんなの助力のおかげです。
そろそろ自分で調べる姿勢を見せた方が懸命な気もするが・・・ そのままenter押すとその場所のファイルを開こうとするだけ ちなみにcdコマンドはChange Directoryのことで それ以降に指定したディレクトリ(ファイル)へ移動するコマンド cd付きで実行ファイルの場所を指定してもそんなディレクトリ無い と言われるのは当たり前ね
>>720 Helloのスペルがちがうけど、まあいいか
ごめん訂正ディレクトリ(ファイル)じゃなくて(フォルダ)の間違い 寝ぼけてるな・・・
あ、やっぱりできたか。
>>711 のレスを見た時はファイル名に指定して実行のとこにかいちゃったのかなあ。
できれば
>>702 の方法でも実行できるようになってね。
コマンドプロンプトとか最初は意味分からんと思うけど、慣れると楽なものだから。
printf("こんにちわ\n"); とか printf("いやっほー!でてるー!?\n"); とかそういう風に変えるだけでも楽しい時代の幕開けだなw
>>721 サンクス、なるほどね自分が何打ち込んで何していたかわかったよ。
一通り完了したんでしばらくは自力でがんばってみます。
>>722 あまりの嬉しさに草生やしてしまったんだよ(←言い逃れ)
たまに優しくなるなこのスレ
bccからvc++に乗り換えたときビルド方法とか設定がよくわからなかった時を思い出した まあいまでもビルド方法はともかく細かい設定はわかってないけど・・・
729 :
デフォルトの名無しさん :2008/11/22(土) 13:22:33
ポインタのポインタがわからん。まいったぜ。
□→□→□ ↑ ↑ ↑int | |int* |int**
それはポインタが良く分っていないってことだな。
二次元配列の動的確保を一回やってみるとなんとなくわかるよ
733 :
デフォルトの名無しさん :2008/11/22(土) 14:30:45
fopenで一太郎やワードファイルをread出来ないのですが、どうすればよいのでしょうか。
ソース貼ってみて
void main() { fopen("test.doc", "r")+ }
fopenで一太郎やワードファイルをread出来ると ソフトが売れなくなるので ジャストシステムやマイクロソフトがC標準化委員会に圧力をかけたのさ。 今この世に存在する全てのC言語は 一太郎やワードファイルをreadできないようになっていて そうしようとした奴の個人情報をインターネットを使って通報するようになってる。 それが損害賠償を請求する裁判を起こすための証拠になるのさ。 未だに信じられないようだけど、全部作り話です。
void main() { char s[1000]; FILE *fp; fp = fopen("test.doc", "r"); fscanf(fp, "%s", s); puts(s); } すいません途中送信しました としてるのですが読めませんどうしたらいいですか
>>737 それだとプレーンテキストて言って、単純に文字コードが並んでるようなファイルしか読めないよ。
strにabc_defみたいな文字列が入っています。 sscanf(str,"%s_%s",name,name2); で_で区切りで読みたかったんですが、すべてnameのほうに入ってしまいます・・・
sscanf(s, "%[^_]_%s", s2, s3);
それはどういういみですか?
調べろよ
>>740 マニュアルひけ、マニュアル。以下は man sscanf より:
> %s ホワイトスペースではない文字で構成された文字列に対応する。《略》
> 文字列の入力は、ホワイトスペースが入力されるか、最大フィールド幅に達
> するか、のどちらかが起こると停止される。
%[...]なら使えるかもしれん。(が、処理系依存かも)
セパレータってやつだったんですね。わかりました。 _が何個かわからない場合どうすればいいでしょうか? abcd_efg_hij abcd_efg_hij_k_l みたいな場合も全部読めるようにしたいです
746 :
デフォルトの名無しさん :2008/11/22(土) 17:01:40
>>738 別にfopenでなくてもいいのです。
全てのtextファイル中から特定の文字を検索するツールを作りたいのですが、
他の関数や方法があれば教えて下さい。
まずtextファイルって何なのか知らんが 一太郎やWordを作ってる人らがそれらのフォーマットを公開しない限り、 それらを独自に読み込むのは基本的には無理
>>737 >>736 の最初の方はある意味真実。
利用者を囲い込むため、他社のソフトでは読めないようになっている。
そのあおりで、自分の文書でさえその会社のソフトで無ければ読めない。
RMSが怒ったってのもうなづける。
一太郎やWordで作ったファイルとノートパッドで作ったファイルと 全て同じだと思ってるわけじゃないよな・・・?
>>745 fgetcで1文字ずつ読みながら処理していくか、fgetsで1行読み込んでから、読み込んだデータをスキャンするのが一番カタい。
sscanf等は、仕様の範囲の処理をやらせるには楽だが、それを超えたことをさせようとすると、とたんに役に立たなくなる。(上のようなケースはまだ工夫次第でなんとかなりそうだが)
751 :
p :2008/11/22(土) 17:42:02
はじめまして。 コマンドラインでcdを使うときは「cd program files」 で思った通りに移動できますが、 しかし、octaveというソフトのコマンドラインで同様の操作をすると スペースが悪さをするようでうまくいきません。 どうすればいいのでしょうか? (C言語とは関係なくてすみません)
>>746 自分で作ろうとしなくても、既にGoogleデスクトップがあるじゃないか。
753 :
p :2008/11/22(土) 17:44:45
すみません。自己解決しました。”で囲めばいいのですね。
754 :
p :2008/11/22(土) 17:51:22
もう1つ、質問させてください。 コマンドラインでコンパイルをしたいのでclとlinkの パスを通しておきたいのですが、 vsvars32.batを実行してもそのウインドウだけでしか有効にならないし、 ウインドウを閉じると効果が消えます。 どうすれば全体的&永続的にパスを通すことができますか?
>>745 %[...] や %n を使えば、一応こういうこともできる
char buf[] = "acd_efg_hij_kl";
char name[16];
int len = 0;
char *p = buf;
while (sscanf(p, "%[^_]%n", name, &len) != EOF) {
puts(name);
p += len;
if (*p == '_')
p++;
}
756 :
p :2008/11/22(土) 18:23:53
自己解決(?)しました。 batファイルを開いて、@setの部分を全部手動で設定すると、 思った通りになりました。 しかし、もっと上手い方法があるはず。。。
757 :
デフォルトの名無しさん :2008/11/22(土) 18:41:18
>>752 グーグルは知っていました。
ただ、勉強も兼ねて自作したかっただけです。
正直出来ないってことに驚きました。
業界絡みで出来ない事ってあるのですね。
情報提供頂いた皆さんどうもありがとうございました。
おまえは何を信じてるんだ?
>>757 wordのファイルフォーマットは公開されてるから、できないことはないけど、素人には無理。
>>757 誰もできないとは言っていないはずだ。面倒だったり難しかったりするだけ。
1つにはオートメーションなど既存ライブラリを利用する手がある。
Wordも一太郎も、人の手による操作だけでなく、
プログラムからの操作も受け付けており、それを使うことをオートメーションと言う。
特にdocは世界的に需要があるので、それ以外に第三者によるライブラリの存在も期待できる。
もう1つは 、もちろん自分で読み取るプログラムを書くこと。
ただのテキストではないが、依然としてただのファイルである。
話の上では、構造さえ分かればバイナリモードで開いて欲するデータを取り出せる。
さっき言った第三者のライブラリと同じことをするわけだ。
もちろん、まずはファイルの構造を調べるとこから始めなければならないが、
すべて一から調べなくても参考になる先駆者の情報を見掛けることはあるだろう。
ちなみに、司法省が五月蠅かったか、最近MSはdocxでないほうのdocの仕様も公開していたはずだ。
一太郎は知らないが。
>>757 できないわけじゃない。
ただ、自作する場合はちょっと手間がかかるだけだ。
具体的には、Excelのファイル読む場合C++で2万行くらい。
mallocってどういうときに使うべきなの? いまいちよくわからん。
>>763 そう思うならあなたには必要ないのでしょう
>>748 いや
>>736 は
>>733 がプレーンテキストのファイルとバイナリファイルとの区別が付いてないと睨んで
こまごまとしたことを説明するのが面倒だから
企業の陰謀をでっちあげて出来ないということを納得させるつもりで書いた
どの道初心者が簡単に出来ることじゃないし
ちょっとやそっとで出来るか出来ないかだけ分かれば大抵の場合はそれで十分なんだから
その手の御伽噺で煙に巻いておけばいい
すぐにCに飽きてJavaだの.NETだのへでも転向するさ
そもそも、ワードやワープロソフトは、文字のみのテキストファイルではなく、 レイアウト、その他ページ設定などの情報が含まれているしね・・・
Microsoft Word の仕様書さえあればWordファイルの読み書きはできる。 ただ、その仕様書がA4で200枚近くあるのが難点だ。
読めるか読めないかだけが質問者にとって重要なのさ そして質問者の脳みそで理解できるほど簡単な方法を教えてくれることを期待している 読めないという回答は全く期待していない そこでスケープゴートが必要になる 悪い報告をする相手を憎むのは防ぎようがないがそれを和らげるためにも でなければ質問者の憎悪は100%回答者へ向かうだろう たとえ回答が100%正しくても
一太郎3までのフォーマットなら、 本文のプレインテキストが先頭に来て、 その後ろにそれと同じ長さの属性リストがくるから、 テキストだけを抜き出すのは容易だよ。 難点は、いまどきそんな古いソフトが使えるかどうかだが。
正直に書いたせいで恨まれてもいいじゃない。 そのための匿名だ。
でもそれで純真なガキ^H^H若者が傷ついたりしたら、寝起きが悪いじゃないか。
>>762 OLE通してアクセスする方が万倍ましだな。
テキスト抽出する部分は xdoc2txt に任せるってのもありなんじゃね?
openofficeからパクればいいじゃない
>>737 には、まず、普通のテキストを検索できるツールを作れるようになってから、
また挑戦しようってアドバイスしてあげるのが正しいと思う。
776 :
前スレ899です。 :2008/11/22(土) 21:54:00
以前にC言語を勉強すると言った者です。 参考書を買って勉強を始めたのですが最初でまったくわからなくなりました。 そこで教えてもらいたいです。 参考書に載っている通りに書いてみます。 一応BorlandC++Compiler5.5というコンパイラを参考書の付属CDからインストールしました。 ■ソースファイルの保存先 ソースプログラムを入力したらソースファイルとして保存します。保存するフォルダはどこでも構いませんが、本書では、C:\tmcsフォルダに保存したものと仮定して進めさせていただきます。 まずここでわかりません。 フォルダ名に\や:など使用出来ませんよね?ここでは「仮定して」と書いてあるので別に問題なしですか? ■ソースファイルを保存したフォルダに移動する ソースファイルを保存したフォルダに移動します。コマンドプロンプトで、フォルダを移動するには、「cd」コマンドを使います。本書では、C:\tmcsにsample.cを保存したので、「cd C:\tmcs」とコマンドを打ち込みます。 ここでのsample.cとはソースプログラム(サンプル)です。 この一文が全く理解出来ません。そもそもコマンドプロンプトの使い方がわかりません。参考書を何回も読んだのですが?マークしか頭に浮かびません。 C:\Documents and settings\name>cd フォルダ名であってますか? 参考書と同じく「C:\tmcs」のフォルダにソースファイルsample.cを保存したかったのですが、 「ca」というフォルダに保存したので、C:\Documents and settings\name>cd caとやってみたのですが失敗しました。 長文でわかりづらいかも知れませんがよろしくお願いいたします。
まずはPCの基礎について勉強しましょう
マイドキュメント以外の適当なフォルダを開いてみ。 アドレスバーに C:\ から始まる名前が表示されるから。
>>776 とりあえず全部ルートディレクトリに置くようにすれば?
ファイルを保存するときは、たとえばソースが test.c なら、\test.c と頭に\をつけるようにして、
cdで移動するときは、どこにいても、cd \ で一発で移動できるから。
780 :
前スレ899です。 :2008/11/22(土) 22:14:49
>>777 すいません。
>>778 よくわかりません。すいません。
PCの基礎から覚えないでC言語は無理なのでしょうか?
>>779 ルートディレクトリ?
基礎どころか、仕組みまで理解しないとC言語は無理です。
>>780 プログラミング以前の問題。
まずはパソコンの勉強からはじめよう。
>>780 ディレクトリって、フォルダのこと。
同じものと考えておけばいいよ。
フォルダ(ディレクトリ)って、階層構造になってるってのはわかるよな?
「ルートディレクトリ」は階層構造になってるフォルダの一番上のところって意味。
PCにはハードディスクが付いてるだろ? それが、マイコンピューターを開いたときにある 大抵はローカルディスク(C:)とか Cドライブ、Dドライブってと書かれてる奴のことだ そのCドライブを開くと色々とフォルダやファイルがあるだろ? その場所を C:\ と書くわけだ さらにその場所から例えばProgram Filesと言うフォルダを開くと 今の場所はC:\Program Files\となる訳だ つまりC:\tmcsとはCドライブを開いた直下にtmcsと言うフォルダを 作れと言ってる
786 :
前スレ899です。 :2008/11/22(土) 22:21:27
DOSコマンドから覚えた時代はもう遠い昔なんだな そんな面倒なことしなくても簡単にコンピュータが使えるような時代になったってことなんだけど
789 :
前スレ899です。 :2008/11/22(土) 22:35:42
>>780 >
>>779 > ルートディレクトリ?
本当の初心者は、こういったキモの単語は質問しない。
ググりゃ一発だしな。
ネタ認定です。
ぶっちゃけプログラムしてたら勝手にOSとかの知識も付いてくるからOSの勉強を先にまとめてやる必要はないよ
いや、これはそんな生易しいレベルじゃないよ
こんばんは、私、Cの達人といふ者です。 困ったら私を呼んでください。 いつ現れるかは、気分次第です。 では、失礼します。 by Cの達人
こんばんは、私、C++の達人といふ者です。 困ったら私を呼んでください。 いつ現れるかは、気分次第です。 では、失礼します。 by C++の達人
こんばんは、私、C#の達人といふ者です。 困ったら私を呼んでください。 いつ現れるかは、気分次第です。 では、失礼します。 by C#の達人
スレってなんですか? by Cの日下部
スレはマルチスレッドのことだからスレ違い
こんばんは、私、COBOLの達人といふ者です。 困ったら私を呼んでください。 いつ現れるかは、気分次第です。 では、失礼します。 by コボちゃん
801 :
デフォルトの名無しさん :2008/11/23(日) 01:24:12
C言語でカレンダープログラムを作成しています。 年月を与えて、その年月のカレンダーを表示させるプログラムです。 悩んでいるのは、そのプログラムを拡張して、年だけ与えたとき、 その年の12か月分のカレンダーを表示させるというものです。 月の入力があるかないかを判定すればできると思ったんですが、 どうプログラムすればいいかがわかりません。 助言願います。
今はどのようにしてユーザからの入力を得ているのさ
803 :
801 :2008/11/23(日) 01:31:13
printf("年:"); scanf("%d",&year); printf("月:"); scanf("%d",%month); という感じにしています。
804 :
801 :2008/11/23(日) 01:32:18
すいません、4行目が%ではなく&です。
やりようは色々あるけど printf("月を入力しますか?Y/N"); scanf("%c",&month_f); if(month_f == 'Y'){ //月指定の処理 }else{ //12ヶ月分の処理 } とか 月に特殊な値(13とか0とか)を指定するとか あるいはargvでオプション指定させるとか
807 :
801 :2008/11/23(日) 01:50:22
ありがとうございました。 助かりました。
あ〜、なんか変な指定してた。1853って、グレゴリオ暦は1582年10月15日金曜日から 始まり、現代に至るが、日本はそれまでの暦を1872年12月3日まで使用し、 その年月日を1873年1月1日として使い始めた歴史があるんだが・・・ その辺を考慮するなら、 if(y<1853) の部分を適当に変えておいて。すまそ。
米国基準なら1752年9月
cal コマンドみたいに、 入力が1個なら年が、入力が2個なら月と年が入力されたと思えばいいのよ。
>>808 1872 までは太陰暦を表示するってか?
閏月を実装する必要があるぜ。
グレゴリオ暦の前はユリウス暦。太陽暦だよ
って日本の話か
↑キーを押すとボールが上昇し、画面の途中で止まるようにする命令を作れと言われたのですがどうしたらよいでしょうか for文っぽい気もしますし、「もし↑キーが〜」という文脈からif文っぽい気もするので、どちらを使えばいいのか迷っています
すいません。正確には画面の途中でいったん止まって、今度は重力に引かれるように下に落ちていくようにするプログラムを作れと言われました
両方だ!
両方使えばいいじゃん
どっちを使えばいいか分かれば作れそうな口ぶりだけど、それが分かっても作るの無理だろ。
819 :
デフォルトの名無しさん :2008/11/23(日) 15:53:59
if( ( ( (unsigned int&)z & ~( (unsigned int&)x | (unsigned int&)y ) ) & 0x80000000 ) != 0 ) ↑これを普通の大なり小なりみたいな条件式に直せないでしょうか? 何をやってるのか良くわからないのですがコメントは下のようになっておりました。 Take the bitwise AND of z and the complement of the inclusive OR of x and y, then bitwise AND the result with 0x80000000 and return it. A bitwise result of zero equals false, while any other value equals true.
x,y,zが全てint型でなおかつ32bitであると仮定すると if ( z < 0 && (x>=0|y>=0) )
別のスレではfloatって言ってたな
822 :
デフォルトの名無しさん :2008/11/23(日) 16:03:11
>>820 すいません、書き忘れました。
xyzは全部floatです。
32bitかどうかっていうのはちょっとわからないのですが・・・
C++だからスレ違い
824 :
820 :2008/11/23(日) 16:07:04
>>822 IEEE的なfloatと仮定するけど
floatでもNANとか考えないなら820の解釈でおk
>>824 ~を考慮してる?
z が負数、かつ、x が負数でない、かつ、y が負数でない場合
では?
826 :
820 :2008/11/23(日) 16:27:04
>>825 わ、|と&間違えてたthx
考慮はしてたけど間違えてたら意味ないなぁorz
それ間違いだし
>>826 if ( z < 0 && (x>=0 && y>=0) )
こういうことですか?
830 :
デフォルトの名無しさん :2008/11/23(日) 17:20:11
>>827 人がどこにアクセスしてるかなんて
いちいち追跡してんじゃねーよストーカー野郎
>>830 死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね
死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね
死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね
死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね
死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね
死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね
死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね
死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね
死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね
死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね
死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね
死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね
死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね
死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね
死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね
死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね
死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね
ツェラーの公式がグレゴリオ暦に対応している式だから、 考慮するならその辺は自分で指定しろってことだろ。
まともに「西暦」を扱いたいんなら calコマンドと同じ結果になるかチェックすればいい。 あれは色んな事を全部考慮に入れてある。
ファイルの入出力まで勉強を進めてきました。 while(!feof(fp)){ ch = fgetc(fp); putchar(ch); } ↑の場合、feof()というのはファイルの終端でも0を返して、終端を越えてる時に0以外を返すから 「abc」というファイルをcまで読み込んだ時、 1.putchar()で画面にcが表示される 2.whileの継続条件で、ファイルポインタは終端だからfeof(fp)が0を返す 3.ch = fgetc(fp)が実行される 4.putchar(ch)で画面にわけわからないのが表示される 5.whileの継続条件で、feof(fp)が0以外を返してwhileループを抜ける という流れになるんですか?
>>835 なんで2.から3.になるんだ。
feofの前の!を見落としてる?
838 :
デフォルトの名無しさん :2008/11/23(日) 19:17:39
>>819 そもそもビット演算する意味って何ですか?
速度?
速度以外に考えられない
840 :
835 :2008/11/23(日) 19:28:54
>>836 2.でまだfeof(fp)が0を返す為にまだwhileから抜けずに4.の
わけわからないのが1つ余計に表示されちゃうのかなと思ったんです。
状況によるけど、FP演算をするとそのプロセスのコンテキストスイッチの ときに、FPレジスタも保存しなければならなくなって、 コンテキストスイッチが遅くなる、というデメリットを生じることがある
842 :
デフォルトの名無しさん :2008/11/23(日) 19:58:29
>>839 そうですか・・・
if ( z < 0 && (x>=0 && y>=0) )
それで↑で正しいんでしょうか
どうもうまく動かないんです
素直に z < 0 && ! (x > 0 || y > 0) としたらどうよ
間違えた。z < 0 && ! (x < 0 || y < 0) だ。
>>842 NaNとか-0あたりで想定外の挙動してんじゃね?
(この二つが入ってると違う結果になる)
正直、全体の流れを読まんとそれ以上はわからん。
あと、俺は浮動小数点の規格には精通してないから
他にも例外的な理由でうまく動かんのかもね
>>845 ありがとう。
なんか違うところが原因な気がしてきたorz
ひとまず別なところの原因究明します。
本当にありがとう。
847 :
デフォルトの名無しさん :2008/11/23(日) 21:36:57
以下のように記述しておりますが,コンパイル時にエラーが出ます. エラーは下に載せます. ファイル:main.cc #include<stdio.h> #include"sub.h" int main(){ int tmp = get_int(10); fprintf(stderr, "tmp:%d\n", tmp); return(0); } ファイル:sub.h #include<stdio.h> extern int get_int(int num); ファイル:sub.cc #include<stdio.h> int get_int(int num){ return(num); } エラー: underined reference to `get_int(int)` このとき,main.ccの #include "sub.h" を #include "sub.cc" に変更すると コンパイルでき,実行も出来ます.どこが可笑しいのでしょうか? よろしくお願いします.
848 :
847 :2008/11/23(日) 21:38:32
申し訳ありません, sub.h の中身を間違えていました. #ifndef __SUB_H__ #define __SUB_H__ extern int get_int(int num); #endif です.よろしくお願いします.
リンクに失敗しているのかな $ g++ main.cc sub.cc とやってもダメ?
850 :
847 :2008/11/23(日) 21:52:57
>>849 初歩的なミスでした・・・
$ g++ main.cc
としか書いていませんでした.
お手を煩わせてしまい申し訳ありません.
ありがとうございました.
便乗質問。 普通のプロトタイプ宣言とexternつけた宣言に、何か違いがありますか?
ないです デフォルトでexternなので書かない人が多い
>>852 よく見るプロトタイプ宣言はexternが省略された形と考えればよいのですね。
ありがとうございました。
extern宣言からプロトタイプ宣言に発展。
質問です。 キーボードから入力した文字列を逆順に表示するプログラムを作成してみたのですが cygwinで実行すると如何しても文字化けしてしまいます。どこがいったい駄目なのでしょうか? ご教授ください。 #include <stdio.h> void str_reverse(char src[]); int main ( void ) { char src[128]; printf("文字列を入力して下さい >>> "); gets(src); str_reverse(src); return 0; }
void str_reverse(char src[]) { int i, j, n; char dst[128]; for(i=0; src[i]!='\0';i++) ; n=i-1; for(j=0;n>=0;j++,n--) { dst[j]=src[n]; } printf("%s",dst); dst[j]='\0'; }
>>856 printf()を関数の最後にもってこないと、まずいんじゃないの?
>>855 入力してるのは日本語? Cygwinだとcp932(≒Shift_JIS)で入力されるが、
cp932の日本語文字は「2バイト」文字だ。2バイトの1バイト目と2バイト目
が入れ替わったら、そりゃ化けるだろう。
対策はいくつかあるが、ぶっちゃけ初心者向けとは言えない。
UNIX系OSならwchar系APIに逃げる手もあるが……。
>>858 無知で申し訳ないのですが、具体的な例でいえばどこを
どのように修正すればよろしのでしょうか?
>>858 ちなみに入力しているのはアルファベッドです
全角入力してなかったら、文字化けは考えなくていいよ。
>>861 文字列を入力して下さい >>> asdfg
gfdsa0aXl
このような感じなんですがこれでも大丈夫なんでしょうか?
ちなみに
文字列を入力して下さい >>> asd
dsaといったように3文字以内ならなんともないのですが・・・
君は、値をとりかえたいんだろう? しかしそのコードは値を代入してるだけだ
答えありきで質問してる?
単にdstを初期化すればいいんじゃないの? char dst[128]; → char dst[128] = {0};
ああ、printf と dst[j]=0 が逆なのか
>>854 ん?static な関数でもプロトタイプ宣言は有効ですよ。static/extern とプロトタイプは関係ないのでは?
関数のプロトタイプ宣言 と 定義 変数の宣言 と 定義 static/extern によるスコープ制御
>>868 プロトタイプがいかにして生まれたかを述べてるんだろ
871 :
854 :2008/11/24(月) 17:51:35
C++から輸入しただけ。 C++でどのような経緯があったかは知らん。
>>873 関数 setMatrix で mat 自体に領域の確保が必要ですよ
875 :
873 :2008/11/24(月) 18:31:29
>>874 mat=(struct Matrix*)malloc(sizeof(struct Matrix));
ってことですね。
お早い回答ありがとうございます。
無事出来ました。
876 :
868 :2008/11/24(月) 20:41:19
877 :
デフォルトの名無しさん :2008/11/25(火) 00:18:11
あげ
doubleについてなんですが数値の範囲が 仮数部2^52、指数部2^11って書いてあったり 1.7E-308〜1.7E+308って書いてあったりするんですがどういうことですか?
>>878 使ってるコンパイラの float.h を見れ
DBL_MIN 〜 DBL_MAX が正のとりえる範囲で
DBL_MANT_DIG が仮数部のビット数
>>878 数値は2進数で表現されるので、指数部が 2^11 = 2048 ってことは
2^2048 ≒ 3.2×10^616 程度の値を表現できるってことだ
ただし負の指数も表現したければ取れる範囲は -1024〜+1024 になるので (実際には少し違うけど説明が面倒いので)、
2^1024 ≒ 1.7×10^308 程度の値が最大値ということになる
882 :
デフォルトの名無しさん :2008/11/25(火) 17:35:48
関数ポインタ エディタ
関数ポインタを使う事のデメリットを教えてください。
いいかげんな実装してるとわけわかめになる?
>>884 関数ポインタを使う上でいい加減な実装にならないようにするためには、
どのようなコーディング(どんな事に注意)をすればよいですか?
なんにでも当てはまるけど、仕様(動作)をよく理解することかな。 仕様の読み間違いしてるとあらぬ方向にいく可能性が高い。
>>887 * *
* + うそです
n ∧_∧ n
+ (ヨ(* ´∀`)E)
Y Y *
なんだうそか
ゆっくりしていってね
NOOBです。 入力を最大8桁にするにはどうすればいいんですかね? MAXCHAR 8 使用したいけどまったくわからん・・・ #include <stdio.h> main(void) { int a[3]; int i; for(i = 0; i < 3; i++) { scanf("%d", &a[i]); } printf("%d\n", a[0] + a[1] + a[2] ); return 0; }
>>891 標準入力から入力させてると、桁数の制限は無理。
行単位で読み込んで、8桁以上だったらエラーにしてもう一回入力させるとかじゃだめなの?
>>892 むしろエラー表示させて終了させたい
かわいい俺に優しく教えてくれ
>>893 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
main()
{
char str[100];
int n;
fgets(str, sizeof(str), stdin);
if (strlen(str) > 8) {
puts("桁数多いよ");
return 1;
}
n = atoi(str);
printf("%d\n", n);
return 0;
}
数字以外が入力されたときのエラーチェックとかないけど。
895 :
894 :2008/11/25(火) 21:39:35
>>894 改行も入ってくるから、それにも対応しないといけないか。
>>894 ,<<895 thx
atoi関数は初めて見たかな
でもgetchar関数を使用したいとわがまま言ってみる
#include <stdio.h> #include <stdlib.h> #include <string.h> void getline(char* s, int size) { int i; for (i = 0; i < size; i++) { s[i] = getchar(); if (s[i] == '\n') { s[i] = '\0'; return; } } } main() { char str[100]; int n; getline(s, sizeof(str)); if (strlen(str) > 8) { puts("桁数多いよ"); return 1; } n = atoi(str); printf("%d\n", n); return 0; }
数値以外が入力されたらエラーになる処理は、自分で挑戦してみそ。
p = strchr(str, '¥n'); if (p) *p = '¥0'; n = strtol(str, &end, 10); if (!(*str && !*end) || end - str > 8) { errx(1, "error¥n"); }
901 :
897 :2008/11/25(火) 21:57:57
getline()は、サイズより長い行を入力されたら最後に0がつかないな。 まあいいか。 これも自分でやってくれ。
<<901 やってみるお
903 :
デフォルトの名無しさん :2008/11/25(火) 22:25:23
error LNK2019: 未解決の外部シンボル _runge が関数 _main で参照され ました。 fatal error LNK1120: 外部参照 1 が未解決です。 この意味ってどういう意味?
fabs(tmp);と if(tmp < 0) tmp = tmp*-1; ってどっちが早い?
907 :
デフォルトの名無しさん :2008/11/25(火) 22:35:55
>>904 何で tmp = -tmp って書かないの? まぁコンパイルされたらどっちも一緒のような気はするけど。
910 :
909 :2008/11/25(火) 22:48:41
ああ、ifの下か。
912 :
908 :2008/11/25(火) 22:58:11
標準ライブラリにちょうど良い関数あるなら、それを使うのが原則 大抵はアルゴリズムの専門家が組んだ高速なものだし、 処理系によってはライブラリ関数を認識してインライン展開とか 自前実装には難しいことをやってくれたりもするそうな
条件を書くときなんですが (i++<a)が比べてから足す (++i<a)が足してから比べる で合ってますか?
設計をキチンとしないとまともなソフトウェアを作れない事に今更気付いた ……面倒だな
>>914 前者が足す前の値で比べる、後者が足した後の値で比べる
917 :
デフォルトの名無しさん :2008/11/26(水) 01:19:27
C言語のプログラムを走らせて wrong value Segmentation fault とだけエラーが出て終了します。 wrong value は勿論自分で書いた標準出力もしくは標準エラーではありません. このようなエラーが出る原因は分かりますでしょうか? ある関数の中でメモリ領域を確保しているのですが、 その確保の時点で以上のエラーが出ているようです。 このエラーは初めての遭遇で、対処できません。 またググっても良い検索結果が得られませんでした。 よろしくお願いします。
メモリ領域確保のパラメタが間違っていて、かつ、 エラーを無視して 0番地をアクセスしてるんだろう エスパースレじゃないんだから、ソースか関数名ぐらい書け
>>917 malloc関数のサイズの引数が間違っているんじゃないか?−>wrong value
mallocが失敗しているのに、戻り値をチェックしないで0番地書き込み−>Segmentation fault
どこかでバッファオーバーランでもしてんじゃ?
>>914 >>916 に補足すると、比べるのと実際に足されるのがどっちが先かはわからない
あくまで比べる値が足されてるか足されてないかだけ
923 :
917 :2008/11/26(水) 01:52:50
>>918 申し訳ありません。
ソースは膨大なので貼りませんでした。
>>919-920 mallocが失敗していて0番地に書き込んでいる点は確認できました。
しかし、読み込んでいる関数は多所で使用しており、
関数を複数回読んだ時点でエラーが出るのです。
エラーを出す箇所(関数を読む回数)は同じで、再現性があります。
924 :
917 :2008/11/26(水) 01:55:36
連続投稿失礼します。 mallocに渡す引数は『他所で使用している』 場合と同様の渡し方をしています。 単純に正整数を与えるだけです。 メモリの解放も忘れずに行っているのですが・・・ よろしくお願いします。
うるせえ黙ってソース貼れ
×貼れ ○うpれ
927 :
917 :2008/11/26(水) 02:01:58
>>925-926 申し訳ありません。
ソースの開示は出来ません。
スレ汚し失礼しました。
928 :
:2008/11/26(水) 02:02:30
#include <stdio.h> main() { printf("Hello World!!\n"); } CのHello Worldってこれでいいの?
使ってるうちにメモリのフラグメンテーションが発生して新たなメモリ確保に失敗することもあるよ
931 :
デフォルトの名無しさん :2008/11/26(水) 02:28:52
windowsでncursesを使いたいのですが、Cygwinを使わないと無理でしょうか?
>>927 再現する最小範囲を作れないあなたが悪い。
ポインタ宣言および実引数の値の流れが明白となっている部分、加えてmallocを呼び出す部分、
これだけのソースで問題を解決する手がかりが得られるかもしれませんが、それを見せることすら嫌うのでしょうか?
のはさておき、『他所で使用している』時と同じ値が変数に格納されていますか?
まぁデバッガの使い方覚えるといいと思うよ
935 :
931 :2008/11/26(水) 02:59:37
>>934 せっかくお答えいただいたのですが、
PDCursesではなく、ncursesを使いたいんです。
なんでncursesにこだわるの?
>>928 だめ。引数がないなら int main(void) ついでに return 0; といった感じで
int型の値を何か返すのが標準スタイル。
938 :
928 :2008/11/26(水) 03:41:54
>>930 ,937
レスありがとうございます。
両方をコンパイルしてみました。
どちらも警告など出ず無事に実行ファイルが出来ました。
で、ファイルサイズを見てみたのですが、同じサイズです。
Hello Worldくらいじゃサイズは変わらないのですかね?
標準スタイルということで、
>>937 さんが指摘された
ほうを覚えておくことにしました。
>>937 ん? main() と返り値を省略すれば int がかえることにならないのでしょうか?
int main(void) には異論もあるようですよ。
>>940 なるわけないじゃん、馬鹿なの?死ぬの?
戻り値を省略なんて許されない
またこの展開かよ
intを返す関数と仮定します という警告をなんどかみた
厳密にどうとかどうでもいいからとりあえず書いとけ、な! そうするだけで何も問題は起きないから これで良いだろ
もうやめてぇえええええええええええええええええええええええ
もちつけ、コンパイラが都合よく解釈してくれている部分は、確かにある。 まぁ、標準スタイルというのは、あくまでもISO、ANSIという標準化機構で、 世界的に工業製品やらその他、標準的な規格を決めている団体だから とりあえず従っておけば、どのコンパイラでも無難に通るだろうということだ。 独自の環境では、別にvoid mainだろうと、知ったこっちゃない。 また、ISO、ANSI準拠では、プログラムの開始、主体となる関数が mainであるという前提もあるが、独自の環境では必ずしもmainが 開始とは限らない。くどいが、とりあえず世界的な標準スタイルということで。 ただし、C++だと int main() と、引数が無い場合は省略しているんだなw
>>945 それでいいと思いますが、
>>928 がいいか悪いかを判断するのであれば、根拠が必要となります。
950 :
デフォルトの名無しさん :2008/11/26(水) 06:39:27
for(j=0;j<8;j++){ PORTA = port[j]; PORTB = abc[(i+j)%32]; 皆はこの3行を文章で説明しろと言われたらどう説明しますか?
>>950 それだけじゃ説明できません。
PORTA ってなんですか?
PORTB ってなんですか?
952 :
デフォルトの名無しさん :2008/11/26(水) 08:00:00
>>928 省略するなら #include モナー
>>952 それはダメw printf()があるし
954 :
デフォルトの名無しさん :2008/11/26(水) 08:34:40
>>954 いや、警告を出して通すものもあるが、理屈としては成り立たんぞ・・・w
956 :
デフォルトの名無しさん :2008/11/26(水) 08:56:45
>>956 ???意味不明。printfについて調べてこいw
っつか、コンパイラが都合よく解釈してくれるものは良いが、 そういうのを抜きで、ある標準ライブラリを用いる際に、 必要なヘッダを取り込まなくて通るものだろうか? 我々特派員は、その真相を探るべく・・・
C言語なら関数プロトタイプがなくてもなんとかしてくれる(もちろん間違う場合はあるw) C++なら関数プロトタイプは必須
960 :
デフォルトの名無しさん :2008/11/26(水) 09:23:40
>>957 これは printf に限った話ではない
> 警告を出して通すものもあるが
通さない C 処理系を1つでも知っているか?
また通すなと規格にあるか?
あくまで C でだぞ、C++ ではなく
includeさぼったらまずハマるのはmath.hだな
962 :
デフォルトの名無しさん :2008/11/26(水) 10:08:52
グローバル変数は無理だな
964 :
デフォルトの名無しさん :2008/11/26(水) 11:09:56
死のHello World
965 :
デフォルトの名無しさん :2008/11/26(水) 11:25:31
__declspec(dllimport) int puts(const char *); main(){puts("Hello, world!\n");}
死ね
>>959 だからさ、それはコンパイラが都合よく工面してくれているからでしょ?
そういうのは不適切だって。
都合よくって、言語仕様なんだが。
>>966 ここにはCに詳しい住人は多いかもしれないが、
入試に詳しい住人は少ないと思う
何にせよ問題傾向を見るべきでしょ?という程度の一般的な回答しかできないだろう
戻り値省略したらintになるとかプロトタイプなくても動くとか知らない人は結構多い
プロトタイプ無しの関数呼び出しは 戻り int 仮定で 引数は呼び出し元の型をその型のまま積むんだっけ? 浮動小数点数は常に double へ格上げ? float a; double b; func(a,b); /* func(float,double) として呼ぶ? */ ま、include するなりして、プロトタイプ宣言を確実に行えば、こういうこと気にする必要はないw
リテラル定数 1.0f は格上げかかってたのは記憶してたけど 変数値も格上げでしたか… って printf とかの可変引数部と同じルールだわな
>>957 Lattice-Cで、Dモデルにするとアウト。
>>974 >って printf とかの可変引数部と同じルールだわな
そりゃそうだ。つーか、昔はプロトタイプが無かったんだから当然だね。
ドライバーのinfファイルが右クリックしてもインストールと出ず、 このままではダウンロードのしようがないのでプログラムとして動作させたいのですが可能でしょうか?
でも規格では (...) と ( ) は別物扱いなんだよな。
この質問はあくまで初心者のふとした疑問なので気軽にこたえてあげてください 昔はプロトタイプ宣言無かったってことは、返り値がintじゃない関数は呼び出し元より 前に書いておかなきゃいけなかったんですか? 相互に呼び出すときどうしてたんですか? なんだか殺伐としているので断りをいれてみました
>>981 プロトタイプ宣言は昔からありましたよ。
ただ、使用している箇所より前に、プロトタイプ宣言もしくは関数の定義がない場合は
戻り値がintの関数としてみなされるということ。
配列から要素を消してなくなった分は詰める みたいなことはどうやったらできますか?
memmove
985 :
デフォルトの名無しさん :2008/11/26(水) 21:23:02
関数原型と関数宣言を混同している悪寒
>>981 引数の型はノーケアーなプロトタイプ宣言 (結局戻りの型のみ宣言) という時代を経由して
引数の型も宣言するプロトタイプ宣言が出てきた
>>982 、
>>986 ありがとうございます
引数の話とプロトタイプ宣言全文の話をごちゃごちゃに混ぜて勘違いしていたみたいです
988 :
931 :2008/11/26(水) 22:09:19
>>936 UNIXやLinuxへ移植する際に、PDCursesよりncursesの方が便利そうなので。
>>981 K&R1 の頃は、
double sub1();
double sub2();
main() {
sub1(0);
sub2(0);
}
sub1()
int a;
{
}
sub2()
int a;
{
}
という感じでした。
>>990 流石にそれは大嘘過ぎ。
double
sub1(a)
{
}
だろ。
>>991 そうだった、すっかり忘れてしまいました。訂正。
double sub1();
double sub2();
main() {
sub1(0);
sub2(0);
}
sub1(a)
int a;
{
}
sub2(a)
int a;
{
}
double sub1();$ double sub2();$ main()$ {$ sub1(0);$ sub2(0);$ }$ sub1(a)$ int a;$ {$ }$ sub2(a)$ int a;$ {$ }$
foo(a) int a; { } ってなんか気持ち悪い foo(int a)にしろよ
996 :
デフォルトの名無しさん :2008/11/27(木) 09:45:36
>>995 何が気持ち悪いのかはっきりせんようならどっちもどっちだろ
$ってなんか気持ち悪い
998 :
デフォルトの名無しさん :2008/11/27(木) 10:54:35
998 !!!!!!!!!!!!!!!!!!!!!!!1
何か気持ち (・∀・)イイ!
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。