1 :
デフォルトの名無しさん :
2009/06/06(土) 23:11:16 BE:302947384-DIA(278040)
早すぎ
4 :
デフォルトの名無しさん :2009/06/08(月) 06:54:14
tureって常に1なのですか?それとも0以外なら何でも良いのでしょうか? これに関する規格はどこかで読めないでしょうか?
>>4 0(整数値)はfalseに変換される。
0以外の整数値はtrueに変換される。
trueは1に変換される。(他の値にはならない。)
false整数値は0に変換される。
これが規格のどこかに書いてあった。
忘れたけどね。
6 :
デフォルトの名無しさん :2009/06/08(月) 07:36:26
テキストIOでは改行が\nにおきかえられるとなってますが これは単純に\rが無視されるだけなのかそれとも\r\nと続いたときのみ\rが無視しされるのどっちなんでしょう? \r\r\nのような場合はどうなりますか?
\r\n→\n
>>7 \r\nの2バイトを\nに変換する
\r -> \r
\r\r\n -> \r\n
登場した順に処理していくから \r\r\n -> \r\n ってことなの?
11 :
デフォルトの名無しさん :2009/06/08(月) 13:32:30
#define MAX_LEN 200020 int main(int argc, char **argv) { unsigned int from_len, to_len,mv_len; char *p = NULL; char in[MAX_LEN],from[MAX_LEN],to[MAX_LEN]; のというプログラムで、コマンドラインからの引数(文字列)をプログラム内の変数に代入したいです。 具体的にはfromにargv[1]の文字列を、toにargv[2]の文字列を入れたいのですが…。 from=argv[1]というようにやっても、 「型が合わない変数に代入しようとしています」というエラーが出てしまいます。 どうしたらいいのでしょうか?
strncpy
13 :
デフォルトの名無しさん :2009/06/08(月) 13:40:58
なるほど、それを忘れてました。 ありがとうございます!
文字列コピーでそれを忘れてましたってw
>>15 文法的には、if(execv(argv[0],argv[])==(-1)){ の argv[] の部分がおかしい。
内容自体はC言語の話から外れるが、UNIX系OSのexecvのことであるのなら、
argv[] を argv とすればよかろう。
あ、ごめん。execvは標準Cライブラリに入ってたか。
18 :
>>15 :2009/06/08(月) 20:29:14
Ubuntuで実行しています。どうしたらいいですか?
20 :
>>15 :2009/06/08(月) 23:09:21
unistd.hをインクルードして、 argv[]をargvでコンパイル出来ました。 ありがとうございます。
POSIXだね。exec*()シリーズは。 ISO/IEC 9899 : 1999 (E)には、載ってなかった。 最新のドラフトISO/IEC 9899:201xにもないな。 regexとか入ってくれないものかなぁ。
学校のPCで授業をやっているのですが、自分のつかっているコンパイラの名前・バージョンなどがわかりません。 どこをみればわかるのでしょうか?OSはGNU Network Object Model Environmentです。 お願いします。
大概はヘルプにバージョン情報があるもんだけどな? なけりゃ知らん
GNOMEはOSじゃないけどな。 コンパイルはどうやってんの? コマンドラインなら、大抵は -v オプションで出るよ gcc -v とか
>>22 gccって打ち込んでるならコンパイラ名はgccで通じるよ
正式にはGNU Compiler Collectionだけど
副作用完了点についてちょっと曖昧だったので確認させてください arr[idx++] = data++; idxとdataが別のものである場合、それぞれインクリメント前の値で処理が行われるのであってますよね?
また燃料が・・・・
>>26 参照後 セミコロンまでの間のどこかで インクリメントがなされる
idx は arr[ ] に値を積んだ後 ; までの間
data は 右辺値 として参照した後 ; までの間
29 :
26 :2009/06/09(火) 16:17:59
char *p, *q; *p++ = *q++; は完全に合法ですよね? *(arr + idx++) = data++; と展開するといかにも怪しい感じになるんですが、どうなんだろうと思いまして。。
>>28 合法なはずだけどどうだったろうかと思って心配になってました。
ありがとうございました。
>>30 hoge++ と書いた場所から 副作用完了点までのどこかで hoge のインクリメントが発生する
という仕様
hoge++ と書いた場所から 副作用完了点までの間に hoge(ポインタ使用のエイリアスも含む)
が登場しちゃうと仕様の立場としては
後のhoge参照前にインクリメントが発生するのか
後のhoge参照後にインクリメントが発生するのか
定まらない
(さらに C89なら このようなケースで鼻から悪魔出しても良いとなっている)
副作用完了点 は インクリメントが終わっていると断言できる点 であって 何時インクリメントを発生させるかを規定しているわけではないのさー
文系で専門学校入ってC言語とかも苦労してるんですが慣れますか?
>>33 お前は何をやってもダメ
C言語どころか日本語も英語もダメ
とでも言えばいいのか?
ついでの疑問 a[i++] = i ; こいつは即論外として a[i @] = i ++ A; |i @参照 |参照値により a[ ] を |i A参照 |i インクリメント (A記述〜 ; までの間のにインクリメント操作挿入) こう解釈できそうだけど @での i参照と Aの i 参照の翻訳順(?)が @→A とは限らないから やっぱNG ってこと?
どっちも即論外
右辺確定の為 i A 参照 A ↓ 添え字確定の為 i @参照 ↓ a[] に右辺値を代入 B A〜B間ならどこでも i のインクリメントを発生させてよいことになる ポストインクリメント演算子とその参照の共存は論外
""文字列を連結するマクロってあります?
>>38 strcat()でできることと比べて何がしたいのか分かりやすく言ってくれ
>>38 こんなん?
#include<stdio.h>
int main(void){
const char *p="abcde" "12345";
puts(p);
return 0;
}
c=getch(); とやると error C3861: 'getch':識別子が見つかりませんでした となってしまいます。 なにがいけないんでしょうか? (コンパイラはVC++EEです
#include <stdio.h> がソースの頭にないとか
getchだからconio.hかなー
こにお?
うん。こにお。 ではなくて、コンソールIO
>>45 コンソールIOの略だったことを今更になって知った俺がいる。
このスレに私の書いたプログラムを載せた場合、 ソースコードのここはこうしたほうがいい 等の助言を頂くことはできますか?
助言できる場合もあるし、できない場合もある。 助言できない典型例は、「何がしたいのか分からないので改善方法も分からない」ってやつかなぁ。 まあ、気軽に書いてみたらいいよ。
長いソースだったり、インデントの調整が面倒ならソースそのものを外部ロダに上げて リンクを貼ってね
>>47 codepad
ttp://codepad.org/ ここにソースを貼り付けるのがオススメだよ。
なお、2chに書いたソースの利権は2ch管理者の物になるので
根幹に関わる大事なところは伏せた方が絶対によい。
訴訟になったりした時のためにも。
俺のコードなら2chに寄贈してやんよ
>>50 そもそも、そんな大事なソースなら掲示板に晒してはいけない。
すでにほかの人に権利があるコードを張ったら誰のものなの?
>>53 書いた人の物だろ。
んで、もしその規定に反するようなソースを貼り付けたら
どうなるのかは・・・知らない。
掲示板に貼り付ける程度の10〜20行程度のプログラムに著作権が 法廷で立証できるかは疑問だがな
57 :
56 :2009/06/10(水) 22:06:21
あとまあ、いかなるソースでも、 switch(掲示板に貼り付ける程度の10〜20行程度のプログラムに利権が ) case 主張できない :自分の権利も認められない case 主張できる :2ch運営の権利となる。 結局自分の権利は認められないことになるな。
20行あれば割と重要な部分も書ける気がするが
>>58 重要な部分とは、アルゴリズム=アイデアでしょ、アイデアは保護できない
>>59 アルゴリズムもアイディアも保護できないなら、
何なら保護できるの?
たとえば今では定番のリストに関連する関数なんて20行あまりで全部書けそうだしな ああいうのは権利放棄されたのかね?それともそういう以前の問題かな?
>>56 そういう詰め込み方がありなら
1レス2kBで相当書けそうな気はする
>>62 広く一般に知れ渡っている知識やアルゴリズムは、著作権の対象とはならない。
これは一般的な考え方であって、実際には法廷で戦わないと結論はすべて出ない。
が、まず負けるだろう。
例えばだ、アルゴリズム辞典等で乗ってるアイデア等は、その後同じプログラムを
書いても、勝つことは難しい。では何が一番良いか、プログラムが同じでも、それに
長いコメントを書くことだ。コメントは明らかに著作物だと認められる。あと
大きなプログラムも著作権が認められやすい。
だが、実際は総て法廷で争う以外結論は出ない。
そもそも、知識やアルゴリズムは著作権でもって保護されるものじゃないし。
vc++環境下で組まれたソースをgcc向けに調整した際に警告がでたのですが NULLって数字としても使えるものなんですかね? gccだとNULLをポインタ変数以外で使うと警告がでます。
関数のプロトタイプ宣言の際にstaticが付くのと付かないのでは何が変わるのでしょうか?
>>65 アルゴリズムもアイディアも保護できないなら、
何なら保護できるの?
>>68 著作権で保護されるのは実装、つまりプログラマがプログラムを書くことに費やした努力。
アルゴリズムを考えるのに費やした努力を保護するのは特許権。
>>69 ありがとうございます。
ではソースを分割した際にexternをつけて関数などを宣言するのは理解しているのですが
プロトタイプ宣言ではなく関数の実体のところにexternをつけると扱いは同じなのでしょうか?
実体にはextern付けられないでしょ?
デフォルトがexternなのでみんな省略しているだけ
画像を1ピクセルずつ読み取って その色データをエスケープシーケンスで文字”■”に色をつけて コンソール上に画像みたいなものを表示させたいのですが どうすればいいのでしょうか? windows APIのDIBを使うのでしょうか?
ファイル形式がわかってればそのファイルを直接読めばいいよ。
76 :
デフォルトの名無しさん :2009/06/11(木) 12:57:39
77 :
デフォルトの名無しさん :2009/06/11(木) 13:29:47
r
>>71 externは不要ですよ。
関数の場合
extern char foo(int num);
char foo(int num);
どっちでも同じ。
変数の場合はおっしゃるとおり
extern long hoge;
long hoge;
意味が違う。
条件文AとBがあるとして if(A){ if(B){ ・・・・・ } } ってのと if(A && B){ ・・・・ } って一般的には動作変わってしまうものでしょうか?
場合によるかな
変わらないんじゃないかな
83 :
デフォルトの名無しさん :2009/06/11(木) 20:50:43
変わらないでしょ。 どっちもAが偽だったらBは評価しないでしょ。
>>79 全く同一で、変わらないよ。
C++で&&が変にオーバーロードされているとかじゃないかぎり。
86 :
84 :2009/06/11(木) 21:06:03
>>79 それから揚げ足をとるようだけど、
条件文じゃなくて条件式ね。
87 :
81 :2009/06/11(木) 21:12:24
思い違いをしてました。ごめん。
88 :
79 :2009/06/11(木) 21:35:37
様々な意見ありがとうございます
自身で実際書いたプログラムとしては、aを配列添字(別の関数から値を取得)、Bを配列として
条件式A : a!=-1 // エラー値
条件式B : b[a]==NULL
のように記述したのですが、
>>79 の前者だと・・・・・の部分が全く実行されず
疑問に感じたので質問させていただきました(自身はこの二つは同じものだと考えていたので)
ご指摘いただいた副作用や短絡評価について少し調べてみましたが、原因がよく分からなかったため
とりあえず後者の記述で統一しようかと思います
お騒がせしました。
短絡評価なんかに頼っちゃいけません
>>88 もし本当にそうだとしたら、原因は別のところにある。
使っているコンパイラの最適化のバグとか、メモリを破壊しているとかなど。
>>89 いやいや、君C言語で仕事したことあるの??
dllは異なるアプリでメモリを共有して使っている?とのことなんですが グローバル変数やstatic変数を使わなければ危険はないんでしょうか?
dragon=0; printf("%x",dragon); で16進数表示をさせると 0と表示されますが。 00や0aなどのように2桁で表示させるには if文で一桁だった場合だけ0を付けるというやり方でよろしいでしょうか?
printf("%02x",dragon);
95 :
デフォルトの名無しさん :2009/06/11(木) 22:28:04
#include <stdio.h> double angle; main(void) { printf("角度を入力"); scanf("%f",&angle); printf("%f",angle); } 何がだめなんでしょう
>>95 scanf("%lf", &angle);
97 :
デフォルトの名無しさん :2009/06/11(木) 22:30:52
ありがとうございます
>>91 あるよ?
短絡評価はいたずらにプログラムを複雑化し、可読性を下げる
さらには実行順序を強制することでコンパイラの最適化の機会さえ奪う
使うべきでない
深刻かつ基礎的な話なので入門スレの話題としてはややスレ違いになって いる件について
短絡評価はわからないので禁止
101 :
デフォルトの名無しさん :2009/06/11(木) 22:54:53
if (i >= 0 && a[i] == NULL) これ自体はこれで問題ないし、可読性も悪いとは思わない。 if (i >= 0) { if (a[i] == NULL) { } } 可読性なら、こっちのほうがよろしくないと思うぐらいだ。
static変数をまとめて処理するのはどうするのでしょうか structに入れようとしてもエラーが出てしまい、できません
>>102 こんな風に書いたらエラーが出たって事?
typedef struct{
static int a;
static int b;
static char* c;
}ABC;
構造体変数をstaticにする。 static struct ttt a;
105 :
91 :2009/06/11(木) 23:09:25
>>98 >さらには実行順序を強制することでコンパイラの最適化の機会さえ奪う
>101が言うような
if (i >= 0) {
if (a[i] == NULL) {
}
}
こんなif ifになっているコードと短絡評価は等価だよねぇ。
>短絡評価はいたずらにプログラムを複雑化し、可読性を下げる
可読性は水掛け論だから取り扱わないことにするとしても
>さらには実行順序を強制することでコンパイラの最適化の機会さえ奪う
こちらは全く当てはまらない指摘では?
106 :
デフォルトの名無しさん :2009/06/11(木) 23:15:20
質問です 基本的な文体、構造体やポインタまでひととおり理解したら、次はライブラリの扱い方を勉強すべきと言われました なのでライブラリを勉強しようと思うのですが・・・まず何をやればいいのかわかりません 最初に「Hello World」を表示したように、ライブラリの扱いを覚えるならまずこれをやれ、ってを教えてください
クイックリファレンスでも買って眺める
qsortを使ってみろw
110 :
デフォルトの名無しさん :2009/06/11(木) 23:25:13
>>108 つまり
#include<math.h>
を読み込んで平方根とか累乗の値を求めるのもライブラリを扱ってるうちに入るんですか?
しかし、それで何かができるって気がしません
ライブラリを使いこなせばあれこれできるようになると聞きますが
まず、目的がないとダメだな。
>>110 じゃあ標準関数(ライブラリ)を使いそうなお題を自分で用意して
それに取り組め
>>105 それは順序性のある条件だからそれでいい
(if二段構えの方がいいと思うが)
問題なのはこんなの
if(i >= 0 && j >= 0)
コンパイラはj >= 0を先にやりたくても出来ない
こんなのに短絡評価を使うのは馬鹿げているので、こう書くべきである
#define AND(A,B) (!!(A) & !!(B))
#define OR(A,B) (!!(A) | !!(B))
if(AND(i >= 1, j >= 0))
>>110 C言語だけではたいしたことは事はできない(一部の天才を除く)。
これは別にC言語が悪いわけではないが、APIというものに頼らねばならない。
技術者ですらAPIや外部ライブラリに頼る形になる。
んでどうすりゃ良いかというと・・・
>基本的な文体、構造体やポインタ
これが「本当にしっかり理解出来ているなら」次にC++に進むのが個人的にはオススメ。
(理解出来てないと死ぬけど。)
そしてC++から利用できるライブラリがいっぱいあるから
それを使ってより色んな事が出来るようになれる。
>>88 の見てふと思いついたんだけど
a != -1 && b[a]==NULL
a != -1&&b[a]==NULL
この二つって、演算子の前後の空白の違いだけだから問題ないよね
でも、それってこう読まれたりしないの?
a != -1 & &b[a]==NULL
&にしちゃうと先に評価も何も、両方評価してから演算してさらに評価ってなるんじゃ?
>>113 それは逆にコンパイラの最適化機能に期待しすぎだ。
そっちのほうが必ず速いという保証が全然ない。
むしろ遅くなる可能性も大きい。
>>115 しない。
119 :
デフォルトの名無しさん :2009/06/11(木) 23:34:29
>>111 >>112 画像や動画をいじるプログラムを作れるようになるのが目的です
たとえばjpgファイルを読み込んで、色を反転させて表示させたりとか、そういうの
しかし「どこの延長線上にそれができるようになるのか」という、スタートラインがわかりません・・・
例えば「画面に赤い点を表示する」ということすらどうやっていいかさっぱりわからない
>>114 ええ、もう別の言語ですか・・・
120 :
105 :2009/06/11(木) 23:35:19
>>113 君のレスの言いたいことを理解したわ。
#define AND(A,B) (!!(A) & !!(B))
これは無理矢理にbool型ないしint型にした上でビット演算を適用している訳か。
・・・これって短絡評価による最適化の邪魔が無くなるというメリットより
bool型ないしint型に変換する方が遅そうだけど、本当に速い?
最適化のためにと思って変な書き方をすると、かえって遅くなるとか、ぜんぜんかわらないとか ありがちだけどな。
122 :
デフォルトの名無しさん :2009/06/11(木) 23:35:56
>>119 本当に基本はできた自信があるなら、
既存のプログラムのソース読んだら?
関係ありそうな本買ってきて、サンプルプログラム見るとか。
>>115 maximal munchというルールがあってだな
&は後ろに&や=が来ないと確認してからトークン切られるようになってる
>>118 &&と空白なしで記述された場合はそうとしか読まれないってことで大丈夫?
それと、短絡評価についてだけれど、
if (A && B)とあった場合に、コンパイラが気を利かせてBを先に評価するようなことはありえないの?
if (i >= 0 && 1==1) と書かれていた場合とかでも常に i>=0を評価する?
>>119 画像は特定の圧縮フォーマットを使ってる場合はそれ相応のデコード処理をする必要があるけど
それをやってしまえば色深度に応じた2次元配列のデータに過ぎない。
>>123 おお、ありがとうございます。すっきりしました
画像いじるならバイナリファイルの操作できれば可能だよ
128 :
114 :2009/06/11(木) 23:38:36
>>119 >画像や動画をいじるプログラムを作れるようになるのが目的です
だからこそのC++なのだ。
C++はすんげー険しいけど、そういう事をしたいなら外部に転がっているライブラリを使うことになる。
>例えば「画面に赤い点を表示する」ということすらどうやっていいかさっぱりわからない
それは俺の言う、
>別にC言語が悪いわけではないが、APIというものに頼らねばならない。
>技術者ですらAPIや外部ライブラリに頼る形になる。
ってやつだ。つまりC言語の言語仕様にないから純粋なC言語ではできないんだ。
そして外部に転がっているライブラリはC++用のライブラリでクラス化されていたりする。
その方が使いやすいからね。
>>124 短絡評価は必ず左からやることになってるけど、
1==1は、常に真だからコンパイル時に取り除かれちゃう可能性はある。
130 :
124 :2009/06/11(木) 23:39:23
ごめん。。&&を||に読み替えて。。 if (A || B)とあった場合に、コンパイラが気を利かせてBを先に評価するようなことはありえないの? if (i >= 0 || 1==1) と書かれていた場合とかでも常に i>=0を評価する?
>>106 >>111 がボソッと言っているが、
もう目的としての勉強は要らない段階。
あとは、これ作りたい(作らないといけない)→それにはあれが必要
→「それ」を使えるようにする(or 挫折)、の繰り返しで。
132 :
デフォルトの名無しさん :2009/06/11(木) 23:40:58
>>122 そういうものですか
なんかわかりやすい「次はこれをやれ」ってのは、文法を覚えるときとは違ってないんですね
>>125 とりあえずbmpファイルをtxtファイルに変換してみて読み込んでいじってみるとかそれくらいはできたんですけど
bmpファイルの読み方がいまいちわかんないんで思い通りに画像をいじるという段階には程遠いんです
1ピクセルごとの三原色とかわかりやすく順番に書いててくれたらいいのに、とか
いや圧縮してるわけだからそういうふうにはならないんだろうけど
>>119 amazonあたりで「画像処理」とかで検索したらそういう書籍がいっぱいでてくるよ。
まあでも、その前に、標準関数でファイル入出力とか文字列操作とかは
できるようになってたほうがいいね。
>>130 言語仕様上そうなんじゃない?
||がオーバーロードされていたらどうするんだ。
・・・と思いきやC言語スレだったか。
>>132 BMPにも種類がいろいろあるとかはさておいても、
RGB値についてはわかりやすく順番に並んでない?
136 :
128 :2009/06/11(木) 23:43:17
>>132 だからこそクラス…(ry
まあ俺はC++大好き人間だから多少偏ったこと言ってるかも。
他の人の意見も合わせて総合的に自分で判断してくれ。
でも俺はC++に移るのがオススメ。
>>134 ||をオーバーロードするのとboolへのキャストを用意するのとどっちがいいんだろ
画像ファイルはめんどいよ 何の形式だか忘れたけど、1ピクセル分のRGBを16ビットに詰め込んでて Gだけ6ビット割り当ててるんだったかな? 人間の目はRやBよりGの変化に敏感だからって
139 :
デフォルトの名無しさん :2009/06/11(木) 23:47:19
>>127 要するにjpgファイルやらbmpファイルやらが、どういうふうに処理されているのか理解できていれば、データをいじれるってことですよね?
>>128 やはりC++ですか
次はJavaに手を出してみようかなと思っていたのですが、そういうことなら考えてみます
とはいえ、そもそもCですらまともにちゃんとしたプログラムを何か作れてもいないわけだから、別の言語の習得なんてまだまだだと自分では思っていたのですが
>>135 とりあえず何枚かデタラメに白と黒だけのbmpファイル作ってtxtに変換して読み込んでみたんですけどよくわかんなかったです
>>138 それは一般的な16bitのRGBフォーマットだ
>>139 今mspaint.exeで白黒24bitBMPを作ってバイナリエディタで見てみたんだが、データ部は見事に
00 or FFで埋め尽くされていたよ。
142 :
128 :2009/06/11(木) 23:52:26
>>139 >次はJavaに手を出してみようかなと思っていたのですが、そういうことなら考えてみます
ああ、Javaを教えてくれる人がもし身近にいるとかだったらJavaでもいいかも。
でも所詮Java止まりだろう。
もっと高級言語(Pythonとか)でもいいだろうけど、
普遍的なのはやっぱC++だよ。
C++は難解さも一段と勝るけど。
>>141 まずは
ファイルフォーマット 仕様
という単語にbmp jpeg pngといったキーワードとセットにしてぐぐるということを教えてあげないと
144 :
デフォルトの名無しさん :2009/06/11(木) 23:53:08
>>141 txtで読み込んでました
あの超初心者っぽい質問なんで恥ずかしいんですが、そんなふうにファイルの内容を16進数表記で表示させるにはどうすればいいんでしょうか
145 :
デフォルトの名無しさん :2009/06/11(木) 23:54:48
あ、バイナリエディタって書いてましたねごめんなさい
>>113 ひとつ確認
if(a && b)
if(a & b)
副作用が無くてこれらの意味が同じになる場合についてのみ話してるんだよね?
148 :
デフォルトの名無しさん :2009/06/11(木) 23:58:43
>>146 例えばこれを読み込んでデータを二次元配列に展開して、FFを00に、00をFFに変えたのち出力すれば白と黒が反転したbmpファイルができるってことですよね?
画像をいじるプログラムを作れるようになるという、最初の一歩が踏み出せた気がします
画像処理をするには2つの道がある。 1、画像フォーマットを勉強して、1からエンコーダ・デコーダを書く。 2、ありもののライブラリの使い方を調べる。 初心者を脱したくらいのレベルだと1のほうに魅力を感じるかもしれない。 それは悪いことではないが、しばらくプログラマをやっていくと、2の方が重要なことに気づく。 30年かけて蓄積されたライブラリを最初から作ったら、作りたいものができるまでそれ以上の時間がかかるわけだし。 外部ライブラリを使うというのは独特、これはこれで高度な技術。 C言語の外部ライブラリを使いこなせるようになるには、C言語の知識だけじゃダメだったりする。 ライブラリとは何か、ってとこからOSや処理系の知識まで複数の分野をカバーする必要がある。 文法や標準ライブラリの勉強というのはいわば箱庭の中で遊んでいるようなもの。 その温室から外に出るには、自力で調べ自力で試行錯誤する力を身につけなければならない。 っつっても、いまやグーグル先生がいるから茨の道手ほどでもないんだけどけどね。
FFと00ならそれでもいいけど エンディアnゲフンゲフン
>>148 全部反転したらだめだよ。
RGB値のとこだけ。
それがどこなのかはファイルフォーマットを調べてね。
一歩踏み出せてよかった
考えてみればグーグル先生のいない時代に先輩達はどうやって勉強してきたんだろうな 参考書や規格書を毎回手でめくって調べてたんだろうか 想像も付かない
>>149 違う?
意味が変わる場合は設計も変えろって事?
>>154 a == 2
b == 1
であるとき
( a && b ) == 1
( a & b ) == 0
!!a == 1
!!b == 1
( !!a & !!b ) == 1
>>153 でもある程度の時代からパソ通のフォーラムがこのスレのような専門的な質問とかも
できるようになってたので金持ってるやつはそういうところで情報交換してたみたい。
C言語覚えるのに、LSI-C試食版のマニュアルにお世話になった。 プレーンテキストファイルだったけど、コンパクトにまとまってて重宝した。 アセンブラもついてたしな。
副作用が発生しないこと前提で、短絡評価をさせないことによって コンパイラが最適化しうる余地を作ったってことになるのかなぁ?
>>155 バイブルには載ってないけどDLLのstrings見るとそれっぽい関数があるんだけど!
という時代?
短絡評価自体が無駄な評価をしないという最適化の一種じゃないの
>>158 あのマニュアルは良かった
Windows95 で使ってたから
DOSモードで直接RGBプレーンに書き込んで画面表示なんかも出来たな
A000:0000 〜 だっけか
>>153 今でも参考書や規格書は買うが。
昔はネットニュースでFAQをはじめとするドキュメントを入手してたな。
あとはフリーソフトウエアのソース参考にしたりとか。
DLLなんて無い時代
>>162 それはテキストVRAMの位置じゃね?
というかDOS/VとPC98系ではその辺の仕様が違うはず
>>161 if (複雑な条件 && i != 0)
と書かれていた場合に、 i != 0を先に評価することで処理が速くなることはあると思うよ
副作用がないことを明示すれば最適化してくれるようなオプションとか属性とかないのかな
&を使わせることで
・両辺の評価を行うことが強制されるのかどうか
・評価順を最適化することが許されているのかどうか
これがわからん
>>113 はそうであるかのごとく書いているけれど
>>168 両辺の評価は強制
最適化は実際やってるコンパイラがあるのかわからん
>>168 &は+とかと同じだから
両辺とも評価されるし、評価順は不定(コンパイラが好きにしていい)
>>74 ncursesライブラリでコンソール上に色付きで表示できるよ
画像データはBMPが単純だからBMPのフォーマットを調べてバイナリデータを解析すればいいよ
>>74 SetConsoleTextAttribute
SetConsoleCursorPosition
そうなの? 右辺なり左辺なりが0であることがわかれば、もう一辺の値がどうであれ0になることはわかるのにね ああでも最適化できるかというと難しい気がしてきたわ。。
>>173 副作用がなければそういう最適化もできるよ。
そもそも今時のコンパイラなら、短絡評価の違いが現れる場合以外、
&でも&&でも同じように最適化したコードを吐いても不思議ではないと思う。
可読性と効率は相反する要求 平均実行速度の最適化なら見た目の記述云々より 必要な処理を最低限のリソースで実現するプログラムがいい コンパイラの最適化なんかよりアセンブリか機械語レベルで人間が直した方がいい
じゃあ最初からそっちで書けば?
>>174 なるほど。。コンパイラさまさまだね
>>175 すごいですねー
実際どういうときに速くなりますか?
>>113 >AND(A,B) (!!(A) & !!(B))
VC++2008だと最適化有り無し共に&&より遅かった
>>66 NULLはCでは
#define NULL (void *)0
とかで定義されてる
C++では単純な0かもしれないし、何かのオブジェクトかもしれない
32ビット環境では、intといったら32ビットで、メモリアドレスも32ビットだが
64ビット環境では、intといったら32ビットで、メモリアドレスが64ビットになるかもしれない
アドレスと整数を暗黙のキャストで都合よく変換できてることに依存すると後々困ったことになる
型が異なる演算や代入なんかでNULLを使いたいならキャストすべし
>>178 やっぱり遅そうだもんな。
どう考えても処理が増えてる。
普通にメモリアクセス増えるし、真面目にbitandとるから、そりゃ遅いよ。
最適化スレに行けって話になっているけれど、更にダメ出し。
!!A はコンパイラにとってはA ? 1 : 0 と同じこと。
つまり、条件分岐を行なうか条件セットを行なうコードになる。
従って、処理速度的にメリットはない。
尤も、マクロではAND(i >= 1, j >= 0)としているので
省略はされて、(i >= 1) & (j >= 0) と評価されるから関係ないといえば関係ない。
で、このコードは条件分岐を二回経てから&を行なうので、
単純に i >= 1 && j >= 0と書くより早くなる筈がない。
>>113 結論、せめて得意のCPU向けのアセンブリ出力くらい眺めてから書こう。
>>181 メモリアクセスは「全く」増えないと思うよ。
恐らくは最適化で全てレジスタに配置されている筈だから。
183 :
デフォルトの名無しさん :2009/06/12(金) 14:17:27
POSIXの標準関数で ファイルがあるかないか調べる関数 ってなんだっけ? 関数名が思い出せない
184 :
183 :2009/06/12(金) 14:23:24
自己解決しました
for(i=0;i<10;i++){ } と for(i=0;i<10;++i)
187 :
186 :2009/06/12(金) 16:01:05
ごめんなさい途中送信しました for(i=0;i<10;i++){ } と for(i=0;i<10;++i){ } ってどう違うのでしょうか?
>>187 原則同じ。C++流に慣れた人がしばしば後者を使いたがる。
# 私もだけど。
C++なのに++Cにする不思議
便乗質問。 C++だとどう違うの? 「コンパイラによる最適化は無効な条件下において」 C言語でもC++でも、 for(i=0;i<10;i++){ } は後置増分演算子だからテンポラリオブジェクトを作る分だけ for(i=0;i<10;++i){ } の前置増分演算子版よりか遅くなりそうなイメージなのだが。
C++だとiがイテレータの場合があって、 実体がクラスだと無駄なコピーコンストラクタ呼ばれたりするので大差が付くことがある
Cでは++iもi++も値のコピーだけど、C++では++iは有効な左辺値を返す。 つまり、インクリメントされたiの参照が返る。 ++iはコピーしない文、コストが安い…だったと思った。^^ イテレータの話が出たのでついでに。 STL愛用者は(そうできるケースでは) for( i = 0 ; i != 10; ++i) { } のように書いたりする。なぜなら、 != をサポートするイテレータの方が < をサポートするイテレータよりも種類が多いから。
194 :
191 :2009/06/12(金) 18:13:26
>>192-193 ありがとう。
イテレータじゃなくて生のポインタだったとしても、
「コンパイラによる最適化は無効な条件下において」
は遅くんだよね?
実測は不可能な程度だとしても、理論値的な意味で。
>>191 組込型なら違いはない。
その例では式の結果が使われていないから前置インクリメントと同じコードを吐けばいいし、
例えそうでなかったとしても、インクリメントする命令を後回しにすればいいだけ。
よほど複雑な式ならともかく、最適化なんて意識しなくても自然とそういうコードになると思う。
色付文字ってエスケープシーケンスの8色だけなんでしょうか?
197 :
194 :2009/06/12(金) 19:47:09
>>196 Linuxとかだと、最近は256色端末も使えると思う。
どれくらい広まっているのか知らないけど。
>>194 なまぽで for 文の条件式ならほぼ確実にコンパイラが最適化しちゃうけど
最適化がないなら、理論的にはPOD型でも遅くなる。
この件に関しては名著 C++ Coding Standardsでも
「時期尚早に最不適化してしまわない」や
「インクリメント演算子とデクリメント演算子の標準形式を使おう」
といった項で説明している。小さな習慣ですむなら守るべきだろう。
200 :
194 :2009/06/13(土) 08:30:22
>>199 やっぱりそうだよね。
俺は元々++i派だから大丈夫だ。
ありがとうございます。
環境依存だから確認した方がいいよ x86 + gcc の場合だけど、前置式も後置式もステップ数は変わらなかった
メモリ上のデータは全部リトルエンディアンでいいんでしょうか?
そんなこたない。
でも、統一しておかないとシフト演算とかで困るような気がするんですけど
シフト演算はレジスターで行われるからエンディアン関係なし。
//構造体 typedef struct { int NO; char NAME[10]; } STD_t; STD_t sample[2]; sample[0].NAME="長谷川"; こんな感じで構造体char型のNAMEに文字列を入れたら 「'const char [5]' から 'char [10]' に変換できません。」というエラーになりました。 constについて調べましたが、定数宣言?は行ってませんし、なぜこういうことになったのでしょうか?
>>208 char nane[10];
name = "長谷川";
ができないのと同じ。
>>208 char NAME[10];
を
char *NAME;
にするか、
sample[0].NAME="長谷川";
をstrcpyなんかを使って書き直せ
なぜに長谷川さんw
212 :
201 :2009/06/13(土) 17:19:53
>>202 最適化しない場合で。
"i++"より"++i"が優れてるのは、演算結果を一時的に
覚えておく必要が無い点だけど、レジスタがたくさんある普通の
CPUで単純な演算なら、その辺の差は必ずしも出ない
宗教家が出てきたw Effective C++の第二版にも書いてあった気がする。 Google Coding Standardsにも確か書いてあったと思う。 いるんだよ、こういう人がw
>>212 PowerPCターゲットにしたコンパイラで、最適化しても前置インクリメントの方が
速くて、そっち使ってたことがあったな。
少なくとも後置きが前置きより早くなることは普通はありえないよな やってることが少ないんだから 前置きを習慣づけて損することはないならそっちの方がいいと思う
コンソールの文字表示ってすごい時間かかるみたいなんですけど これを高速化するにはハードを変えるしかないんでしょうか?
そうです。もしくはバッファにためにためまくって、 もうこれ以上無理っていうところで初めて実際に出力するようにすれば だいぶ早くなります。
構造体の隙間埋めの仕方は環境依存ですか? ファイルI/Oで構造体を丸ごとバイナリread/writeするのは危険ってことでしょうか
>>218 読み込みと書き込みを行うのが同じエンディアンでCPUのビット数が同じなら問題ないはず
>>218 やるのなら、コンパイラに対してパディングするなっていう指示をした上でやるべき。
>>218 同一OS環境で、コンパチCPUで 、同一アプリケーションで読み書きかなら問題ない。
ひとつでも違えば危険、
↑アプリケーションのレビジョンも同一を追加してくれ
構造体まるごとread/writeしてるコードって、なぜかその構造体を コード全体で使いまわしてる例が多いな。 それをやられると、すごいコードに柔軟性がなくなる。
Cなら構造体のパディングを前提にしたプログラミングは当たり前だけどね というか、データ構造の仕様が先にあって それに合わせて構造体を定義するものだろう
構造体丸ごとリードライトしたのちバイナリファイルを見ると変なパディングがあったり エンディアンの問題があったりすると思いますが、 完全に安全なプログラム(パディングなし、他の環境でコンパイルした プログラムでも全く同じファイルを書き出す・読み出せる) にするためにはどうするのが望ましいでしょうか。 (あるていど速度も犠牲にするということで)
>>227 charで読み出して合成するしかないね
でも浮動小数点は・・・・
構造体のメンバをぜんぶunsigned charにする。
>>227 writeWord(FILE* fp, WORD w)
{
fputc(w & 0xff, fp);
fputc((w
>>8 ) & 0xff, fp);
}
writeDWord(FILE* fp, DWORD w) ・・・
みたいな関数を作っておいて、項目ごとに書き出せばいいよ。
一番安全なのは構造体を丸ごとリ−ドライトしないこと。 汎用的なデータ形式にエンコード/デコードするのが正攻法。
エンディアンはビッグエンディアンにする事が多い
スピードが問題じゃなかったら、テキストにするってのもあるな。 ファイルのヘッダは、構造体まるごとリードライトのバイナリなのに、 本体はテキストになってるって変態フォーマットも見たことある。
今はPC性能も高いからXMLやjsonなんかでデータ保存や通信するのも十分ありだと思う。 むしろその方が他のアプリと連携しやすい。
>>227 パディングがあっても無くても、環境ごとに構造体を
正しく定義すればOK
汎用性を求めるなら229の言うように全部
unsigned charにするのが確実
>>231 ,234が神。「達人プログラマー」にもそう書いてある。
バイナリが将来にわたる保守性を破滅的状況に導く極端なケースについても紹介。
か、かみ
Boost.Serializationを使えば話が早いのでは? ・・・っとここはC言語スレだったか。
#pragma once があるのに #ifndef HOGE #define HOGE #endif を使うのはどうして?
>>240 pragma はコンパイラによって様々
once が使えないことがあるから
#pragma once は VC++ 専用?
>>242 そう。
だけどあまりに人気があるpragmaだから、他のコンパイラも採用していることがある。
#pragma onceでは、実質同じファイルをインクルードしてしまうことがあるし、 コンパイル時間も多くかかるようになる(場合が多かったと記憶している)
ファイルからchar[4]に読み込んでからuint32_tに変換するコードなんですが、これで正しいでしょうか? #include <stdio.h> #include <stdint.h> enum Endian { LITTLE_ENDIAN, BIG_ENDIAN }; uint32_t read_uint32(const char* data, Endian e) { uint32_t ret = 0; unsigned char* p = (unsigned char*)data; int i; switch(e) { case LITTLE_ENDIAN: for(i = 0; i < 4; ++i) ret += p[i] << i * 8; break; case BIG_ENDIAN: for(i = 0; i < 4; ++i) ret += p[3 - i] << i * 8; break; } return ret; } int main(void) { char little[] = {0xDD, 0xCC, 0xBB, 0xAA}; // リトルエンディアンで保存された0xAABBCCDD char big[] = {0xAA, 0xBB, 0xCC, 0xDD}; // ビッグエンディアンで保存された0xAABBCCDD printf("%0X %0X\n", read_uint32(little, LITTLE_ENDIAN), read_uint32(big, BIG_ENDIAN)); // => 0xAABBCCDD 0xAABBCCDD }
>>245 正しい
けど実行環境のバイトオーダーが分かってるなら、
普通に4バイト読んで、必要に応じてhtonl()等を呼べばいい
>>245 関係ないがLITTLE_ENDIANとBIG_ENDIANは記号定数としてstdio.hで定義されてる可能性がある
その書き方で変換できてるが、こういう場面では += を使わずに |= を使うべき
あるいは
uint8_t *p = (uint8_t*)&ret;
for(i=0; i<4; ++i, ++p) *p = data[i];
のようにも書ける
ありがとうございます もうすこし改良することにしました
当方プログラミング経験がほとんどないのですが、仕事でC言語を使うことになってしまいましたorz Cを演習しながら覚えられる良書はありませんか?
>>249 書籍スレも見つけられないような盆暗には、どんな良書も焚き付け程度にも役に立たないと思いますが。
それなりに経験あるプログラマが必死になって仕事探してもなかなかありつけないのに、
なんで
>>249 みたいなところに仕事が行くんだろう?
経営者が無能、または、
>>249 を辞めさせるために
>>251 >253か、或いは外注に出せる予算がなくなって内製せざるを得なくなったとか。
まぁ、ろくなもんじゃないよ。
就活しにそうです
外注しようとしたら高いな! まあいっか。プログラマが世の中にたくさんいるってことは簡単にできんじゃね? ちょっくらおぼえて作ってよ。C言語っての有名らしいしさ。 という発想なんじゃないのかなー
どう考えても、パワハラ(漢字で書くと羽輪原)です。 プログラミング言語のない人が書いたCのプログラムなんて やさしさの半分はメモリリークでできているでしょう。
mallocの使い方がわからず、リークさせるものがない
259 :
デフォルトの名無しさん :2009/06/15(月) 21:46:23
sinをx-x^3/3!+x^5/5!...で計算すると.-1.#IND00って 出るんですけどなぜ?
>>259 x^n/n! が無限大というか double で扱える範囲外とか
コンソール上にbitmap画像を表示したいのですが、 どうすればいいでしょうか? 一応エスケープシーケンスを使って8色の画像なら表示できました。 できれば256色表示したいのですが・・・
タッチタイピングくらい出来ないとプログラマにはなれませんか?
いいえなれます
うん
自称タッチタイプできるってやつの大半は我流だしな。 あと、テレビとかで、外人のジャーナリストとか学者がタイプするところを みてると、けっこう一本指打法だったりする。
タッチタイプできたところで、 ほとんどのプルグルマは思考速度の方がはるかに遅い^^ 考えてる時間1000に対して打ち込む時間1。 他人のコードを読んでいる時間が1000000、 課長が俺好みの女で業務中にわざと足を広げて 俺にパイパンのあそこをちらちらと見せ付けてくるのが気になってる時間が1000000000000くらい。
>>266 時間比率から考えると
女課長は脳内に1万人以上24時間待機してるな
とうとう壊れたPGがでてきたか・・・ タイピング速度をもろ要求されるのはパンチャーくらいだろ とにかく打つのが仕事なんだし
>>261 256色表示可能な端末エミュレータの準備はできてる?
私が壊れても大丈夫、控えとバックアップ含め30人いるから…
タイピングが速いと客先とかでインパクトを与えることができるよ。 なるべく静かで、なるべく速い方がかっこいい。速いけどうるさいのははた迷惑
タイプ速度と同じくらいスラスラコード考える脳があればさぞや楽しいだろうなぁ
>>272 会社組織でやってるとバンバン仕事回ってきて死ぬよ
バグ鳥は他人がやってくれるならいいけど
コードを量産するのが無能な働き者だったらいないほうがマシだな
頭の中でコードが出来上がってる時は、めんどくせーと思いながら ひたすらコーディングするだけ。
タイピング速度を上げると、万能プログラミングマシーンになれるのですね。理解できません。
タイプに思考速度が追いつかないって、思考速度が遅すぎなんじゃね? 頭の中にコードができてるのに、タイプが追いつかないであせることがしばしばある。
ああ読み間違えていた。 脳が追いつかないのかよ。ご愁傷様
エディタ、IDEをうまく活用できてるかどうかも重要じゃね
ちょっと前にどっかのスレで、一日にかける行数どのくらいって話になったときにも、 「パンチャーじゃねえし」とか言って、暴れてるやついたな。 コンプ強すぎ。
ある程度書くと減り始めるから 行数カウントは難しいかも トータルではあまり行数は増えないけど 書く量はそこそこ
最終形がある程度見えてもりもり書ける人はいいなあと思う。 いつも書いてる途中でリファクタリングしまくってる
int main(void) { int i,sum=0; int num[3] = {10,20,30}; for(i=0; i<(sizeof(num)/sizeof(num[0])); i++) sum += num[i]; printf("%d\n", sum); // @1 hoge(num); return 0; } void hoge(int *num) { int i,sum=0; for(i=0; i<(sizeof(num)/sizeof(num[0])); i++) sum += num[i]; printf("test : %d\n", sum); // @2 } hoge関数でsizeofを読んでしまうとポインタサイズの取得になってしまい困っていますs。 @1と@2の結果を同じにしたいのですが、何か良い方法がないでしょうか?
Cでは無理 素直にmain()で求めたsizeof(num) / sizeof(num[0])を関数の パラメータに持たせなせえ
hoge(num); ↓ hoge(num,(sizeof(num)/sizeof(num[0]))); void hoge(int *num) ↓ void hoge(int *num,int size) for(i=0; i<(sizeof(num)/sizeof(num[0])); i++) ↓ for(i=0; i<size; i++)
これはhoge関数の中のね for(i=0; i<(sizeof(num)/sizeof(num[0])); i++) ↓ for(i=0; i<size; i++)
main 文の中の num は配列型(より詳しく言うなら int[3] 型)、 関数 hogeの中の num はポインタ型( int* 型)。 型が違うのだから、当然利用するメモリサイズも違う。 配列型は全体のサイズを1要素のサイズで割るとその要素数がわかるというだけの話で ポインタ型にはそのような特性はない。 したがって、hoge を void hoge( int (*num)[3] ) { int i,sum=0; for(i=0; i < sizeof *num / sizeof (*num)[0]; i++) sum += (*num)[i]; printf("test : %d\n", sum); // @2 } のように記述し、呼び出しでは hoge( &num ); とすれば、意図したとおりの動作となる。
>>288 このときのhogeの引数の型って何になるの?
>>289 int(*)[3] (int3つの配列へのポインタ)
292 :
デフォルトの名無しさん :2009/06/16(火) 13:08:09
配列について聞きたいんですけど 配列の要素数って最初に宣言しないといけないんですか? たとえば int a[]; って宣言しといて、aにどんどん要素を入れていってあとで要素数を決めるってことはできないんでしょうか
>>292 途中で追加することはできません。頑張ってmalloc()/realloc()/free()の使い方を勉強してください。
realloc()使え
>>293 realloc()だけあれば他は要らないけどね。
# 初心者は使い分けた方が判り易いか……
malloc(size) = realloc(NULL, size) も free(ptr) = realloc(ptr, 0) も保証されてるの?
後者はどうなんだろうねえ。 realloc(ptr,0)の戻り値はNULLもしくはfreeに渡すことができるポインタらしいんだけど。
ほい。 -- realloc() は、ポインタ ptr が示すメモリブロックのサイズを変更して size バイトにする。 新旧のサイズのうち、小さいほうのブロックに含まれる内容は変更されない。 新しく割り当てられたメモリの内容は初期化されない。 size がどの値であっても、 ptr が NULL の場合には malloc(size) と等価である。 size が 0 で ptr が NULL でない場合には、 free(ptr) と等価である。 ptr が NULL 以外の場合、 ptr は以前に呼び出された malloc(), calloc(), realloc() のいずれかが返した値でなければならない。 ptr が指す領域が移動されていた場合は free(ptr) が実行される。 -- 4行目と5行目に注目。
あらほんと。man見てたのにそこ読めてないとか俺バカス
俺はmallocの代わりに使うことはあってもfreeの代わりには使わないな
何をしようとしているのかを明示するためにも 使い分けた方がいいんじゃなかろか。
上級者はその辺も意識して使い分けるって事か。 malloc free と等価であることが明らかな環境であれば、reallocで済ませると。 すごーい
素直にfree使えば混乱が無くていいと思うアマグラマでした
プロなら #define FREE(p) realloc(p,0)
308 :
デフォルトの名無しさん :2009/06/16(火) 23:36:45
realloc(ptr, 0)で得られたポインタって、もう一回reallocしても大丈夫なのかな? そうであれば、二重freeの危険性があるfree使うより、reallocで解放した方が安全だったりする?
例え出来てもfreeと等価になるかどうかは知らん。
>>308 それなら
#define FREE(p) (free(p),(p)=NULL)
とか
SAFEDELETEとか作ってたことを思い出す
>>311 DirectX のサンプルには必ずあった気がする
realloc(0, 0) って未定義?
realloc(0,n)はmalloc(n)のように振る舞うと決められている malloc(0)の挙動は処理系定義で、NULLを返すか、 1以上の何らかのサイズでmallocしたかのように振る舞うか(ただしその領域にアクセスしたらダメ) どちらかを選ぶことになっている
315 :
284 :2009/06/17(水) 00:58:55
>285 了解です。 C++ならいい方法があるのでしょうか? >288 ひとつの解決方法として参考にさせていただきます。
C++ならvector辺り使うとか?
またマネージドからCに来た人が沸いてるのか?
C言語の入門者が、Cではそれできないよ、といわれて、C++ならできるの?という疑問を持つのはよくあること
>>315 C++なら参照渡しだろ?
と元の話を読まずに書いてみるテスト
配列が固定サイズならCでもなんとかなる
異なるスレッドやDLLではある関数内のローカルstatic変数は共有されないんでしょうか?
>>321 共有されるのでマルチスレッドでは問題になる
あれ?共有されないのはグローバル変数でしたっけ? スレッドやDLLの安全性がよくまとまってるサイトとかありますか?
325 :
デフォルトの名無しさん :2009/06/17(水) 23:27:45
for文のカウンタ変数はintって、どこに書いてあるの
だれがそんなこといったん?総力あげて戦うつもりもないけど。
intじゃなくてもいいからどこにも書いてないよ
そもそもfor文は、カウンタを使わなくても良いし...
329 :
デフォルトの名無しさん :2009/06/18(木) 05:03:14
doubleでも動作保証されてる、int以外の例どこにあるの
>>329 頭固すぎだろ
doubleをカウントアップ用変数に使った場合、==で判定するケースは足しこむ数字と==で比較する数字に
注意しないとだめかもな
double == doubleて使いものになるの? 小数点数を駆使したコード書いた事無いからよくわからんけど
ならないよ
>>331 足しこむ数字にもよるし単なるカウントアップ/ダウンなら安全にするために
左側をカウンタ、右側を判定に使う数字とした場合
>= とか <= を考えた方がいいかもね
無限ループ #include <stdio.h> int main(void) { double i; for (i = 0.0; i != 1.0; i += 0.1) { printf("%f\n", i); } return 0; }
これはOK for (i = 0.0; i != 1.0; i += 0.125) { printf("%f\n", i); }
for (i = 0.0; i != 1.0; i += 0.1) ↓ for (i = 0.0; i <= 1.0; i += 0.1)
337 :
デフォルトの名無しさん :2009/06/18(木) 07:28:54
doubleやfloatは使わないほうがいいことになってる。 使うときは条件判断で「<」か「>」を使い、値の範囲に注意する。 ループの判定で、「==」や「!=」がちゃんと動くか保証がない以外にも、 すごく大きな数だと、+1しても値が変わらないことがある。
再帰関数が必要になるケースってどういう場合なんでしょうか? 簡単なケースだとfor文でもいけそうですし、多くなるとスタックの問題もありそうですし
339 :
デフォルトの名無しさん :2009/06/18(木) 09:22:09
一番出番が多いのは、ツリー型のデータ構造を扱うとき。
A(B){A(Bx(B));}な場合 ループで処理するとA(B)の停止条件が既知でないとBx(B)を遡れない
341 :
デフォルトの名無しさん :2009/06/18(木) 11:49:24
昔の人が書いたソースコードを見ていたら main(argc,argv) int argc; char**argv; { hogehoge; } っていうように書いてる人がいました、 これって文法違反じゃないの? でも無事にコンパイルもできるし。 これってどういう意味ですか? グローバル変数?
343 :
デフォルトの名無しさん :2009/06/18(木) 11:52:05
>>341 main(int argc, char **argv)
{
hogehoge;
}
の昔の書き方。
昔のプロトタイプはパラメータの型チェックがなかったのさ。 っていうか、もしかしてCにオーバー道路がないのも、この古い遺産のせい?^^
>>342 , 343, 344
なるほど、ありがとうございます!
よくわかりました!
ちなみに、knuth先生がwc.wでこのように書いてました。
おかげで f(double a,double b){ } が f(a,b)double a,b;{} とかけてショートコーディングでたまに使う
K&Rの書き方って今のコンパイラでも通るんだ。 ANSI通さないコンパイラ使わないといけなくなって、K&R形式に書き直したことはあったけど。
unprotoize使うといいよ
1 #include<stdio.h> 2 #include<math.h> 3 4 // gcc ex3.c -lm 5 6 int main(){ 7 int i; 8 float x1 = 0.0; 9 double x2 = 0.0; 10 11 for(i=1; i<20000000; i+=1000000){ 12 x1 = 1.0/i; 13 printf("%20.18lf %20.18lf %20.18lf\n", x1, 14 ((float)sqrt(1+x1)) -1, x1 / (((float)sqrt(1+x1)) +1)); 15 } 16 17 printf("--------------------------------------------------------------\n"); 18 19 for(i=1; i<20000000; i+=1000000){ 20 x2 = 1.0/i; 21 printf("%20.18lf %20.18lf %20.18lf\n", x2, sqrt(1+x2) -1, x2 / (sqrt(1+x2) + 1)); 22 } 23 } このプログラムを実行すると x1 の方の ((float)sqrt(1+x1)) -1 の値が途中から0になるのはどうして?
>>349 (float)1.0000001192 == 1.0
だからじゃないか?
x1が0になっちゃうからじゃないか?
無限大はすぐそこにあるってことですね
353 :
デフォルトの名無しさん :2009/06/18(木) 19:43:11
再帰は漸化式が似合う。 n!=n*(n-1)! int fact(int n) { if(n==0) return 1; else return n*fact(n-1); }
354 :
デフォルトの名無しさん :2009/06/18(木) 19:49:56
<=が保証されんのなら、forは結局intだね。 float なんかの、良例あるかな
ループにループカウンタは必ずしも必須ではないし、カウンタがintである必要もないよと さんざん言われているのに、forは結局intだね(キリッ といわれても困る
>>354 ループ条件にポインタを使うことはあるね。
C++だと、イテレータとかも出てくる。
>>354 無限ループの為の空っぽ指定
while (1) や while (true) とかと違ってマジックナンバー使わないし
lint なんかで警告されないし
>>354 ・されるのなら
・されないのなら
どっち?
されないと思ったから結局intにつながるのか、
されると思ったからfloatの良例を求めているのか
>>359 まあね
非ゼロなら何でも良いけど代表で1が居るのが気持ち悪い ってのは教条主義すぎか…
for(;;) while(1) while(!0) while(0==0)
enum {forever = 1}; while(forever) { programing(); sleep(hour(3)); }
>>362 foreverの値を1にするのが気持ち悪いそうです
LOOP: programing(); sleep(hour(3)); goto LOOP;
>>338 すべてのアルゴリズムは、再帰がなくても書くことができる。
>>354 「<」を使えばいい。
for (double x = 0.0; x < 1.1; x += 0.1)
こういうふうに、値の範囲が分かった上で使うのはいいのだ。
入力された初期値や増分でやるのは、あまりよろしくない。
>>366 そのかわり余分な空間計算量が必要になりませんか。2分木を非再帰でかくのは結構パワーが必要ですよ。
まあ必要か必要じゃないかって話だから。 再帰のほうが分かりやすければ再帰を使えばいい。
再帰って何回くらい保障されてるの?
確かANSIで規定されてるのは13回くらいだったはず。 しかし実際には10000回くらいやってもぜんぜん平気。
スタックの空き/再帰関数で使う量
用語の質問です。 質問@「関数の引数に空の配列を入れて、関数の中でそこに値を代入すると、帰って来た配列も書き換えられている」 事をポインタと言うそうですが、単にポインタを使うと言うとアドレスの場所を指すポインタと勘違いされてしまいました。 実際「*」等も使用していませんし、この用語の使い方はあっているのでしょうか? 質問A#include<stdio.h>をヘッダファイルと言い、画像などのフォーマットもヘッダーファイルと言う名前が使われています。 これは同じ物を指しているのでしょうか。 両方とも名前が同じなので口頭で伝える際に上手く伝えられません。 まだ習ったばかりなので、細かい用語に勘違いがあったら申し訳ありません。 よければその勘違いも含めて答えて下さったら嬉しいです。よろしくお願い致します。
>>373 「配列を渡して書き換える」ことをポインタとは言わんよ。
>>373 両方とも間違ってるな。
修正は他の人だれかやってあげてくれ。
>>373 引数に空の配列を
func(char a[])
このことだと思うけど
func(char *a)
と同じだよ。
画像などのフォーマットにはヘッダー部が含まれているだけじゃないかな。
それを定義したヘッダーファイルを見たのかもしれないけど。
画像ファイルは、ファイルの先頭あたりに入ってる情報をヘッダーと言うことは あるだろうけど、ヘッダーファイルと言うことはなさそう。
>>373 質問2 ヘッダーという意味では先頭に付加されてますが「先頭に付加される物」という言葉が同じだけと思ったほうがいいでしょう。
C言語などでincludeするヘッダーはご存知のように構造体の定義などが別ファイルとして記述できたりします。
特定のファイルフォーマットで使われるヘッダーというのはファイルのサイズや構造を明記したエリアのことをいいます。
char *shirokoro shirokoro="horumon" とやるとどんな文字の長さでもshirokoroの中にはいるんですか? これは動的にちょうどいいメモリの量を確保してくれるんでしょうか?
>>379 文字列の先頭のアドレスが変数にはいるだけ。
文字列は最初から、どこかに確保されている。
381 :
デフォルトの名無しさん :2009/06/18(木) 22:31:20
>>373 ちゃんと授業聞いていたのかという疑問もあるなあ。
@Cでは関数の引数に配列を渡すと、実際にはポインタ(先頭アドレス)が渡される。
AC→「ヘッダファイル」と画像→「ファイルヘッダ」が混乱していると思われる。
「header」を英和辞典で引いて、その英単語の意味を理解せよ。
>>379 "horumon"は文字列リテラルの先頭アドレスを返している。
それをchar*型のshirokoroで受け取っているだけ。
"horumon"自体はコンパイル時に定まっているためプログラム起動時に勝手に確保される。
意味分かる?
@ 「引数として配列を渡す実際にはポインタ(先頭アドレス)が入る。」 こういう意味だったのですね。 A #include<stdio.h> はヘッダー「ファイル」である 画像などのヘッダー はヘッダー情報が格納された「エリア」である 前者はヘッダファイル、後者はファイルヘッダ なるほど、わかりました! レスありがとうございます。大変参考になりました! 本当は習ったというより独学で教科書を先読みしている段階です・・・ 矢張り自分の認識の甘さを痛感しました。もう少し勉強しようと思います。 ありがとうございました!
>>383 あたまいいな。
今後もがんばれ。応援してる
>>368 超亀レスだが、最近と言うか数時間前に2分木を非再帰で書いた。
3日くらい前から、紙とペンで唸りながらようやく形になった。
単純なことなら再帰の方が速くできるが、通りがけ順でfor()+イテレータ(構造体に一工夫したモノ)のように各節を扱うことはできない。
非再帰(非スタック利用)で書くことで、これができるようになった。
再帰はとても便利だとは思っている。
クイックソートにしろツリーにしろ同じ処理、同じ構造に適用するにはとても優れている考え方。
実際のプログラミングで再帰を使ったのは、ポップアップメニューを動的に作る関数だったな、ああ、なつかしい。
386 :
デフォルトの名無しさん :2009/06/19(金) 00:08:56
あのですねprintf関数とかscanf関数とかもC言語で作られた関数でそれを#include<stdio.h>で読み込んでるだけだと聞きましたが 例えばprintf関数がどういうコードかとか読むことってできるんでしょうか 特にsqrt関数とかどういうふうにやってんのか気になります
読めるよ
388 :
デフォルトの名無しさん :2009/06/19(金) 00:11:20
確かに質問の形態はイエスかノーかを聞いてるように思えるでしょうが実際はその方法を聞いているということをご理解いただきたい
>>386 gccのソースコードでも眺めるといいよ
>>388 読めるってわかったらとりあえず調べないか?
やり方を聞くまで動けない人間なんて要らないよ
sqrt関数はコールバックを使ってる
>>388 VC++も、ライブラリのソースがついてくるよ。
stdio.hに書いてあるのは、printfのプロトタイプ宣言だけ。 コードは、コンパイルして機械語になって、ライブラリに入ってる。 ランタイムライブラリのソースコードをインストールすれば読める。
vfprintf()ならマジうけると思ったら、マジだった ですよねぇ、普通そうですよねぇ
396 :
デフォルトの名無しさん :2009/06/19(金) 01:16:47
>>386 sqrtなんかは、FPUの平方根求める命令使って求めてることが多いんじゃない?
>>386 >#include<stdio.h>で読み込んでるだけだと聞きましたが
いいえ。stdio.h にあるのは宣言だけです。
コンパイルされた現物はライブラリにあり、そのソースは
あったりなかったりです。
FPU関係はアセンブラだろう
ふつうにニュートン法でかいてた
malloc とかは明らかにアセンブラですよね?って思ったら K&R第2版に、mallocの生の版が出てきてちょっと驚いた。 システムコールを使うからUNIX限定だけど 環境依存のコードをどうやって関数内に閉じ込めるかについて とても勉強になった。
>>malloc とかは明らかにアセンブラですよね? それは無い。明らかに無い
取りあえず猫は勉強したんだが、レベルアップするためには次何やればいい?
405 :
デフォルトの名無しさん :2009/06/19(金) 19:52:08
#include <stdio.h> #include <fcntl.h> #include <sys/stat.h> #define STDIN 0 #define STDOUT 1 #define STDERR 2 int main ( void ) { char prompt [64] = "-> "; char command [256]; int st; int out; /* 出力ファイル用ファイル記述子 */ fprintf(stderr, "%s", prompt); /* ファイルをオープン */ out = open ("outfile", O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR); /* リダイレクション処理 * 標準出力 -> ファイル */ dup2(out, STDOUT); while (gets(command) != NULL) { if (fork () == 0) { if (execl(command, command, (char *) 0) == (-1)) exit(1);} else { wait (&st); fprintf(stderr, "%s", prompt);}}} シェルを実現するプログラム。入力したコマンドの実行結果をoutfileに出力したいが、うまく行かない どこを訂正すればいいか教えて下さい。
406 :
デフォルトの名無しさん :2009/06/19(金) 21:38:40
関数f(x) = ((2*x*x*+25)/(1+x*x)の式のxに aとbを代入したf(a),f(b)をS = (f(a) +f(b))/2 っていう形にして Sを使いたいんですけど、どうしたらいいか教えてください。
日本語でおk
408 :
デフォルトの名無しさん :2009/06/19(金) 21:42:53
お願いします!!
409 :
デフォルトの名無しさん :2009/06/19(金) 21:46:18
関数 f(x)を作って、S = (f(a) +f(b))/2って書けば普通に動くぞ。 例えばこうだ。 int f( int x ){ return x; } int main() { int s = ( f( 10 ) + f( 6 ) ) / 2; } これで晴れて s は 8 だ。
410 :
デフォルトの名無しさん :2009/06/19(金) 22:11:07
わ〜お! 感動です!! 本当にありがとうございます。 最近Cをはじめたばかりなのでやりたいことはいっぱいあるんですけど、 今みたいに思ったことがなかなかできないんですよね(笑)
411 :
デフォルトの名無しさん :2009/06/19(金) 22:23:58
続けざまですいません・・・ ((2*x*x*+25)/(1+x*x)の部分はどこにいれればいいんですか?
413 :
デフォルトの名無しさん :2009/06/19(金) 23:52:19
int f(int x) { return (2 * x * x + 25) / (1 + x * x); }
double f(double x) { double x2 = x*x; return (2*x2 + 25)/(1 + x2); } f : R -> R, ∀x e R∃y e R[y = (2*x*x + 25)/(1 + x*x)]
415 :
デフォルトの名無しさん :2009/06/20(土) 00:28:32
405も頼む
416 :
デフォルトの名無しさん :2009/06/20(土) 05:05:34
ここに、役に立つ話は何も無い...侵入生の雑談だろ? お遊戯とか、お歌とか...しばらく遊んでろ。
>>415 どううまくいかないのか分からないが fflush
418 :
デフォルトの名無しさん :2009/06/20(土) 09:42:34
初歩的な質問でごめんなさい。ポインタの中身の数値同士を足した数が必要なときはどうすればよいですか? 例えば、 st1->a=12 ,st2->b=13のときその中身同士を足した数を変数に代入して関数の引数に使おうと思ったのですが・・・ 当たり前ですが int wa=st1->a+st2->bとしてもだめですし・・・誰か教えて下さい。
>>418 それがダメなら分からんね
ポインタの指してる先がおかしいんじゃね?
int wa = st1->a + st2->b でいいのでは
st1->a st2->b まず確認したいんだけどこの二つ型は?
>>418 > int wa=st1->a+st2->bとしてもだめ
どう「だめ」なのかちゃんと日本語で説明してくれないと教えようが無い。
型で警告でてるとかそんなんじゃないの?
*pってやるとpの指してるものの中身を得られるよ
>>418 それはポインタの中身じゃなくて構造体のメンバのようだけど
なんてハイレベルなんだ! エスパー的に
>>426 いやすでに上で型は何?ってでてる。
構造体もいわゆる型だ
質問 char str[80] = "これはファイルシステムのテストです\n"; FILE *fp; char *p; p = str; while (*p) { if (fputc(*p, fp) == EOF) { printf("ファイル書き込みエラー\n"); exit(1); } 本ではこうなってたんだけど、これってなんでpをインクリメントしなくてもいいの?
431 :
デフォルトの名無しさん :2009/06/20(土) 14:18:33
>>429 本に乗ってるソースコードが間違ってるのはよくあること。
>>428 それちゃんとソース全部書いてる?
}が一つ足らないだろ
次のページに ++p; } って書いてあったりして。
fpも初期化してないし、ファイルシステム関係ないし
435 :
デフォルトの名無しさん :2009/06/20(土) 14:46:07
436 :
デフォルトの名無しさん :2009/06/20(土) 14:46:36
>>422 segmentation faultになってしまいます。
>>436 だから型を教えてくれと
構造体なのか、単なるint型なのかchar型なのか
構造体ならその中が何かと・・・
構造体です。実際はipの構造体で、たしか unsigned int ip_len unsigned int ip_hdl と宣言されていてip_lenとip_hdlの差が必要なのでその差を計算したいのですが… セグメってしまいます。
>>438 ptr->a.ip_len
とかしないとできないよ
下記の表現の違いを述べよ. char aa[]=”abc”; …@ char bb[10]={‘a’,’b’,’c’,’\0’}; …A char *cc = aa; …B
441 :
デフォルトの名無しさん :2009/06/20(土) 15:11:28
@は4個のchar型の配列。Aは10個のchar型を持つ配列。Bはポインタ。
Cコンパイラにエラーを吐かれると、自分が間違ってるんじゃないかと 気が滅入るものだがCコンパイラははっきし言ってある種の馬鹿なので 気にしないほうがいいw C/C++は古参のプログラミング言語で、プログラミング言語理論の 発達の前に既にあったもの。その後の理論から見て修正したほうがいい 文法とか表現法とか多数あるんだが(どれとかいちいち指摘はしないが) 今更直せないというものが多い。 C/C++が絶対正しく自分が間違いなんだとは思い込まないことが肝要 質問する以前の問題としてこのことを踏まえるべき。 以上、適当に修正してテンプレに入れておくことを推奨
443 :
デフォルトの名無しさん :2009/06/20(土) 15:50:55
>>442 分かった。
以下の様に修正して入れようか?
Cコンパイラにエラーを吐かれても、自分が間違ってないと
思う輩ははっきし言ってある種の馬鹿なので気にしないほうがいいw
C/C++は古参のプログラミング言語で、仕様書にあるとおりに書けないヤツを
駆逐する能力がある。
C/C++の仕様書が正しく自分が間違いなんだと心にたたき込むべし。
「プログラムはあなたの思うようには動かないが あなたの書いたようには動く」
質問する以前の問題としてこのことを踏まえるべき。
445 :
デフォルトの名無しさん :2009/06/20(土) 16:00:59
ガタンッ
パチ パチ パチ 。
448 :
デフォルトの名無しさん :2009/06/20(土) 16:08:28
よって賛成多数と認め、次のスレで
>>444 を反映するものとする。
449 :
444 :2009/06/20(土) 16:10:35
単に冗談だったのだが 今更そんなこと言えない空気になってしまった。
適当に乗って遊んでるだけだからw
規格からはみ出してもなんとなく動くからやっかいなんだよな
>>451 なんとなく動いてるということが 後から判明した時には…
454 :
デフォルトの名無しさん :2009/06/20(土) 16:39:46
#include <stdio.h> #include <assert.h> struct ST { int a; int b; }; int main( void ) { struct ST st = { 12, 13 }; struct ST *st1 = &st; struct ST *st2 = &st; int wa = st1->a + st2->b; assert( st1->a == 12 ); assert( st1->b == 13 ); assert( wa = 12 + 13 ); } ちょー問題なく動く。
455 :
デフォルトの名無しさん :2009/06/20(土) 16:41:01
はっ。19行目にエラーが。w assert( wa == 12 + 13 );
457 :
デフォルトの名無しさん :2009/06/20(土) 16:43:51
何ゆえ?
ポインタの使い方もわからない人に余計なこと教えるなってことだろw
459 :
デフォルトの名無しさん :2009/06/20(土) 16:54:17
いえす
assertだよw 何がよくないか聞きだしたりして、ちゃんとわかる人を作らないと 社会に出てこられても大変なだけだw
462 :
456 :2009/06/20(土) 16:57:14
assertの何が悪いんだ
464 :
デフォルトの名無しさん :2009/06/20(土) 17:01:26
#include <stdio.h> struct ST { int a; int b; }; int main( void ) { struct ST st = { 12, 13 }; struct ST *st1 = &st; struct ST *st2 = &st; int wa = st1->a + st2->b; } assertなしのこれならOKってことね。
>>463 基礎がわかってないのに応用とかもっと後のこと教えてどうすると
467 :
デフォルトの名無しさん :2009/06/20(土) 17:04:05
>何がよくないか聞きだしたりして、ちゃんとわかる人を作らないと なるほど。これは自分には無理そうです。 ほかの人、がんばって答えてあげてください。
469 :
デフォルトの名無しさん :2009/06/20(土) 17:05:35
でも、assert以外でちゃんとプログラムが動いていることを 確認する有効な方法って何? もちろん、強力なIDEが値やアドレス監視機能を提供してくれるのがベストだけど。 まさか、printf で値を表示したりしないよね?
C言語でデザインパターン実装するにはどうすればいいの?
>>470 そうそう
で質問の仕方もわかってないし、ソースも断片しか貼ってない(片方は閉じてさえいない)
初心者もいいところじゃん
assertなんてまだ先の先
473 :
デフォルトの名無しさん :2009/06/20(土) 17:13:22
#inclede <stdio.h> main(){ int a; int b; int n; int i; for(i=0;i<n;i++) { if(a==i) { a=a+b; printf("%d\n",a); } else { a=a-b; for(j=0;j<n+j++) { a=f(a); } } }
474 :
デフォルトの名無しさん :2009/06/20(土) 17:24:43
475 :
デフォルトの名無しさん :2009/06/20(土) 17:33:56
476 :
デフォルトの名無しさん :2009/06/20(土) 17:45:37
質問の仕方が悪かったのでもう一度。 #include <stdio.h> #include <stdlib.h> #include <string.h> /* strcpy */ #include <netinet/in.h> /* ntoh hton */ #include <arpa/inet.h> /* sockaddr_in */ #include <net/ethernet.h> /* ether_header ETH_P_ALL */ #include <sys/socket.h> /* socket */ #include <netinet/ip.h> #include </usr/include/netinet/udp.h> #include </usr/include/netinet/tcp.h> #include </usr/include/netinet/if_ether.h> /** mac address "network to ascii" */ union { unsigned int x; unsigned char y[4]; } A;
477 :
デフォルトの名無しさん :2009/06/20(土) 17:46:20
続き1 struct st1{ unsigned char a; }; struct st2{ unsigned char a; unsigned char b; }; struct st4{ unsigned char a:1; unsigned char b:1; unsigned char c:1; unsigned char d:1; unsigned char e:1; unsigned char f:1; unsigned char g:1; unsigned char h:1; }; struct ipfrag{ unsigned char ip_fra1:1; unsigned char ip_fra2:1; unsigned char ip_fra3:1; unsigned int ip_off:13; };
>>476 最初の質問の番号を名前欄に書いたほうがいいなw
267 :('A`):2008/09/18(木) 21:51:43 0
部屋に湧いたゴキブリをガチャポンのカプセルに閉じ込めて
何匹も飼っている俺が断言する
ゴキブリが軟便を出すようになったら、死が近い証拠
268 :('A`):2008/09/18(木) 22:00:31 0
http://p.pic.to/zkvzp 現時点での長老
288 :286:2008/09/18(木) 23:05:57 0
ごめんコマンドーに釘付けだった
ちなみにゴキブリ共は走ってる所を
上からカプセルをかぶせるようにして捕まえた
http://c.pic.to/s8rjj 先代長老(故)
画質悪くてすまんね
376 :('A`):2008/09/24(水) 03:03:51 O
長老がなかなか死なん
なんかウンコ喰って生き延びてるぽい
414 :('A`):2008/09/27(土) 22:05:45 O
http://m.pic.to/xon6l 10匹目捕獲成功
480 :
418です :2009/06/20(土) 17:48:25
続き2 char *mac_ntoa(unsigned char *d){ static char str[18]; sprintf(str,"%2x:%2x:%2x:%2x:%2x:%2x",d[0],d[1],d[2],d[3],d[4],d[5]); return str; } void print_arp(struct ether_arp *arp){ printf("hardware address format %u\n",ntohs(arp->arp_hrd)); printf("protocol address format %u\n",ntohs(arp->arp_pro)); printf("hardware length %u\n",arp->arp_hln); printf("protocol length %u\n",arp->arp_pln); printf("operation %u\n",ntohs(arp->arp_op)); }
481 :
418です :2009/06/20(土) 17:49:27
続き3 int main(int argc, char *argv[]){ int rsock,rsin_size; struct sockaddr_in rsin; struct ether_header *eth; struct ip *ip; struct tcphdr *tcp; struct udphdr *udp; struct ether_arp *arp; char p0[1518], *p; unsigned int data_length=ip->ip_len-ip->ip_hl;
482 :
418です :2009/06/20(土) 17:50:27
続き4 if ((rsock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0 ){ perror("socket"); return(0); } rsin_size = sizeof(rsin); while(1){ if(recvfrom(rsock, &p0, sizeof(p0), 0, (struct sockaddr *)&rsin, &rsin_size) < 0 ) { perror("recvfrom"); } p = (char *)p0; eth = (struct ether_header *)p; print_ether(eth); if(ntohs(eth->ether_type) == ETHERTYPE_IP){ p=p0+sizeof(struct ether_header); //ehternetのヘッダが終わった先.同様にUDPのヘッダ分ずらす。 ip=(struct ip *)p; print_ip(ip); if (ip->ip_p==17){ p=p0+sizeof(struct ether_header)+sizeof(struct ip); udp=(struct udphdr *)p; print_udp(udp); p=p+sizeof(struct udphdr); print_data(p,15); }
483 :
418です :2009/06/20(土) 17:51:51
続き5 if(ip->ip_p==6){ p=p0+sizeof(struct ether_header)+sizeof(struct ip); tcp=(struct tcphdr *)p; print_tcp(tcp); } } else if(ntohs(eth->ether_type) ==ETHERTYPE_ARP){ arp=(struct ether_arp *)p; } } } これでdata_lengthがセグめっちゃいます。
484 :
418です :2009/06/20(土) 17:53:12
>>関数をいくつか省略しました。
>>483 そこまで大きいのはtxtにしてロダ経由の方が・・
487 :
デフォルトの名無しさん :2009/06/20(土) 17:58:16
なんでこのレベルのプログラム書いている人が 「ポインタの中身の数値同士を足した数」の得かたもわからないのん?^^ っていうか、肝心の struct ip がどんな構造体なのかどこにも書いてねーでやんの。 sturct ip *ip は初期化されてねーし。 わかるかボケ。w
struct ip *ip; このポインタは ipという構造体型のポインタ unsigned int data_length=ip->ip_len-ip->ip_hl; この行の前にipにstruct ipの実体を入れてない
プ板はボケツッコミの様式美を確立してないのが弱いところだと思うね
490 :
418です :2009/06/20(土) 18:04:41
>>488 ほんとだすみません。
struct ip{
unsigned int ip_hl:4;
unsigned int ip_v:4;
u_int8_t ip_tos;
u_short ip_len;
u_short ip_od;
u_short ip_off;
u_int8_t ip_ttl;
u_int8_t ip_p;
u_short ip_sum;
struct in_addr ip_src,ip_dst;
}
標準のライブラリってあらかじめインクルードガードされてるの?
>>490 それもないとわからないけど俺が言いたいのは
ip = malloc(sizeof(ip));
とかして実体を作る必要もあるし
長さを計算するってことはそもそも今回作ってるアプリで実態を用意しないで
どこかからもらってきた領域がその構造体ってことだよね。
その辺の関数は省略してるのかな?
まあ業務に関するとあれなんでかけない関数は名称を hoge(); とかしておけばいいよ struct ip *ip; ip = hoge(); //ipに入れるstruct ipサイズの領域のアドレスが渡される? で今回の計算でいいのかな?
>>491 Solaris だと、たぶん全部されてると思う。
>>487 コピペだけでやりくりしてる文型プログラマなんだろう
こういうやつが後の悪夢を生むんだなー
496 :
418です :2009/06/20(土) 18:14:10
実際はパケットをうけとるものなのでipは実行してほっとけば入ってきます。 それで問題の unsigned int data_length=ip->ip_len-ip->ip_hl; がなぜだめなのかがわかりません。
>>494 Solarisでは、ということは基本的に保障は無いわけですね。thx
>>495 まあここで散々言われてるがへこまずどう聞けば的確な答えがもらえるかとか
を学んで欲しいわ。
そうでないとこういうソースを後で見る側が死ぬww
unsigned int data_length=(unsigned int)ip->ip_len-ip->ip_hl;
>>491 C標準のライブラリなら何度includeしても問題は発生しないことになってる。
501 :
デフォルトの名無しさん :2009/06/20(土) 18:35:55
>>488 の指摘にあるように
struct ip *ip;
を宣言してから
unsigned int data_length=ip->ip_len-ip->ip_hl;
を計算するまでの間にipには何か入れる関数を呼んでるんだよね?
504 :
デフォルトの名無しさん :2009/06/20(土) 18:45:48
っていうか、もう答えでてるじゃん。 Segmentation Faultじゃろ?不正なメモリへのアクセス。 どう考えても ip の値がおかしい。 「ipは実行してほっとけば入ってきます」ってあるんだから そのほっといて入ってくる処理のほうがおかしくなってる。 ほっとくと入ってくる処理を書いたやつのケツに いますぐちんぽ突っ込んでデバッグしろって言って来い。
505 :
デフォルトの名無しさん :2009/06/20(土) 18:49:01
ちなみに、たいがいのプログラマはバグを指摘されると 「はぁ、ふざけんな。てめぇの方のバグだろ?」 と逆ギレするので(特に理系プログラマに多い)、 バグを指摘するときはなるべく強硬な姿勢で、 有無を言わせず、怒りをあらかじめあらわにした上で 上から目線で、力強く、がなりたてるようにいうことが肝要。 これ間違えると逆襲されるから注意ね。
506 :
デフォルトの名無しさん :2009/06/20(土) 18:50:26
>>503 いえ、このままです。実際に送られてくるパケットを解析するので。
>>438 で
unsigned int ip_len
unsigned int ip_hdl
となってるが
>>490 は片方がshortになってねーか?
実行マシンはx86じゃなければ境界踏んでねえかな?
ipに何か入れるとか言ってる関数ってすでにプリコンパイル済みで
ip構造体の中身が変わってるのにリコンパイルしてないとかそんなことやらかしてねえ?
それはプログラマではなくただのコーダ―
>>506 それじゃあ受け取ってないってw
int main(int argc, char *argv[])
これに渡されるのか?
510 :
デフォルトの名無しさん :2009/06/20(土) 18:54:51
>>508 愛のコーダ(大島渚)、怒りのプログラマ
とりあえず、ソースをアップロードしろ。 多くの人が指摘しているとおり、ipに有効な値が入っていない。 (C90までの)C言語では、宣言とコードを混ぜることができない。 struct ip *ip; unsigned int data_length = ip->ip_len - ip->ip_hl; までに、ipに値を代入することはできないのだよ。 わかるか、規格書を読んでから出直してきてください。ありがとうございました。
んー。 >(C90までの)C言語では、 原因はこれ、かな。w data_lengthをip=(struct ip *)p;のすぐ後ろあたりに書き込んだものの 中途宣言のエラーが出たから先頭に移動したら… っていうか、釣りだよね、これ?^^;;;
>>504 その事を意識して見直したら解決しました(´・ω・`)ほんとみなさんすいません。
>>511 自己レス
間違えました。
>(C90までの)C言語では、宣言とコードを混ぜることができない。
これは、正しかったが、
>ipに値を代入することはできないのだよ。
これは、間違っている。極めて特殊な方法で代入できる。混乱させてすみません。
>>507 の指摘したサイズの違いは大丈夫なのか?とどう解決したのか知りたいわww
一言で言えば、バグで上司にしかられてもちんこはびんびんなわけです。
data_length=ip->ip_len-ip->ip_hl*4; ?
static char str[18+1]; ?
519 :
デフォルトの名無しさん :2009/06/21(日) 01:40:54
バイナリファイルの取扱いで質問です バイナリファイルは基本的に16進数ですよね だから16進数のまま扱いたいのですがどうすればいいでしょうか どういうことかっていうと、たとえばバイナリファイルの「f」の部分のみを抽出して「0」に置き換えるとします そうするとC言語の普通の文法だと10進法で処理されるからうまくいきません たとえばa[10000]っていう配列に順番にバイナリファイルを読み込むと10進法で記録されちゃいますよね そうじゃなくて配列の1番目から順番に、0〜fの16進法の数値を入れたいんです どうすればいいでしょうか
まず、C言語は10進法では有りません、どちらかと言うと16進法 char a[10000]っていう配列に順番にバイナリファイルを読み込むと160進法 で記録されます
×160 ○16
charの配列に読み込むとして、 charが8ビットなら、1要素に十六進法で2桁分格納されるということに気付け。
523 :
デフォルトの名無しさん :2009/06/21(日) 01:53:12
>>520 たとえば
0123456789abcdef
というバイナリファイルがあるとします
これを読み込んで、char a[15]という配列に順番に最初から格納していくと
a[0]=0
a[1]=1
a[2]=2
・
・
・
a[10]=a
a[11]=b
という具合になるんでしょうか?
なるとしてですね、たとえばこの場合、fの部分のみを0に変えたいとします
しかし
if(a[n]==f) a[n]=0
とやっても変わらないですよね?
だって演算の時はfじゃなくて15になってるから(実際できませんでした)
入門編の質問はおもしろいなぁ。 16進数のfはC言語では0xfと書く。fとはかけない。
525 :
デフォルトの名無しさん :2009/06/21(日) 02:08:39
>>522 16進数は2進数で言うところの4ビットを1文字にまとめたもので、charは8ビットだから、charの配列には1要素あたり16進数が2つ入るという認識でいいでしょうか?
>>524 書くとしてどこに書けばいいんでしょうか
今いろいろやってみたんですが
424d4605・・・で始まるバイナリファイルをchar型のa[10000]という配列に読み込んでみたところ
a[0]を%xで表示すると42となりました
これは
>>522 さんの言うとおり、16進数の文字列が1要素あたり2文字入るということだと思うんですが
それでですね
a[60]の場合、バイナリエディタで見たところ、この位置には「ff」があるんですね
だからa[60]を%xで表示すると、上の理屈だとffにならないとおかしいと思うんですが、なぜか「ffffffff」と8つも入っています
char型の配列には1要素あたり16進数の数が2つしか入らないはずなのに、なんで8つも入ってるんでしょうか?
あとこれを%dで表示すると-1になってしまいます、訳がわかんないです
普通unsigned charの配列に入れるけどな。
424dでビットマップファイルを読もうとしてると分かってしまう俺様
528 :
デフォルトの名無しさん :2009/06/21(日) 02:12:05
>>526 おお、unsigned charにしてみたら、ちゃんとa[60]の要素がffになってくれました
しかしなんで charのままだとa[60]はffffffffになって、unsigned charだとffになってくれたんでしょうか・・・さっぱりわかりません
530 :
デフォルトの名無しさん :2009/06/21(日) 02:26:34
>>529 なるほど
charの場合は正負を表現する符号がついて、ffffffffのうち上位6つのfは負の数を表すもので、残りの2つのfがもともとのバイナリファイルにあったffってことですね
unsigned charは符号が付かないので最後の2つのffのみが残ると
ワロタ
do〜while文についての質問です。 判定部分でインクリメントやディクリメントしたほうが良い理由はなんでしょうか?
絶対にしたほうがいいということは無いです。場合によります
>>533 別にそんなことないよ?
誰が言ってた?
Cでプログラムつくったときに 何行くらいなら大規模っていう? 企業レベルで。
100万越えぐらいから
学生レベルでは?
1人なら、1000行じゃない?
1000なんてちょっと書けば余裕で超えると思うけど・・・
1000行で大規模って言わないだろ。 むしろ普通にライブラリを書いたりしてあっという間に数千行だよ?
学生で1000行書ければ上出来。
最近の学生はその程度なのか 優秀な学生はここにはいないのか
入門篇だしな、優秀な学生がいるわけない
200行で一苦労だぜorz
行数じゃない。密度だろ
初めて1000行超えた時の感動を忘れた俺が居る。 今は全然そう思わない。
俺も学生の頃1000行超えた時におお、と思ったなぁ。 あのころは行数が気になってちょくちょく見てたもんだ。
549 :
547 :2009/06/21(日) 14:00:33
>>548 だよね。
今はファイルを分割して記述してすら1ファイル1000行
行っちゃうこともあるから、もう全部合計しても鬱になるだけw
肝になる部分以外の記述だらけで疲れてくる
職業プログラマってひとつきに1万行くらいは書くものなのかな
コンピュータ内に16進数など存在しない。
何進数があると思って言っているんだ?
で、でんあつ・・・?
どうせ2進数なんだよとか言いたいんじゃない? これだから**はw
>>551 発注の場合、一ヶ月1000行ぐらいだと思うよ
テストとかドキュメントも含めて
え?たったの1000行/月でいいの?
デスマーチは嫌じゃ
行数がお金になる時代でもないですし。
>>557 機能次第じゃないの?
文字列操作とかやりだすとたいしたことしてないのにやたら行数食うけど
そういうのじゃなければ案外少ない行数であれこれできるしねえ
案外昔書いたやつコピペして、仕様書に合わせて改変してるんじゃないのけ?
562 :
デフォルトの名無しさん :2009/06/21(日) 22:14:05
>>533 continueしたときのカウンタの変更忘れを防ぐため。
プロセッサの中は情報エンタルピーが詰まっているだけで何進数でもない
エンタルピーと聞くとタルピーを思い出す
565 :
デフォルトの名無しさん :2009/06/22(月) 00:03:52
明解C言語入門を買ってきて最初のところにテキストエディタに 例文を打ち込んでプログラムを実行しろって書いてあったんだがどうやって実行するの? borland c++ compilerをダウンロードしてTerapadに打ち込んだんだがこのあとどうすればいいのかわからない。
ちょっと質問です。2分木のノード削除がうまくいかない(NULL をのぞいて鼻から悪魔状態)ですが、打つ手が尽きて、もうデバッガで調査するしかないのでしょうか。
>>566 ソースをプリンタに印刷してじっくりにらめっこした?
画面だけでは発見出来ないバグが印刷すると簡単に
発見できたりするよ
>566 デバッガで走らせてもいいし、怪しそうなところにデバッグ用の出力入れるのもよいかも。 自分では、論理ミスはしてないと思っていても、実はある条件分岐がうまくいってないことはよくある。 ソースをどこかに上げて意見を聞いても良いかもしれないよ。 その時は、どのように実装したかを説明するようにしよう。そうすると、意外にも間違っている箇所に気がつくことがあるから。
>>566 他から領域破壊されてるとかじゃない限り
二分木程度ならコード眺めてたら分かるんじゃない?
NOT素子はエンタルピーが可逆だから発熱しないんだってな。
そもそもデバッガ使ってないの? デバッガ使わずにどうやってバグ見つけるの?
printfデバッグ
俺もデバッガあんまり使わなくて、非効率的なことをやっているなあと言われ、自覚してる 日々勉強っすね
575 :
デフォルトの名無しさん :2009/06/22(月) 00:54:42
環境:cygwin ,コンパイラ:gcc hoge構造体へのポインタ変数hogeにmallocでリソースを割り付け、 使い終わった後に解放するというシンプルなプログラムです。 解放する際に、free関数の引数に構造体hogeの先頭のメンバ変数numを アドレスとして渡しています。 hogeそのものと&(hoge->num)が一致するので、 &(hoge->num)で渡しても 問題がないか検討してみました。結果、エラーは表示されませんでした。 解放する際は hogeの代わりに&(hoge->num)でも構わないでしょうか。 struct imp{ int num; char name[20]; }; void main(void){ struct imp *hoge; hoge = malloc(sizeof(struct imp)); … free(&(hoge->num)); }
ほとんどの場合うまくいくだろうが、俺はそうやらない。
577 :
デフォルトの名無しさん :2009/06/22(月) 00:57:43
構造体hogeじゃなくてimpでした。あと検討→検証
うまくいくんでないの? 俺もやらないけど。
>>575 そういうおかしな癖を付けるな
後から苦労するぞ
それも並大抵の苦労じゃない
大丈夫。すぐプロジェクトから抜ければ デバッグするのは俺じゃねぇ。
>>575 そのソースを人に見せたら馬鹿にされる。されない場合は無能のレッテルが
だな
>>575 そのソース持って上司に伺いを立てに行け
クビにならなきゃいいけどな
583 :
デフォルトの名無しさん :2009/06/22(月) 01:09:14
>>575 保証はされていないはず。
いずれにせよ、そんなことをしないといけないのは、コーディングが下手な可能性が高い。
>>575 は、何らかの特殊な事情があって &(hoge->num) と書きたい状況にあるのか
もしくは言語仕様やコンパイラの実装への関心からそういう質問が出てきたのか
そのどっちかだろうな。本人は何とも言ってないが
585 :
デフォルトの名無しさん :2009/06/22(月) 01:22:10
>>585 前者です。あるプロジェクトに対する品質検証で、
リソースリーク検出ツールを使ってソースを網羅的に検査します。
検査後、リソースリークの疑いのある指摘がリスト表示されます。
リストされた中には、ツールの誤指摘が含まれているので、
人手で精査して正常検出/誤検出か判断します。
その精査作業で
>>575 のようなケースにぶつかりました。
これがリークかそうでないのかで悩んでいたわけです。
ほれを書いた人物を検出すべし
えっと、既存のコードに free(&(hoge->num)); というのがあって、そこにリソースリーク検出ツールが反応したってことかな。 じゃあ、この「デバッグするのは俺じゃない」「馬鹿にされる」「クビにならなきゃいいけど」って さんざん言われてるコードの面倒みなきゃいけないほうの立場か。そりゃ大変だな。
>>575 そのコンパイラでは問題が無くても、別のコンパイラで
は問題になる可能性が高い。
構造体のアドレス値と先頭要素のアドレス値を一致させることを
コンパイラが守る義務は無いので、freeにmallocで得た
アドレス値以外を渡す可能性がある。そうなるとfree関数は
正常に動作しない。
>>583 保証されている。
ISO/IEC 9899:1999 (E) 6.7.2.1 Structure and union specifiers Semantics 6, 7, 13訳すの面倒だから自分で読んでおいて。
C++は、保証されてないと昔聞いたことがある。今度確認しておきます。
ANSI Cも今度確認しておきます。n1336も今度確認しておきます。
impの定義が変更されて、numの前にメンバが入るかもしれないわけで。 ソース修正に回す方がいいだろうね。
まあ仕様がどうあれそんな普通やらない事をするのは止めたほうが皆幸せになれると思う
保証されていたとしても、修正しておいた方がいいよ。 もちろん最新の注意を払って。
ええと、細心、ね。。一応orz
594 :
583 :2009/06/22(月) 01:49:01
>>589 あぁ、先頭にパディングは入らないって決められてるのか。失礼した。
>>592 いいかげんなことを言うな。
コードの著作権は会社なり団体にあり、それが固定された
コンパイラに解釈させて正しく動作する限り、
それが他のコンパイラに解釈させて異常動作することを
以て勝手に変更する行為は、会社に対する業務妨害罪に抵触する。
ある会社内部の業務約款が他の会社で通用しないという理由で
その会社の約款を修正することが認められるならば、社名の
変更だって可能になるだろう。
(以上縦読みプリズ)
>>589 コンパイラ作成者はISOの規格を遵守する義務は法的には
全くないことには注意。強制力の無い紳士協定みたいな
もので結ばれているに過ぎない。
た、たてよみできない。。。 だからこそ規格に準拠したコンパイルであることが明記されてたりするんですね
コンパイラ。。。だめだねよう
ねたらしぬ
ああ。。実はデスマってて。。バグ埋めないように気をつけるわ
>>596 そのCコードが、それを所有する会社なり団体の業務約款に
相当するものかどうかの判定は、日本語で書かれた会社登記
関係書類や近年の活動内容と照らし合わせた上で、最終的には
CPUアセンブリニモニックコードとCPU動作統計検査で
判定されることになるが、
こういうの訴訟にされてもまともに審議するヒマな裁判所
など無いから念のため。(訴訟自体認められないんで)
603 :
デフォルトの名無しさん :2009/06/22(月) 13:00:03
学校のLinuXだと int main(stdin) でよかったのに、家のCygwinだとエラーが出ます。 どういう問題があるんでしょうか?
>>603 そんな阿呆なコードの断片だけ引用しないで、きちんと全文貼り付けた上でエラーメッセージも貼りましょう。
>>603 俺のマシンに入ってるcygwinでは問題ない。
バージョンが違うのではないだろうか。
607 :
デフォルトの名無しさん :2009/06/22(月) 13:24:03
#include <stdio.h> typedef struct{ int number;//学生番号 char name[20];//名前 char password[8];//パスワード }student; int main(stdin) { student *person1, *person2; student class[2]; scanf("%d",&person1->number); scanf("%s",person1->name); scanf("%s",person1->password); printf("%d,%s,$s,%s,%d",person1->number,person1->name,person1->password); } つりとかじゃなくて普通に分からない。
どこで教わったか知らないが、main関数の書き方は int main() int main(int argc, char *argv[]) の2パターンだけ知っていればいい。
610 :
デフォルトの名無しさん :2009/06/22(月) 13:29:15
>>608 この場合上でいいのかな?
俺的にはscanfのたびにコマンドラインから入力するシステムにしたいんだが。
>>610 自分のアプリを起動するときにオプションとかを指定するタイプなら下
ただ単に起動してアプリ内で入力待ちをするのなら上でいい
>>610 コマンドラインからはコマンドを実行することができるだけ。インタラクティブな操作はできない。
613 :
デフォルトの名無しさん :2009/06/22(月) 13:32:39
Int main()にしたら行けた。 でも今度は一つScanfを入力したところで変なエラーが出た。 26454 [main] class 2432 _cygtls::handle_exceptions:Ellor while dumping state(probably corrupted stack) Segmentation faulst (core dumped)
>>613 person1に適切な値が代入されていないから。
615 :
デフォルトの名無しさん :2009/06/22(月) 13:35:43
でも、ちゃんと数字で入力したんだぜ?
「代入」と「入力」の言葉の違いに要注意。
ポインタを使うのはまだ早い
person1に何も代入されていないってことは、person1はどこを指していると思う?
619 :
デフォルトの名無しさん :2009/06/22(月) 13:39:19
>>618 つまり、Numberに何も代入されてない=アドレスが決まってないのに、&でアドレスを指定したのがいけないってこと?
>>619 student *person1, *person2;
これだと構造体をさすポインターだけしかない
person1 = (person1)malloc(sizeof(person1));
としないと実体ができない
621 :
デフォルトの名無しさん :2009/06/22(月) 13:44:45
>>620 な、なんだそりゃあ
そんなの学校で習ってないです。
学校ではそういうの無しに出来たと思うのですが…。
622 :
デフォルトの名無しさん :2009/06/22(月) 13:53:39
思ったんですけど、アドレスで指定するのが駄目なのなら int main() { student person1, person2; student class[2]; scanf("%d",&person1.number); scanf("%s",&person1.name); scanf("%s",&person1.password); printf("%d,%s,%s",person1->number,&person1->name,&person1->password); } では駄目なのでしょうか?
623 :
デフォルトの名無しさん :2009/06/22(月) 13:57:11
お、なんか上手くいったっぽいです。 しばらくこの方向でやってみます。 答えてくださった方ありがとうございました。
>>622 やりかたはそういう方向性でもいいんだけど何の学習をやるのかにもよるよ
あと、その書き方だとポインタじゃなく構造体に直接入れるので&つけてるとエラーになると思うよ
処で、そのclassという配列は一体何に使うの?
>>622 int main()
{
student person1, person2;
student class[2];
scanf("%d",&person1.number);
scanf("%s",&person1.name);
scanf("%s",&person1.password);
printf("%d,%s,%s",person1->number,person1->name,person1->password);
}
正しくはこうな
それからclass[2]が全く使われてないんだけどこれから使うのか?
627 :
デフォルトの名無しさん :2009/06/22(月) 14:28:29
マイクロソフトの有料の方(プロフェッショナル)じゃないと最適化できなくて困ってます CPU別に最適化できるフリーのコンパイラってありませんか?
>>626 最終の printf 部漏れてる漏れてる
直ってないなw どうでもいいが、8バイトのパスワードは8要素の配列には入らないと思うんだ。
printf("%d,%s,%s",person1.number,person1.name,person1.password); こうか失礼 汚れ仕事は(エラー発見)はコンパイラにさせる癖がついてしまってるんで
char *を渡すべきところにchar (*)[20]を渡してるけど大丈夫?と心配された(大丈夫なんだけど)
>>630 は汚れ仕事をコンパイラにさせた後でレスをすべきだと思う
s/間違え/間違い/g
s/い/ったこと/
s/char */パイパンまんこ/
* そのままだとちゃんと動かない気が
したけど気のせいだったとさ
C++ Coding Standardsには 「PODは、Cと移植性のあるレイアウトを持つ:メンバー変数は、宣言順に格納される」 とあるし、Effective C++ではCスタイルのstructはFORTRANなどにも渡せるとあるので structの最初のデータメンバがstructのアドレスと一致することがCで保証されているなら C++でも(それがPODである限り)保証されていると見ていいんじゃないかなーとか思った。 思っただけ。
アドレスが一致することが保障されてるとしても、そんなことをする意味があるのか
いや、後ろの空白が巻き込まれる。 意図してるのかどうかはしらないが
641 :
デフォルトの名無しさん :2009/06/22(月) 19:00:47
構造体の先頭メンバがポインタだったら・・? struct imp{ int *num; char name[20]; }; int main(void){ struct imp *hoge; hoge = malloc(sizeof(struct imp)); hoge->num = malloc(sizeof(int)); *(hoge->num) = 10; strcpy(hoge->name,"taro"); free(hoge->num); } 構造体の宣言によるけどこんな荒業が使える。
ちゃんとhoge開放しろよ
使えますん free(hoge) -> free(&(hoge->num)) -> free(&hoge->num) free(hoge->num) -/-> free(hoge)
>>641 どう荒技なのかよくわからんが、
free(hoge)とfree(&(hoge->num))が同じかどうかの話でしょ
645 :
デフォルトの名無しさん :2009/06/22(月) 19:22:45
>>644 荒業はいいすぎた。ところで
free(&(hoge->num))をやった後にfree(hoge)をやると2重フリーになるのでfreeを
呼ぶのは一回でいいのかな。
ごめん、
>>641 が何をいいたいのか分からん。どこさして技って言ってる?
>>645 試してみたら、二重開放になっていた。
よって、呼ぶのは1回でよい。
cc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-44)
CFLAG=-Wall -std=c89 -ansi -pedantic
規格通りということだな。
>>589 ANSI Cにも同じようなことが書いてあった。
n1336は、ISO/IEC 9899:1999 (E)と変わってない。ちなみに6, 7, 13ではなくて5, 13だった。
C++は、個人的に利用しないのでどうでもいい。
648 :
644 :2009/06/22(月) 19:36:01
>>645 free(hoge->num);をやった後に、
free(hoge);、もしくはfree(&hoge->num);をすればいいのでは?
>>647 何自信満々に確保した領域をほったらかしにしてんの
>>649 >>641 の場合、
free(&hoge->num)とfree(hoge)は等価だと何度いえばわかるんだ。
だから、
>>645 の言うとおり、>free(&(hoge->num))をやった後にfree(hoge)をやると2重フリーになる
のよ。
>>641 はfree(&(hoge->num))じゃなくてfree(hoge->num)なことに突っ込まれてんだよ
二回mallocしてるのに、一回しかfreeしてないのにはなんの違和感も覚えないのか?
荒技w なんか面白いこと思いついた気がしただけだろ そっとしといてやれ
>>652 そんなことは見ればわかるだろ。
ちなみに私のレスは、>642,643,647,650ね
何度も言っているが、
>>645 は、>free(&(hoge->num))をやった後にfree(hoge)をやると2重フリーになる
かと聞いているので、なると答えただけだよ。
まぁ、入門篇だからしかたないか。
>>650 そりゃ同じものを指してるんだから2重フリーになるよ。
> よって、呼ぶのは1回でよい。
でもこうはならないだろ?っていうのをみんな言ってんだけど
657 :
644 :2009/06/22(月) 20:04:10
>>655 2重フリーになるのかどうかを聞いてるのではなく、
1度のfreeで両方とも解放されるのかどうかを聞いてるように見えないか?
流れ的に。
641=645がアホで終了していいだろ
それは勘違いだな。
free(hoge->num)しているのは、
>>641 があったので前提としていた。
そのあとで、
>>645 >ところで
>free(&(hoge->num))をやった後にfree(hoge)をやると2重フリーになるのでfreeを
>呼ぶのは一回でいいのかな。
は、free(&(hoge->num)とfree(hoge)のいずれかを1回呼ぶと解釈された。
その後は、ぐだぐだになっていったということかな。
私が読み取り間違えていたの?
構造体ひとつ開放するだけなら「一回でいいのかな」なんてことはでてこない。
理解できた。確かに、そうとれる。
わかったことは、641,645が、free(hoge->num)とfree(&(hoge->num))を等価と考えていたので、
free(&(hoge->num))とfree(hoge)が等価だと最近聞いて、混乱したと。
その結果、2重フリーを気にしたが、示したコード片は、まさに2重フリーをするコードであったので、
>>647 (私だが)が641,645の知りたいこととは違ったことをいい始めたと。
>>641 どう荒技なのかよくわからんが、
(話していた内容は)
free(hoge)とfree(&(hoge->num))が同じかどうかの話でしょ
(free(hoge->num)は話題に出ているもののどちらでもない、関係ないものだよ)
(なのでhoge自体が解放されてないよね)
で、やっぱり荒技の意味は相変わらずわからないが、
>>648 に続く。
>>641 の
> 構造体の先頭メンバがポインタだったら・・?
と、荒技、ということを考えると
free(hoge->num)と記述することで、hoge->numの先が解放され、さらにhogeとhoge->numが
同じものを指している(もちろんダウト)から、hoge自体も解放される
ということを言いたかったのではないかなあと、今なら思える。
663 :
デフォルトの名無しさん :2009/06/22(月) 20:25:51
641だが hoge->numとhogeを%pで表示させると同じ値だったから一度のfreeで解放 させられないかと思ったんだ。でも駄目みたいですね。 あと645の&〜は記入ミスです。
>>663 そんなばかな。
とりあえず、コンパイラとそのバージョン、実行環境を教えてくれ。
665 :
デフォルトの名無しさん :2009/06/22(月) 20:39:23
>>645 コンパイラ:gcc version 3.4.4
実行環境:cygwin
666 :
デフォルトの名無しさん :2009/06/22(月) 20:40:30
struct imp{ int *num; char name[20]; }; int main(void){ struct imp *hoge; hoge = malloc(sizeof(struct imp)); if(hoge == NULL){return 1;} hoge->num = malloc(sizeof(int)); *(hoge->num) = 10; strcpy(hoge->name,"taro"); printf("No :%d\n",*(hoge->num)); printf("Name :%s\n",hoge->name); printf("hoge->num = %p\n",hoge->num); printf("hoge = %p\n",hoge); free(hoge->num); free(hoge); printf("%p\n",hoge->num); printf("%p\n",hoge); return 0; }
667 :
デフォルトの名無しさん :2009/06/22(月) 20:42:39
実行結果 -------------- hoge->num = 0x6b0188 hoge = 0x6b0168 -------------- ごめんなさい 6と8をごっちゃにしてました。 どうみても同じじゃないです。お騒がせしました
かわいいやつめ
∧___∧
/ - - \
| ▼ |
/| =(_人_)= |
>>668 / ((ヽ、__ ゚し-J゚__ノ)) もしゃ
| _____ ノ もしゃ
∪⌒∪ ∪
ひっ
671 :
デフォルトの名無しさん :2009/06/23(火) 03:08:00
荒技というならfreeせずにプログラム終了して、 メモリ解放はOSのプロセス管理に任せるくらいのことはしないと。
それ別に荒いとは思わんけどね。 よきに計らってくれるんだから任せた方がスムーズに決まってる。 他言語でガベージコレクタを手動でせっせと起動するかっていうと、たいていの場合は任せるっしょ。
>>672 > 他言語でガベージコレクタを手動でせっせと起動するかっていうと、たいていの場合は任せるっしょ。
確かに「他言語で」GCが言語仕様上規定されているならそうするだろうが
GC機能がないC/C++では、それは全く当てはまらないと思うが。
>メモリ解放はOSのプロセス管理に任せる
これは単にうまく動いてくれちゃっているだけで
言語仕様上はメモリーリークするコードになっているわけじゃないか。
いや、言語仕様上、正常終了したときはmallocで割り当てたメモリは解放されるよ。 今更free論争なんて蒸し返したくないんで、あんまり突っ込まないで欲しいけど。
それ仕様のどこに書かれてる?
言語仕様じゃなくてOSの仕様だろ
さぁ盛り上がってまいりました
free(&hoge[0])
ホント規格厨は手に負えんな
>>680 環境によるんじゃない?
開放してくれるのもあればしないのもあるだろうし
組み込みレベルになるとしないのもあるんじゃないかな?
限定はよくない。
「今更free論争なんて蒸し返したくない」のと 「あんまり突っ込まないで欲しい」のは本当らしい。
まあ古くからある言語だからなあ。
scanfでchar(文字でなく値)の読み取りをしたいんだけど 調べたら%hhdっぽいような事は書かれてたんだけどmsdnで調べても無くて VCで実際にやってみても%dと指定したのと同じになってるんだけど もしかして出来ないの? ちなみにshort型は%hdで行けました
"%hhd"はC99以降です。
あ…ありのまま 今 起こった事を話すぜ! 「2chのプログラム板を眺めていたと思ったら いつのまにか古のネットニュースになっていた」 な… 何を言ってるのか わからねーと思うが(ry
板更新しろ
691 :
デフォルトの名無しさん :2009/06/23(火) 20:30:16
2重freeに引っかからないように自作してみた。これは有効ですか? void vfree(void **p); int main(void) { char *str; str = (char*)malloc(10); printf("str = %p\n",str); vfree(((void**)&str)); printf("str = %p\n",str); vfree(((void**)&str)); printf("str = %p\n",str); return 0; } void vfree(void **p) { free(*p); *p = NULL; }
692 :
デフォルトの名無しさん :2009/06/23(火) 20:38:31
#define vfree(p) {free(p);p=NULL;} でいいんじゃない?
そうね!
>>688 熟語の意味を辞書で引いて揚げ足取るやつとか居ないから違うと思われ
695 :
デフォルトの名無しさん :2009/06/23(火) 22:01:54
C言語で、別のソースファイルに書いたラベルにgotoするにはどうしたらいいですか?
696 :
デフォルトの名無しさん :2009/06/23(火) 22:03:08
#include が使えるかもしれない。
>>695 むり。
関数の外にはgotoできない。
>>695 どうしてもしたい場合は setjmp/longjmp
SEH
>>686 調べが足りませんでした
>>687 氏の方法で実装してみようと思います。
ありがとうございました
>>695 すんげークソ設計な予感がするけど
大丈夫か??
703 :
デフォルトの名無しさん :2009/06/23(火) 23:59:55
>>606 >>607 >>608 ありがとうございます。goto無しでやるように書き換えようと思います。
>>701 ミニゲームのゲームオーバー画面からタイトル画面に飛ばせたらと思って…
後、例えばとある関数があって、その関数は引数によって微妙に処理を変えたいのですがどうすればよろしいでしょうか?
例えるならCASLUの命令のように。
LD GR1,GR2 //これだったらGR2の中身をGR1にコピー
LD GR1,X //これだったらX番地の内容をGR1にコピー
LD GR1,X,=2 //これだったらX番地+2番地の内容をGR1にコピー
といったような感じに、引数によって内容をが微妙に異なるようなことは出来るのでしょうか?
704 :
デフォルトの名無しさん :2009/06/24(水) 00:08:40
>>703 > 引数によって内容をが微妙に異なるようなことは出来るのでしょうか?
できる。
705 :
デフォルトの名無しさん :2009/06/24(水) 02:21:49
関数に複数の値を渡したいのですが、その数値の数を流動的に決めることはできないのでしょうか たとえば複数の数を渡して、その中から一番大きい数を返すina maxという関数を作るとして このint maxに渡す数が1と2の2つだけだったり、10と20と30と40と50の5つだったり、そういう複数のパターンに対応させるようにしたいのです
...をつかう
707 :
デフォルトの名無しさん :2009/06/24(水) 02:25:14
ごめんなさい、もうちょっと詳しくお願いします
va_listをつかう
>>703 引数によってというのがわからん
引数が10以下なら〜20以下なら〜とかなら普通にできるがそういう意味じゃないよな
>>703 そういうのはジャンプしないほうが
状態の遷移を考えて・・・
絶望的に設計が下手糞だな・・・
>>713 経験だからねえ
スクリプトがメインの時代だとこういうジャンプを考えるのはありえなくないんだわww
その昔N88BASICくらいしか学生が手に出来なかった時代は余裕でやらかしてたからww
715 :
デフォルトの名無しさん :2009/06/24(水) 12:11:18
上のを見て思ったんですけど void func(int *p,int num); void func(int *p,int *p2); void func(int *p,int *p2,int *p3); みたいな3つの関数って宣言出来るんですか?
その辺はC9xによって違うとかC/C++で違うとかあるような。 ここで規格を語ってる方ひとこと↓
>>715 そういう機能はオーバーロードと呼ばれていて、Cではできません
C/C++で書いてgcc/g++でコンパイルして実行するという前提で、 ある問題(例えば100万以下の素数を生成する)をコーディングしたとして、 そこで書いたアルゴリズム(プログラム)の実行時間を知りたい場合、 どのような方法で知るのが一般的なのでしょうか? コマンドラインからコンパイルor実行時に何かコマンドを繋げる、 プログラム中に time.h sys/* などをインクルードしてプログラム実行開始からの時間を取得して計算する、 などが考えられるのですが、具体的にどのようなコードを追加したりするのか教えていただけると助かります。
timeコマンド使えばいいんじゃね?
C99のtgmath.hが引数の型によって呼び出す関数を振り分ける 特殊なマクロを提供しているのは知っていたので 早速、「tgmath.h 実装」でぐぐってみたら、gcc は独自拡張で実装してたり、 あるサイトでは厳密なCコードでは実装できないと書かれていたり、 どうなってんのって感じ。^^; Sun Studio 12 がC99完全合致らしいので それのヘッダを見れば秘密がわかるのか?
721 :
デフォルトの名無しさん :2009/06/24(水) 13:16:03
Crypt関数について質問です。 printf("%s\n", crypt("hogehoge","ab")); 例えばこの出力を100万回ループさせると 十数秒かかるのですが、Perlで同じことをすると1秒程度で処理を終えます。 調べたところPerlのCrypt関数は、CのCrypt関数を使っているそうなんですが CとPerlではなぜ処理速度がこんなに変わるのでしょうか?
perlでは画面出力してないとかいうオチじゃないだろうな
723 :
721 :2009/06/24(水) 13:34:07
>>722 Perlでは下のprint文を同じく100万回ループさせています。
print crypt("hogehuga","ab") . "\n";
C言語の方を puts(crypt("hogehoge", "ab")); に変えてみろ
>>721 >CのCrypt関数を使っているそうなんですが
C“には”「Crypt」なる関数は用意されていません。
>CとPerlではなぜ処理速度がこんなに変わるのでしょうか?
最軽量コンパイラとインタプリタの比較ですか?
本当にそれが crypt 関数によるところであるかどうかは ベースとなる処理速度の違いを差し引く必要があるので crypt関数を取り除いて(pirnt文だけで)空回ししてみるとわかるかも。 (デバッグモードのcではprintfが異様に遅いとか…)
727 :
721 :2009/06/24(水) 13:49:24
>>724 putsで試してみたのですがprintfと変わりませんでした。
ちなみにcryptを使わずにprintfだけにすると速いです。
>>725 たまたまCとPerlの両方でプログラムを書いたら実行速度があまりに違ったので
その原因を知りたくなりました。
>>726 printfだけだと速いですがcryptが入ると遅くなりました。
となるとやはり、Cの方のcrypt関数がヘボいアルゴリズム使ってるのかもね。 もう少しちゃんと動くライブラリを探すと良いかも。
>>721 10万回ループで26秒かかった(cygwin)
2ちゃんのトリップ検索はアセンブラだったような
Bitslice DESアルゴリズムとかいうのを使ってるらしい
>>730 perlって、そういう最適化がきくのかね。
Cryptが同じ引数なら、同じ結果になるって知っていれば、
最適化できるけど。
100万行表示で1秒?
そのPerlがたまたま前回の結果をキャッシュしていて 全く同じ引数が与えられたら計算せずに前の値を返して いるだけなんじゃねーの? いくらなんでも速度が違いすぎるぞ
定義域より外の値を引数に入れたら ・中で定義域に収まるように(端点などに)修正する ・エラーを返す どっちがいいかな。好みの問題?
>>734 エラーを返す
だな。
呼び出してる側が本来は修正をしないといけないのに勝手にエラーに
ならないようにされると後々困ることになる。
バグ取りにならない
>>734 両方とも妥当な場合がある、結果仕様による
じゃあ定義域に修正する関数を別に用意してそれを通して引数に渡す、とだったらどっち? いちおうゲームに使う予定なんで、できるだけエラーでストップして欲しくないから修正を使いたいんだけど あんまり嫌われるようだったら考え直したい
だから仕様による、その場合強固なシステムがいい場合も有る
>>738 それでいいかもな。
修正する関数は、デバッグモードのときにはエラーで止まるようにして
リリースのときには修正するようにするとか。
>>740 あ、それいいですね。いただきます
ほかの方もあざっしたぁー
>>740 それは無い
同名のものは、出来る限り同じ機能であるべきだ
>>738 命名規則を決めておいて自動修正有り無しの両方つくるとか
流れをぶった切って質問。 math.hみたいな感じの統計版ってある? 大げさなものじゃなくて、中央値とか分散とか程度でいいんだけど・・・
744 :
721 :2009/06/24(水) 18:41:38
>>728 CとPerlでは同じライブラリを使ってるという情報がありました。
他のライブラリでも試してみたほうが良さそうですね。
>>729 トリップ検索で有名なフリーソフトはたくさんありますが
だいたい1秒間に〜100万トリップ程度は検索しているようです。
ということは100万回Cryptしているのだと思うのですが
ソースが手に入らないのでどういったプログラムを書かれているのかわからないです。
>>732 画面の描画ではなくてプログラムの実行が1秒で終わるということでした。
>>730 >>733 乱数を生成してループの度に結果を変えましたが
特にキャッシュしているわけではなさそうです。
・ループ部分も含めてソースを示そう ・出力はどうしてんの?100万行をttyに垂れ流し? ・もし/dev/nullとかに捨ててるなら、 ちゃんと動いてるか確認しよう
a.hがb.hをインクルードしていて、 b.hもa.hをインクルードしている場合 何が起こりますか?
includeできる回数には上限があるのでそこで止まります。
インクルードが深くなりすぎてコンパイルがとまります
C++に対抗してプリプロセッサメタプログラミングとかできないの?
ずっとやってきてるじゃないか。
つーかC++使ってCソース書けばいいだけだろ?
754 :
デフォルトの名無しさん :2009/06/24(水) 22:41:25
#include <math.h> #include <stdio.h> #define n 10 int kaijou( int x ),m; double SIN=0,angle=1; main(void) { printf("角度を入力"); scanf("%lf",&angle); angle=atan(1)*4/180.0*angle; printf("%frad",angle); for(m=0;m<=n;m++) { SIN=SIN+(double)pow(-1,m)*(double)pow(angle,2*m+1)/kaijou(2*m+1); } printf("サインの値は%f",SIN); } int kaijou(int x) { int y=1,count; for(count=1;count<=x;count++) { y=y*count; } return y; } テイラー展開を使ってsinを求めるんですけど角度が大きくなると 値がおかしくなります 項数を増やすと-1.#indo00って出ます なぜ?
>>754 ソースはほとんど読んでないけどレスしてみる。
オーバーフローしてない?
コンパイラができません bcc32は内部コマンドまたは外部コマンド 操作可能なプログラムまたはバッチファイルとして認識していません。ってでます ↑環境変数の設定やbcc32.cfgとlink.cfgファイル作ってもできません
pathを通しましょう
どうやって通すのですか?
set PATH=通したいパス;%PATH%
760 :
デフォルトの名無しさん :2009/06/24(水) 22:56:11
>>756 bccじゃなくて、VisualStudioを使った方がいいよ。
761 :
デフォルトの名無しさん :2009/06/24(水) 22:56:24
C言語でプログラミングを書くときに ------------------------- 前処理(変数初期化) 本体 (異常があったときに ラベルに飛ぶ) return(OK) :ラベル 例外処理 ------------------------- というようなスタイルで書いているのですが、 こういう構造が古いと書いてあったウエブがあったのですが、 どこが古いのかわかりますか? そのウェブサイトを思い出せれば、いいのですが、 再度検索してもヒットしないので もしウェブサイトにこころあたりがあれば 教えてください。
>>761 >どこが古いのかわかりますか?
goto使ってるとこじゃない?
チラシの裏で。 bccも悪くないよ。 「初心者のうちは。」
>>761 linusの最近のコードでもそういう書き方してるし、いいんじゃないの?
テイラー展開するとなんかの近似値を求められるってことは 思い出せた なんだっけ?
VC++を使っているのですが、sinやcos等の三角関数の計算を行っている ソースファイルはどこにあるのでしょうか? また、ネットを漁っていて気になる発言があったのですが、 CPU(もしくはOS)に、三角関数の計算アルゴリズムが実装されているのでしょうか? 以上、よろしくお願い致します。
>>766 なにかってのは元の数式の近似値だよね?
重い計算をしなくてもテイラー展開しておけば簡単な計算式でできると。
math.h
>>765 > テイラー展開って面白そうだね。
> sin cosを大量に使うゲームには有効そう
標準ライブラリのdouble sin(double x)やdouble cos(double x)の実装がどうなっているかは
しらないが、近似値を求めると言うことはテイラー展開(正確にはテイラーの定理)を使っている可能性はある。
>>766 いろいろ近似値を求められるよ。
πとかeとか。
数学オタクの俺が言うんだから間違いない。
ちなみにテイラー展開とテイラーの定理をごっちゃにしているやつが
多すぎるのでそういう輩の説明は信用しないように。
>>765 テイラー展開は元々平均値の定理から導かれた物だ
微分を知っていれば事足りる
テイラー展開つかうと 標準関数ライブラリのsinやcosよりどれぐらい高速なんですか?
>>772 math系のソースの中身が見えない場合は実測してみなとなんとも
最近は環境によってはハードウェアレベルでsin計算しちゃうのもあるのでテイラー展開するまででないとかある
遅 い で す あくまでも勉強用と考えましょう ライブラリは様々なテクニックを使って例えば0やπ/2に近い時は 最適化されていたりするので もしくは数値演算コプロセッサを使う事を前提としていたりするので
>>759 コンパイルできました
ありがとうございました
>>772 三角関数の値なんてfpuの一命令で求められる時代なんだから、標準ライブラリより速くなることはない。
777 :
770 :2009/06/24(水) 23:23:00
ふーん、そうなのか。 やっぱ数学オタクの俺のいうプログラミングの話は信用しない方が良いかもね。
>>776 漏れが愛用しているZ80にもそんな機能があるのだろうか。
でもゲームによってはatan2とか必要になるだろうしさすがにatan系までハードウェアで計算はしないからいるんじゃない?>テイラー展開
テイラー展開は普通は大学1年で覚えるよ
>>781 面白そうと言った者です。
高卒です、すみません
D3DXライブラリ使えば 三角関数使わないっすよね?
その代わりクォータニオン(四元数)を理解しないといけない 元々ジンバルロックというガウス座標特有の現象を避ける為に 考え出されたもので宇宙ステーションのアーム操作にも応用されている
>>786 ゲームによってはいると思うよ。
モデルとモデルのアングル求めたりアングルからベクトルに直したりと・・・
ごめん ×ガウス座標 ○オイラー座標 物理と混同していた
790 :
デフォルトの名無しさん :2009/06/25(木) 00:06:44
>>763 初心者だからこそ、余計なところでつまずく環境はお勧めできないと思うんだ。
792 :
721 :2009/06/25(木) 03:06:14
>>745 出力は/dev/nullですが、プログラムは実際には動いています。
以下プログラムのコピペです。
for (i = 0; i < 10; i++) {
for(j = 0; j < 8; j++){
str[j] = rand() % 8 + 1;
}
printf("%s\n", crypt(str,"ab"));
}
何が分からんのか分からん。 cryptの実装の違いだろ。
794 :
721 :2009/06/25(木) 03:29:18
色々調べたのですが、やはりcryptは遅いそうなので 他のライブラリを試してみることにします。 レスを下さった方ありがとうございました。
はぁ?
今更だけど……、 自分の必要なだけの精度しか求めないようにするとか、 入力に何らかの仮定ができて、もっと簡単な近似式を使えるとか、 大量のデータの計算でSIMD命令を活用するなど、 どうしてもという理由があって特定の目的に絞れば、汎用品である標準ライブラリよりは速くできるかもしれない。
>>742 デバッグとリリースモードで動作の違うのは普通にあるよ。
そりゃあ違うのは実在するが
>>740 みたいにそんな気軽にやるもんじゃないだろw
assert()とか普通に使ってる。
デバッグモードとリリースモードで動作が同じなのが原則で 異なるのは例外とすべき
デバッグのときにエラーチェックして止まるってのは、まあ、普通に行われてることですね。 達人プログラマー(うろ覚え)で、リリースビルドでもassertは無効にするなって書かれてたり して、スキル高い人でも、そうじゃないって意見はあるけど、一般的にはassert()とか assert()的な動作のコードはよく使われています。
>>792 バカか。動作のおかしいperlの方出せよ
#!/usr/bin/perl
for($i=0; $i<10000; $i++)
{
for($j=0; $j<8; $j++){ $str .= int(rand(8)) + 1; }
print crypt($str, "ab"),"\n";
}
time ./cryptest.pl > /dev/null
real 0m3.636s
user 0m3.600s
sys 0m0.010s
main()
{
int i,j;
char str[10]={0};
for(i=0; i<10000; i++) {
for(j=0;j<8;j++) str[j]=rand() % 8 + 1;
printf("%s\n", crypt(str, "ab"));
}
}
time ./cryptest > /dev/null
real 0m3.431s
user 0m3.400s
sys 0m0.000s
#include <stdio.h> main() { int i,j=0,sum=0; while(j<=0){ printf("aは? ");scanf("%d",&j); } sum=0; for(i=0;i<=j;i++){ sum=sum+i; } printf("1から3までの和は %d\n",sum); }
804 :
k :2009/06/25(木) 12:02:21
#include<stdio.h> float fmin(float,float); float main(void) { float a,b,min; printf("aの値は?\n"); scanf("%f",&a); printf("bの値は?\n"); scanf("%f",&b); min=fmin(a,b); printf("%fの方が小さい\n",min); return 0; } float fmin(float x,float y) { float z; if(x<y) z=x; else z=y; return z; }
ある設定NOが1-99まであって、そのNOに応じて EEPROMから設定内容を読みだすのですが、 設定内容の読み出し関数が設定NOの数だけあり、戻り値がunsigned longだったり charだったりばらばらです。 ifやswitch文で99も分岐させるのは嫌なのですが、関数ポインタに しても型が違うのでうまくいきません。どういうやり方がすっきり作れる でしょうか?
switch
>>805 読み出し関数が設定NOの数だけあり・・・
それならswitchでいいだろ
戻り値は違うけど関数の引数は同じ?
引数はvoidで共通です。
typedef unsigned long (*proc)(void); static const struct { proc func; int ret_type; } proc_table[] = { {(proc)func_1, 1}, /* char */ {(proc)func_2, 1}, /* char */ {(proc)func_3, 4}, /* int */ {(proc)func_4, 2}, /* short */ : とかやっといて、 unsigned long ret = proc_table[code].func(); してから proc_table[code].ret_type で switch 分岐、キャスト。
× [code] ○ [設定No]
swicth 並べるなりしたほうが速いとは思うけど…
>>810 の亜種
共通の戻りの型を一まとめにテーブル化 要素に設定No をおいて
渡された設定No をキーに for でなめてく
typedef long (*l_proc)(void);
typedef char (*c_proc)(void);
static const struct { l_proc func, int NO } l_proc_table[] = {
{ func1, 0 },
:
};
static const struct { c_proc func, int NO } c_proc_table[] = {
{ funcA, 10 },
:
};
for (i=0;i<sizeof(l_proc_table)/sizeof(l_proc_table[0]); i++) {
if (l_proc_table[i] == <渡された 設定No>) {
l_proc_table[i].func(); /* 呼び出し: 被代入変数は ptr で受ける? */
return;
}
}
for (i=0;i<sizeof(c_proc_table)/sizeof(c_proc_table[0]); i++) {
if (c_proc_table[i] == <渡された 設定No>) {
c_proc_table[i].func(); /* 呼び出し: 被代入変数は ptr で受ける? */
return;
}
}
何々? Cで仮想関数モドキをやろうとしてるの?
下の関数のコール元で「cTest」の値を取得するには、どうすればよいでしょう? void addCopy(char *pData) { char cTest = 10; pData = &cTest; }
関数を変えていいなら char addCopy(char *pData) { char cTest = 10; pData = &cTest; return cTest; }
>>815 そのコードでは無理
void addCopy(char *pData)
{
char cTest = 10;
*pData = cTest;
}
ならば可。
呼び出し元は受け用の実体変数を用意して
char c;
addCopy(&c);
と呼び出せば良い
>>813 戻り値の型の数だけテーブル化はいいですね。
どうも1つのテーブルにこだわりすぎて思いつかなかったです。
設定NOは2つのテーブルで同じものは絶対ないので、
おかしなことにもならないですし。
>>817 やはりこれでは無理ですか。
ありがとうございました。
>>818 1つのテーブルだと テーブルのindex == 設定NO とすることができるので
呼び出しにかかる時間コストはゴミという利点はあるけどね。
for でなめて引っ掛ける という性質上
時間コストは1つのテーブルの時より悪くなるのは仕方ないな
複数テーブルでも、呼び出されないはずのエントリにダミーの関数登録しておくとかで O(1)にできそうだけどね。
で、結局テーブルの実体の記述はその数だけ並べなきゃいけないから switch でも良いじゃん とループ マクロである程度の簡略化はできるだろうけど、エントリの数だけ並ぶのは同じだし #define IMP(no, func) case no: result = func (); break; unsigned long result; /* 最も大きいサイズの型で受ける予定で */ switch (NO) { IMP(1, funcA) IMP(2, funcB) : } #undef IMP
呼び出し側で場合分けすれば
ランダム関数を用いたCPUとのじゃんけんを作ろうとしたけど、うまく作るのって難しいのね。 単純そうだが、上手なアルゴリズムは難しいな。
昔、雑誌に相手の癖をみてジャンケンするコードが載ってたんで、 対戦してみたら、ほんとうに勝てなかったな。
>>826 すげーな、それ。
ベイズ推定とかしていたのだろうか。
>>824 乱数を用いた初心者向けのプログラムの中でも
もっとも簡単な基礎プログラムな気がするが。
829 :
デフォルトの名無しさん :2009/06/26(金) 19:17:31
なぜC言語にはPerlのようなパターンマッチングという概念がないのでしょうか。 system関数で外部コマンド使うとか、自作するしかないのでしょうか。 自作を試みても100行超えてしまいます。Perlではたった1行で済むのに・・。何この差・・
そういう人は、Perlの巣に帰っていいから、二度とこないでいいよ
>>829 言語の目的が違うから?
perlは元からテキストなどを扱いやすいようにしてある言語だと聞いてるけど。
Cは元はそういう趣旨じゃないし。
それに一行で済むって、それはインタプリタ内で命令にあった処理を行ってるだけで
早い話あなたが実装した100行超のようなのが見えないところに実装されてるだけですよ
regex.h
>>829 scanf 系のマッチングでなんとかなるかもしれないし、ならないかもしれない
ほんとにスクリプトとマネージドからくる奴はうざいのが多いな
パターンマッチと言ったら普通 Prolog とか Haskell のものを指すだろ
一体
>>829 は何を指して「パターンマッチ」と言っているんだ?
正規表現のマッチングを100行かそこらで作ってしまうのはすごいな。
>>829 適当なライブラリ探してきて使えばいい。
printfもscanfも、ライブラリ関数だ。
一番シンプルで使いやすい正規表現ライブラリは何なの? このさいc++でもいい
正規表現ってなんですか?
ぐぐってください
a=(b=b+1)を簡潔にするとa=++bになるらしいんだがどうして? a=b++じゃだめなのかな
俺のせいきを見ろっていう芸術表現のこと
>>844 a=++bの動き:bを1加算してからaに代入する
a=b++の動き:aにbを代入してからbに1を加算する
明らかにa=(b=b+1)は上の動き
>>844 前置インクリメント、後置インクリメントでググると良いよ
正規表現についてしらべました。 なんとなくわかりました。 でもこんなのコンパイラを作る人とかにしか関係ないと思うのですが なんで必要なんですか?
え?
>>849 何も分かっていないwwww
もういいよ、じゃあコンパイラでも作ってろ
そのレベルじゃ必要ないから忘れていいよ。
俺も特に使わないな。大抵は普通の文字列検索で事足りる
つまり、正規表現機能つきのマクロがほしい、と。
strstr 相当のBM法かと思ってた
>>853 お前「なんとなくわかりました。」
俺「何も分かっていないwwww」
お前「わかってたら質問しません。」
だから俺がさっきから「何も」分かっていないと
言ってるじゃないか。
部分否定じゃなくて完全否定だよ?
頭おかしいのかな?
861 :
デフォルトの名無しさん :2009/06/27(土) 00:33:14
829です。 C言語でCGIプログラムをつくりたいのでパターンマッチングがないと不便です。 Perlでやれというのはなしで。
ライブラリ探すか、無ければ作る それがC/C++の世界
>>861 パターンの種類を列挙できるならやってみて
なんでPerlは無しなの?ひどくね? Webサーバは何使うの?
どうせCのほうが速いからとか、くだらない理由。
CGIは別プロセス起動のオーバーヘッドがある ApacheモジュールのPHPのほうがCのCGIより速いんじゃない
Perlを使える環境構築に頓挫したからだよ多分
#include <stdio.h> int main(void) { int a,b; char d; printf("aha"); scanf_s("%d",&a); printf("bha"); scanf_s("%d",&b); printf("dha"); scanf_s("%c",&d); printf(" %d ",a); printf(" %d ",b); printf(" %c ",d); return 0; } dの入力ができません。 どなたか試してくれませんか。
" %c"
構造体の中に関数ポインタを持たせたい場合はどのように書けばいいのでしょうか? あとその構造体の中の関数ポインタに登録されている関数を実行するコードはどのように書けばいいでしょうか?
>>870 #include<stdio.h>
struct foo{
int a, b;
void (*bar)(struct foo *);
};
void prt_a(struct foo *p){
printf("a=%d\n", p->a);
}
void prt_b(struct foo *p){
printf("b=%d\n", p->b);
}
void prt_ab(struct foo *p){
printf("a=%d b=%d\n", p->a, p->b);
}
#define CALL_BAR(x) (x)->bar(x)
int main(void){
struct foo hoge={1,2,prt_a}, huga={3,4,prt_b}, haga={5,6,prt_ab};
CALL_BAR(&hoge);
CALL_BAR(&huga);
CALL_BAR(&haga);
hoge.bar(&hoge);
return 0;
}
872 :
870 :2009/06/27(土) 19:23:31
ポインタ配列と二次元配列は状況によって使い分けろと教わりました。 ポインタ配列のほうが効率良くメモリを使用できると思うのですが、 二次元配列でないと駄目な状況とはどのような場合なのでしょうか?
2次元配列の方が効率いいだろ 1回のmallocで済む
メモリー使用効率はポインタ配列の方がいいだろ。 使わない所はNULLで開放してればいいわけだし
データの構造によるんでしょ
配列の中で色々やる場合は 連続してる方がキャッシュ効率が良くなって速くなりそうな気はする
構造体のソートの時は構造体を指すポインタ配列を持っていれば ソートは速いね。 構造体が大きければ大きいほど。
.
>>875 のような小さいエリアなら2次元配列を大きめに確保しておけばいいしね
構造体Aに構造体Bが含まれているのですが構造体Bの中で構造体Aのポインタをもつ場合は どのように宣言すればいいのでしょうか?
>>882 >883
struct A;
struct B {
struct A *a;
};
struct A {
struct B b;
};
typedef を解除する方法はないの?
untypedef
>>885 typedefは#defineのようなプリプロセッサーに対する指令でないから
untypedefはない。
スコープでどんこらする事のような
int hoge; //hogeになにか入れたりします。 if(hoge % 1 == 0) { //処理 } こういうロジックがあるのですが hoge % 1 って常に0ですよね・・・?
配列HOGE[5]に"abcd"という文字列が入っています これを使って、全く別のint型の変数abcdにアクセスしたいのですが、どのような方法がありますか?
リフレクション
デバッグシンボルを元にリフレクションを行うという手法は存在する。
894 :
890 :2009/06/28(日) 10:28:38
回答ありがとうございます なんとできないのですか・・・ 抽象的な質問になって申し訳ないのですが こういう場合、普通どういう方法を使うのでしょうか? 自分だと、単純にif文かswich文で 文字列abcdが入っていたら、変数abcdをうんたら〜しか思いつきません
ああchar型配列に入ってる文字列と同じ名称の変数にってことか・・・ まあ仕組みを組めばできなくはないけどな・・・・
896 :
デフォルトの名無しさん :2009/06/28(日) 10:40:42
変数名というのは人間界のものなんだよ。 Cにもハッシュテーブルがあれば、やりたいことが簡単にできそうだけどね。 解決策としては、全部番号にする手がある。 文字列をデータベースみたいに配列に格納して、変数も配列にする。 で、1番の文字列が見つかったら、1番の変数を操作するようにする。 変数名じゃなくて、文字列表の中の番号を使う。
>>894 >>自分だと、単純にif文かswich文で
>>文字列abcdが入っていたら、変数abcdをうんたら〜しか思いつきません
それでいいんじゃない?
対象の変数が少なければ、それが普通かと
int main(int argc,char *argv[]) { Person dmy={"",0,NULL}; Person *start=&dmy; Person *wkdtp; Person *ip; char name[30],age_ss[10]; while(1){ printf("名前="); gets(name); if(strcmp(name,"")==0) break; printf("年齢="); gets(age_ss); wkdtp=(Person *)malloc(sizeof(Person)); if(wkdtp==NULL){ printf("メモリを確保できません\n"); exit(1); }
899 :
898 :2009/06/28(日) 13:57:29
898続き strcpy(wkdtp->name,name); wkdtp->age=atoi(age_ss); for(ip=start;ip->next!=NULL;ip=ip->next){ if(wkdtp->age < ip->next->age){ wkdtp->next = ip->next; ip->next = wkdtp; break; } 一番下のfor文で、 ip=startでip->nextの値はNULLになるのではないでしょうか? 後まだ存在しないip->next->ageにアクセスしようとしていいのでしょうか?
900 :
898 :2009/06/28(日) 14:04:02
自己解決しました。 スレ汚し申し訳ありませんでした。
901 :
デフォルトの名無しさん :2009/06/28(日) 15:24:58
execv*()の引数用の配列をmalloc()で確保したいのですが、 exec*()前にmalloc()したメモリはfree()しなくても大丈夫ですか?
execvから返ってきた場合(エラーの場合)は freeする。 エラーが起きなければ返ってこないので freeしようがない。
>>889 処理のところにちょこちょこbreakが入ってたりしない?
なんかのなごりというのが有力な気もするけど。
INT_MIN % 1 とか変な結果になりうることがなかったっけ?
>>904 うはっマジだ。ぐぐったら1じゃなくて-1だな。
#include <limits.h>
volatile int m = INT_MIN;
volatile int n = -1;
void main() { int i = m % n; }
VC落ちたw
>>889 元々二回に一回等の処理したくて %2だったのが %1に変更されたんじゃないかと推測
二回に一回の処理したくて hoge &1 == 0 と勘違いしたんじゃないかな。
908 :
デフォルトの名無しさん :2009/06/28(日) 21:15:54
typedef int num; って書けば、変数宣言するときに num i ; で int i ; と同じ意味になる(numはintの別名になる。)というのはわかってるんだけど typedef struct tagDATEDATA { int Year ; // 年 int Mon ; // 月 int Day ; // 日 int Hour ; // 時間 int Min ; // 分 int Sec ; // 秒 } DATEDATA, *LPDATEDATA ; って書いた場合はなにがどうなるの?
DATEDATAがstruct tagDATEDATAの別名で LPDATEDATAがstruct tagDATEDATA*の別名になる
910 :
デフォルトの名無しさん :2009/06/28(日) 21:33:44
…ありがとう。 理解は出来たが、いややっぱり複雑で…微妙に理解出来てないかも。 LPDATEDATAって入力したらこの構造体へのポインタになる・・・の?
そのとおり。 DATEDATA date; LPDATEDATA pDate = &date; pDate->Year = 2009;
そんなtypedefは、まねる必要は無い。 とつくづく思うが、そんなリスト見かけるよな。
913 :
デフォルトの名無しさん :2009/06/28(日) 23:15:08
C言語ではなくLinuxのシステムコールなのでスレ違いかもしれませんが 適切なスレが見つからないため質問させてください。 sample.txtの変更を監視するプログラムです。 epollの練習に書いてみたのですが、epoll_ctlがエラーを返します。 fd = open("sample.txt", O_RDONLY|O_NONBLOCK); epfd = epoll_create(1); memset(&ev, 0, sizeof(ev)); ev.events = EPOLLIN|EPOLLET; ev.data.fd = 0; epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev); for(;;) { epoll_wait(epfd, &ev, 1, -1); printf("sample.txt is changed.\n"); } このコードが期待通りに動きません。 調べてみるとepoll_ctl(2)が-1を返しており、errnoにEPERMが入っています。 また、fdを通常ファイルではなく、標準入力(1)にすると正常に動作します。 sample.txtの権限は644としており、読み書きが可能な状態としています。 どこが間違っているのでしょうか?
epollって、対象fdがソケットやパイプじゃないと使えないんじゃないの?
? : これってどういう意味でしたっけ ググってもヒットしてくれなくて・・・
条件演算子でぐぐれ
ありがとうございました
919 :
デフォルトの名無しさん :2009/06/29(月) 20:08:33
携帯からで失礼します '0'<=c && c<='9' 'a'<=c && c<='z' || 'A'<=c && c<='Z' (*p>='a' && *p<='z') (*p>='a' && *p<='z')&&(*p>='A' && *p>='Z') 上の5つの条件式なんですがなぜ上のように記述するのかいまいちわかりません 良かったら解説というか考え方をお願いします
>>922 そういう式だけを抽出してきたのではと思ったのだが・・・
不等号の向きが・・・まぁ単なる書き写し間違いかと
925 :
922 :2009/06/29(月) 20:15:37
携帯だから打ち間違えたのか 本当にその式でいいのか分からない 真ん中の && と一番最後の >=
>>922 >>923 >>924 >>925 4つ目は打ち間違いでした
*p<='z'ですね
>>925 一応プログラムはちゃんと動いてたのであってるとは思います
ちなみに3つ目は英文字列を全て大文字に変換するプログラム
4つ目は英文字以外を全て空白に変換するプログラムで使用した条件式です
どうも理解できないですね(馬鹿なだけ)
文字コードで連続しているのはわかりました
>>926 '0'<=c && c<='9'
この部分は
0x30 <=c && c<= 0x39
としてるのと同じ
>>926 4つ目間違えました
すいません
この条件だとこうなるのかな(!(*p>='a' && *p<='z')&&!(*p>='A' && *p>='Z'))
>>927 cの値が0x30以上かつcの値がcの値が0x39以下ってことでいいんですかね?
>>929 そうですね
a-z A-Zも同じようにそれぞれの文字コードの範囲としても置きかえれます
よくある入力された文字が数字もしくはアルファベットかどうかチェックするロジックでしょ? *pの方は文字列チェックでcだけの方は1文字だけ?
>>930 なるほどなるほど
ちなみに'0'<=c && c<='9'とc>='0' && c<='9'は同じ意味になりますよね?
>>931 1文字だけって訳じゃないです
なるべくctype.hを使うべき。どうしようもないとき以外は。
isdigit()とisalpha()もしくはisalnum()使え
スレ違いだと思うのですが教えて下さい。。。 プログラムで出力したファイルを バッチファイルで日付を入れてリネームしたいのですが ワイルドカードの使い方がわかりません。 例えば test.txt ->test_090629.txt としたいのですが、 拡張子を除いた部分の「test」をどうやったら抜き出せるのかわからないのです。 OSはWindows vistaです。 よろしくお願いします。
c>='0' && c<='9' じゃなくて '0'<=c && c<='9' の方が数直線的に見やすくてよくね?って言ったらハァ?って顔された俺は異端なのかね
まあどっちかに定数を持っていく方がいいと思うよ 右なら右とか
cが'0'以上で'9'以下 というように、cを主語にして考えるので、前者の方が見やすい。
c>='0' && c<='9' 嫌ならこう書いてもいいしな
>>937 おれもその表記のほうが好きだ。数学的思考。
やっぱり異端なのかorz c < '0' || '9' < c とかもわかりやすいと思ってたのにな。。 100 <= i && i < 1000 とかさ。。。
>>939 「cは、'0'と'9'の間にある」っていう
ひとつのパターンで見る考え方もあるが?
世の中のコードを検索して比率を調べてみたら面白いかもしれない。
>>937 数学的な値域の表現 0 ≦ c ≦ 9 の形に近い というやつね
>>939 たまたま 1回 c の評価をしてるだけ って立ち場だね
c が '0' 以上で' d が '9' 以下 なら
c <= '0' && d <= '9'
って書くし と。
どちらの主張も理解できるだけに悩ましい。 おれは上段のほうが好み
符号の向きが揃ってる方が個人的には見やすい
946 :
939 :2009/06/29(月) 23:59:36
>>943 主語は左に無いと読みにくくて・・・。
あと&&が左右を完全に分断しているように見えるので、
おっしゃるような一つのパターンとして見ることができません。
数式なら断然「0 ≦ c ≦ 9」が見やすいんだけどね。
>>944 うん。
大小比較は大抵 < か <= にそろえてる
>>946 その辺は数学の数式に慣れろというのと同じでc言語のお作法になれろというか
バグを出しにくい書き方を覚えろとしかいえない
949 :
939 :2009/06/30(火) 00:10:09
>>948 C言語としても、どちらの作法もありだと思います。
私の場合、長年慣れ親しんだ前者が見やすいのでバグを出しにくいですね。
950 :
デフォルトの名無しさん :2009/06/30(火) 00:12:15
>>948 この件で、C言語のお作法ってあるのかな?
とおもって、K&Rパラパラめくったら、同じようなコードを発見!
表紙の白いバージョン53ページ
if ( c >= 'A' && c < 'Z')
って書いてあるぞ。28〜29ページにも同じようなコード。
ということです。
でも、個人的には 'A' <= c && c <= 'Z' のほうが好きだけど。
気持ち悪いのがすきなんだな
>>950 K&Rの書き方は他の部分でも必ずしもスマートなわけではないと記憶してる
お作法というのは先輩お作法だな たぶん 'A' <= c && c <= 'Z' これは嫌いなグラマー多いと思う
確かに、ぐぐったらc >= '0' && c <= '9'の方が多かった
{ } の付け方みたいな話だな。 まさかGNUコーディングスタイルとかで決まってないか?
条件式で主語が左とかいう思考が理解できないのだが。 もしかして世の中ではソース読むときにいちいち日本語に直して理解するのが多数派なのか?
文字だと気持ち悪いが、 0.0 <= x && x <= 1.0 は許容。
>>956 そんな難しく考えてなくて
c <= 'Z'
1つだとこう書く
たまたま文字の範囲チェックなので挟む
でも
c >= 'A'
c <= 'Z'
の間なので
&&で繋げる
それだけ
※このスレはあくまで個人的な感想です。コードの書き方・読み方には個人差があります。
C言語を勉強し始めて3週間目の初心者です。 今「*」で図を書くプログラムに挑戦しているのですが平行四辺形・菱型・星型・渦巻き・ハートができません。 基礎であろう四角形と三角形(逆三角形と旗型)は作成できました。 作成する際の条件なのですが、 @2〜9を入力すると入力した行分の高さの図ができる。 A繰り返しをしようする。 です。 どうか皆さんの知識を分けていただけないでしょうか?お願いします。
平行四辺形は▲▼ 菱形は ▲ ▼ 星はええと、*なのか☆なのかによる 渦巻きハートは努力次第
つか宿題じゃないのソレ。 挑戦するだけなら自分にわざわざそんな条件つけないしょ
このスレの範囲じゃないね 宿題スレへどうぞ
☆なのはたん、ハァハァ
渦巻きは、四角い渦だと楽かな。 ハートは半円二つ+三角形で。
>>961 星型は*です。
>>962 宿題ではありません。三角形と四角形が@Aの指定があったのでそのままの条件で作れないかと思い
そのようにしました。
2行とかありえないだろ
***** ***** ***** ***** ***** -- これだって立派に菱形でもあり平行四辺形でもある。
と、私が小学生のときに発表して、先生を困らせたんだよなぁ。
困る先生にも困ったもんだ。 今回の「◆」と「▲▼」にしたって、単に「対角線が水平と垂直になる四角形」と 「二辺が水平で残りの二辺が傾斜した平行四辺形」とするだけでいいのに。
>>966 「*」と言われても、フォントによって五傍星も六傍星も八傍星もあるのだが。
あらかじめテキストファイルに出力したい絵を描いておいて、 入力に応じてファイルを選択して表示すればいいんじゃないの? ファイルを1行ずつ読むところで繰り返しを使用するし
それやるなら、配列でデータ持たせとく。
さてと、そろそろヒントを書いておくかね。 ・平行四辺形(▲▼) 三角形(▲)を作れればその応用。行内の開始点は▲と同じで、長さ一定とするだけ。 ・菱形(◆) これも三角形(▲)と逆三角形(▼)の応用。▲を出力したら、続けて▼を(1行減らして)出力すればいい。 後は高さに注意。三角形の行数の2倍-1行必要だから、2行では菱形に見えない。 ・星型 これはややこしいな。出力したい形をエディタで書いておいて、規則性を探してみればいいよ。 順番としては、後回しにすることお勧め。場合によっては、>973-974のようにデータ構造を考えた方がいいかも。 ・渦巻き 四角い渦巻きならそれほど難しくない。これもエディタで書いてみてから 上半分と下半分に分けて規則性を探せばいい。 但し、9行使っても目立った渦巻きにならないのに2行では渦どころか一巻きもできない。 そこはどう解釈する? 規則性を見つけやすいだけ星型よりはましかな。 ・ハート >965にもあるけど、上半分の半円を工夫すれば後は菱形の応用かな。これも行数に注意。
試しにうずまき作ってみた。MAXを9にすれば9行になるけど ぎりぎり一巻きぐらい。 #include <math.h> #define MAX 60 main() { int i,t; double v,w,x,y; char table[MAX][MAX+1]; memset(table, ' ', sizeof(table)); w = 3.0/180;/* radian */ v = 0.03; for(t=0; t<1000; t++) { x = t*v*sin(w*t*M_PI); y = t*v*cos(w*t*M_PI); x += MAX/2; y += MAX/2; if(x < 0 || x >= MAX || y < 0 || y >= MAX) continue; table[(int)y][(int)x]='*'; } for(i=0; i<MAX; i++) { table[i][MAX]=0; printf("%s\n", table[i]); } }
>>976 table[MAX][MAX]にしておいて、printf("%.*s", MAX, table[i])とした方がいいと思うの。
二次元文字配列みたいなことをしたいのですがうまくいきません。 ↓だと大量に警告が出てコンパイルは通るのですが、実行するとcore dump吐いて落ちてしまいます。 これの正しい書き方が分かる人がいましたらご教示ください。 #include <stdio.h> int main() { char ***pppChar = { {"abc", "def", "ghi", NULL}, {"jkl", "mno", NULL}, NULL }; char **ppChar, *pChar; for(ppChar = *pppChar; ppChar != NULL; ppChar++){ for(pChar = *ppChar; pChar != NULL; pChar++){ printf("%s ", pChar); } printf("\n"); } return 0; }
>>970 は?
指摘してる人もいるが2行だと要求してる図形にならないのもあるだろ
>>978 // 二つ問題がある。一つは可変長配列の初期化、もう一つはポインタの型
#include <stdio.h>
int main()
{
char * firstStrings[] = {"abc", "def", "ghi", NULL};
char * secondStrings[] = {"jkl", "mno", NULL};
char ** stringArrays[] = {firstStrings, secondStrings, NULL};
for (int i = 0; stringArrays[i] != NULL; ++i) {
for (int j = 0; stringArrays[i][j] != NULL; ++j) {
for (int k = 0; stringArrays[i][j][k] != '\0'; ++k) {
putchar(stringArrays[i][j][k]);
}}}
for (char *** p = stringArrays; * p != NULL; ++p) {
for (char ** q = * p; * q != NULL; ++q) {
for (char * r = * q; * r != '\0'; ++r) {
putchar(* r);
}}}
return 0;
}
>>978 いっぺんにchar型へのポインタ配列のポインタ配列は初期化無理みたいね
#include <stdio.h>
int main(void)
{
char *ppChar1[] = {"abc", "def", "ghi", NULL};
char *ppChar2[] = {"jkl", "mno", NULL};
char *ppChar3[] = {NULL};
char **ppChar[3], ***pppChar;
char **ppCharx;
ppChar[0] = ppChar1;
ppChar[1] = ppChar2;
ppChar[2] = ppChar3;
for (pppChar = ppChar; *pppChar != NULL; pppChar++) {
for (ppCharx = *pppChar; *ppCharx != NULL; ppCharx++)
printf("%s ", *ppCharx);
printf("\n");
}
return 0;
}
警告をつぶすのが先か 考え方を整理するのが先か 迷いどころだな ●一番外の配列の要素数宣言は省略できるけど、内側は無理(固定量ならOK) ●内側がポインタになってて そこに配列の先頭を渡す宣言で、なおかつ その配列が個別に実体の大きさが違う int で似たようなのを考えると こんな感じかねぇ… int pData1[] = { 1, 2, 3, 0 }; int pData2[] = { 4, 5, 0 }; int pData3[] = { 6, 0 }; int *ppData[] = { pData1, pData2, pData3, NULL, }; int i; for (i=0; ppData[i] != NULL; i++) { int *pData; for (pData = ppData[i]; *pData; pData++) printf("(%d)", *pData); printf("\n"); }
>>977 1行に2個'*'がでることもあるし。。
これがエラーになっちゃうんですよ 何とかなりませんかね char **ppChar[] = { ppChar1, ppChar2, ppChar3 };
エラーメッセージに従えばいいと思います。
>>983 %.<数値>s というフォーマット知らない?
フォーマット文字列内の数値部を引数からもってくる って仕様の
%.*s という指示があるわけで 決して * を表示しようとしているのではないぞ
ああ、すごく、すごく見間違えていたよ。
>>987 エラー E2063 strstr1.c 16: 不正な初期化(関数 main )
どうもポインタ配列で他のポインタ配列を初期化しようとすると
だめみたいだ
配列のサイズが決まってないからじゃないの? 関数ポインタの配列だと同じようにポインタで初期化できてるし(ポインタ配列じゃなく関数だけどさ)
ついでにgcc4.4.0のエラーも貼っておく strstr1.c: In function 'main': strstr1.c:19: error: incompatible types when assigning to type 'char **[3]' from type 'char **'
>>992 char **ppChar = { ppChar1, ppChar2, ppChar3 };
こう書いてるだろ?
char **ppChar[] = { ppChar1, ppChar2, ppChar3 };
とは全然意味が違うんだぜ
次はppcharがconstじゃないと言う落ちだな。
ppChar1〜3 が char** になってない、以外に想像がつかんのだが。
こういうソースです #include <stdio.h> int main(void) { char *ppChar1[] = {"abc", "def", "ghi", NULL}; char *ppChar2[] = {"jkl", "mno", NULL}; char *ppChar3[] = {NULL}; char **ppChar[3], ***pppChar; char **ppCharx; char **ppCharx[] = {ppChar1, ppChar2, ppChar3}; for (pppChar = ppChar; *pppChar != NULL; pppChar++) { for (ppCharx = *pppChar; *ppCharx != NULL; ppCharx++) printf("%s ", *ppCharx); printf("\n"); } return 0; }
そもそも >char **ppCharx; >char **ppCharx[] = {ppChar1, ppChar2, ppChar3}; なんだコレ。
char **ppCharx;←無視して下さい 書いてありません
char **ppCharx[] = {ppChar1, ppChar2, ppChar3}; ↓ char **ppCharx[3] = {ppChar1, ppChar2, ppChar3}; これでだめなの?
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。