独りよがりのためのスレッド 大体トリッキーなコードを書く奴に限って 致命的なバグを出したりするんだけど、 書きたいもんはしょうがない。
サンプルまでに有名な奴を1つ #define swap(a,b) a^=b^=a^=b
4 :
デフォルトの名無しさん :2001/02/26(月) 22:11
そして3は浮動小数点演算に上記のマクロを使用して氏んだ
>>3 それと、以下のようなコードに注意
int a=9;
swap(a,a);
ASSERT(a==0);
6 :
デフォルトの名無しさん :2001/02/26(月) 22:32
if(A) B; の代わりにA&&B if(!A) B; の代わりにA||B
7 :
デフォルトの名無しさん :2001/02/26(月) 22:59
8 :
デフォルトの名無しさん :2001/02/27(火) 01:00
>>7 Bは条件判断文じゃなくて
実行したい関数とか命令であることに注意
うちの会社でそんなコード書いたら書き直しだな
9 :
デフォルトの名無しさん :2001/02/27(火) 01:03
>if(!A) B; の代わりにA||B やっぱA or Bでしょう。 open(IN, "hoge.dat") or die; 日本語訳「hoge.datを開け、さもなくば逝ってよし」
10 :
3 :2001/02/27(火) 01:07
>>4 またまたお得情報! うん、確かに使えない
>>5 ASSERTって何? namcoの戦車ゲーム? でもスペル違うな〜
あ、いやまじで疑問。
11 :
8 :2001/02/27(火) 01:12
確かにperlじゃ普通かも ごめん宇津だし脳
12 :
デフォルトの名無しさん :2001/02/27(火) 01:23
>>10 ASSERTの使い方については、
『Writing Solid Code』という本を読むといいよ。
13 :
10 :2001/02/27(火) 01:31
14 :
13 :2001/02/27(火) 01:40
実験してわかったぴょん swap(a,a)のように本マクロで同一変数を使用した場合、 a^a の結果が a に代入されるため、結果 a==0 になってしまう Cって奥が深いぴょん
お礼になるか分からないけど最近作った駄作だぴょん #define bitchack(a,b) (a>>b)&1 aのb番目(0〜)のbitが勃っていたら1、勃っていなかったら0
16 :
デフォルトの名無しさん :2001/02/27(火) 02:09
17 :
15 :2001/02/27(火) 02:26
>>16 bitcheckぴょん
ついでに出てきた駄作ぴょん
#define bitset(a,b) a|=(1<<b)
#define bitreset(a,b) a&=~(1<<b)
代入したくなかったら=を捨てるぴょん
18 :
1 :2001/02/27(火) 09:26
意外とトリッキーなのが出てこないな。 最近書いたもっともトリッキーなコードはswitch文かな。 default以外の各case毎に同じ2〜3行の処理をさせたいが、 だからといって関数を作るほどではない。 そういうときにあなたならどうする?ちょっと考えてみそ 一番あり得そうなのは、 switch(c) { case 0: case 1: switch(c) { case 0: /*0*/ break; case 1: /*1*/ break; } /*0,1*/ ....; break; default: /*others*/ break; } これを綺麗に書くにはどうすれば?
19 :
デフォルトの名無しさん :2001/02/27(火) 09:30
まずインデントを入れること。
20 :
デフォルトの名無しさん :2001/02/27(火) 09:34
case (n) 文の代わりに、 result = (n == 0 ? 0処理 : n == 1 ? 1処理 : n == 2 ? 2処理 : デフォルト処理) ってやつ。 見やすいけど条件文に不慣れな人には理解しにくいかも。
21 :
1 :2001/02/27(火) 09:52
>>20 あ、なるほど
?:の優先順位のバグがちょっと気になるけど、
簡単なswitchを書くならこちらの方が見やすいかもね。
効率が悪くなるのが残念だけど。
22 :
デフォルトの名無しさん :2001/02/27(火) 10:09
>21 コンパイラの最適化を信じなさい(笑)
>>1 キボーンは、こんな感じでちゅか。
switch(c) {
case 0:
/* 0 */
....;
if (0)
case 1:
/* 1 */
....;
/* 0,1 */
....;
break;
default:
/* others */
break;
}
トリッキーなコードに浸っているようでは所詮厨房
トリッキーコードに浸って厨房っぷりをはっきするスレッドでは。
26 :
デフォルトの名無しさん :2001/02/27(火) 11:32
大昔・・・、 FORTRANで、いかに短い行数(=パンチカードの枚数)で、万年カレンダー等の プログラムを作れるかを競ってたなぁ〜。 結構ロジック・アルゴリズムの勉強にはなったよ。
28 :
1 :2001/02/27(火) 11:35
>>23 exactly!だだ出来ればブロックで囲むとなお可。
>>24 25の言うとおり、厨房ぶり満載のスレッド。
1で書いたけど、実際仕事でトリッキーなコードを書く奴に
ろくな奴がいないのは承知。でも書きたいんだよ
Z80のアセンブラで最速かつ最短の乗除算ルーチンを…
30 :
1 :2001/02/27(火) 11:37
>>27 それと、N88BASICで1行プログラミングとかね。
31 :
名無しさん@お腹いっぱい。 :2001/02/27(火) 12:29
>>23 申し訳ないけどif(0)のあたりが意味不明だぴょん
誰か解説お願いだぴょん
てゆーか、今まさにそのコードを使ってみたいぴょん
・・・あ、やっぱ四の五の言わずに実験してみるぴょん
33 :
デフォルトの名無しさん :2001/02/27(火) 14:51
>>32 ぴょん
実験しても、理解しにくいと思いまちゅ。
gotoだと見た目にトリッキーさに欠けるから、if(0)を使ってるだけでちゅ。
使うのは、砂場のお遊びまでにしといてくだちゃい。
34 :
24 :2001/02/27(火) 16:16
ポインタから0か1のbool型に変換したい時に普通 b = (ptr != NULL) なんて書くところを b = !!ptr と書くのはどう? トリッキーでもないけど読みやすさの点から結構気に入った書き方
35 :
1 :2001/02/27(火) 16:19
>>33 でも結局、gotoを使ってるんだよね。
switch文ってのがつまりgotoな訳で。
>>32 正規表現のメタキャラクタのエスケープを例にあげやう。
動作を追っていって理解してくれ
for(i=0;strSrc[i]!='\0';i++)
{
switch(strSrc[i])
{
case '$':
if(strSrc[i+1]!='\0' && strSrc[i+1]!='\n') break;
if(0)
case '^':
if(i!=0 && strSrc[i-1]!='\n') break;
case '.':
case '[':
case ']':
case '|':
case '*':
case '+':
case '?':
case '(':
case ')':
result+="\\";
}
result+=strSrc[i];
}
36 :
デフォルトの名無しさん :2001/02/27(火) 16:40
>>23 うわ、面白い!!
テストしてみよ、どう動くんだろう。
俺厨房。糞コードマンセー
37 :
24 :2001/02/27(火) 16:52
assert(ptr && "スタック異常") assert(i<N && "インデックス範囲外") アサート発動時にコメントを付加する方法 でも全然トリッキーじゃねーな
38 :
デフォルトの名無しさん :2001/02/27(火) 16:55
MSBとLSBの入れ替え n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xaaaaaaaa); n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xcccccccc); n = ((n >> 4) & 0x0f0f0f0f) | ((n << 4) & 0xf0f0f0f0); n = ((n >> 8) & 0x00ff00ff) | ((n << 8) & 0xff00ff00); n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000);
39 :
デフォルトの名無しさん :2001/02/27(火) 16:59
トリッキなコードを書くヤツは厨房だが トリッキなコードも書けないヤツはもっと厨房。
40 :
デフォルトの名無しさん :2001/02/27(火) 17:09
トリッキーなコードを書ける知識があればこそ、 実務においてそれらを正しく避けることができるのだ。 とか言ってみるテスト
41 :
デフォルトの名無しさん :2001/02/27(火) 17:23
むかしグラフィックが異様に遅い初代PC88での話し。 画面クリアをなんとか高速にできないか?とおもいZ80のインストラクション表をみながら これなら16bit単位で書き込めて、メモリ書き込みとアドレス更新が一発じゃんと思ったのが LD SP,xxxx LD BC,0 PUSH BC アドレスがディクリメントされていくのでケツからクリアされていくが 効果はあった。 でも後で気がついた話し。 DMAとめてクリアしてDMA再起動させたほうが早かったんだよね。
42 :
36 :2001/02/27(火) 17:24
ちゃんと動くじゃん、仕事で使ってみたいな。 やっぱ、書き直しか? つーか、上司が糞だから通りそうで嫌だな。
43 :
1 :2001/02/27(火) 17:30
>>41 をを、目から鱗。
既に今の時代では使えないのがなおさらトリッキーでgood!
44 :
デフォルトの名無しさん :2001/02/27(火) 17:59
IF(0) ってどういう動作になるんですか?
>>42
45 :
デフォルトの名無しさん :2001/02/27(火) 18:08
>>41 Oh! FMで似たようなコード見た気がするよ。
もちろん6809だけど。
>>39 ごめん。Pascalだとあんまりトリッキーなのは、書かせてもらえないの(藁
47 :
1 :2001/02/27(火) 18:28
42ではないが
>>44 if(0)で次の1文がとばせるんですが、
switchのcaseで飛んできたものは実行される、という訳です。
上から順次実行してきた場合はとばされるけど、
case宛にjumpしてきたコードは実行される。
言葉にすると難しいな。やっぱ42さんお願い
49 :
デフォルトの名無しさん :2001/02/27(火) 18:39
>>47 ありがとうございました。
解かりました。
if(0)を FOR文等に変えてみてもトリッキ−な事できますね。
50 :
1 :2001/02/27(火) 18:45
>>49 まさにそれこそトリッキーだが、動くのかな?
動いたところで実用価値が無いがそこはそれ、トリッキーであれば許可。
誰かfor文の中にgotoするテストをしてみて。
予想では、初期化は実行されないが、終了条件などはチェックされそうだな。
51 :
デフォルトの名無しさん :2001/02/27(火) 18:47
for(;0;)
52 :
デフォルトの名無しさん :2001/02/27(火) 18:52
>>50 できました。
繰り返しが0だったらIf(0)と同じ効果ですね。
53 :
デフォルトの名無しさん :2001/02/27(火) 19:26
Life with UNIXにのっていた最悪プログラムコンテストのグランプリはすごいとおもった。 int main[] = {VAXのマシンコード};
55 :
1 :2001/02/27(火) 19:31
>>53 そんな事出来るの?コンパイラ依存でなくて?
実験実験。ブルースクリーン出そうだが。
56 :
53 :2001/02/27(火) 19:35
昔の話しで環境依存だとおもう。 最近のはデータセクションにコードは置けないだろうから。
>>56 たぶん、エントリーポインタ書き換えればいけるよъ( ゚ー^)
58 :
1 :2001/02/27(火) 19:42
>>56 考えてみればそうだね。
今エントリポイントを操作して頑張ってたけど、
どうあがいてもプログラムロード即死亡。
コードセクションにデータをおければいいんだが。
コードってゆうか #define "debug.c" debug.cの中にはデバッグ用のソースが入っている。
#if _UNIX_ #include </dev/tty> #elsif _DOS_ #include <con> #endif
62 :
デフォルトの名無しさん :2001/02/27(火) 23:47
#define "整数" int #define "始まり" main #define "終わり" return #define "表示" printf "整数" "始まり"() { "表示"("%s" , "ハローCワールド"); "終わり" 0; }
なんか、このスレに一人だけ素の厨房がいるな
キミのことかね?
#define駆使してMindもどきがつくれそうだな
66 :
デフォルトの名無しさん :2001/02/28(水) 10:46
もっと面白いの期待age
67 :
デフォルトの名無しさん :2001/02/28(水) 11:54
unsigned char main[] = {0xc3 /* ret */}; とりあえず動きました。 環境:Win98, VC++98
68 :
デフォルトの名無しさん :2001/02/28(水) 14:27
>>67 Win2kでは無理だろ。……多分だけど。
69 :
デフォルトの名無しさん :2001/02/28(水) 15:05
>>53 知る人ぞ知る、MAZE BATTLEみたいなもんか。
70 :
デフォルトの名無しさん :2001/02/28(水) 15:12
>>68 win2000動作確認しました。
動いた。
>>62 error C2007: #define の後に識別子が必要です。
72 :
デフォルトの名無しさん :2001/02/28(水) 15:27
73 :
デフォルトの名無しさん :2001/02/28(水) 15:29
>67 cygwin gcc on win98se でも動いた。 main=195; の方がかっこいいかも。
74 :
デフォルトの名無しさん :2001/02/28(水) 15:45
>>72 む、VC++6.0のデフォでOKだと思って、
新規で作ったら通らなくなった。
でも、古いプロジェクトファイルのほうはリンク通る。
ちと調べましゅ。
お馬鹿でスマン
75 :
デフォルトの名無しさん :2001/02/28(水) 16:09
あで??何が違うんだろう・・T-T; 鬱だ。
char main=-61; 動いちゃったぴょん Linuxならふつーに動くッぽいぴょん
77 :
デフォルトの名無しさん :2001/02/28(水) 22:44
トリッキーの極みと言えば、やっぱり(67の様な)オブジェクトコードの埋め込みや、 自己書き換えだと思うけど、誰か本格的にやってる人いない?
>>41 >>43 2人とも、まだまだあま〜いじょ。
0クリアするコードも含めて0クリアして、はじめて
トリッキーと言えるのっ。 もちっと考えてみそっ!
79 :
デフォルトの名無しさん :2001/02/28(水) 23:26
関数の実体のコピーは合法でしょうか? func1() { /* ... */ } func2() { /* ... */ } /* 関数のサイズは、コンパイラが出力するMAPファイルやアセンブラ出力で関数の 位置関係から算出します。 この場合、func2のアドレスとfunc1のアドレスの差を関数のサイズとみなします。 */ typedef (*tclosure)(); #define FUNCMAXSIZE 8192; test() { static char closure_code[FUNCMAXSIZE]; tclosure closure; memcopy(closure_code, func1, (size_t)(func2 - func1)); closure = (closure_code)closure_code; closure(); /* 実行 */ }
>>79 何に使うの。具体例を。
if ( 用途が無い ) return 屑コード;
81 :
79 :2001/02/28(水) 23:39
これができて何が嬉しいかというと、普通のファイルに関数そのものを置ける事。 DOSのsmallモデルとかの、実行ファイルのサイズに制限のある環境で、 擬似的にオーバレイが可能になるとか。 他に利点無かったかな・・・
∩ ∩ (゜∇゜) ピョピョ ( ) ⊥⊥
83 :
79 :2001/02/28(水) 23:46
まあ、処理系依存なんだけど、大抵の環境で同じ様な事が出来る筈。 TEXTセグメントに納まらなくなった場合とかに、アセンブラで書いて小さくする手間が省ける。 アセンブラを直接弄らない事で、ある意味移植性は高くなる。(藁
(cond ((用途が無い?) '屑コード) ((実用にはならないけど面白い?) 'そうだね) (else '何かあるの?))
85 :
デフォルトの名無しさん :2001/02/28(水) 23:47
>>79 func2()がfunc1()よりも後ろに置かれてるという保証はあるの?
86 :
85 :2001/02/28(水) 23:49
ごめん。わかってるみたいね。
87 :
デフォルトの名無しさん :2001/02/28(水) 23:49
>>85 引き算したり比較したりしてうまいことやる。
if ( func1 < func2 )
{
...
}
else
{
...
}
88 :
79 :2001/02/28(水) 23:51
>>85 だからー、79で
>関数のサイズは、コンパイラが出力するMAPファイルやアセンブラ出力で関数の
>位置関係から算出します。
と書いてあるだろが。
ちゃんと読んでね。
if文などの条件演算におけるXOR表現 (a < 0 != b < 0) …この程度常識っすかね?
90 :
79 :2001/03/01(木) 00:01
まあ、今となってはあまり意味が無いか。 ゲームボーイなどの携帯ゲーム機ではいまだに有効な筈・・。
91 :
>89 :2001/03/01(木) 00:05
たしかその式はC言語では違法だった様な。コンパイラが警告ださない? 非ゼロ同士が一致するかは保障されてない筈。 でも大抵の環境で有効かな? アセンブラ出力見ればはっきりするけど。
>>84 面白い=トリッキーコード≠屑コード。
"The International Obfuscated C Code Contest"なんて
どこが面白いでちゅか?
93 :
>91 :2001/03/01(木) 00:11
んなわけねーだろ。 関係演算子の値は、常に0か1だ。
あ、そうかも。式の値に対しての真偽値のことと間違えてた。 しまん
95 :
デフォルトの名無しさん :2001/03/01(木) 00:36
// MSVC has for scope bug. #if defined(_MSC_VER) # define for if(0);else for #endif
多分トリツキーなことになると思うのでここで質問。 printfをあちこちに埋め込んでデバグ用出力をよくするんだけど #ifdef DBG_FLG printf("hoge:a=%d",a); #endif などとあちこちに書くのはとても面倒。そこで、マクロで debug_printf("hoge:a=%d",a); などと1行ですますマーベラスなアイディア、あります?
97 :
デフォルトの名無しさん :2001/03/01(木) 01:12
>>96 いつも使ってる奴のコピペ
ほんとはdprintf((式))一個だけでも良いんだけど、
引数チェック付きprintfということで・・
#ifdef DEBUG
#define dprintf(a) printf(a)
#define dprintf0(a) printf(a)
#define dprintf1(a,b) printf(a,b)
#define dprintf2(a,b,c) printf(a,b,c)
/* ... */
/* 条件付き出力 */
#define d1printf(t, a) do { if (t) {dprintf(a);} } while (0)
#define d1printf0(t, a) do { if (t) {dprintf(a);} } while (0)
#define d1printf1(t, a,b) do { if (t) {dprintf1(a,b);} } while (0)
#define d1printf2(t, a,b,c) do { if (t) {dprintf2(a,b,c);} } while (0)
/* ... */
#else
#define dprintf(a)
#define dprintf0(a)
#define dprintf1(a,b)
#define dprintf2(a,b,c)
/* ... */
#define d1printf(t, a)
#define d1printf0(t, a)
#define d1printf1(t, a,b)
#define d1printf2(t, a,b,c)
/* ... */
#endif
98 :
>96 :2001/03/01(木) 01:20
ごくあたりまえの手段だが・・・。 #ifdef DEBUG #define debug_printf printf #else #define debug_printf 1 ? (void) 0 : printf #endif
99 :
96 :2001/03/01(木) 01:23
>>97 やはり、printfの引数の数が鬼門ですね・・・
引数の数にあわせてdefineを代えるのも面倒(ごめんなさい)。
ここをトリックで切り抜ける方法がなんかないもんでしょかね。
100 :
97>99 :2001/03/01(木) 01:26
だからー、全体を括弧で囲めば、dprintf一個でも良いの。 dprintf(("p:%lx ->n:%lx\n", (long)p, (long)n));
101 :
96 :2001/03/01(木) 01:28
>>98 素ゥ晴らしい! 君は英雄だ!
ありがとう! 2chって素敵
負けた。 実行されないコードがコンパイラによって削除されるかが鍵だなー。
103 :
97 :2001/03/01(木) 01:37
あ、普通削除されるか・・
104 :
96 :2001/03/01(木) 01:38
>>102 コンパイラの最適化で消えてなくなるようです。
(今 .s を出力して確かめてみた)
まさに実用的なマーベラストリックですね。
105 :
デフォルトの名無しさん :2001/03/01(木) 01:43
>>97 Cよちよちの初心者です。お世話になります。
#define d1printf(t, a)
上の','とaの間にある半角スペースは、ある種のトリックでしょうか。
「コピペ」の言葉が、ちょっと気になったものですから・・・。
空白は全然、なんの関係もないです。 みたまんまのマクロです。
97じゃないけど、()のなかの空白は気にしなくてもいいよ。
108 :
襴様 :2001/03/01(木) 01:54
110 :
外付けSCSI :2001/03/01(木) 02:32
#ifndef DEBUG #define DB(x) #else #define DB(x) x
>>98 うわーかっこいい!サイコーだぴょん。
ん?・・・ちょっと待つぴょん
#ifdef DEBUG
#define debug
#else
#define debug 1?(void)0:
#endif
とすると、printfだけじゃななくてもどんな関数
(一時的なロギング関数とか)でもオッケーだぴょん。
こんな感じだぴょん
debug hoge();
112 :
デフォルトの名無しさん :2001/03/01(木) 06:52
>>111 110さんのが、トリックを使わずに、可読性・汎用性も高く
副作用も少ない、すばらしい書き方の見本ではないのかな。
トリックをすべて否定している訳では無いよ。
98のは昔のDOS処理系のLSI-C試食版やTurboCでも期待通り展開される。
>>110 括弧つけるのが面倒だぴょん
生意気言ってごめんだぴょん
>>114 デバッグ用のコードがシンプルでなければ・・・、
デバッグ用のコードのデバッグをやるはめになる恐れがある。
まーふぃー(嘘)
116 :
デフォルトの名無しさん :2001/03/02(金) 16:28
今でもよく使うトリック。 char* GetHogehogeFilename() { static char filename[_MAX_PATH + 1]; .....(hoge hoge)..... return filename; }
>>116 これはトリックというのか?
リエントラントでないのでsage
トリックというより、単なる糞コードだな。
>>117 > リエントラントでないのでsage
うむ。でも便利。Windowsだと怖いが。
120 :
デフォルトの名無しさん :2001/03/02(金) 18:12
Windowsだとなぜ怖い? どんなOSだろうと使い方間違えればすぐにバグの原因になるコードだと 思うけど。
>>120 Windowsだと、いつリエントラントが要求されるようになるか
わからん。
DOSでリエントラントが要求されるケースはかなり特殊。
122 :
デフォルトの名無しさん :2001/03/02(金) 19:19
再帰呼び出しでなくても、 char *a,*b; a = GetHogeHogeFileName(); b = GetHogeHogeFileName(); fp = fopen(a,"r"); で動作保証されないよね? 使い方に注意する必要があるというのはそういうことです。
123 :
デフォルトの名無しさん :2001/03/02(金) 20:59
スレッドを多用したプログラムから対策無しに利用した時点で 中身の保証が出来なくなってアウトってことだろ。 でもそれだけなら他のOSでも言える事だと思うけど・・・Windowsでは 何か違うの?
最近のは知らないんだけど 昔のstrtokとかいうのも、そんな実装じゃなかったっけ?
125 :
デフォルトの名無しさん :2001/03/02(金) 21:12
私にはレベルが高すぎて理解できないので、
どなたか教えてください。
>>98 さんの
#define debug_printf 1 ? (void) 0 : printf
>>111 さんの
#define debug 1?(void)0:
の行と、
#define debug
の違いを詳しく。
↑失礼、記入漏れあり。訂正いたします。 #define debug の違いを詳しく。 ↓ #define debug_printf #define debug の違いを詳しく。
自分でcppだけ実行して展開してみろ>125
今、Cの本しか無いんです。
ヒントだけでもいいですから、教えてください。
>>127 さん
自分で調べることが大切だ、ということを教えているのだよ。
>>128 b=( a>0 ? 3 : 0 );
たとえばこれ、分かりますか?
多分Cの本には載ってるぴょん
>>129 それはわかります。
Cの本で"プリプロセッサ”の章も調べた上でお聞きしているのです。
例えば、その本の中で、
グローバル変数の実体宣言と外部宣言のマクロを使った説明があるのですが、
(以下、引用)
#ifdef GLOBAL_VALUE_DEFINE
#define GLOBAL
#else
#define GLOBAL extern
#endif
でマクロ定義して、GLOBAL_VALUE_DEFINEの定義/未定義によって、
GLOBALの置換文字列を空文字列またはexternにします。(以下、略)
つまり、上記での「空文字列」のやり方と何が違うのかと。お願い致します。
>>130 3項演算子ですね。
代入演算子より優先順位は高いので、括弧は不要でしょう。
>>131 あんまり変わらないぴょん
なんであんなふうになってるかというと
printfには引数があるからだぴょん
>>133 じゃあ、これでもいいって事ですか?
#ifdef DEBUG
#define debug
#else
#define debug //
#endif
136 :
デフォルトの名無しさん :2001/03/03(土) 00:49
>#define debug // "//"自体が#define行のコメント子になっちゃうでしょ。
>>136 コメント>マクロ という事ですか。ふーむ。奥が深い。
もう少しおつきあい下さい。 これなら、どぉ? #ifdef DEBUG #define debug #else #define debug /##/ #endif
やっぱ、だめ臭いな。
もうこのスレから出てってくれ>125
141 :
フォルトの名無しさん :2001/03/03(土) 02:21
>>96 VC++6.0ならこれでOKみたい。
#ifdef DEBUG
#define debug_printf printf
#else
#define debug_printf
#endif
それが通らないコンパイラは存在しないだろう。 ただし引数が評価されるために副作用があるけどな。
まあ好き好きだから、それを使っとけ。 このようなコードでも、君の書いた通りには動くことだし。 if (...) debug ...; ...;
144 :
デフォルトの名無しさん :2001/03/03(土) 02:44
>>98 bccでは
「エラー E2468 : void 型の値は許されない」
となってコンパイルが通りません。
なぜにああいう形にする必要があるのか知りたいです。
(だいたい、A?B:Cは BとCが同じ型の必要があると思うのだが・・・)
debug_printfの引数部分に副作用があるものがあるときには
>>141 のほうが評価されて正しい結果になると思います。
まあ、もしdebug_printfの返り値を使用していたり、
debug_printfの引数の評価順に依存した副作用とかがあると
141のやつでもだめだとは思いますが・・・
>>140 理由は良くわかりませんが、厳しいですね。。。
>>142 引数評価されたほうが、debug版との動作の差がなくなると思うのだが・・・
(なんの副作用もなければ最適化で消えると思うし)
#ifdef DEBUG #define debug #else #define debug 1? 0: #endif gccで問題なく実行できたぴょん
四の五の言わずにまずトライ&エラーの精神を持つべきだぴょん 失敗は成功のおっぱいだぴょん
147 :
デフォルトの名無しさん :2001/03/03(土) 03:36
>>146 トライアンドエラーもよいけど、
たまには言語の仕様とか勉強して
理論的にプログラム書こうね!
149 :
デフォルトの名無しさん :2001/03/03(土) 03:51
>>147 はどうやらVC++で
for ( i = 0; ... )
{
}
と書けるようにするテクニックを紹介してるみたいだ。
150 :
デフォルトの名無しさん :2001/03/03(土) 03:55
>>149 for (int i = 0; ...) でしょ.
Watcom もこれできないんだよな−
もう一回だけチャンスを。
#ifdef DEBUG
#define debug
#else
#define debug if(0)
#endif
>>140 なんかすごいの出してくれたら、そうします。
>>151 すばらしいぴょん
それが正道っぽいぴょん
いつのまにかそんなにトリッキーじゃなくなってるぴょん・・・
>>151 なんだ、まだやってたのか。
この場合は三項演算子を使うのが定石であって、
それ以外の解は存在しないんだって。
151ではこれが正しく動かないだろ?
if (...)
debug printf(...);
else
...
>>154 机上では、動くはずなんですけど。それより、
定石を破るのが「トリック」なのでは・・・?
これだったらどうだろう? #define debug if(1) ; else
「どっか逝け」の声は、もう十分に聞こえております。 が、 まだ煮え切らないので。 if-else のネストだけが問題なら、 #define debug while(0) で、だめ?
>>158 -159
moe ? printf("ハァハァ") : debug printf("逝ってよし!");
だめだめ。
あと、 debug printf("ヽ(´ー`)ノ") , debug printf("やっぱり氏のう"); だめだめ。
3項演算子でなくても #define debug_printf 0 && printf でどう?
1 + debug_printf("だめだめ\n");
>>163 ちょっと一眠りして、ひとつ考えてみたんですけど
まだつきあってくれます?
とりあえず書きますので、また駄目出しお願いします。 #ifdef DEBUG #define debug #else #define debug 0 && #endif
166 :
151 :2001/03/03(土) 09:20
>>163 さん以外の方でも結構ですので、どなたか
>>165 の「だめだめパターン」を教えてください。
167 :
151 :2001/03/03(土) 10:38
もやもや感が残るので、友達の使ってないPC-9821noteを借りてきました。
それで、MS-DOS6.2 + TurboC 2.0 で検証しました。
>>143 ,
>>154 ,
>>160 -161,
>>163 は全てOKでした。
それより、
3項演算子を使うやり方で、
>>163 のパターンを検証すると、
#define DEBUG
#ifdef DEBUG
#define debug
#else
#define debug 1 ? (void)0 :
#endif
int i;
i = 1 + debug 3; /* error ! */
と書くと、/* error ! */の所で、コンパイラがエラーを返すんですけど・・・。
"Not an allowed type in function main"ってメッセージです。
環境のせいでしょうか。
168 :
151 :2001/03/03(土) 10:48
訂正: 上記、#define DEBUG の記述をコメントアウトしたときに、 コンパイラがエラーを返します。 ごめんなさい。
もうこのスレ 151 にあげるから気が済むまでおやりなさい
170 :
1 :2001/03/03(土) 11:25
さすがにかなりウザいと思い始めたり。 仕方ないので新しいネタ。 自分自身をファイルなどで読み込むことなく、 自分自身を表示するプログラムを書いてみそ。 ちなみに「可能です」。 わからない人は下の答え(たぶんすぐ誰かが書くだろう)を見ないで、 しばらく考えてみてはどうでしょう。面白い(かもしれない)よ ちなみにN88BASICなら 10 LIST ですね。
171 :
1 :2001/03/03(土) 11:31
>>170 #include "hoge.h"
--hoge.h
int main(void){printf("#include \"hoge.h\"");return 0;}
こういうのはやめてね(涙)。
振り返ってみると、確かに「荒らし」のごとくの連続書き込み。 151は、これをもちまして永遠に2chから去ることとなりました。 ご迷惑をおかけしました皆様方には、お詫び申し上げます。さようなら。
>>170 > 10 LIST
system .... cat .... "What?" .... finish->face
printf("main=0x%x\n",main);
なんか有澤誠が出てきそうなネタだな>不動点プログラム
>>176 これって何か役に立つの?
取り立ててすごいわけでもなく、毒にも薬にもならない。
たとえば、自分の中の関数名一覧をとりだせちゃうとか、
そういうのだったらいろいろ応用(?)も効くと思う。
178 :
デフォルトの名無しさん :2001/03/03(土) 23:24
>>170 ネタが高度すぎてだれも付いてこられないもよん。
>>170 子プロセスでシェルを起動して、ソースファイルを
typeとかcatに渡すってのは?
>>179 ファイルを読んじゃ駄目ってんだから、たぶん反則だとおもうぴょん
181 :
1 :2001/03/04(日) 01:03
>>178 高度なパズルで、トリッキーなコードとは無関係だったからかも。
昔ソースコードに感染するウィルスを考えていたときに作ったんだけどね。
>>179 180さんの言われるとおり反則ですね〜。頑張って下さい。
182 :
デフォルトの名無しさん :2001/03/04(日) 01:40
埋め込みオブジェクトコードの話題キボン
文字コードを利用する奴はなんか反則っぽいのでいや。 昔、FORTRANですごいの見たことあるんだけど思い出せない。
184 :
デフォルトの名無しさん :2001/03/04(日) 02:48
void call_func(void *func, ...) { func(...); } というような関数は実装できますか?
キャストしておしまい>184
187 :
デフォルトの名無しさん :2001/03/04(日) 03:03
>184 関数ポインタ使え!
>>184 void mick( int a )
{ printf("%d\n",a); }
void jack( void b() ,int a)
{ b(a); }
main()
{ jack( mick, 8 ); }
もっとかっこよく実装できるはずだがそこは諸兄に任せるぴょん
189 :
1 :2001/03/04(日) 03:17
どういうときに効果的に使えるんだろう。
関数を引数に渡したくなったことはないけど、
もしかしたら綺麗にプログラミングするときに便利かもね
>>183 とりあえず文字コード(0x22とか)に頼らなくても作れます。
現在printfを使わないでやるのに挑戦中です。
(要するにcoutなどを使ってみる)
>>189 >関数を引数に渡したくなったことはないけど
基本的に関数に引渡す値は、構造体に入れておけば
引数を渡しまわせるので、実地においてその辺りで
悩むケースは稀だと思うぴょん
191 :
1 :2001/03/04(日) 03:45
>>190 悩むことは無くても、効果的に使用できる状況は知っておきたいね。
知らなくても美しく(かつ読みやすく(笑))書くことは出来ると思うけど。
>>191 引数を渡すパターンも
>>188 で示してるつもりだぴょん
でも可変引数はこのパターンだと確かにちょっときついぴょん
トリッキーでも美しくもないのでsageるぴょん
>>170 >自分自身をファイルなどで読み込むことなく、
>10 LIST
ワラタヨ! イイカラスーパートリッキナコタエダシテミセロ サイテンシテヤッカラ
大して面白くはないな #define X(x) #x char x[]=X(main(){puts(X(#define X(x) #x));printf(X(char x[]=)X(X(%s);),x);printf(X(%s),x);});main(){puts(X(#define X(x) #x));printf(X(char x[]=)X(X(%s);),x);printf(X(%s),x);}
訂正。無駄なことをしていた。 #define X(x) #x char x[]=X(main(){puts(X(#define X(x) #x));printf(X(char x[]=X(%s);%s),x,x);});main(){puts(X(#define X(x) #x));printf(X(char x[]=X(%s);%s),x,x);}
>>195 デタウンコ、マタコンパイルシテミタノカー
ウンコノゲンリョウト、コンペアシテミタノカー
..... < 10 LIST
198 :
Ken :2001/03/04(日) 11:19
>>198 ヘイ!ケン ソンナノココニカクト スキールヨリモラールガオチール
200 :
1 :2001/03/04(日) 12:14
>>194 -195
なるほど、文字列化演算子を使う方法ですか。思いつかなかった。
#xはコンパイラによってはサポートされていないんだけど、
ほとんどのコンパイラでコンパイルできるし、これくらいは可でしょう。
>>197 答えですか。そんじゃ文字コードに依存しない物を
int main(){char c='"',*text="int main(){char c='%c',*text=%c%s%c;printf(text,c,c,text,c);return 0;}";printf(text,c,c,text,c);return 0;}
>>200 イイヨ リカイシヤスイ イイコタエ
モスコシ トリッキナモンダイ ダシテクレ
202 :
1 :2001/03/04(日) 13:27
>>201 問題考えるの簡単じゃないんだよ。
もう少し引っ張れると良かったんですが。
アセンブラレベルとかだったらトリッキーなコード多そうだけど、
ついてこれない人が大部分だろうし。
ちょっと考えてみます。誰かネタふって(笑)
c=a++ + + + + + ++a;
203 :
1 :2001/03/04(日) 13:46
ちょっと思いついた問題。休日の午後だというのに厨房だな俺。 ビット数を求める最短のプログラムを書け、ってのはどうでしょう。 32bitの問題として、例えば5ならビット数は2(0101)って感じです。 あ〜ちなみにこのスレッドは 「こんなトリッキーなコードを書いたよ」 とか、 「この冗長なコードをトリッキーに出来ないかな」 とか、そういった話題も大歓迎です。 本来はそっちが目的だったし。
>>189 SPMDプログラミングモデルで他ノードに対して関数呼び出しさせるときとか。
あ、クラスタなどでの並列プログラミングの話ね。
>>202 ワルイコトシタ... スマンナ ジカンガ アレバ キョウリョクスル
c=a++ + + + + + ++a;
maximal munch ノ モンダイダナ
...ト コタエテシマウト マタワルイノデ オイトク
206 :
1 :2001/03/04(日) 14:24
>>204 なるほど、並列プログラミングとかだったら意味があるな。
みずからそんなコードを書くことはしばらく無いと思うけど、
頭の片隅に置いておきます。tnx
207 :
デフォルトの名無しさん :2001/03/04(日) 14:46
>>203 ビット数って立っているビットの数? それとも任意の数を表すのに必要なビット数?
とりあえず両方出しておくよ。
int b; // 答えのビット数
DWORD d; // 入力データ
//立っているビットの数を求める(dが例えば5ならbに2を格納)
for(b=32;(int)d>=0&&b>0;b--,d=d<<1);
//任意の数を表すのに必要なビット数を求める(dが例えば5ならbに3を格納)
for(b=0;d!=0;b+=d&1,d=d
>>1 );
208 :
207 :2001/03/04(日) 14:52
補足のコメントが逆だった。
//任意の数を表すのに必要なビット数を求める(dが例えば5ならbに3を格納)
for(b=32;(int)d>=0&&b>0;b--,d=d<<1);
//立っているビットの数を求める(dが例えば5ならbに2を格納)
for(b=0;d!=0;b+=d&1,d=d
>>1 );
209 :
1 :2001/03/04(日) 14:55
>>208 立っているビットを想定していました。
言葉足らずですみません。
で、for文を使った一般的な方法だけれど、
それをトリッキーに書いてみてはどうでしょう。
有名なのに↓があります。
int numofbits(long bits)
{
bits = (bits & 0x55555555) + (bits >> 1 & 0x55555555);
bits = (bits & 0x33333333) + (bits >> 2 & 0x33333333);
bits = (bits & 0x0f0f0f0f) + (bits >> 4 & 0x0f0f0f0f);
bits = (bits & 0x00ff00ff) + (bits >> 8 & 0x00ff00ff);
return (bits & 0x0000ffff) + (bits
>>16 & 0x0000ffff);
}
これは自分で考えるとすると結構ハードだと思うのですが。
かくいう俺も独自で思いついたのはありません。
>>209 条件から「最短のプログラムを書け」を削除しなきゃ。
ライシュウマデ モーコラレナイノデ マァ'スゴーク'カンタンナヤツヲ ヒトツ オワビニ Z80アセンブラデ ジサツプログラムヲ ツクレ メモリクウカンハ 0-FFFFh スベテ RAM ソノルーチンヲ ヨブト RAMエリア スベテ 0クリア ルーチンハ リロケータブル デアルコト スグ コタエラレルヤツハ カクナ Z80ナラ ニーモニックヒョウグライ ナントカナルダロ
212 :
1 :2001/03/04(日) 15:30
>>210 exactry。時間最短にしときましょか(笑)
>>211 Z80じゃなきゃ無理なのかな?
x86で出来ないかなぁ。
213 :
1 :2001/03/04(日) 15:32
>x86で出来ないかなぁ。 z80だと00hがNOPなので全クリアでぐるぐる状態になるのですが x86で00hって何の命令でしたっけ? add [ebx+esi],alかな?
215 :
デフォルトの名無しさん :2001/03/04(日) 17:56
>>214 00hだけで完結する命令はないみたいね。
ちなみに add [ebx+esi],al のアセンブル結果は 00h,04h,33h
と思ったらあったね。add [eax],al が 00h,00h
>>215 , 216
16bitモードの時、[bx+si]のModR/Mが00だったので
32ビットモードだとレジスタに'e'が付くだけだと思い込んでました
鬱だ
218 :
1 :2001/03/04(日) 20:18
>>215 eaxとesiが0だったら、メモリを荒らすことなく
ずっとぐるぐる動き続けることができるのでは?
状況がわかりにくいので「自殺プログラム」って
何をするべきなのかわからないのですが。
>>203 int numofbits(unsigned int n)
{
static const int bits[] = {
0, 1, 1, 2,
(途中省略)
30, 31, 31, 32,
};
return bits[n];
}
すいません。くだんねーのでsageます。
>>218 自分のプログラムも含めてクリアする。つまり自殺。って事では。
>>219 一番最速!しかも、たぶん一番最小(34byte程度のテーブルなら)。
しかし、スレ趣旨から外れてるのは確かに。でもよく使うよね。
>>220 ゴメソ。テーブルの数はまちがいじゃん。鬱・・・。
222 :
1 :2001/03/04(日) 22:21
>>219 いや素晴らしい、ワラタ
マジで最速ですな。
>>220 自分のプログラムをクリアするだけ?
他のアドレスもクリアするんでしょ?
自分自身を先のアドレスへコピーして、
今までの自分を0でクリアする、そういうプログラムの事なのかな?
この場合はメモリが循環していないと駄目だよね。むーん
>>203 int count(int a)
{
int ret=0;
for(;a;a>>=1)ret+=a&1;
return ret;
}
挑戦してみたぴょん。でももうちょっと削れそうだぴょん
致命的なバグを発見したぴょん でも秘密にしとくぴょん
225 :
1 :2001/03/05(月) 00:05
>>223 サンクス。限度まで削って……
int ret=a&1;
while(a) ret+=(a>>=1)&1;
return ret;
あまりかわらんなぁ。
226 :
1 :2001/03/05(月) 00:07
>>224 言われて気付いた ^^;
トリッキーなコードは書くべきじゃないね(笑)
>>225 気のせいか処理が長くなってる気がするぴょん
228 :
1 :2001/03/05(月) 00:37
>>223 最終案
do ret+=a&1;
while(a>>=1);
これだと可読性もあるし、ベストかもしれない。
テーブルもループも使わず、
>>209 の様な形で
かっこよくかつ短くビット数を得るトリッキーなコード
誰か考えてくれないかなぁ。
>>228 渋くて速くてかっこいいぴょん
で、答が落ち着いたところでデバッグしとくぴょん
int count( unsigned int a )
つーか、この時間たぶん誰も見てないぴょん・・・
230 :
デフォルトの名無しさん :2001/03/05(月) 01:56
うむ。処理系によってはちゃんと動く場合もあるかもね。
>>230 処理系依存の処理ってどこ?
っていうか何に対してコメントしてるの?
>>231 unsignedについてのコメントと思われるぴょん
右シフト時、処理系によって符号の扱いが違うかもしれない
ということ(0埋めか符号そのままか)だぴょん
unsignedにしとけば符号は関係ないので常に0埋めとなるぴょん
233 :
お手軽な奴をひとつ :2001/03/05(月) 03:46
int numofbits(unsigned bits) { return bits ? numofbits(bits / 2) + bits % 2 : 0; }
234 :
1 :2001/03/05(月) 06:26
>>233 いいねぇ。いかにもfc.comp.lang.cっぽい書き方が通っぽい。
たかがbitcheckでスタックを結構喰うのが難点だけど、
読みやすくていいんじゃないでしょうか。
>>230 unsigned/signedの右シフトなら、ANSI-Cではしっかりと仕様が決まってます。
signedの場合、最上位ビットは必ずそのまま設定されるはずですよ。
あんま出番がないのでさみしいから・・・。
>>222 >他のアドレスもクリアするんでしょ?
Yes
>自分自身を先のアドレスへコピーして、
そんな事はしなくていいですよ。
>今までの自分を0でクリアする
一番最後にね。ヒント。
>この場合はメモリが循環していないと駄目だよね。
そう。処理中にNMI要求もない事が条件。
237 :
1 :2001/03/05(月) 07:05
>>236 なるほど、意外と複雑じゃ無いみたいですね。
書けないこともなさそう。98emuでも入れて、
その中で試しに書いてみようかな。
俺はx86系アセンブリをあまり書いたことがないから
トリッキーに美しく書くのは無理だろうけど。
俺はライフゲームの無限生成パターンみたいなのを
想像していて、例えば mov [next eip],code みたいに
次々と自分自身を変更するコードを考えてた。
自己書き換えは実行のみ可能なセグメントではエラーになるよ >237
239 :
1 :2001/03/05(月) 07:29
>>238 だからPC-9801(というかdos)を想定してました。
(確かにeipという書き方で誤解を生みますね)
code/dataセグメントが分かれてしまう環境では
自殺プログラムって原理的に不可能ですよね?
自殺プログラムが作れる条件は多分
・メモリが巡回している
・全ての領域に書き込み可能
なんじゃないのかな?
>>239 Winだろうが別にdataセグメントにコード置いたってかまわないし
codeセグメントにwrite属性付けることも可能ですよ
241 :
1 :2001/03/05(月) 12:23
>>240 へえ、知らなかった、tnxっす。
実はセグメント周りは弱いんだよね。
コンパイラオプションでも調べてみます。
さすがにメモリ巡回はしていないよね?
242 :
デフォルトの名無しさん :2001/03/05(月) 12:44
243 :
1 :2001/03/05(月) 12:54
>>242 なるほど。同じアルゴリズムなのかな?後でチェックしてみよう。
209の可読性を失わせるなら、代入が減る分こちらの方が早いかも。
int numofbits(unsigned int bits)
{
bits = (bits & 0x55555555) + (bits >> 1 & 0x55555555);
bits = (bits & 0x33333333) + (bits >> 2 & 0x33333333);
bits = (((bits >> 4) + bits) & 0x0f0f0f0f;
bits += bits >> 8;
return (bits + (bits >> 16)) & 0xff;
}
某本からの転載です
>>243 基本原理はおんなじっぽいぴょん
disasしたら0xaaaaaaaaとか出てきたから
割り算とかはこれらの数字を作るためのトリックっぽいぴょん
245 :
デフォルトの名無しさん :2001/03/06(火) 17:50
CSVファイル(とか)を作るコード。 do{ &nbsp;&nbsp;&nbsp;/* なんか処理する */ }while(!((終了条件) || (fputc(',', fp), 0)));
#define START_A 0x101 #define END_B 0x102 #define STOP_C 0x103 というような定義文がたくさんあり、 stringという文字列を読み込んで if(strcmp(string,"START")==0) hoge(START); のようなif文を定義文の数だけずらっと並べてたんですが、 スマートに美しくコーディングできるでしょうか?
247 :
デフォルトの名無しさん :2001/03/06(火) 18:53
定数宣言に#defineなんて使うのですか? constじゃなくて?
248 :
こういうのじゃ駄目ですか? :2001/03/06(火) 19:07
>>246 struct _tbl { int id;
char* name;
} tbl[] = { {0,"START"},
{1,"END"},
{2,"STOP"},
{-1,""}};
for(int i=0;tbl[i].id != -1;i++){
if(strcmp(string,tbl[i].name)==0){
hoge(tbl[i].id)
break;
}
}
249 :
デフォルトの名無しさん :2001/03/06(火) 19:55
> 定数宣言に#defineなんて使うのですか? > constじゃなくて? フツーでしょ。 constは、このデータはいじりません宣言でしかないだけでしょ。 定数宣言じゃないですよ。 と言うか、もしかして君、そうしてるの?
247じゃないけど、const派だなぁオレは。デバッガでも追いやすいし。 つか、普通は最適化で直埋めされるから速度も問題ないし…。
252 :
デフォルトの名無しさん :2001/03/06(火) 21:22
読みにくいコードコンテストみたくなってきたな
253 :
coder :2001/03/06(火) 21:27
gotoを使わないための苦肉の策。 while(0) { ... if (...) break; ... if (...) break; ... } 割と普通? gotoは使わない!ってんじゃないけど、 インデント的に嫌いなもんで。
>>246 職人への道のりは、かなり遠く感じるぞ。
まずは言語より、考え方の勉強だな。
>>253 coderさん、Pro? それともネタ?
256 :
coder :2001/03/06(火) 21:47
>>255 間違えた。
これじゃ何もしないじゃん。(苦笑)
じゃあ、こんな感じかな。
while(1) {
...
if (...)break;
...
break;
};
一応、Proです。^o^v
>>256 プロのcoderさんなので、お聞きします。
ネストが2重以上になった時のいい方法、教えて。
>>248 どうもすみません。
数字の部分は既に定義が決められているので
tbl[] = { {START_A,"START_A"},
{END_B,"END_B"},
{STOP_C,"STOP_C"},
としてやってみます。
>>254 すみません。精進します。
>>256 無限ループは危険だと思うぴょん。有限ループがいいと思うぴょん。
do{}while(0);とかはどうかぴょん。
260 :
coder :2001/03/06(火) 22:10
>>257 break(2);
ってやりたくなる時ですか?
基本的には2重以上にネストしないように見直しますが、
どうしても必要になったのなら、ためらいなくgotoを使います。
もしくは、ネストの内側でreturn。(←あまり薦められない)
あ、やっぱり別関数にするかな。
要するに状況に応じて対処します。(あたりまえ)
ちなみに、Proって言ってもGAME関係です。
納期・効率が優先される世界なので、一般的ではないかも。
#故に「トリッキー」に惹かれてきたわけですが。
できれば個性は語尾ではなく、内容で示していただけると幸いです。 全く内容のない書き込みなら、語尾だけで個性を表すことも仕方ないと 思いますが、わりと良い内容を書かれているだけに残念です。 老婆心によるお節介なので、sage。
262 :
coder :2001/03/06(火) 22:14
>>259 さん
コードを見直してみたらそのようにやっていました。^_^;;
それで、while(0)って。。(恥&言い訳)
263 :
79 :2001/03/06(火) 22:34
昔、こんな感じの事やってました。(今もたまに・・) (TurboC) static char csetcode[] = "\x55" /* push bp */ "\x8b\xec" /* mov bp,sp */ "\xb4\x02" /* mov ah,2 */ "\xb7\x00" /* mov bh,0 */ "\x8a\x76\x08" /* mov dh,[bp+8] */ "\x8a\x56\x06" /* mov dl,[bp+6] */ "\xcd\x10" /* int 10h */ "\x5d" /* pop bp */ "\xcb" /* retf */ /* "\xc3" */ ; typedef void (far *tcset)(int, int); #define cset(x,y) (*(tcset)csetcode)(x,y) /* test */ int main() { cset(40,13); return 0; }
>>259 初心者ですが、・・・do{}while(0); は、有限ループなの?
do先に一回{}無条件実行、while(継続条件式)って思ってましたが。説明お願い。
>>264 有限ループである。
何故ならば、継続条件式が偽であるため、
継続せずに終わるからである。 だぴょん
>>265 回らない条件ループ。シュール。だったら、while(0)をタイプする意味はなあに?
>>261 なんか無視していいよ。だってここは2chだもの みつを
>>266 while(0)を入れないとコンパイル通らないからだぴょん
てゆーかそもそも do{〜;}while() ってゆー構文だし、
一度だけ回るループとか思ってほしいぴょん
ああ、261が言ってるのって'ぴょん'とかって発言してるやつ(ら?)のことか・・だもん
1回しか通らないんじゃループとは言わねぇ! …という突っ込みは無しですか?(^^;)
ループには展開されないよ。>269 アセンブラの出力でも見れば?
271 :
デフォルトの名無しさん :2001/03/06(火) 23:36
switch(val) { case 0: return TRUE; break; case 1: return FALSE; break; } return する場合でも break を入れる律儀な俺。 break 入れてる? スレ違い?
警告出るから入れない>271
>>263 こういうのってfar呼出しになるからDOSだと効率悪いね。
特にポインタ渡すような関数は。
コードをheapにコピーして置けばnearで呼べるかな?
>>263 素直にインラインアセンブラ使えばいいんでないの?
DSEGにコード追い出せるのが利点とか。>274 あと実行時に変更ができる? まあ、inline-asmでもできるか。
276 :
デフォルトの名無しさん :2001/03/07(水) 03:24
あたりまえすぎるが bool f = false ; : if(pushed) foo = !foo ; : マジでこれ仕事で使っていたが上司に「鳥キーな事してるね」 いわれたアル. フツーあるよね!?
277 :
1 :2001/03/07(水) 03:26
なんか突然書き込み増えるから怖いね。
>>259 do{/*...*/}while(0);は覚えておきます。
俺知らなかったよ、内容あるじゃん(笑)
>>261 >>246 コンパイラ依存だけれど、
#define HOGE(x) if(strcmp(string,#x)==0) hoge(x)
と定義して、
HOGE(START);
などとやれば、見た目はすっきりします。
しかし俺ならばstd::mapなどを使って書くだろうけど。
>>250 C++ではあまり普通ではないようですよ。
constで定義すると、コンパイラに正確に最適化される上に
型チェックも行えるので、最近はconstが主流です。
しかし、
#define XXX_xxx1 0x1
#define XXX_xxx1 0x2
#define XXX_xxx1 0x4
...
などとやる場合はdefineの方が素直です。
ここでconst、enumを使うのは邪道でしょうね。
278 :
1 :2001/03/07(水) 03:30
>>263 dataセクションに実行付加が付く可能性が高いので、
最近では危険でしょうね。TurboCでは大丈夫だと思うけど。
>>276 多分普通だと思います。boolでなくintの場合は
a=1-a;とやるのがgoodでしょう。ぱっと思いつきにくいよね。
>>277 自己レス。
#define XXX_xxx1 0x1
#define XXX_xxx2 0x2
#define XXX_xxx3 0x4
ですね
279 :
1 :2001/03/07(水) 03:47
ちょっとした質問があります。 スレと直接の関連が無いのでsageますが…… 1:unionの効果的な使用法 昔は(PC98の)VRAMをint配列とunionしたりして そこそこ意味があったけれど、最近は効果的な 使用法がいまいち思いつきません。例えば、 struct label{char tag[4];char dummy;char data[15];} union{char raw[20];struct label x} abc; などとやって、abc.rawに"SOME USAGE"を代入、とかかな? 2:protectedの継承の意味 C++での話です。動作はわかるんですが、どういう意味があるのか どういう場面で使うのかさっぱりわかりません。 protectedを効率的に使ういい場面を知っている人は教えてください。
unionを使うところって、OOPならポリモーフィズムを使うべきところが ほとんどだから、それで正しいんじゃないかな。
281 :
デフォルトの名無しさん :2001/03/07(水) 04:16
276が意味不明。も少し詳しい説明きぼん
282 :
1 :2001/03/07(水) 04:22
>>280 なるほど、C++に移行した結果残ったCの遺物と。
最近ハードに密着しなくなったのも原因かもしれないですね。
>>281 予想ですが、bool f=false;/*...*/f=!f;
というコードの話だと思います。
283 :
デフォルトの名無しさん :2001/03/07(水) 06:58
>>277 0x1, 0x2, 0x4の定義だけは#defineでって、そんなもんかね?
const でやっちゃうけど。なんかマズイことあったっけ?
Delphiなんかだと、集合型があってスマートにかけるんだけどねえ。
>>276 むしろBoolで、 f = 1 - f; とされることのほうがトリッキーだよ。
ちなみに、Pascal(またか)だとBoolean型は f := not f; とするしか選択がない(藁
Boolでなくboolだ。これだからPascal野郎は…。
>>279 非公開メンバは普通 protected にする
private は身内にすら見せないから不便
>>285 おまえC++も質問の意図もまったくわかってねえよ。
逝ってよし
非公開メンバは普通 vrivateにする private は身内にすら見せないから便利
yes
291 :
276 :2001/03/07(水) 09:41
失礼タイプミス スマソん 282さんの通り bool f=false; /*...*/ f=!f; でおます トグル変数なんですな さらにこれをかいた当時はCだったので int f=false; /*...*/ f=!f; としてトリッキーと見られたみたい ついついくせでboolとしてしまったある
292 :
デフォルトの名無しさん :2001/03/07(水) 09:51
>>285 それよか、お友達にはprivateな部分が見えちゃっていいのか?
って方が気になる > かみんぐあうとC++
293 :
デフォルトの名無しさん :2001/03/07(水) 11:13
>>292 そこらへん、Bjarneがどう考えていたのか興味あるね。
D&Eの邦訳って出てたっけ?
洋書は高いしなー。
294 :
デフォルトの名無しさん :2001/03/07(水) 11:24
>>248 ループの継続条件は、変な番兵でやるより、番兵なしで、
i < sizeof tbl / sizeof *tbl の方がいいと思うぞ。
あと、線形探索よりも、テーブルをはじめにqsortしておいて、
bsearchで二分探索の方が普通だと思うな。
295 :
285=288=アホ :2001/03/07(水) 11:48
privateメンバとpublicメンバの話をしているのはよくわかった。
で、private継承とpublic継承は知ってるか?
285で反応している
>>279 の質問は、protected継承の話なんだが。
292もアホに反応するなよ。
>>279 private/protectedな継承は外部に対してスーパークラスの
インターフェイスを隠したい時に使えますね。(んなこた解ってるって?)
他の言語なら継承を用いずにコンポジションで実現しなければならない
場面で利用出来そうです。
JavaのStackクラスなんかは失敗例で、コンポジションを使うべき、
或いはprotectedな継承が使えれば良かったケース。
# 用語の使い方からC++屋じゃないことは明らか(藁
297 :
デフォルトの名無しさん :2001/03/07(水) 11:54
C++でprivateメンバの実装が見えちゃうって事自体は、 Cとの互換性を保つために仕方がないと割りきったんじゃないかなぁ。 要は、スタックにオブジェクトを確保するためにデータメンバが必要で、 インラインで呼び出すために、privateメソッドのインターフェースも必要と。
>296
多分、
>>279 はprivate継承の意義はその通りだと知っているはず。
でも、protected継承の意義が不明ということだと思う。
この辺は、Effective C++に詳しいね。
>296 気が付かなかった。 Vectorのインタフェース丸見えですな。
>>292 -293はfriendの事だって気付かなかった・・・俺ってバカだ。
うーむむ、俺も「friendにだけなら許す」という
アクセス属性が欲しいと思った事が何回かあるし。
別のキーワードを嫌った面もあるだろうけど、
特に、演算子のオーバーロードで多用される点からも、
「friendはメンバ関数の一種として扱え」って事かな?
301 :
デフォルトの名無しさん :2001/03/07(水) 12:51
javaのStackクラスはあくまでVectorクラスの拡張ですよ。
302 :
1 :2001/03/07(水) 13:28
一般的でないために質問がわかりにくかったみたいですまないです。
こういう腐ったことを考えるのこそ、まさにオタの厨房ですな。
>>298 tnx。早速本屋で立ち読みします
>>298 protectedな継承なら、それをさらに継承したクラスからも外部には
非公開の親の親の機能を使えるじゃないですか。
通常のStackの外部インターフェイスとしてはinsertElementAt()
みたいなメソッドは不要なはずですが(だと思ってるけど)、Stackを
継承してStackの途中の要素に対してアクセスする何かを作る時、
privateな継承だとStackのpublic/protectedなインターフェイスしか
使えないっしょ。
だからといってprivate/protectedな継承がいいといっているわけじゃない。
コンポジションで代用出来るから敢えて必要な機能じゃないよね。
304 :
292 :2001/03/07(水) 13:47
305 :
デフォルトの名無しさん :2001/03/07(水) 13:49
トリッキーっつーか、C++になってないか? > スレ
ごめんよー
307 :
デフォルトの名無しさん :2001/03/07(水) 13:54
publicじゃない継承はコンポジションみたいなもんなんだからコンポジション したときにその変数をprivate/protectedにするかの選択ができるように private/protected継承ができるんじゃないの? 俺のトリッキーコード 既存のクラスライブラリがあって、そのライブラリのソースコードには触れられなくて でもあるメンバ変数にアクセスしたかったとき #define private public #include <XXXXXXX.h> とやったぞ
308 :
1 :2001/03/07(水) 13:56
>>305 すまないです。C++スレで質問すべきでした。
>>307 >publicじゃない継承はコンポジションみたいなもんなんだからコンポジション
>したときにその変数をprivate/protectedにするかの選択ができるように
>private/protected継承ができるんじゃないの?
そのとおり
>#define private public
>#include <XXXXXXX.h>
有名だよね。
でもそのクラスをさらに拡張しようとする人は泣くかもね(藁
元の設計意図は大事に&元の設計はきちんと(藁藁
このへんで抜けます。
>302の1 あ、Effective C++に載っているのは 「public継承はis-aという意味である」 「private継承はhas-aの代替手段である」 「protected継承の意味は知らん」 って事だけです。 まあ、よほどの達人以外、買って損はしない本だと思うけど。
311 :
1 :2001/03/07(水) 15:14
>>310 やっぱ書いてないよね?昔読んだときに書いてない気がしたんだ。
面白い本だというのは激しく同意。
312 :
デフォルトの名無しさん :2001/03/07(水) 23:11
ここは原典にもどってみよ〜ナリよ〜 こゆのはどうよポン time_t tt = time( NULL ); struct tm * ptm = localtime( &tt ); printf("今日は%.2s曜日ナリ〜","日月火水木金土"+ptm->tm_wday*2);
わりとふつーっぽい>312
ふつーナリか。。。(ショボン
原典⇒原点 ということで、減点
>>315 イスラム原典
ハンムラビ法典
信長の野望 (原典版)
317 :
デフォルトの名無しさん :2001/03/08(木) 01:12
>>312 .2s
っての初めてみました。
2文字までって事?
文字列引数の長さ調整ができたのか〜
318 :
1 :2001/03/08(木) 13:22
>>312 一般的にするにはこう言うのがいいのかもね。
string sample="今日は";
time_t tt = time( NULL );
struct tm * ptm = localtime( &tt );
sample+=&("日\0月\0火\0水\0木\0金\0土"[ptm->tm_wday*3])+string("曜日です");
全然トリッキーじゃないけど、参考までに
>>318 Perlだとこうなるな。
$str = "今日は";
$str .= ('日','月','火','水','木','金','土')[(localtime(time()))[6]];
$str .= "曜日です。";
320 :
トリッキーの1 :2001/03/08(木) 21:50
>>319 素晴らしい。perlの方でより美しく書けてしまうのが悲しい。
かくいう俺もperlよく使うけど……。
なんとかCで
sample+=(char**)({"日","月","火","水","木","金","土"})[ptm->tm_wday];
みたいに書く方法無いかな?(ちなみに↑は無理ですよ)
321 :
デフォルトの名無しさん :2001/03/08(木) 22:24
出現順番ちがうけど、 sprintf( work, "今日は%2.2sです",&((short*)"日月火水木金土")[dayofweek]) short*はあんまり意味なし。+にすればもっと簡単。
sprintfの様な関数を使わずには無理かな? 標準関数だから使っても問題なしなんだけれど、 やはりオーバーヘッドなどを考えてしまう厨房な俺。
323 :
デフォルトの名無しさん :2001/03/08(木) 23:38
printfはそんなにオーバーヘッドかい?>322
自分で作るとなるとかなりのオーバーヘッドになりそうで。 %sなどをサーチしてそこに文字列を代入する手間を考えると、 結構な労力が必要かと思われます。 暇を見て後でdisassembleしてみます。
>>323 strcatを使って同様(
>>318 )のコードを書いて、
>>321 のコードと簡易プロファイラ(QueryPerformance*)で比較した結果、
大体5:8という結果が出ました(両者最適化済)。
個人的な予想だと1:10位だったので、sprintfは全然overheadになってない感じです。
やっぱり実際profileを取ってみないと、本当のボトルネックはわかりませんね。
326 :
デフォルトの名無しさん :2001/03/09(金) 12:38
下のコード、DVDの暗号を解除するコードなそうなんですけど、
これこそトリッキーなコードだと思いませんか?(笑
#!/usr/bin/perl -w
# 526-byte qrpff, Keith Winstein and Marc Horowitz <
[email protected] >
# MPEG 2 PS VOB file on stdin -> descrambled output on stdout
# arguments: title key bytes in least to most-significant order
$_='while(read+STDIN,$_,2048){$a=29;$c=142;if((@a=unx"C*",$_)[20]&48){$h=5;
$_=unxb24,join"",@b=map{xB8,unxb8,chr($_^$a[--$h+84])}@ARGV;s/...$/1$&/;$d=
unxV,xb25,$_;$b=73;$e=256|(ord$b[4])<<9|ord$b[3];$d=$d
>>8 ^($f=($t=255)&($d
>>12 ^$d
>>4 ^$d^$d/8))<<17,$e=$e
>>8 ^($t&($g=($q=$e
>>14 &7^$e)^$q*8^$q<<6))<<9
,$_=(map{$_%16or$t^=$c^=($m=(11,10,116,100,11,122,20,100)[$_/16%8])&110;$t
^=(72,@z=(64,72,$a^=12*($_%16-2?0:$m&17)),$b^=$_%64?12:0,@z)[$_%8]}(16..271))
[$_]^(($h>>=8)+=$f+(~$g&$t))for@a[128..$#a]}print+x"C*",@a}';s/x/pack+/g;eval
[Hot Wired - 7行でDVD暗号を解読するプログラム]
http://www.hotwired.co.jp/news/news/technology/story/20010308302.html
327 :
デフォルトの名無しさん :2001/03/09(金) 12:42
見事にevalってますなぁ。
328 :
トリッキーの1 :2001/03/09(金) 14:18
>>326 ナイスネタ。
N88BASICと同様、1行にたくさん書いてあるのが逆に美しく感じられます。
evalっていかにもインタプリタって感じで、色々怪しい事が出来そうですね。
恥ずかしながら今まで知りませんでした。
1行80文字未満で7行以下。これを越えるのはRubyしか無理かな。
気合いの入ったRuby使いさん、チャレンジしてみませんか?(笑)
329 :
デフォルトの名無しさん :2001/03/09(金) 22:03
>>326 暗号を解除するプログラムが暗号ですね。
ageとくよ
331 :
デフォルトの名無しさん :2001/03/10(土) 21:06
RSAアルゴリズムを二行のPerlコードで表したのもらしい。 これって実用性あるのだろうか? print pack"C*",split/\D+/,`echo "16iII*o\U@{$/=$z;[(pop,pop,unpack"H*",<> )]}\EsMsKsN0[lN*1lK[d2%Sa2/d0<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<J]dsJxp"|dc`
332 :
デフォルトの名無しさん :2001/03/10(土) 21:49
これevaってるのはpack+の文字数をケチるためだけ?
333 :
デフォルトの名無しさん :2001/03/10(土) 23:31
>>321 sizeof(short) != 2 な処理系だと?
334 :
デフォルトの名無しさん :2001/03/12(月) 00:51
>>315 -316
なんだかスゲー笑った。
あげー
335 :
デフォルトの名無しさん :2001/03/25(日) 13:33
336 :
デフォルトの名無しさん :2001/03/25(日) 19:17
オタッキーなコード・・・・・・ もぇっもぇっ、さくらたん、とか、アニメ落ち、とか コメントに書いてあるのだろうか。
>>336 そうだよん
あとデバッグメッセージかな
OutputDebugString("こりすたん。。。ハァハァ")
338 :
335 :2001/03/27(火) 00:09
というか、swapという単語を辞書で引けって感じ・・・(^^;
ちなみに、
>>2 のマクロはa==bの時はデータ異常になるという蟲持ち。
341 :
335 :2001/03/27(火) 03:30
>>342 自分のスキルアップのためにも、人に聞く前に自分で計算してみな?
と、ごまかしておこう
昔、手書きで計算してみて納得したけど、もう忘れたよ(^^;;;
>>340 問題があるのは値が a==b のときではなく
swap(a,a)のように同じ変数を入れたとき、らしいぞ!
ゴ〜
344 :
デフォルトの名無しさん :2001/03/27(火) 08:42
a==bだと0になっちまうだろ。
345 :
SAGE :2001/03/27(火) 09:10
>>335 手計算してみれ。
(a,b) =
・(0,0) -> (0,0) -> (0,0) -> (0,0)
・(0,1) -> (1,1) -> (1,0) -> (1,0)
・(1,0) -> (1,0) -> (1,1) -> (0,1)
・(1,1) -> (0,1) -> (0,1) -> (1,1)
344も0になるかどうかやってみれ
347 :
デフォルトの名無しさん :2001/03/27(火) 17:29
348 :
デフォルトの名無しさん :2001/03/28(水) 00:15
349 :
347 :2001/03/28(水) 11:46
ふつうのコードでしょ。
a^=b^=a^=b
も理解できるはず。
a==bの場合は大丈夫。
&a==&bのときは両方0
>>343 としたのは間違い。
スマン
4 名前:デフォルトの名無しさん投稿日:2001/02/26(月) 22:11 そして3は浮動小数点演算に上記のマクロを使用して氏んだ
351 :
優しい名無しさん :2001/03/28(水) 15:45
^= ってなーに?
そもそも生のSwapなんてするか? 使うのはソートの時くらいじゃないの?
新しいネタきぼーん!!!
>>352 あぁ、あれかぁ。
じゃ「1」と「10」なら、「0001」と「1010」で、、、えーっと・・・
(0001,1010)→(1011,1010)→(1011,0001)→(1010,0001)
お!す、すげーーー。さんすく。
#^=を、"x乗"のことかと思って、何のことかさっぱりわからんかった。。。
#知らなかったのは、俺だけ?それとも、質問できずに困ってた人、いない?
356 :
デフォルトの名無しさん :2001/03/29(木) 01:07
いないと思われ。 てゆーかー、 > (0001,1010)→(1011,1010)→(1011,0001)→(1010,0001) の意味が不明。 1010 ^ 0001 = 1010 1011 ^ 0001 = 1010 とかいった表現にしてほしい。してほしい。。。。
357 :
デフォルトの名無しさん :2001/03/29(木) 02:58
>347 >xor eax, eax なつかしいね、これ。 代入で0クリアするよりも、何クロックか速いんだよね。
>>356 1010 ^ 0001 = 1010
↑お前が間違っとるやんけ。
>>355 は (a,b) の変移を1行で書いたのだろ。
goto文をつかわずにネストの深いfor文から抜け出す方法
↑return
361 :
デフォルトの名無しさん :2001/03/29(木) 16:57
↑longjmp(藁
↑終了フラグでネスト毎にブレーク(w
363 :
347 :2001/03/29(木) 17:06
↑throw
364 :
347 :2001/03/29(木) 17:07
↑throw
協議の結果、returnを採用することにいたしました。 上司にはそのように報告し関数を一つ追加申請します。 ご協力ありがとうございました。
366 :
デフォルトの名無しさん :2001/03/29(木) 19:10
俺が感心したのは次の半透明演算。ビット演算って奥が深いね。 RGB各5bitの16bitピクセルデータc0とc1の半透明演算。 c = (c0 & c1) + (((c0 ^ c1) & 0x7bde) >> 1);
367 :
デフォルトの名無しさん :2001/03/30(金) 00:36
>>366 うーん。ちょっと方向が違うかも試練がラスターオペレーションコードも
奥が深いね。3項のヤツ。。。
368 :
デフォルトの名無しさん :2001/03/30(金) 01:58
>>211 古いネタなので再掲
>Z80アセンブラデ ジサツプログラムヲ ツクレ
> メモリクウカンハ 0-FFFFh スベテ RAM
> ソノルーチンヲ ヨブト RAMエリア スベテ 0クリア
> ルーチンハ リロケータブル デアルコト
> スグ コタエラレルヤツハ カクナ
誰も答えてないようなので・・・・・
LD BC,0
LD HL,0 ;なくてもよい
LD E,L
LD D,H
INC DE
LD (HL),0
LDIR
ここはプログラムっぽいのならなんでもいいのかな? echo10回実行のシェルスクリプトってこう書くよね #!/bin/sh foo=1 while [ "$foo" -le 10 ] do echo hogehoge foo=$(($foo+1)) done これをスマートに出来るかな? bashなんでrepeat命令は無しです
#!/bin/sh ruby -e '10.times { print "hogehoge\n" }'
371 :
デフォルトの名無しさん :2001/03/30(金) 09:41
>>369 #!/bin/sh
echo hogehoge | head -10
372 :
デフォルトの名無しさん :2001/03/30(金) 09:41
>>369 #!/bin/sh
yes hogehoge | head -10
これは間違い。スマソ。
>368 HLの初期値がLD (HL),0やLDIRを指してると失敗するぞ まあ普通はそんなとこには置かんが‥
375 :
デフォルトの名無しさん :2001/03/30(金) 10:09
>>369 #!/bin/sh
for i in 0 1 2 3 4 5 6 7 8 9; do echo hogehoge; done
376 :
368 :2001/03/30(金) 12:46
>>374 そっか、じゃあ
LD HL,LDIRの次
とすれば完璧!
>>369 コピペです。ちょっとすっきり
#!/bin/sh
for i in 'seq 10'; do echo hogehoge; done
可変個の引数を取るshスクリプトで、引数それぞれに処理を行うとき、 while [ $# -gt 0 ] do 処理 $1 : shift done これって常識?
こういうリスト操作を考えたんだけど・・・ すでに前例があるのか知ってる人いない? typedef struct DLList_ { struct DLList_ *prev, *next; } DLList; void Ope(DLList *a, DLList *b) { b->prev->next = a->next; a->next->prev = b->prev; b->prev = a; a->next = b; } /* 注:以下の説明で {12345} の様に表記されているものは double linked list を意味する。つまり、5->next は 1 となる。*/ #define Merge(a, b) Ope(a, b) /* A の要素 a の後ろに b を追加する。 引数: A={12345}, a=3, b={678} 結果: A=={12367845} */ #define Divide(a, b) Ope(b, a) /* A の要素 a から b までを削除する。 引数: A={12345}, a=2, b=4 結果: A=={15}, a=={234} */
381 :
デフォルトの名無しさん :2001/03/31(土) 16:52
>>379 一つの関数で、リストへの追加と削除を済ましてしまうという
ところがミソにゃのか!?
ただ、あらかじめprev,nextメンバは自分自身を指すようでない
とダメっぽいので
typedef struct DLList_
{
struct DLList_ *prev, *next;
DLList_(){
prev = next = this ;
}
} DLList;
とすると、より(他人が見て)分かりやすいにょ。(C++になるけど)
>>381 そーゆー事。
もちろん要素が単独の場合、それらの prev,next は自分自身を
指す事を想定しています。
>>382 やっぱりそーゆー事でしたか。
もう一回、見直したけどこれは安全に使える部類だあね。
例にもある通りマクロを使えば、一瞬意味不明に思える
コードも隠蔽できるし。。
これから作ろうとしてるプログラムでちょうどリンクどリスト
使う予定だったので、さっそく使って見るなりよ。
384 :
デフォルトの名無しさん :2001/04/05(木) 19:52
ポリンキーなコード
385 :
デフォルトの名無しさん :2001/04/05(木) 20:15
>>378 >>380 常識はこうだろ。
for i in "$@"; do echo $i; done
386 :
デフォルトの名無しさん :2001/04/07(土) 01:49
スパンキーなコード
オタッキーなコード < all
388 :
デフォルトの名無しさん :2001/04/07(土) 12:39
390 :
デフォルトの名無しさん :2001/04/08(日) 17:14
>>366 それって半透明 の何? 飽和加算? 飽和減算?
ちなみに RGB全て 10000 と RGB全て 01111 を「半透明」すると
RGB全て 01111になるよーな…? 飽和加算でも飽和減算でもない…と思う。
どっか間違ってなければ。
391 :
デフォルトの名無しさん :2001/04/08(日) 17:30
>>390 透明度50%の半透明合成だろ。
要するに (c0+c1)/2 をRGBの各チャンネルで行っている。
392 :
デフォルトの名無しさん :2001/04/08(日) 18:46
>>390 あんがとさん
うかつだった>俺
そんなことやっても 1/2できるんだ…
そーいや俺 半々半透明 って
((c0 & mask) + (c1 & mask)) >> 1
しかやった事無かった。
393 :
デフォルトの名無しさん :2001/04/08(日) 19:28
394 :
デフォルトの名無しさん :2001/04/10(火) 02:57
俺もそう思う。
並列演算とか考えなければ、単純な演算回数は
>>366 が5回、
>>392 は4回で済む。
395 :
デフォルトの名無しさん :2001/04/10(火) 09:02
MSBが空きビットならOKだけどさ
396 :
デフォルトの名無しさん :2001/04/10(火) 09:17
7で割った余り
int mod7(int x)
{
while( x >= 14 ) x = ( x
>>3 )+( x&7 ) ;
if( x>=7 )x-=7;
return x;
}
397 :
デフォルトの名無しさん :2001/04/10(火) 09:25
swap(a,b) {a+=b;b=a-b;a-=b;}
398 :
デフォルトの名無しさん :2001/04/10(火) 22:11
399 :
392 :2001/04/11(水) 02:15
>>395 ,398
あぁっ 本当だ。
じゃー x86でアセンブラ使える人とかは
キャリフラグ使ってね、てことで…
だって もう半々半透明なんて使わないもん、俺。
400 :
デフォルトの名無しさん :2001/04/11(水) 10:02
C++による例外プロテクト delphiの try..except代わり void proc(int no) { struct except{ except(int no){ // 関数の実体をここに書く } ~except(){ //例外が起きても必ず実行したい事を書く } } } infunc(no); }
401 :
デフォルトの名無しさん :2001/04/12(木) 09:56
>>399 RGBのうち一番上のRはキャリー使えるけど、GとBはキャリー使えないじゃん。
>>366 はR,G,Bすべて5bitの精度を保っている。
402 :
392 :2001/04/12(木) 10:27
>>401 あぁ、演算結果は5bitでも
「4bit同士の足し算」って所が問題なのか。
それはまったく そのとーりです。
月光仮面おじさん登場!!!
ホームページを作ったものの、まったくアクセスが上がらな
くて悩んでいる人のためにお役に立ちましょう。
効率よく宣伝できる共有宣伝掲示板を18個設置しました。
全部宣伝して回ればなんと1,000以上の掲示板にカキコしたこ
とになり即、効果が期待できます。さらに共有掲示板の隠し
リンクを発見してそれらも全部宣伝して回ると計2,000以上の
掲示板にカキコしたことになり、さらにアクセスアップを期
待できます。もう、今日からアクセスが無くて悩むことは無
いです。今すぐここからアタックアタック!!
http://home9.highway.ne.jp/cym10262/
トリッキーじゃない。ばいばい。
405 :
デフォルトの名無しさん :2001/04/13(金) 18:30
406 :
デフォルトの名無しさん :2001/04/14(土) 21:10
宿題でもいいからなんかネタないかなぁ
408 :
デフォルトの名無しさん :2001/04/14(土) 21:59
こ、これは・・・! すごいな。 どうやってこんなの考えられるんだろう・・・ ソースを貼り付けられないのが残念だ。
すげえ、
>>407 1シーケンスポイント内で複数の副作用が
起きているように見えるのは気のせいか?
411 :
410 :2001/04/21(土) 10:44
あちゃー 余計な事書いたら一瞬にしてスレが沈んでしまった。 結構面白い(ものが出てくる可能性がある)スレだったのに・・・ もしかして俺って、スレ殺しの達人?
412 :
デフォルトの名無しさん :2001/04/21(土) 10:51
>>407 なるほど。級数展開をやってるのね。大きなAAほど
値が正確になっていくのか。
413 :
デフォルトの名無しさん :2001/05/01(火) 03:44
すごいねこのスレ もったいないからあげておこっと
414 :
デフォルトの名無しさん :2001/05/01(火) 09:35
Cで typedef void (*VirtualFunc)(void*); typedef struct { VirtualFunc hello; } Animal; typedef struct { VirtualFunc hello; Animal* super; } Cat; void helloAnimal(void* self) { printf("...\n"); } void helloCat(void* self) { printf("にゃお〜\n"); } Animal* newAnimal() { Animal* animal = (Animal*)malloc(sizeof(Animal)); animal->hello = helloAnimal; return animal; } Cat* newCat() { Cat* cat = (Cat*)malloc(sizeof(Cat)); cat->super = newAnimal(); cat->super->hello = cat->hello = helloCat; return cat; } int main() { Animal* pet = (Animal*)newCat(); pet->hello(pet); return 0; } とかやってた人いない?
415 :
デフォルトの名無しさん :2001/05/03(木) 02:01
あーげっ
>>414 さすがにそこまではしないなぁ。
多態までCでやると手間とか可読性とかいろいろと。
構造体を作って、その構造体を第一引数に取るように関数をつくって
メンバ関数ちっくにするぐらいはやるけどね。
416 :
>414 :2001/05/03(木) 02:17
俺もCで
>>414 みたいな多態まがいまでやったけど、手間掛かるね。
継承、多態を実装する場合スタックに作れないのはいいんだけど。
Cでやる場合、
・自前でコンストラクタデストラクタ起動する手間。
・インスタンス毎にメソッド関数のポインタの領域が取られる。
(C++のvirtualの様にはいかない)
まあ関数テーブルをstaticな所に置いておけばいいんだけどね・・。
・自分しかメンテする人がいない。
言い換えれば、教える手間が掛かる(苦笑
C++嫌いでここまでやるなら、
Objective-Cのトランスレータ使った方がいいかも。
(スクリプト〜のスレにリンクあります)
417 :
416 :2001/05/03(木) 02:23
ヒープベースでいいなら、インスタンスのチェインを作ったり、 マクロで変換したり色々楽する方法はあるけど、 純粋なCの使い方じゃないんだろうなあ・・ ↑に追加するなら、あと、 ・コンパイラが型保障してくれない。 これが痛い。どうしても(void*)使いまくる事になるからね。
418 :
416 :2001/05/03(木) 02:30
よって完全を喫したい場合、デバッグ時などで メソッド関数の入り口で if (self->classid == 〜) とかする必要がある。 利点は ・OO(風)実装の質加減を自分で決定できる。 ・Cは言語仕様が小さいので環境を選ばない。 ・どうせ(void*)主体なのでC++の様な大掛かりなtemplateは必要ない。 ぐらいかな。
欠点追加 ・インライン展開してくれない。(inlineキーワードが使えない) アクセサとか、なにも考えずに定義できない。 gccやVisualC++ならCでも__inline__使えるので、 使えない処理系毎にマクロで切り分けるはめに・・ ・本質と関係無いコードの量が多くなる。 モチベーションが低下する。しょうがないんだけど。 思考するための言語の使い方としては最悪。 だから純粋にOO可能な言語でプロトタイプ作って C移行やるのがベストかも。(どうしてもやるなら)
420 :
416 :2001/05/03(木) 03:01
純粋OO言語→Cのトランスレーターがあればそれ使うのが一番良い。 (ありがちな問題として「純粋OO言語」のライブラリ群をどうやって Cへ変換するるかだけど、それぐらい無かったら自分で作る。) やっぱりCで自分で書くのは疲れるよ。無茶するのは健康に悪い。
421 :
416 :2001/05/03(木) 03:27
楽する方法 typedef enum {method1, method2, method3 ...} method_t; static struct { methodid_t id; methodproc_t } method_tbl { method1, method1_proc method2, method2_proc : }; dispatch(obj, method1, param...); こんな風にメッセージの受け口は全部dispatchにするとか。 method探索の効率はhashとか使えばそれほど悪くならない。 必要ならマクロかなにかでdispatch->直呼びに変換する。
422 :
416 :2001/05/03(木) 03:39
楽する方法その2 ブロックの間だけ使用するインスタンス群の自動デストラクト ヒープベースでのみ使用できる。 インスタンスのチェインを作る必要がある。 { handle_t h = enter_scope(chain); obj_t obj1 = newobj(chain, classid1); obj_t obj2 = newobj(chain, classid2); obj_t obj3 = newobj(chain, classid3); ; leave_scope(chain, h); obj1/2/3の自動デストラクト } もちろんハンドルを保持すればデストラクトを持ち越す事ができる。 この辺は実際に使って有効だった手法。
423 :
414 :2001/05/03(木) 03:56
>>414 みたいなのは、C++コンパイラが買えなかった頃
LSI-C試食版でC++に憧れつつやってました(厨房だ
>>415 第一引数を構造体にするのは安上がりにC++気分が味わえて実用的ですよね。
424 :
414 :2001/05/03(木) 03:56
>>416 -422
ぐわっ。なんかすごいです。ここまですれば実戦でつかってもメリット多かも
>>422 なんかはC++でもブロックを越えて、半自動的にヒープの
オブジェクトをデストラクトするのに便利かも、ですね
一般的には言語にない機能をカバーしようとしてトリッキーになってしまう
ことが多い気がします。
むかーしの雑誌で、例外未サポートのC++コンパイラ(ワラ)でTRY/CATCHマクロ
を実装する(大域jumpをつかう)記事が出てたけどトリッキーだった。
私はC++使ってるとgarbage collectionがないせいでトリッキーになることが
多々あります。頭悪いのかも。
自分で書いたcollection classにひたすら参照カウンタを上げ下げする
コードを追加してるとなんのクラスを書いてるのか分からなくなってきます。
>>416 なんか凄い参考になった気がするのでage
426 :
デフォルトの名無しさん :2001/05/04(金) 04:02
オトッキー
427 :
1 :2001/05/04(金) 19:59
おひさです。実務が忙しくて。 多態って聞いたことないのですが、どんなのですか? 例示してもらえません?
428 :
デフォルトの名無しさん :2001/05/06(日) 22:12
オトッキーってファミコンのゲーム?
429 :
デフォルトの名無しさん :2001/05/25(金) 23:54
Java で define がない。 似たようなことはできるけど、面倒。 もっとラクにdefine する方法ない?
430 :
デフォルトの名無しさん :2001/05/26(土) 00:01
schemeにあるよ>define
432 :
429 :2001/05/26(土) 00:08
>>430 前はそれやってました
(自作プリプロセッサもどきでコンパイル前にマクロ置き換え)
でも、この間事故でえらい目にあったので
なるべく標準的な機能を使いたいんだ
defineある言語に乗り換えれば?>432
>>433 ネーチブなJavaVMが載ってるマシンで動かすものなので
Java以外で動かすのはもったいないのだ。
定数のdefineならインターフェイスに書けば? 他のdefineは目的によっては不可能じゃない?
436 :
429 :2001/06/02(土) 01:48
>>435 ありがとう。インターフェイスの勉強してきました。早速使ってみます。
トリッキーな手法があるかなーと思って期待してたんだけどね。
437 :
デフォルトの名無しさん :2001/06/02(土) 09:04
このスレタイトル、どうしても取り憑きーなコードに見えてしまうぞ。 バグが取り憑いたコードならいくらでもあるのだが。
439 :
デフォルトの名無しさん :2001/06/03(日) 13:24
よく、0と1を交互に使いたいときは a = 1 - a ; などとやりますが、これを拡張して a = 2 - a ; としますと、 a=0または2 なら 2または0 になり、a=1 なら 維持します。
440 :
デフォルトの名無しさん :2001/06/03(日) 16:06
漏れの感覚だと -1,0,1 の三状態を使うなあ a=-a で済むし
442 :
439 :2001/06/05(火) 05:55
>>441 すみません。そっちの方がかっこいいですね・・・
修行しなおしてきます。次は負けん!
あと 0 と 1 の交換は a=1-a よりも a=a^1 を使うなあ アセンブラコードにしてみれば解ると思うけど まあ、用途によっては a=2-a の方が便利な時もあるっしょ
444 :
デフォルトの名無しさん :2001/06/10(日) 13:14
445 :
デフォルトの名無しさん :2001/06/10(日) 17:41
>>444 そういえば前も書いたけど、それって立派なルール違反を犯しているんじゃないの?
トリッキー以前の話だろ。問題外。
446 :
デフォルトの名無しさん :2001/06/10(日) 18:50
思いっきりパクリやん
448 :
デフォルトの名無しさん :2001/06/10(日) 19:58
その昔ほとんど誰もつかわなかったが、よく考えられたと感心した例 平均:a$=right$("00"+hex$(b),2) WIZ :a$=right$(str$(100+b),2) いまのVBならこうか 通常:a=format(b,"00")
449 :
デフォルトの名無しさん :2001/06/10(日) 21:48
>>443 アセンブラコードにしてみてもわからんのだけど、
xor a, 1 と sub 1, aで何か違う?
450 :
デフォルトの名無しさん :2001/06/10(日) 22:15
>>449 sub 1,a ってアセンブル出来んだろ。
451 :
デフォルトの名無しさん :2001/06/10(日) 22:24
>>450 3オペランドならできんこともない。
lui r0,r1,1
sub r1,r2,r2
453 :
デフォルトの名無しさん :2001/06/10(日) 22:50
>>452 どうちて?
lui r0,r1,1
xor r2,r1,r2
とコストは変わらんでしょ。
X86ならXORの圧勝だが。
>>446 パクリつーか、iocccに応募した本人みたいよ。
sub 1,a という概念自体に強い衝撃を覚えたよ(ワラ
結果は 1 に代入されるんだろうか…これも時代かねえ
>>453 x86 ならじゃなくて逆に mips くらいなもんなんじゃないの?
i386 でも最適化すれば高々二倍の差しかなさげだ [a=1-a] ⇔ [a=a^1] DEC EAX ⇔ XOR AL,1 NEG EAX まあコンパイラがこんなコードを吐くとは思えんが
458 :
デフォルトの名無しさん :2001/06/11(月) 04:30
そろそろ前みたいにトリッキーなコード希望age
ていうかキミが提供してちょ>458
>>459 おれも思った。
ところで、GoFのDesignPatternsがトリックの宝庫に思えてしまう
おれって厨房?
461 :
デフォルトの名無しさん :2001/06/11(月) 06:14
sub getwday { local($year, $mon, $day) = @_; local($wday); if ($month == 1 || $month == 2) { $year--; $month += 12; } $wday = int($year + int($year/4) - int($year/100) +int($year/400) + int((13*$month+8)/5) + $day) % 7; return $wday; } メジャー過ぎてトリッキーに感じないけれど、Zellerの 公式(曜日の算出)
>>461 >((13*$month+8)/5) + $day) % 7
イカス!
これそんなにメジャーだったんだね。知らなかった。
>>463 最近の RISC は大体そうなんかな?
ていうか、何に使われてるチップ?
Intel Architecture-64bit
466 :
デフォルトの名無しさん :2001/07/12(木) 13:31
もったいないからage
467 :
デフォルトの名無しさん :2001/07/14(土) 03:39
みっちゃんみちみち
468 :
デフォルトの名無しさん :2001/07/14(土) 10:02
>>424 大域ジャンプと、スタック取得を使うと簡単な
マルチスレッドもどきが作れますよ。どこでも動いて
便利。組み込みスレでは当たり前だ!と叩かれたけど
AnsiCで書けるのは面白いと思うんだけどね。
469 :
デフォルトの名無しさん :2001/07/14(土) 10:10
> 大域ジャンプと、スタック取得を使うと簡単な > マルチスレッドもどきが作れますよ。 それって、co-routineすね。 POSIX Thread(pthread)を、 カーネルでthreadableじゃないOS(Unixとか)で実装する場合、 co-routineで実装するよね。
470 :
デフォルトの名無しさん :2001/07/14(土) 13:39
楽をするためにたまにやってしまう、「すべてのインスタンス」のset使用。 class T { static set<T*> instances; public: T() { instances.insert(this); }; ~T() { instances.erase(instances.find(this)); }; };
471 :
デフォルトの名無しさん :2001/07/14(土) 14:29
>>468 意味的にANSI-Cでは書けないと思うけど。
472 :
デフォルトの名無しさん :2001/07/14(土) 14:34
473 :
デフォルトの名無しさん :2001/07/14(土) 15:33
>>486 つーかANSIの範囲で書けるなら書いてみてくれ
474 :
デフォルトの名無しさん :2001/07/14(土) 20:30
475 :
デフォルトの名無しさん :2001/07/15(日) 10:11
>>474 DOSとかでマルチスレッドもどき管理するとき。
スレッド切り替えは陽に呼んでやる必要があるんだけどね。
>>470 ,475
デバッグに役立ちそう。イタダキマス。
そんなにトリッキーでもないような。
へっだ int _cre_tsk( void (*)(void), int ); /* タスクの登録 */ void _sta_tsk( void ); /* タスクの起動 */ void _wai_tsk( void ); /* タスクの切換 */
本体その1 #include <setjmp.h> #include <malloc.h> #include "rt.h" #define LMTTASK 5 /************************************************************************/ /* タスクリスト構造体 */ /************************************************************************/ volatile struct TASKLIST { jmp_buf buf; /* ジャンプバッファ */ int size; /* スタックサイズ */ int flg; /* タスク登録フラグ */ void (*name)(void); /* タスク登録関数 */ } tasklist[LMTTASK]; volatile int taskmax=1; /* 最大登録タスク数 */ volatile int crntid=0; /* 現在のタスク番号 */ /************************************************************************/ /* タスクの登録とジョブ制御 */ /************************************************************************/ _cre_tsk( void (*name)(void ), int size ) { volatile int id; tasklist[taskmax].name = name; tasklist[taskmax].size = size; crntid = ++taskmax; id = setjmp( tasklist[0].buf ); /* タスクスケジューリング(ラウンドロビン^^) */ if( id ){ if( ++id >= taskmax ) id = 1; crntid = id; longjmp( tasklist[id].buf, 1 ); } return( 0 ); }
本体その2 /************************************************************************/ /* タスクのスタート */ /************************************************************************/ void _sta_tsk() { alloca( --crntid ? tasklist[crntid].size : 1024); if( crntid > 0 ){ //crntid -= 1; tasklist[crntid].name(); }else{ crntid = 1; longjmp( tasklist[1].buf,2 ); /* タスクの起動 */ } } /************************************************************************/ /* タスクスイッチャ */ /************************************************************************/ void _wai_tsk() { if( setjmp( tasklist[crntid].buf ) ){ return; }else if( tasklist[crntid].flg ) { longjmp( tasklist[0].buf, crntid ); } tasklist[crntid].flg = 1; _sta_tsk(); }
使用例。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <setjmp.h> #include "rt.h" int main( void ); void task1( void ); void task2( void ); void pr( int, int, char* ); main() { if( _cre_tsk( task1, 0x700 ) ); if( _cre_tsk( task2, 0x700 ) ); /* 開始ルーチン */ _sta_tsk(); return( 0 ); } void task1( void ) { int i=0; char work[10]; for(;;){ sprintf( work,"%d", i-- ); pr( 5,10,work ); _wai_tsk(); } } void task2( void ) { int i=0; char work[10]; for(;;){ sprintf( work,"%d", i++ ); pr( 25,10,work ); _wai_tsk(); } } void pr( int x, int y, char *str ){ printf( "\x01b""[%d;%dH""\x01b""[0K%s" , y+1, x+1, str ); }
481 :
デフォルトの名無しさん :2001/07/18(水) 16:41
a += b -= (a = b-a); 加減算でのスワップってがいしゅつ? &a=&bだとだめだけど・・
482 :
デフォルトの名無しさん :2001/07/18(水) 21:55
>>474 必要ってわけじゃないけど、所有関係や参照関係すらない object を
数え上げることができるのがコード書くときに楽。あんまりトリッキー
じゃないのでスレ違いっぽいのは確か(可読性も高いよね)。
例えばドキュメント、ページ、その中の画像オブジェクト、というような
階層状の構造をもつ何かを編集するソフトで、特定の画像ファイルの消去等
の際には、ドキュメント→ページ→画像オブジェクト、アンドゥバッファ中
の画像オブジェクト、クリップボード上の画像オブジェクト、などいろんな
ところを見なくちゃならないでしょ。そういうときに「全ての画像オブジェ
クト」ってのを用意して手抜きするわけです。
>>481 a ^= b ^= ( a ^= b ) ;
整数型のスワップならこうだろう。
って、昔はアセンブラなんかでは良く使った手だな…。
>>483 アセンブラなら直接交換する命令を使ったが。
そんなのもないやつ?
486 :
481 :2001/07/21(土) 13:05
487 :
デフォルトの名無しさん :2001/07/21(土) 13:56
32bit signed int -> 16bit signed int に飽和させながら 変換するのでトリッキーというか、分岐を起こさせずにやる 方法ありませんか(Cで)。
488 :
デフォルトの名無しさん :2001/07/21(土) 14:46
>>487 符号無しなら簡単だけどねえ
原理としては最初に16bit左シフトして、
あちこちシフトしながら or 繰り返せば
0か オール1になるから、 ORすればクリップ出来る
符号付きで同じ方式を使うとすると、 17+15に分けて
上位17bitがオールゼロか オール1なら 0に
でなければ MSBによって $7fffか$FFFFを作って
OR するという事で
シフトと論理演算だけで出来ない訳じゃないけど厳しいねえ
×最初に16bit左シフト ○最初に16bit右シフト
全然ダメ 488 は間違いね 恥ずかしい・・・
491 :
デフォルトの名無しさん :2001/07/21(土) 15:23
>>487 どういうことだかわからないんだけど、こうしたいっていう具体例を
挙げてもらえる?
492 :
488 :2001/07/21(土) 15:32
アセンブラなら出来た Cでも書けない事はないけど short clip16(int x) { short c; _asm { mov eax,x ; cdq ;//edxに符号拡張して sar eax,15 ;//桁溢れがあるかどうか xor eax,edx; add ax,0ffffh; mov ax,0 ;// adc ax,-1 ;//桁溢れがあれば0 でなければ-1 not ax xor dx,0x7fff;//8000か7fffか xor dx,word ptr x and dx,ax xor dx,word ptr x mov c,dx }; return c; }
ええと課題は short clip16(int x) { if(x> 0x7fff) return 0x7fff; if(x<-0x7fff) return -0x8000; reutnr x; } を 分岐を使わず書け なんだと思うのだが
494 :
デフォルトの名無しさん :2001/07/21(土) 15:39
>>487 491 さんの言う通り、いまいちわからんのぉ。
Cレベルで分岐しない・・・って事じゃないよね?
そうするとターゲットプロセッサとコンパイラ依存
の問題だから、環境書かないとダメですぞ。
たとえばこの問題、ARM とかならCで分岐使ってても、
コンパイル後は分岐無しになったりするし。
汎用的な答えとして、
・テーブル引く
ってのはあるけどね
495 :
デフォルトの名無しさん :2001/07/21(土) 15:41
分岐なしか。 if文なし、ならできるけど・・・
496 :
デフォルトの名無しさん :2001/07/21(土) 15:53
result=(short)((h&0x7fff)|(h
>>30 )|(((h&0x7fffffff)<0x7fff)*0x7fff));
こんな感じ?検算してないけど。
条件文入ってるからダメか。
497 :
496 :2001/07/21(土) 15:54
result=(short)((h&0x7fff)|(h
>>30 )|(((h&0x7fffffff)>0x7fff)*0x7fff));
の間違いでした
>>496 ,497
内容の確認はしてないけど、その手なら MIPS でも分岐命令は
出なさそう。
出題者の意図次第ですが、
>>492 さんの解答がいいところを突いて
る予感はします。これも内容確認してませんが(w
>>498 492はちっとなげーし、なによりインラインアセンブラは歓迎されねーだろ
500 :
488 :2001/07/21(土) 16:55
じゃ、同じ方式で、 途中、0なら0 でなければ -1 の部分が綺麗じゃないけど
short clip163(int x)
{
int f=x
>>31 ;
int w=( f ^ x )
>>15 ;
w|=w<<16; w|=w
>>8 ; w|=w
>>4 ; w|=w
>>2 ; w|=w
>>1 ;
return (short)( ( ( (f^0x7fff)^x) & w) ^ x);
}
>>497 は残念だけど負数の時にうまくゆかないよ
絶対値はabsマクロが分岐無しに展開してくれるから
absは有りだよね
501 :
497 :2001/07/21(土) 17:08
>>500 わりい。ちょっと直す。
result=(short)((h&0x7fff)|((h
>>31 )<<15)|(((h&0x7fffffff)>0x7fff)*0x7fff));
これでだいじょぶかな?
502 :
488 :2001/07/21(土) 17:19
確かに条件判断 >0x7fff は分岐に展開されないから 利用せて貰うと
これが c でもアセンブラ並なコードが出た
return (short)( ( ( ( (x
>>31 ) ^ 0x7fff)^x)
& (-( abs(x) > 0x7fff)) )
^ x);
>>501 まだダメ 負数だとオーバー時 -1 になってしまうよ
クリップだから -$8000 にならないと
503 :
497 :2001/07/21(土) 17:24
>>502 あはは。寝ぼけてた。ごめん。・・・旅に出ます。
a xor b and c xor b
は cが1なら a xor b xor b = a cが0なら b
という事でビット毎の代入パターン
( (x
>>31 ) ^ 0x7fff は 0x7fff+(x<0)
>>499 じゃあ自分で、ってんで作ってみたぞ。
int clip (int a)
{
unsigned int b, res;
b = a + (a & 0x8000);
b = ((b >> 15) - 1) >> 31; // 0:over 1:not over
b ^= 1; // 1:over 0:not over
res = a | -b; // over なら 0xffffffff
res += (b << 15); // over なら 0x8000 加算 -> 0x00007fff
res ^= -(a >> 31 & b); // 元が負でoverなら 0xffffffff で xor -> 0xffff8000
return (int)res;
}
これも、もちろん内容の確認はしていない(w
くどい様だけど、条件次第だからねぇ。
abs がどう展開されるかもコンパイラ&プロセッサ次第。
たぶん、「算術&論理演算だけで片付ける」ってのが、
出題者の意図だとは思うが。
たぶん、CPUがx86系で 条件判断が入ると遅いという事じゃないのかな? それとも命令数を数えてコーデングしてて、分岐が入るとメンドクサイから 嫌だとか 条件によって代入とか 条件によって次命令スキップなんて 命令を備えてるCPUも多いんだけどね。
スマソ
x86系でPCMのクリッピングに使います。
たしかにアセンブラレベルじゃMMXやcmovcc使えばいいし、
Cコンパイラでもgccとかは自動的にcmovcc使ってくれるのでよいのだが。
それとはちょっと別に「分岐を起こさせずに」ってのは、実質的な
意味よりも、
>>505 の言うように「算術&論理演算だけで片付ける」
ってのでの方法をちょっと知ってみたかっただけなので・・・。
508 :
デフォルトの名無しさん :2001/07/21(土) 18:45
せっかくだからガンガントリッキーに攻めようぜ
今の所
>>502 の
(short) ( ( ( ( (x
>>31 ) ^ 0x7fff)^x ) & (-( abs(x) > 0x7fff)) ) ^ x)
これが一番綺麗だね
でも
>>502 のコードは条件が入ってて
こいつが setcc al に展開される
その後 eaxを使うと パーシャルレジスタストール に引っかからないのかな?
まあパーシャルレジスタストールなんて数年したら
そんな事もあったなあなんてレベルの話なんだろうけど
速度はこのスレじゃ関係ないでしょ いかにトリッキーかのスレなんだから
>>511 いや、いかにトリッキーかというのはあとから付いてくるものだよ。
なんつーか、「こんな方法があったのか!」っていうヒザポンな
解法をみんなで思いつくのが本来の趣旨 のような。
わき道にずれてごめんsage
abs はだいたいマクロによって 1) 符号によって -1を作って 2) 1) XOR 元の値 3 2)−1) の3命令に展開されるよね CMOVccのような条件転送 があれば 1) 負数にして 2) 符号が負数なら元を代入 って2ステップで出来るけど
514 :
デフォルトの名無しさん :2001/07/21(土) 20:08
こういう事かな
unsigned iabs(int a)
{ int f=a
>>31 ;
return (a^f)-f;
}
だとすると -fが無くても1しか違わないから
>>509 は
int f= (x
>>31 );
(short) ( ( ( ( 0x7fff-f ) ^ x ) & (-( ( x ^f ) > 0x7fff)) ) ^ x)
せめてこういうふうに書いて欲しいな //Selectの各bitが 1なら aを 選択 0 なら bを ビット単位に 選択 #define BitMask(a,b,Select) ( ( (a ^ b) & Select) ^b) (short) BitMask( 0x7fff-f , x , -( ( x ^f ) > 0x7fff ) )
516 :
デフォルトの名無しさん :2001/07/21(土) 21:02
/* ぽりんきーなコード */ if(a*a+b*b==c*c) printf("三角形の秘密はね、");
フェルマーの定理でも証明するつもりか?
>>516
PCMのクリッピングなんで、+32767〜-32768からはずれた、 あまり大きな数値や小さな数値は絶対に入ってこないので、 数値を最初に32768を足して、unsigned int 32->unsigned int 16 の 飽和変換を行ってからまた 32768 を引こうかと思ったんだけど unsigned int 32->unsigned int 16 の飽和はどうしようか・・・ 教えて君ですまんそ
あ、なんでもないです518は忘れてください
一応、条件演算子無しで書いてみた。
short clip16(int x) {
int f=(x
>>31 );
x ^= f;
x = (((-(x&-0x8000))
>>31 ) | x) & 0x7FFF;
x ^= f;
return (short)x;
}
>>518 ええとね、PCMのクリッピングで悩む必要はないよ。
44.1Kだから1秒に およそ9万回しかクリッピング処理は回って来ないからさ
それより、その処理本体で悩んだ方がいいと思う
皆さん凄いですね。 フリーソフトの作家さんが、セミコロンを使わないでCのプログラムを 書いて遊んでいたのを思い出しました。
523 :
デフォルトの名無しさん :2001/07/24(火) 02:31
>>522 そんなことできるのかー。
Perlなら簡単そうだけど、Cで出来るのか。
trigraphつかえばできそうだけどそうじゃないのかな
ううーん すべての 式; はif(式){}で置き換えられるとして 変数宣言はどうするんだ
変数は引数でもつかってりゃいいか void sub(char *msg) { if(msg = "Hello world!\n", printf(msg), 0) {} } int main() { if(sub(0), 0) {} }
あmainのreturn書いてないやw returnが書けないのか・・・ まぁ関数から値を返すときは関数に変数のポインタを渡せばいいけど mainにreturnが書けないのはイタイ
>>525 -527
トリッキー、つーかただの嫌がらせだな(w
529 :
デフォルトの名無しさん :2001/07/29(日) 18:03
// 指定したアドレスにクラスオブジェクトを構築し、 // コンストラクタを適用する例 class CADDR_INIT { public: // カスタマイズした new と delete void *operator new(size_t size,void* addr){return addr;} void operator delete(void* pMem,void* addr){} // 通常の new と delete void *operator new(size_t size){return ::operator new(size);} void operator delete(void* pMem){::delete(pMem);} }; class TA : public CADDR_INIT { int a,b; public: TA(){a = 1,b = 2;} }; void func() { TA* p = (TA*)0x12345678; new(p) TA; // p->a = 1、p->b = 2 になる } ■どんな時に利用するか? ・ディスク媒体等から読み込んだデータにコンストラクタを適用したい時 ・クラスオブジェクト配列の一部だけにコンストラクタを適用したい時 ・メモリマップドIOをクラスオブジェクトに見立てて利用したい時
ウイッキーなコード
add word ptr[ptr+0xxh], reg ptr: jmp 0xxxxh
533 :
デフォルトの名無しさん :2001/07/30(月) 04:44
アセンブラ覚えたいょぅ
>>533 Delphiでもやってみたら? 俺は あれのCPU窓で覚えたよ。
536 :
デフォルトの名無しさん :2001/07/30(月) 17:22
>>535 VCってなに?VirtualCall?
XCHG EAX,ECX JECXZ LABEL
>>536 正解!詳細を知りたければ、エロゲー板へどうぞ!
540 :
デフォルトの名無しさん :2001/08/08(水) 03:00
ヴォヤッキーなコード
541 :
:2001/08/08(水) 03:09
JECXZって80386以降か。 よくそんなニーモニック知ってるのぅ。
TEST EAX,EAX JZ LABEL と較べてフラグを保存できる上、1バイト小さい。
543 :
デフォルトの名無しさん :2001/08/10(金) 03:00
あげ
544 :
デフォルトの名無しさん :2001/08/23(木) 21:58
2分木を再帰やスタックを使わないでトラバースする方法って 無いでしょうか?(昔どこかでできるという様な話を聞いたんですが)
545 :
544 :2001/08/24(金) 00:24
ちなみに、葉に親ノードを専用に保持する領域を作ったり、 紐付き2分木の様なnullポインタを使う方法では無いらしいです。 どなたかご存じないでしょうか。
>>544 rootをarr[1]に入れて、arr[k]の左の子をarr[2k]、右の子をarr[2k+1]に
入れておいて arr[] を一気に舐める、というようなやり方のことかな?
547 :
546 :2001/08/24(金) 01:15
えーと、rootがarr[0]で、arr[2k+1] と arr[2k+2] に子ノードを 置いてもいいんだけど、コードが読みにくくなっちゃうので 俺は546のように置いている。
548 :
544 :2001/08/24(金) 02:04
>>546 いえ、配列を使う(実質スタックですよね?)のでは無く、
左右のどっちかのノードの書き換えのみで行なう様な感じだったと
思うのですが・・
普通にやると、片方のノードはループに書き換えられますが、
もう片方を辿る時に、例えば左辺を親ノードと入れ替えるとか、
そんな感じのコードになると予想しています。
理屈ではできそうなんですけど。
549 :
546 :2001/08/24(金) 02:17
>>548 トラバースするときにえっちらおっちらコピーするわけじゃなくて、
最初から配列に組んじまえばいいんですよ。
(要素の数が劇的に変わったり、左右のバランスが悪いときには
メモリ効率が落ちるが)
左右の子へのポインタを2つとも持たなくていい分、効率がいいこともあるよ。
(要素へのポインタの配列で組むと、ポインタ一個分しか節約にならんけどね)
550 :
デフォルトの名無しさん :2001/08/24(金) 02:19
>>549 結局ヒープソートの基礎以上の内容ではなさげだが……?
ノードには印がつけられるとし、最初はすべてのノードが無印だとします。 ノードをたどりながら印をつけ、そのノードを訪れたとして出力する。 ツリーの末端まできたらそのノードは削除する。 スタックが使えないのでバックトラックできないので、 その後ふたたびルートから繰り返す。 が、印のついていないノードにきた場合は印をつけ、 そのノードを訪れたとして出力する。 ノードが無くなったらトラバースの出力は終わり。
552 :
デフォルトの名無しさん :2001/08/24(金) 08:33
>>544 そのアルゴリズム、読んだ覚えがあるけど
どこで読んだか思い出せない・・・(鬱
確か goto をやたら使っていた様な気がするけど違うかなぁ。
あと、Knuth が紹介していたような気もする・・・
554 :
デフォルトの名無しさん :2001/08/24(金) 13:20
555 :
544 :2001/08/24(金) 22:20
レスありがとうございます。
>>549 子ノードが親ノードよりも後に生成される事が決まっていれば、単純に配列の
添え字の比較で済みそうですが、ここでは単純にポインタで繋がった2分木を
想定しています。
>>551 辿った要素にマークを付けていくという発想は近いかもしれません。
そうすると、全ての要素に対してマーク用にフラグが必要になるのが
嫌な感じですが・・。
>>552 なるほどクヌースの例の本に載ってるのかな。
図書館で調べてきます。
556 :
デフォルトの名無しさん :2001/08/25(土) 15:55
こんなのどう? #include <stdio.h> void main(void) { typedef struct { int i[5]; } INT_ARRAY; INT_ARRAY a; INT_ARRAY b = { { 50, 2, 139, 3049, 8 } }; a = b; printf("%d %d %d %d %d\n", a.i[0], a.i[1], a.i[2], a.i[3], a.i[4] ); printf("%d %d %d %d %d\n", b.i[0], b.i[1], b.i[2], b.i[3], b.i[4] ); } これで配列コピー。 上のレベルを見る限りあんまりトリッキーでもないかな... がいしゅつだったらスマソ。
>>556 それは単に、Cの代入演算子の挙動を理解(つーか誤解)した、という意味に過ぎないのでは?
未だに構造体の代入拒む奴いるよな
559 :
デフォルトの名無しさん :2001/08/25(土) 17:02
void sort4(unsigned int *d) { __asm{ mov ebp, d mov eax, [ebp] mov ebx, [ebp+4] mov ecx, [ebp+8] mov edx, [ebp+12] cmp eax, ebx cmova eax, ebx cmova ebx, [ebp] cmp ecx, edx cmova ecx, edx cmova edx, [ebp+8] mov esi, eax cmp eax, ecx cmova eax, ecx cmova ecx, esi mov esi, ebx cmp ebx, edx cmova ebx, edx cmova edx, esi mov esi, ebx cmp ebx, ecx cmova ebx, ecx cmova ecx, esi mov [ebp], eax mov [ebp+4], ebx mov [ebp+8], ecx mov [ebp+12], edx } }
560 :
デフォルトの名無しさん :2001/08/25(土) 17:36
>>559 トリッキーか?ベタベタじゃん……
>>558 構造体の代入って、CとC++で意味合いが変わるよね?
561 :
デフォルトの名無しさん :2001/08/25(土) 18:06
ソノシートsage
>>557 ありゃ、普通でした?
char配列の場合、なかなかトリッキーなstrcpyができるなぁと思ったんですが。
言われてみればたしかに代入演算子の挙動を理解(誤解なの?)したに過ぎないですね
564 :
544 :01/08/28 00:54 ID:w0po3FXw
結局、辿ったノードポインタを親ノードポインタに書き換え、 マークを付けていく方法でうまくいく様です。 (マークを付けない場合だと、ある構造ではうまく行く様に見えますが、 戻りなどで既に辿った部分に遭遇すると、無限ループになります。)
565 :
おれ :01/08/28 01:43 ID:pVFk2nKI
有名どころで Duff's device.
http://www.tuxedo.org/~esr/jargon/html/entry/Duff 's-device.html
register n = (count + 7) / 8; /* count > 0 assumed */
switch (count % 8)
{
case 0: do{ *to = *from++;
case 7: *to = *from++;
case 6: *to = *from++;
case 5: *to = *from++;
case 4: *to = *from++;
case 3: *to = *from++;
case 2: *to = *from++;
case 1: *to = *from++;
} while (--n > 0);
}
理解した時に世の中にはキチガイがいるもんだと実感した。
566 :
デフォルトの名無しさん :01/08/28 01:50 ID:RxA.u.Us
おー。こんなことできるのか。
>>564 そりゃー、昔のゴミ集めの連鎖辿りでは常套手段だったべさ。
>>2 の手法で、一つのpointer fieldで双方向鎖の実装もあったべさ。
実記憶のみで総100Kbyteとかの時代の話だべ。
568 :
デフォルトの名無しさん :01/08/28 02:19 ID:9IU/Y/5o
>>565 -566
case文ってのがブロックのなかにあっても通用するってのが
目から鱗だったよ。
ただのラベルだからな
570 :
デフォルトの名無しさん :01/08/29 01:34 ID:GIhJkjc.
>>567 こういうの聞いてると昔のコードって
みんなトリッキーなコードになるかも。
571 :
デフォルトの名無しさん :01/08/29 01:44 ID:gasQtqoY
昔のプログラマは偉かったっていうことだ。
565のはたしかにすごいが、かけてもかきたくねー。
573 :
デフォルトの名無しさん :01/08/29 03:06 ID:hol8O3eY
こういうのは、タイトなループだから、 書きたくなくても書かなければならない部類だと思う。 bcopyのsourceは、word境界に揃えたり軒並凄い事になっている。 i960のマニュアルに載っていたb*(), str*()のsample assemblerも面白かった。
574 :
a :01/08/29 09:41 ID:UHzULLbQ
>>565 どうもコードを追う事が出来ない…
これをちゃんと構造化して書くとどうなるの?
575 :
a :01/08/29 09:48 ID:UHzULLbQ
register n = (count + 7) / 8; /* count > 0 assumed */ if (count % 8 > 0) *from+=(count % 8); do{ *to = *from+=8; }while (--n>0); コレじゃダメなの? つーか、ループ内に直接ジャンプって許されるのか…
576 :
デフォルトの名無しさん :01/08/29 09:52 ID:6wtO5bLA
>>575 それじゃ動作違う。
count要素、fromからtoに内容コピーするコードだったのに。
高速化のために8個づつにループを展開して
端数を最初に突入する位置を制御することで合わせてる。
アセンブラ的だな。
577 :
デフォルトの名無しさん :01/08/29 12:54 ID:sxLoQ6aw
こうでしょ。 register n = (count + 7) / 8; /* count > 0 assumed */ switch (count % 8) { case 0: *to = *from++; case 7: *to = *from++; case 6: *to = *from++; case 5: *to = *from++; case 4: *to = *from++; case 3: *to = *from++; case 2: *to = *from++; case 1: *to = *from++; } do { /* loop unrolling */ *to = *from++; *to = *from++; *to = *from++; *to = *from++; *to = *from++; *to = *from++; *to = *from++; *to = *from++; } while (--n > 0);
578 :
デフォルトの名無しさん :01/08/29 15:54 ID:ZdJjaq2Y
なんかベクトルプロセッサ向けに手動最適化する過去の手法っぽい。
579 :
デフォルトの名無しさん :01/08/29 16:03 ID:sxLoQ6aw
>>577 しまったー!間違えたー!
do-whileじゃなくてwhileだー!
580 :
jjdd :01/08/29 16:54 ID:zilLM4HU
こんなコードをみかけたら嫌がらせとしか思えない。
581 :
おれ :01/08/29 17:03 ID:B1bFcds.
>>565 に結構反応があるようなので、jargon の日本語訳を引用してみる。
n. Tom Duff がルーカスフィルム社にいたときに作った、史上もっともドラマチック
なCの落下(fall through)。彼は、データを出力ポートにシリアルにコピーする内側
のループからできるだけ命令をそぎ落とそうと(bum)して、そのループを展開する
ことにした。すると、展開したバージョンはswitch構造とループ構造を織り混ぜるこ
とで実現できるのがわかった。
これを初めて見たときは誰でもショックを受けると思うが、この仕掛け (device) は
現実にまったく合法的な C なのだ。C の case 文がデフォルトで落下する (fall
through) 仕様になっている点は、単独の機能としては昔からもっとも議論を巻き起
こしている部分だ。Duff は「あの論争で僕のコードも1つの論拠になるけど、それが
どっち側に有利な論拠になるかはわからない」と言っている。
[外側の中かっこのペアは実際には取り除けるので、そうすればもっとわかりづ
らくなる -- GLS]
うわ、動きやがる。スゲ気持ち悪い。 #include <stdio.h> void main(void){ int i,j; for(i=0;i<8;i++) for(j=0;j<8;j++) switch (i) if (j<4) { case 0: putchar('0'); case 1: putchar('1'); case 2: putchar('2'); case 3: putchar('3'); } else { case 4: putchar('4'); case 5: putchar('5'); case 6: putchar('6'); case 7: putchar('7'); } }
>>582 if の条件を変えても(例えば if(1) とかでも)、同じ結果が出るね…。
if の条件は無視されるけど {} のブロック構造は生きてて、
case の実行が止められるって事なんだろうな…。
582 が意図してた事とはちょっと違うのかもしれないけど、勉強になったよ。
584 :
デフォルトの名無しさん :01/08/30 00:12 ID:C3TsWUik
>>583 blockにlocal変数があると、compilerは面倒だなー。C++だと悲惨だ。
?
586 :
デフォルトの名無しさん :01/08/30 00:36 ID:MsZQr7Hg
>>582 げ、マジでコンパイル通るね。
いい勉強になったよ。さんくす。
>>565 のやつはむしろgot文を使った方が可読性良くないかい? register n = (count + 7) / 8; /* count > 0 assumed */
switch (count % 8)
{
loop:
case 0: *to = *from++;
case 7: *to = *from++;
case 6: *to = *from++;
case 5: *to = *from++;
case 4: *to = *from++;
case 3: *to = *from++;
case 2: *to = *from++;
case 1: *to = *from++;
if (--n > 0)goto loop;
}
>>587 { } をなくすととたんに普通のコードに見えてくるなぁ(^^;
>>582 みて思いつきました。
落下しないswitch case
#include <stdio.h>
#define SWITCH(a) switch(a) if(1)
#define CASE } else if(1) { case
int main(void)
{
int i;
for(i=0;i<3;i++) {
SWITCH(i) {
CASE 0: putchar('0');
CASE 1: putchar('1');
CASE 2: putchar('2');
}
}
return(0);
}
590 :
名無し :01/08/31 23:27 ID:4J0FhXA6
bitswapってないですか? aの13bit目と、bの27bit目だけを交換する、という感じで。 ボトルネックになりかねないところなので 速度優先で行きたいんすけど、当方厨房なのでご教授願います。
int c = a; a = (a & ~0x2000) | ((b & 0x8000000) >> 14); b:0000x000 00000000 00000000 00000000 a:00000000 00000000 00x00000 00000000 ベタ。てきとーに。
592 :
デフォルトの名無しさん :01/09/01 00:04 ID:8UdnvL3A
値が2のべき乗かどうかを知る簡単な方法があったと思うんですが、 どういう処理だったか思い出せません。 (たしか引き算とかand取ったりするやつです) どなたか教えてくださると助かります。 既出っぽいですけど。
>>592 確か
n & (n - 1) == 0
じゃなかったっけ?
594 :
デフォルトの名無しさん :01/09/01 00:48 ID:fRlPzhIU
>>593 その公式つかって、二進数で数字を表したときの1の個数を
調べる方法あったよね。
かーにはん・りっちーの本に載ってたはずなんだが、
読んでも見つからないし、思い出せない。
だれかおしえてくらはい。
>>591 それなら、ビット位置を引数に括り出して
typedef unsigned char bitpoint_t;
template <typename T>
inline bool
bit_p(const T num, const bitpoint_t bit)
{
assert(static_cast<T>(-1) > 0 && "call bit_p() with signed value");
return ((num & (static_cast<T>(1) << bit)) >> bit);
}
template <typename T>
inline void
bitswap(T& a, const bitpoint_t m, T& b, const bitpoint_t n)
{
assert(static_cast<T>(-1) > 0 && "call bitswap() with signed value");
const bool bit_a = bit_p(a, m);
const bool bit_b = bit_p(b, n);
a = (a & ~(static_cast<T>(1) << m)) | (static_cast<T>(bit_b) << m);
b = (b & ~(static_cast<T>(1) << n)) | (static_cast<T>(bit_a) << n);
}
こうかなぁ。ベタなコードだけど、m, n が定数の場合には、コンパイラが頑張って
最適化してくれるから、そこそこの出力が得られる。
アセンブラでガリガリ書くのは私の手に負えんので、できる人お願い。
>>594 int bitcount(unsigned n)
{
int cnt;
for (cnt = 0; n; n &= n - 1)
cnt++;
return cnt;
}
>>590 あとこんな方法とか
t = ((a>>an)^(b>>bn)) & 1;
a ^= t<<an;
b ^= t<<bn;
予めan=13,bn=27って分かっていれば
t = (a^(b
>>14 )) & (1<<13);
a ^= t;
b ^= (t<<14);
598 :
名無し :01/09/01 23:43 ID:CCvPomMw
599 :
592 :01/09/01 23:45 ID:cxkeoCoY
600 :
デフォルトの名無しさん :01/09/02 12:02 ID:SHIZw3Bc
>とにかくこの C 言語のソースを見てください.実際にコンパイルできて, >ちゃんと実行できますよ. >このプログラムを実行すると, e^(引数の数)の値を表示します. >このプログラムは以前 遊び半分で作ってみたコードです. >初期値が main のアドレス値で, e の値に収束します. #define EE main(x){double _=1,__=67;__= #define ee ;printf("%lf\n",__);} #define Ee _+x*( #define eE )/--__ #define OO (int)main EE Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee OO eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE ee
>>600 それ、半角スペースがつぶれてちゃ意味無いよー。
602 :
デフォルトの名無しさん :01/09/02 12:10 ID:SHIZw3Bc
#define EE main(x){double _=1,__=67;__= #define ee ;printf("%lf\n",__);} #define Ee _+x*( #define eE )/--__ #define OO (int)main EE Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee Ee OO eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE eE ee
603 :
デフォルトの名無しさん :01/09/03 06:50 ID:nmjujq7g
age
long chinpo; chinpo++; ちんぽプラプラ
先ほど多摩川で
>>605 の死体が見つかったそうです。
みなさんも気を付けましょう。
607 :
デフォルトの名無しさん :01/09/08 03:17
え!!多摩川で!
C++ チンポ(Chinpo)プラプラ(purapura)
609 :
デフォルトの名無しさん :01/09/08 14:02
longってことは、 チンポが長いんだ
610 :
デフォルトの名無しさん :01/09/08 14:35
>602 誰かマクロ展開してくれ わけわからん
自分でやれ>610
>>610 (゚Д゚)ハァ?
プリプロセッサ使えよ。
613 :
デフォルトの名無しさん :01/09/08 15:29
>612 つべこべ言わずにやれったらやれ!
616 :
デフォルトの名無しさん :01/09/08 20:00
Unixに展開コマンドあるよ。 cpp ← C プリプロセッサ cpp sample.c >> sample.txt とすれば、展開後のソースが sample.txt で得られる。
618 :
デフォルトの名無しさん :01/09/11 19:22
都立キーな高度
↑ 孤立気味な行動
↑ 凝り過ぎな投稿
621 :
デフォルトの名無しさん :01/09/11 21:29
↑ 太り過ぎな近藤
622 :
デフォルトの名無しさん :01/09/11 21:32
↑ ウィッキー仲人
↑ ボヤッキー泣こうぞ
↑ ナッキーは○○○
625 :
デフォルトの名無しさん :01/09/12 02:17
↓ モンキーの動向
↑ ウキッ ウキキッ!! (猿真似してみました…)
627 :
デフォルトの名無しさん :01/09/12 05:21
トリッキーの1よ。 今大変な事が起きておる。 スレの危機だ。 今こそお前の出番だ。 スレを救うのだ。 age
ボクにもやらせて。えっとね ↓ ドンキー任天ード
↑ コレッキリーにシヨーヨ ……オレモナー
age
頭の中であのマクロが展開出来ないようでは展開したものを見ても多分 分からないと思うので、作者に代わって大意を述べると、 e=1+1/1!+1/2!+1/3!+1/4!+..... =1+1*(1+1*(1+1*(1+ .... )/3)/2)/1 で、これを67!になるまでで打ち切って計算しているだけ。真中の(int)main は最終的に67!で割り算されるから何であってもほぼ0とみなされる。 ただし、ひとつの式の中に複数の同じ変数に対する副作用を持つ式を 書いた場合は、ANSIやISO9899などでは結果は保証されないので、この プログラムはANSIやISO9899ではないです。従って例えばIOCCCに投稿 しても不適合になります。カンマ演算子など、評価順序を決定する演算子 の前後に分かれていれば問題はないのですが... 例えば、int i=7;printf("%d",++i * ++i ); の出力が 64,72,81のどれに なっても構わないし、厳密にはこれで異常終了するような実装でも 構わなかったはずです。
最近使ってみた(VC++コードの一部・IQ低し) char Buf[128]; crlf[3]={13,10,0}; wsprintf(Buf,"Hello%sworld",crlf);
634 :
デフォルトの名無しさん :01/09/27 02:49
for(i=0; n; i++) n &= n-1;
>>635 トリッキーの1さんを利用するのは許せない
int n = 0; char *ps, sz[] = "a\0bcde\0fgh\0"; while(sz[n]) n += strlen( (printf("%s\n", ps = &sz[n]), ps) ) + 1;
>>376 LDIRを使う方法の場合
LD HL,LDIRの次
(LDDRを使う場合はLDDRの前になる)
は必須です。しかも問題の条件からこれをリロケータブルにやらないと
いけません。その部分もきちんと考えるとどうなります?
※LDIRの動作はLDIの動作の後、BCレジスタが0でなければ、PCをDECします。
(説明書などにはBC=0となるまでLDIの動作を繰り返す、のように記述されて
いるかも知れませんがそれは不正確です。ハードウエア的にトレースして
見れば分かります。)
よってHLレジスタの値が中途半端な所にある場合、LDIRの命令のところまで
消去したところで実行される命令がNOPになるので(Z80では書き換えられた
命令は即実行に影響します)その続きの命令が実行されてしまいます。
0-2番地にコードがないとすれば、 LD BC,2 LD A,'RET' LD (BC), A DEC BC LD A, 'PUSH HL' LD (BC), A DEC BC LD A, 'POP HL' CALL 0 ADDR1: LD D, H LD E, L INC DE ADD HL, ADDR2 - ADDR1 ; ADDRの引き算なのでリロケータブル LD (HL),0 LDIR ADDR2: 或いはSPがまともな値だったら、上記プログラムを逆順にPUSHして RETでそこに飛ぶ、という方法のほうが確実かな。 LD HL, 'LDIR' PUSH HL LD HL, 'LD (HL),0' PUSH HL LD HL, 10 PUSH HL LD HL, 'ADD HL'*256+'INC DE' PUSH HL ……… RET という具合。
641 :
デフォルトの名無しさん :01/10/21 03:35
質問待ちage
642 :
*nix厨 :01/11/04 15:54
#ifdef AAAAA print "Happy 2ch world!\n" exit =begin #endif #include<iostream> int main() {cout << "Happy 2ch world!" << endl; return 0; } #ifdef AAAAA =end #endif
644 :
デフォルトの名無しさん :01/11/04 19:47
html + perl <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><!-- $_ if 0; print "Happy 2ch world!\n"; #--><html><body>Happy 2ch world!<br></body></html>
645 :
デフォルトの名無しさん :01/11/04 19:55
Perl + Ruby + Python + Basic すげー3つもだ。 print "Happy 2ch world!\n";
あ、 ; つけちった。。。 無視してね(汗
4つだし。。。鬱
これ。 mes "Happy 2ch world!":stop
>>648 一個はsmalltalk?もう一個は?
オリジナリティ0につきsage rem /* echo Happy 2ch world! exit */=3; #ifdef 0 print "Happy 2ch world!" exit =begin #endif #include <stdio.h> int main() { printf("Happy 2ch world!\n");return 0; } #ifdef 0 =end #endif
DOS, Ruby, C ? * /= 3; って言う行があるけれど、Rubyは通らなかったんだけど。。
っていうか、一行目ですでに ruby C脱落では。・・
えーと、ミスです(涙) Perl, C, DOSのつもりだったけど、 Perl, C通らないね ^^; 出直してきます
perlは、 =begin =end じゃなくて、 =任意のアルファベットだけからなる文字列 =cut だったはずっすよ。
PerlとC(++)とDosの共存は難しくないでしょうか? エラーメッセージを出してもいいなら出来るけど……
656 :
デフォルトの名無しさん :01/11/05 03:34
@rem , exit if (print "Happy 2ch world!\n"); @goto =(BAT_MAIN) __END__ :=(BAT_MAIN) @echo Happy 2ch world! あやしいけど、動いた。
657 :
デフォルトの名無しさん :01/11/05 04:47
DOS + C + Perl rem (int tr/*//) if (0); $_=<<"EOS"; @echo Hello world @goto END_OF_BAT rem */) {printf("Hello world\n");return;} main () {rem(1); return 0;} /* EOS print "Hello, world"; __END__ :END_OF_BAT rem */
658 :
トリッキーの1 :01/11/05 08:35
>>657 お見事。
最初のremを@remにするのは不可能だよね(笑)
659 :
デフォルトの名無しさん :01/11/06 00:19
LispとCを共存させれたら、褒める。 褒めてつかわす。 あげ
トリッキーの1さん、こないだはどーもでした(笑
>>659 (DEFINE /* (lambda () (display "Hello world")));*/)
(/*);*/){ printf("Hello world."); return 0; }
誉めて使わせ
あー、LISPじゃなくて、Schemeね。
main付け忘れた(鬱 (DEFINE /* (lambda () (display "Hello world")));*/) (/*);*/){ printf("Hello world."); return 0; } main() { DEFINE(); return 0; }
>>660 = 60of7L
こちらこそどうもでした、また会いましょう(笑)
……というレスをはやく付けようと思っていたんですが、
このレスだけで書き込むと内容がスレ違いだし、
何か一緒に書き込むネタがないか…と考えていました(笑)。
結局思いつかなかったんですが。
C++のtemplateを使ってトリッキーな事が出来ないかな、とか考えていたんですが、
普通に書いても結構トリッキーになってしまうので、余り「これ!」っていうネタは
無いですね。
誰かテンプレートのトリッキーな使い方をしたことのある人はいませんか?
>>663 どこかのスレに、フィボナッチの数列を求めるサンプルがあったけど。
これってトリッキーかな
templateを使ってフィボナッチ数列を求めるって事ですか? 例えばchar型やlong型で?? 発想力がないのでtemplateの説明みたいなコードしか思い浮かばないけれど、 実物みたいですね。
666 :
デフォルトの名無しさん :01/11/08 21:45
666ゲットぅ! おーい母さん今夜はリッキーだ!
>>663 なんでgoogleで調べない? ふぃぼなっちの綴りがわかんない
とかじゃないだろうな?
>>668 なるほど、……美しい。こういうtemplateの使い方もあるんですね。
行列式の計算もtemplateで書けそうですね。
ソースサンクスです。
このスレ見つけて面白そうなんで1ソース多言語を 誰もやらなさそうなMindで考えてみた… だがつまらんものしか出来なかつた…いちおうMind+C /*は "Happy 2ch world!"を 一行表示すること。 メインとは /*。 コンパイル抑止。 */ #include <stdio.h> int main(){ printf("Happy 2ch world!\n");}
スレの趣旨とはちょっと違うかもしれないが…。 #include <stdio.h> main() { int a; a=1+-+-+-+-+-+-+-+1; printf("%d",a); }
#include <2ch.h> int main() { age("プラグインって結構トリッキー?"); return 0; }
そんなこともなかろ
674 :
デフォルトの名無しさん :01/12/17 02:36
printf("age\n");
プラグインがトリッキーなのではない。 トリッキーなのがプラグインなのだ。 ゲーテ
676 :
デフォルトの名無しさん :01/12/24 18:01
age
MMX を使用しない飽和演算 // 例えば、x が渡されて x = ( x > 255 ? 255 : x ) を計算 int x, y; y = x - 255; x = y & (y >> 31) + 255; // (y >> 31) は y >= 255 なら 0 、それ以外は -1
保守
680 :
デフォルトの名無しさん :02/01/11 05:14
>>678 何やってんだこれ?
つーか、めちゃくちゃ危険なことやってる気がするぞ。
マクロの中にじかに変数名埋めるなんて正気の沙汰じゃねーな。
これ書いた奴誰だ?
こんなコード書く奴には仕事出したくないぞ
int a,b=0; scanf("%d",&a); a&&(b=100),(printf("a=%d\nb=%d\n",a,b));//論理演算子で条件文を表現
>>680 あふぉ。そーいうことを逝ってんじゃねーだろ。
683 :
デフォルトの名無しさん :02/01/11 07:03
684 :
デフォルトの名無しさん :02/01/11 08:27
>>680 なんでだよ。
{
int pc;
void *jump_table[];
#define NEXT
...
#undef NEXT goto *jump_table[*pc++];
}
なら問題ねーだろ。
NEXTの書き方はへヴォだが。
マクロにする意味無いじゃん・・・
686 :
デフォルトの名無しさん :02/01/11 11:29
687 :
デフォルトの名無しさん :02/01/11 15:03
第八章が秀逸
漏れ、目黒寄生虫館の館長のサイン持ってるよ。
690 :
デフォルトの名無しさん :02/01/13 04:27
>>689 エディタの機能について言及してるが、この人は本当に
エディタを使いこなしテイルのだろうか?
今時これしきの字下げをマクロで組めないような
エディタを使っている時点で藤原氏の底も知れるな。
などと擁護してみるテスト。おれだってこんなソース見たら逃げるっちゅーの
691 :
デフォルトの名無しさん :02/01/13 06:01
Tricky ("code")
>>690 いや10年前の本だってう゛ぁ(藁 DOSならVzEditorとかの時代?
そういう意味からも鵜呑みには出来ないけど、
この本読んで面白がるのは中級者以上だから、ちゃんと情報の取捨選択は出来る筈。
あくまで読み物だからね。
つかトリッキーなコードってよりクソなコードだったっぽ。スマソ(藁
void main() { a: goto b; c: goto a; b: goto c; }
∧_∧ Assembler派としては ( ´Д`) 正直、C言語にビットローテート演算子がホスィ・・・ / \ ついでにビットスキャン演算子もホスィ _ | | ∬ | |_..∬ |\ ̄ ̄ ̄旦 ̄ ̄ 旦.\ ./..\\ \ / \|================| \ ノ \ \ .\ \ ..\_ """"""""""""""""""″″′
696 :
デフォルトの名無しさん :02/01/14 23:32
>>695 ローテートはマクロでどうにでもなるかと
ビットスキャンとは?
あるビットを読みたいとか? a &= 0x04;
> ローテートはマクロでどうにでもなるかと いや、演算子として実装された方が、コンパイラが上手く最適化してくれるという意味。 > ビットスキャンとは? ビットフィールドを順方向(または逆方向)に見ていって、最初に立つビット位置を見つけること。 i486以降だとbsf命令などに相当する。 つまり演算子として実装されていれば、 CPUネイティブのローテート命令やビットスキャン命令に変換してくれる可能性が高くなる。
700 :
デフォルトの名無しさん :02/01/15 02:37
昔はコンパイラが吐いたコードをバイナリでいぢるなんて普通だったが、 Winじゃやりたくねーな・・・。 cp = i["string"];
701 :
デフォルトの名無しさん :02/01/16 01:08
function validateDate(strDate) { if(strDate.match(new RegExp("((19(0[48]|[2468][048]|[13579][26])" + "|20([02468][048]|[13579][26]))\\/02\\/29" + "|(19|20)\\d{2}\\/((04|06|11)\\/(0[1-9]|[12]\\d|3[0])" + "|(0[13578]|10|12)\\/(0[1-9]|[12]\\d|3[01])" + "|(02\\/(0[1-9]|1\\d|2[0-8]))))"))) { return true; } return false; }
gccだと__builtin_なんとかってのがいっぱいあるし、別に塩山市でなければならない理由はないのでは。
asmの常套手段だが、条件分岐のない、飽和演算(8byte) (bl,bhにそれぞれ演算したい値を入れておく) add bl, bh sbb bh, bh or bl, bh この応用で、8bit単位の32bit飽和演算等が可能
このスレがまだ生きていたとは……感謝です。 ネタがなくて申し訳ないですが。
>>703 gccで作ってみた。x86限定。
/* saturate.h */
#ifndef saturate32
static inline unsigned char __saturate8_generic(unsigned char c1, unsigned char c2)
{
__asm__ __volatile__("addb %2,%1\n\t" "sbbb %2,%2\n\t" "orb %2,%0" : "=q"(c1) : "0"(c1), "q"(c2));
return c1;
}
#define __saturate8_constant(c1, c2) ((~(~0u << 8) - (c1) > (c2)) ? ((c1) + (c2)) : ~(~0u << 8))
static inline unsigned short __saturate16_generic(unsigned short c1, unsigned short c2)
{
__asm__ __volatile__("addw %2,%1\n\t" "sbbw %2,%2\n\t" "orw %2,%0" : "=q"(c1) : "0"(c1), "q"(c2));
return c1;
}
#define __saturate16_constant(c1, c2) ((~(~0u << 16) - (c1) > (c2)) ? ((c1) + (c2)) : ~(~0u << 16))
static inline unsigned int __saturate32_generic(unsigned int c1, unsigned int c2)
{
__asm__ __volatile__("addl %2,%1\n\t" "sbbl %2,%2\n\t" "orl %2,%0" : "=r"(c1) : "0"(c1), "r"(c2));
return c1;
}
#define __saturate32_constant(c1, c2) ((~0u - (c1) > (c2)) ? ((c1) + (c2)) : ~0u)
#define saturate8(__x, __y) ((__builtin_constant_p(__x) && __builtin_constant_p(__y)) ? \
__saturate8_constant((__x), (__y)) : __saturate8_generic((__x), (__y)))
#define saturate16(__x, __y) ((__builtin_constant_p(__x) && __builtin_constant_p(__y)) ? \
__saturate16_constant((__x), (__y)) : __saturate16_generic((__x), (__y)))
#define saturate32(__x, __y) ((__builtin_constant_p(__x) && __builtin_constant_p(__y)) ? \
__saturate32_constant((__x), (__y)) : __saturate32_generic((__x), (__y)))
#endif
706 :
デフォルトの名無しさん :02/02/20 00:02
age
707 :
デフォルトの名無しさん :02/02/22 23:19
トリッキーなコードというわけではないけど、 VC6の/FAcで出力される.codファイルのコードダンプをプログラムから メモリに取りこんで、そのまま実行とかはよくやる。 もうちょっと細分化して、スクリプト言語に取りこめたらいいな、 と思うけど疲れるだけなのでやらない。
708 :
デフォルトの名無しさん :02/02/26 17:38
1周年age
typedef struct list { int num; int data[1]; } LIST; LIST *p = (LIST*)data; /* 読み込んできたデータなど */ for( i=0; i<p->num; i++ ) printf("%d,",p->data[i]); みたいに配列を故意にオーバーさせて使うのは一般的?
>>709 ありがちって言うか、それを要求する Win32API が確かあったぞ
711 :
デフォルトの名無しさん :02/02/27 15:44
#define (Funk,/*略*/) void Funk(){/*略*/} 漏れにはトリッキーに思えた。
Dennis Ritchieは「Cの実装への根拠 のない馴れ馴れしさ」と呼んだ。
713 :
デフォルトの名無しさん :02/02/27 16:26
>707 いい情報だ、ありがと それ使うと実行中に自分自身のコードの位置を管理するプログラムがかけそうだね
714 :
デフォルトの名無しさん :02/02/27 16:31
>711がわからないんだけど。誰か説明して
C++において[]演算子のオーバーロードができることから、 リンクリストを扱うtemplateクラスを作って item[-1]; // 前の要素 item[1]; // 次の要素 とか。 もちろん添字に当たる引数はsignedな型にしておく。
>>714 スマソ、ちとミスがあった。
#define HOGE(Funk,/*略*/) void Funk(){/*略*/}
例えば、こんな風な。
int a,b,c;
#define HOGE(Funk,Opr) void Funk(){c = a Opr b}
HOGE(Add,+)
HOGE(Del,-)
HOGE(Mul,*)
HOGE(Dev,/)
void (*pFunk[])() = {Add,Del,Mul,Dev};
普通にAdd,Del,Mul,Dev書くよりもメリットなさそうだが。
タイプ量が減るってメリットはありそうだが
#define HOGE(Funk,Opr) void Funk(){c = a Opr b;} HOGE(Add,+); HOGE(Del,-); HOGE(Mul,*); HOGE(Dev,/); よりも void Add(){c = a + b;} void Del(){c = a - b;} void Mul(){c = a * b;} void Dev(){c = a / b;} のほうが少ないよん。メリット無しだね。
>>722 例で書いただけだかんね。実際に使う場合は、
#define HOGE(Funk,Opr) void Funk(){\
/*略*/
c = a Opr b;\
/*略*/
}
ってな具合に使うから、タイプ量が減る。
あと、似たようなコードを書かずに済むから、バグも減る。
>721 1+(-1) = 0
a=1+-+-+-+-+-+-+-+1; a=1+( -( -( -(-(- ( - ( -1) )))))); a=1+(-1)
1+・・・・+1; の最初の+は演算子として残って、 それ以外の+は消えちゃうわけですか・・・? むむ・・・・あ、+-の間に0を補間していけばいいのか。
a=1+-+-+-+-+-+-+-+1; a=1+(-(+(-(+(-(+(-(+(-(+(-(+(-(+1)))))))))))))); かな
演算子だと、優先順位が左から右ですけど、 符号の場合は優先順位が右から左なんですか?
732 :
デフォルトの名無しさん :02/03/07 16:51
age
>>731 ん?
単項演算子の結合方向は右から、2項が左から
優先順位は単項>2項
だよ
734 :
デフォルトの名無しさん :02/03/07 22:30
データエリアが、そのまま実行できるバイナリになっているOSがあったとな
735 :
デフォルトの名無しさん :02/03/07 23:39
>>734 意味わかんない。
データエリアって何の事?
すごい、1年以上前のスレだ
737 :
デフォルトの名無しさん :02/03/08 04:10
トリッキーかどうか謎だが Exception eName=null; try{ //なんか、Nullだとだめな必須の関数に詰め込む MimeMessage msg = new MimeMessage(); msg.setSubject(request.getParameter("subject"), "ISO-2022-JP"); }catch(eName){ } <body> <input type="text" name="subject"> <%f if(null != eName){ %> ちゃんと入力してYO! <% } %> </body> //-- 入力チェクーをExceptionオブジェクトのインスタンスで判断すると言う横着
738 :
デフォルトの名無しさん :02/03/08 12:52
age
ドンキーコングがトリッキーコードを書く。
ケンタッキーのチキン(鳥)を食べながらコーラを飲む。 トリッキーコーラ
お〜い山田くん
742 :
デフォルトの名無しさん :02/03/08 16:08
744 :
デフォルトの名無しさん :02/03/11 09:08
>>742 ダウソロードしました
goto文を見つけてビクーリしました
取り憑き仲人とは?
748 :
デフォルトの名無しさん :02/03/12 09:46
>>746 いやgoto文ではなくて c00.c にある
ospace() {} /* fake */
に悶えろ。ospace は例えば c01.c の block() なんかで使っている。
漏れは Dennis Ritchie のコメントを読むまで何をやっているのか
解らなかった。
> ... astonishing peculiarity is
> the space allocation: temporary storage is allocated that
> deliberately overwrites the beginning of the program,
> smashing its initialization code to save space.
可変長構造体 struct Hoge { int i1,i2; char pName[0]; }; size_t size = sizeof(Hoge) + strlen(pName) + 1; Hoge*pHoge = (Hoge*)malloc(size); pHoge -> i1 = i1; pHoge -> i2 = i2; strcpy(pHoge -> pName,pName); VC++だとwarningだが、一応使える。
751 :
デフォルトの名無しさん :02/03/15 09:09
保守
754 :
デフォルトの名無しさん :02/04/01 00:11
>750 BITMAPINFOなんかがそれですが、 ポインタじゃ無い理由って何でしょうか?
755 :
デフォルトの名無しさん :02/04/01 00:57
hoge[0]はポインタ宣言扱いですよ。
756 :
デフォルトの名無しさん :02/04/01 01:11
なんで char *hoge; じゃないのか理由が知りたいよ!
757 :
デフォルトの名無しさん :02/04/01 01:16
実体がそこにあるんでしょ
758 :
デフォルトの名無しさん :02/04/01 01:39
そうだ、char 一個分あるんだ。 じゃ、 struct Hoge { char pName[3]; }; でも、Hoge->pName[10] とかって、アクセスするの?
759 :
デフォルトの名無しさん :02/04/01 01:43
そもそもなんで一個分確保するのでしょうか? そんなの無くても配列でアクセスできますよね?
760 :
デフォルトの名無しさん :02/04/01 01:58
それじゃ配列にならないじゃん。 char pName; pName[10] = 'a'; なんて書いてコンパイル通らんでしょ? char pName[1]; pName[10] = 'a'; これならコンパイル通るでしょ?
メモリイメージの問題だろ。 たとえば、大抵の32bit環境で struct X { size_t size; char ch[1]; }; |4byte size|ch[0] ・・・・・・| struct Y { size_t size; char* ch; }; |4byte size|4byte pointer| 〜 |ch[0]・・・・・|
762 :
デフォルトの名無しさん :02/04/01 02:15
0個は処理系依存だから1個だけ確保する
763 :
デフォルトの名無しさん :02/04/01 05:10
struct HogeA { char pName[1]; }; struct HogeB { char *pName; }; 両方とも HogeA->pName[10]; HogeB->pName[10]; と言う風にアクセス出来ますよね?
764 :
デフォルトの名無しさん :02/04/01 05:21
#define MEMCPY(dest,src,size) {\ struct st { char c[size]; };\ *(struct st*)(dest) = *(struct st*)(src);\ }
765 :
デフォルトの名無しさん :02/04/01 05:35
配列のコピーが代入で出来ないから、 構造体で包んでいるって事? でも、 struct HogeA { char pName[1]; }; の場合、コピーされるのは最初の1バイトだけだから、、、
>>763 お前は配列とポインタの違いが全然わかってないな…
出直してこい。
>>763 >struct HogeA {
> char pName[1];
>};
1バイト確保される。
>struct HogeB {
> char *pName;
>};
(Windows+VCとかなら)4バイト確保される。
>>763 (Cで言うところの)文の中のvar[x]という書き方はポインタの
シンタックスシュガーであり、宣言のものとは区別されます
>>767 charのサイズも処理系依存ですよ(9bitとか実際に存在する)
sizeof(char)は1であると規格で決まってますが、これで返ってきた
サイズがバイト数であるとはどこにも書かれてないですから
ついでに 1byte==8bits も、特に決まってない。 慣用的には8bits以外は1word と表現する場合が多い。 (12bits==1word っていうCPUも実在する) だから、charが9bitsでも「1バイト」が必ずしも間違いではない。 でも、そういうの言い出したら…
>>768 知ったかぶりはやめましょう。
> 6.3.3.4 sizeof演算子
(中略)
> 意味規則 sizeof演算子の結果は、そのオペランドの(バイト数での)大きさとする。
>>770 ISO/IEC 14882:1998 によると、
> [expr.sizeof] 5.3.3 Sizeof
> 1 The sizeof operator yields the number of bytes in the object representation of its operand. The operand
> is either an expression, which is not evaluated, or a parenthesized type-id. The sizeof operator shall not
> be applied to an expression that has function or incomplete type, or to an enumeration type before all its
> enumerators have been declared, or to the parenthesized name of such types, or to an lvalue that designates
> a bit-field. sizeof(char), sizeof(signed char) and sizeof(unsigned char) are 1; the
> result of sizeof applied to any other fundamental type (3.9.1) is implementation-defined. [Note: in par-ticular,
> sizeof(bool) and sizeof(wchar_t) are implementation-defined.69) ] [Note: See 1.7 for
> the definition of byte and 3.9 for the definition of object representation. ]
となっており、
> [intro.memory] 1.7 The C++ memory model
> 1 The fundamental storage unit in the C++ memory model is the byte. A byte is at least large enough to con-tain
> any member of the basic execution character set and is composed of a contiguous sequence of bits, the
> number of which is implementation-defined. The least significant bit is called the low-order bit; the most
> significant bit is called the high-order bit. The memory available to a C++ program consists of one or more
> sequences of contiguous bytes. Every byte has a unique address.
> 2 [Note: the representation of types is described in 3.9. ]
となってます。
つまり、
1バイト=文字集合の要素を保持できるサイズ
charのサイズ=1バイト
というわけ。
知ったかぶりはお前の方だ。
マー、イージャネーカ (´ー`)y-~~~
>>771 ハァ?
>>768 が
> sizeof(char)は1であると規格で決まってますが、これで返ってきた
> サイズがバイト数であるとはどこにも書かれてないですから
とか言ってるから書いてると
>>770 で指摘してるのに、なぜ私に向かって
> 1バイト=文字集合の要素を保持できるサイズ
> charのサイズ=1バイト
とか講釈たれるんですか? 言うなら
>>768 に対してでしょうが。
> 知ったかぶりはお前の方だ。
知ったかぶり以前に日本語読解力もないようですね。
774 :
デフォルトの名無しさん :02/04/04 05:21
レジスタを3,5,9倍するコード。 lea eax, [eax * 2 + eax] lea eax, [eax * 4 + eax] lea eax, [eax * 8 + eax] 有名かな?
変数・・・・ノーマル ポインタ・・・サイヤ人 配列・・・・スーパーサイヤ人
関数ポインタ・・・・スーパーサイヤ人2 配列ポインタ・・・・スーパーサイヤ人3 メンバ関数ポインタ・・・・スーパーサイヤ人4
call 次のアドレス pop 初めて見たときは感動した。
>>777 IPを得るにはほとんどこれしかないけどね
>>779 (E)IPレジスタの値を取得するコード。
アセンブリ言語ネタはいろいろ面白いのがあるね。
LOOP: : : : LD HL,LOOP PUSH HL JP SUB2 SUB2: : : : RET
782 :
デフォルトの名無しさん :02/04/05 19:54
VBでデバッグ実行かEXEによる実行かを判定する関数 デバッグ実行の時にはTrueを返信する。 Public Function IsDebug() As Boolean On Error Resume Next Err.Number = 0 Debug.Print 1 \ 0 IsDebug = (Err.Number <> 0) End Sub
783 :
デフォルトの名無しさん :02/04/05 19:55
最後の行はSubじゃなくてFunctionだった 誰もツッコんでくれるなよ・・・・
>>783 アプする前にはちゃんと動作確認しろよ、ボケェ。
下らないところでミスタイプしてるぐらいだから、
他にもバグがある可能性大だろ。
そろそろ保守アゲ♪
786 :
アセンブラAX :02/04/06 02:32
別に 取り付き〜 な訳じゃないですが デバッグログはくときに #ifdef DEBUG WriteLog(...); #endif って 毎回書くのが面倒なので #ifdef DEBUG #define WRITELOG(n) WriteLog(n) #else #define WRITELOG(n) #endif とヘッダに書いておくと WRITELOG( "あぼ〜ん" ); って書くだけで OK って 厨房ですか・・
787 :
デフォルトの名無しさん :02/04/06 04:11
#define MEMBER_OF(a) (sizeof(a)/sizeof(a[0])) ってガイシュツですか?
MEMBER_OFっていうのがトリッキーな名前ってこと?
ふつうはnumofあたりだな
>>786 WriteLog の引数が複数あるときに困るので、WRITELOG は引数なしで
定義するのが普通ですな。
Java を真似て lengthof にしてる。
Message(isError() ? "Error" : "Success"); このくらい普通ですよね?
>>793 三項演算子としては普通だけど、
エラーコードに応じたメッセージ取得関数を用意したほうがいいと思うぞ。
先週、新人研修の講師補助をやってたら、新入社員がこんなソース書いていた。 #include <stdio.h> int main() { int atoi(int n); int a; : 本人は文字を整数に変換したいらしいのだが、明らかに atoi() の使い方が間違っている。 しかしエラーを解決する方法も学ばせようと思い、そのままビルドするよう指示。 すると何故かすんなり通ってしまい、ビクーリした。 # 何故エラーにならんのかは、帰宅中に気が付いた。 # 流石に1年ブランクあるから細かい仕様を忘れてる…
エラーにならない理由の前に、何故そう書いたのか全く理解出来ません!! 何をどうしたかったん
プロトタイプ宣言、だろ、古い本にでも書いてあったんじゃねーか?
798 :
デフォルトの名無しさん :02/04/07 03:22
なんでエラーにならないのYO!
引き数 int で、int を返す、ローカル関数atoiのプロトタイプ宣言て事??
>>796 こうすることで、変数 n に収めた文字がコードに変換されると思ったらしい。
まぁC は初体験だったらしいので…(何だかエチ-表現だ)
>>799 おおむね正解。
ローカル関数っつーより、ローカル(な)プロトタイプ宣言と言った方が正しいかと。
こう書いたのとほぼ同意になるんだったっけ? #include <stdio.h> int atoi(int n); int main() { int a; :
有効範囲が違うだけ
803 :
デフォルトの名無しさん :02/04/07 07:10
宣言だけだから、リンカエラーが出るんじゃないの?
実体を呼び出していなきゃエラーが出るわけ無い
805 :
デフォルトの名無しさん :02/04/07 07:15
同一スコープ内で同名の関数宣言が出てきたらやばいんだよね?
806 :
アセンブラAX :02/04/08 17:04
Do Until not blnRet = False ..... Loop なんてのがあって 切れました・・・ 日本語に訳してみい って 言いたかったです 「blnRet が 偽でない でない間 ループしろ・・・」 ある意味 トリッキー
なんでもかんでもクラスに出来るよ。 って言われました。 こう言う事ですか。 #include <iostream.h> class Piyo { public: Piyo() { cout<<"Piyo"<<endl; exit(0); } }; Piyo p; int main;
お題:『16進表記の文字列に変換したときに何桁になるか』
Delphi:
function HexLength(a:Cardinal):Integer;
begin
a := a or 1;
a := a or (a shr 16);
a := a or (a shr 8);
a := a or (a shr 4);
a := a or (a shr 2);
a := (a or (a shr 1)) and $11111111;
a := a+(a shr 16);
a := a+(a shr 8);
a := a+(a shr 4);
Result:=( a and $f);
end;
c:
int HexLength(unsigned a)
{
a = a | 1;
a = a | (a >> 16);
a = a | (a >> 8);
a = a | (a >> 4);
a = a | (a >> 2);
a =(a | (a >> 1)) & 0x11111111;
a = a + (a >> 16);
a = a + (a >> 8);
a = a + (a >> 4);
return a & 0xf;
}
10進数を16進数に変える方法について
http://pc.2ch.net/test/read.cgi/tech/1007222280/ よりコピペ
810 :
NIH3T3 :02/04/17 20:48
age
811 :
デフォルトの名無しさん :02/04/18 07:38
if 文を使用しているのが気に食わんが、一応挙げとく。 int HexLength(unsigned a) { int b=1; if(a&0xFFFF0000){b+=4;a>>=16;} if(a&0xFF00){b+=2;a>>=8;} if(a&0xF0){b+=1;} return b; }
int col = (int)(log(num) / log(cardinal)) + 1; ごく普通にこれじゃだめなの?
だれに言ってる?
>>812 面白くない、つーか、対数使うのは激しく外出。
>>815 いや、だからごく普通にアレじゃだめなんか?
って話で。別にトリッキーじゃないのは承知。
ただ、一般的な解決手法があるのに、わざわざトリッキーにするのは意味があるのか?
ってしつもんなんだが。
>>816 >わざわざトリッキーにするのは意味があるのか?
意味:面白い
>>816 >わざわざトリッキーにするのは意味があるのか?
理由:速い
>>816 >わざわざトリッキーにするのは意味があるのか?
意味:スレの趣旨
820 :
デフォルトの名無しさん :02/04/18 22:20
>>812 libmath使いたくなかったんです。
821 :
デフォルトの名無しさん :02/04/18 22:26
numが0でも問題無いが?
へえ? 今だと変わった環境だな
>>822 log(0) で例外出ないのか
824 :
デフォルトの名無しさん :02/04/18 23:32
>>816 世の中色んな環境がありますし、要求があります。
浮動小数点をサポートしてない環境でも
>>811 は動きます
また、分岐命令は分岐予測に失敗すると十数命令分ペナルティを払うようなCPUだって
あるので、分岐命令を使わない
>>808 方が速かったりしますしね。
たとえば、マイクロ秒のタイマーが必要な場合に命令数を数えて時間を作ったりしますが
そんな時に実行時間が一定の関数があればそれを入れたり出来る事もあります
>>823 VCでコンパイルして実行してみたけど、きっちり1が帰ってきたYO!
ライブラリ関数内部で0ならリターンしてるんじゃない?
>>826 そもそも必要無い関数と言い切ってしまえばそれまでですね。
ただ、問題解決には色んな方法があるわけで、
その方法の引き出しが多い方が楽しいでしょ?
>>825 よかったね、さすがVCだ。 パチパチ
BCC55でCPPだと例外が出るし
GCCだと負数の大きな数字になるから困ったもんだよね
829 :
デフォルトの名無しさん :02/04/19 11:25
では次のように問題を変形してみましょう。 浮動小数点のサポートのない組込みマイコンだとします。 1、 4*8 のセンサーが1ワードで入力されます このセンサーは8のレベルに分かれており 上位ビットが優先されます。 このワードデータを入力して 0〜8を返す関数を作れ! 例:0x01237000 なら7を返す 2、 4*8のセンサーは8つのグループに分かれており、一つのグループ内では一つでも ONになれば1つと数え、いくつのグループがONになっているかを返せ 例:0x01237000 なら4を返す
830 :
デフォルトの名無しさん :02/04/19 19:13
>>829 つーか、逆にその条件から対数を使用する事を
思い付く奴の方が「神」。
831 :
デフォルトの名無しさん :02/04/19 19:59
>>826 必要の無いところでも最適化する奴は
必要なところでも最適化が出来る。
必要のないところだからといって最適化をしない奴は
必要なところなら最適化が出来る、とは限らない。
この差はけっこう大きい。
その組み込みマイコンには、SIMD系 特殊命令があったりしないの?
いや4ビットマイコンだったりして
つーか、8レベルなら、0〜7じゃねーのか?
エラーが無いがゼロで、順に12345678 かと
>>834
836 :
昔のPC板より :02/04/19 21:18
131 :ナイコンさん :02/02/05 03:19
8ビット×8ビット乗算にADD HL,DEを使うのは素人
132 :ナイコンさん :02/02/06 03:23
>>131 っつーか、そういう発想の出る
>>131 は素人。しかも丸だしの(w
133 :ナイコンさん :02/02/06 12:13
8ビット×8ビット乗算にADD HL,HLを使うのは素人
141 :ナイコンさん :02/02/07 20:24
被乗数:Ereg 乗数:Areg 結果:HLreg
PUSH DE
PUSH AF
LD D,0
LD H,D
LD L,D
SCF
ADC A,A
LOOP1:
JR NC,SKIP1
ADD HL,HL
ADD HL,DE
JR SKIP2
SKIP1:
ADD HL,HL
SKIP2:
ADD A,A
JR NZ,LOOP1
POP AF
POP DE
両方とも使いますが?
>>131-133
142 :ナイコンさん :02/02/08 11:28 8ビット加算&右シフトと、乗数と結果をLregで共有するのがポイント テーブル使わないでもっとクロック削れるかな ; HL = H*L XOR A RR L JR NC,$+3 ADD A,H RRA RR L JR NC,$+3 ADD A,H RRA RR L JR NC,$+3 ADD A,H RRA RR L JR NC,$+3 ADD A,H RRA RR L JR NC,$+3 ADD A,H RRA RR L JR NC,$+3 ADD A,H RRA RR L JR NC,$+3 ADD A,H RRA RR L JR NC,$+3 ADD A,H RRA RR L LD H,A
>>831 「必要の無いところでも最適化する」奴は使えん
「必要の無いところでも最適化できる」奴なら同意だが
コピペついでに古い問題をもう1度引っ張り出して考えてみた。
>>211 >Z80アセンブラデ ジサツプログラムヲ ツクレ
> メモリクウカンハ 0-FFFFh スベテ RAM
> ソノルーチンヲ ヨブト RAMエリア スベテ 0クリア
> ルーチンハ リロケータブル デアルコト
> スグ コタエラレルヤツハ カクナ
>>640 もいいのだが、残念ながら完全リロケータブルではない。
後の方もSPが自分自身の中を指してたら動作がおかしくなるという問題がある。
LD B,37h ;37h=SCFのコード
LOOP1:
INC HL
LD A,B
CP (HL)
JR NZ,LOOP1
XOR A
LD (HL),A
ADD1:
SCF
JR C,LOOP1
LD BC,ADD2-ADD1
ADD HL,BC
LD SP,HL
LD H,A
LD L,A
ADD2:
NOP
LOOP2:
PUSH HL
JR LOOP2
まずはSCF命令を探して0クリアする。もしそれがADD1のところのSCF命令だったらそこを
通過した時にキャリーが立たなくなるのでループから抜けるが、そうでなければもう1度
やり直す。いつかはADD1のSCF命令に行き当たるはず。
(どうせ全部消すから、他を書き換えてもかまわないという考え)
後はそれを元に初期アドレスを求め、SPにセットしてひたすら0をプッシュ。
延々プッシュしたらループのJR命令自身も消されるが、そうなればPUSH HL以外の命令は
全てNOPなので1回りしてきてもう1度実行、結局全てのコードがあぼーん。
っと、ここまで考えて問題点があることに気づいた。最初はBレジスタを使わず直接
LD A,37hと書いていたが、これではその37h自身を先に書き換えたらアウトではないか。
仕方がないのであらかじめ別のレジスタに入れて、そちらをロードすることにした。
(そちらが書き換えられても、もはや用済みなので関係ない)
840 :
デフォルトの名無しさん :02/04/20 13:08
>>838 必要が無いとわかってるならいいんじゃない?
必要性が判断できる奴なら問題ないよん
別にこれが使えたらエライってもんじゃないけど でも sense of wonderが感じられた方がいいんじゃないの?
842 :
デフォルトの名無しさん :02/04/27 10:25
age
TMS320C3xのユーザーズマニュアルにあるブートローダのコードは面白い ROMとシリアルからブートロードするのだけど その部分を1ワード読むのを CALL AR3 と間接コールにしてるのは当然だけど このAR3の示す1番地前に RPTB 命令を置いて DEC するとこのサブルーチン 内でループするようにしている
844 :
デフォルトの名無しさん :02/04/28 20:21
>>843 ごめん、面白そうなのによくわからない
アセンブラはx80系しかわからないんだけど、
そんな俺にも解りやすく説明できたらお願いします。
ちょっとマニュアル見てみたんだけどRPTBって ループ終了番地を指定してループを作る命令みたいだから、 ブートロードのコードってZ80ニーモニックもどきで書くとこんな感じかな? MAIN: : LD HL,SUB CALL SUB ; 1ワード嫁 : LD B,100 LD HL,SUB DEC HL CALL SUB ; 100ワード嫁 : ; ; RPTB ENDLOOP SUB: ;ROM嫁 ENDLOOP: RET 1つのコードを呼び出しで工夫して1バイト読みと 多バイト連続読み両方に使えるようにしてあるのか。 面白れー(w #そういやTMS320C3xってDSPなのか。
age
そういやここの1は最近どうしてるんだ(笑)
あ、 誤:CALL SUB 正:CALL (HL)
849 :
デフォルトの名無しさん :02/05/04 21:41
age
850 :
デフォルトの名無しさん :02/05/13 13:20
保全age
age
switch(1) { age("保守保守"); case 1: }
つーか、このスレ過去の遺物だから保守要らない
echo "ホシュ";
a ┌──┐ │┌─┼┐ ││ ││ └┼─┘│ └──┘b a+b. |a*b. |a^b. ┏━━┓ |┌──┐ |┏━━┓ ┃┌─╋┓|│┏━╋┐|┃┏━╋┓ ┃│ │┃|│┃ ┃│|┃┃未┃┃a,bの内、重なっていない所を選択 ┗╋─┘┃|└╋━┛│|┗╋━┛┃(重なっているところは未選択) ┗━━┛| └──┘| ┗━━┛ ↓こういう状態ね ┏━━━┓ ┃llllllllllllllll┃ ┃lllll┏━╋━┓ ┃lllll┃ ┃lllll┃ ┗━╋━┛lllll┃ ┃llllllllllllllll┃ ┗━━━┛
初期状態 a. | ┌──┐| │ │| ┌──┐ │ │| │ │ └―─┘| │ │ | └──┘b a^=b : aとbを重ね、aを「a,bの内、重なっていないところを選択したもの」にする。 : bはそのまま。 a. |b ┏━━┓ | ┃┏━╋┓| ┌──┐ ┃┃未┃┃| │ | ┗╋━┛┃| │ |bは変更無し ┗━━┛| └──┘ b^=a : 「変更後のa」とbを重ね、 . 「重なっていないところを選択」したものを改めてbとする。 : aはそのまま。 a. |b ┏━━┓ |┌──┐ ┃┏━╋┓|│ | ┃┃未┃┃|│ |:::: ┗╋━┛┃|└──┘:::: ( bが、「最初のa」の位置に移動した ) ┗━━┛| :::::::::::::: a^=b : さらにaとbを重ね、「重なっていないところを選択」したものをaとする。 : bはそのまま。 a. |b :::::::::::::: |┌──┐ : : ┌──┐|│ | : : │ ||│ |:::: │ ||└──┘:::: ( aが、「最初のb」の位置に移動した ) └──┘| ::::::::::::::
>855 分かりづらいだろうから、紙の上でやってね
859 :
デフォルトの名無しさん :02/07/10 13:55
ラスタオペレーションキター(゚∀゚)ー!!
862 :
デフォルトの名無しさん :02/07/12 21:32
xor eax, ebx xor ebx, eax xor eax, ebx
>>862 mov ecx, eax
mov eax, ebx
mov ebx, ecx
ですが何か?
>>863 それでは ecx が破壊されてしまうので面白味に欠ける。
push eax push ebx pop eax pop ebx
>>865 うむ。よく使ったテクだな。レジスタが少ないと仕方ない。
XCHG EAX,EBX
885にて既出。
870 :
デフォルトの名無しさん :02/07/13 15:11
xchg 命令は遅いのだよ
871 :
デフォルトの名無しさん :02/07/13 17:53
10進の正整数から上位4桁目を四捨五入して4桁目以降を0にした数を 求めます。(例えば 987654 => 988000 分かりにくい説明でスマソ) long の場合、10億未満限定ですが。 long f(long data) { long bunbo = 1; while(data/(1000*bunbo) > 0) bunbo *= 10; data += (bunbo >> 1); return bunbo*(data/bunbo); } もっと効率のいい方法を考えているのですが・・・。 全然トリッキーでもなんでもないですね。すみません、逝ってきます。
>>871 「3桁の概数を求める」と言えば分かるぞ。
873 :
デフォルトの名無しさん :02/07/14 00:12
何がじゃ
破壊ダー
876 :
デフォルトの名無しさん :02/07/14 00:16
スタックだろうが eax,ebxの順に入れて eax,abxの順に取り出したら以下略
自信ないのか
何を破壊するの?
873赤っ恥
↓がんがれ
xchg eax, ebx
冫─' ~  ̄´^-、 / 丶 / ノ、 / /ヽ丿彡彡彡彡彡ヽヽ | 丿 ミ | 彡 ____ ____ ミ/ ゝ_//| |⌒| |ヽゞ |tゝ \__/_ \__/ | | ヽノ /\_/\ |ノ _____ ゝ /ヽ───‐ヽ / / ヽ ヽ──' / < ン? \  ̄ ,/ \_____ / ⌒\ \ | \ \\ | |\ v' )) | /⌒ー'‖ | / イ || | / | || \_/ (__つ
遅かった・・・鬱
あー、それ以前の全く見ずに書いてたよ。 それなら納得。
IOCCC のは笑ってしまう。あそこまで良くやる。
>>871 long f(long data) { return (data+500)/1000*1000; }
じゃだめなのか?
最適化で(以下略
人
(...・.・.) <
>>890 だめだハゲ-
>>871 long f(long data) {
return (long)( round(data/1000.0)*1000);
}
>>890 、
>>893 >>871 がやりたいのは
987654 => 988000
9876543 => 9880000
98765432 => 98800000
のようだが。
>>870 xor 3回よりも速い罠
mov 3回よりも速いみたいだが
push/popは勿論論外(w
>>871 long f( long data ) {
return (long)((int)(data/(pow(10.0,(int)(log10(data)-2)))+0.5) * pow(10,(int)(log10(data)-2)));
}
or
long f(long data)
int base;
base = pow( 10, (int)(log10(data)-2));
return (long)( (int)(data/base+0.5) * base );
}
>>871 while(data / (1000*bunbo) > 0)
↓
while(data > 1000*bunbo)
だけで大分速くなりそう。
皆様レスどうも!勉強になります。
>>894 そうです、その通りなのです。
具体的には、dataが3桁以下ならそのまま出力で、4桁以上のものに
ついては、上位3桁のみを残して、4桁目を四捨五入するのが目的です。
説明不足でした、スマソ。もう一回逝ってきます。
>>896 なるほど、(int)log10で桁数求まりますね。高校数学忘れてる・・・ウツダ
一行コード・・・萌えるなぁ。
しかし浮動小数演算コストも伴う諸刃の剣・・・
>>897 うわ〜、むちゃくちゃ速くなりました。ありがとうございます!!
速度比較してみました。といっても、下に書いたコード実行しただけですが。 うちの環境(Athlon1333MHz,VC++6.0 Release,windows 2000)で 1億回ループさせた場合、 896 => 約44秒 897 => 約7秒 でした。やっぱり割り算や浮動小数点演算はコストかかりますね・・・。多謝! //--------------------------------- #include <stdio.h> #include <windows.h> #include <math.h> long f896(long data) { return (long)((int)(data/(pow(10.0,(int)(log10(data)-2)))+0.5) * pow(10,(int)(log10(data)-2))); } long f897(long data) { long bunbo = 1; while(data > (1000*bunbo)) bunbo *= 10; data += (bunbo >> 1); return bunbo*(data/bunbo); } int main(int argc, char* argv[]) { long x = 190742105; long result = 0; DWORD st=0,en=0; st = GetTickCount(); for(int i = 0;i < 100000000;i++) result = f896(x); en = GetTickCount(); printf("f896() : %ld : %d.%03dms\n",result,(en-st)/1000,(en-st)%1000); st = GetTickCount(); for(int j = 0;j < 100000000;j++) result = f897(x); en = GetTickCount(); printf("f897() : %ld : %d.%03dms\n",result,(en-st)/1000,(en-st)%1000); return 0; }
あ、私が最初に書いたコードは約28秒でした。 書き忘れてた、やっぱり逝こう。
903 :
逝って良しの1 :02/07/14 11:34
縦に読むと別の動作をするコード。
age
>>903 口で言うだけなら誰でも出来る。
人にお題を出すなら、まず自分が回答例を
出してからでないと人は動いてくれないぞ。
増してや出題者が「逝って良しの1 」となると・・・(w
906 :
デフォルトの名無しさん :02/07/30 20:50
>>243 こうしたら andが1つ減ってるけど シフトが増えてるか
bits = (bits & 011111111111)
+ (bits
>>1 & 011111111111)
+ (bits
>>2 & 011111111111);
bits = (bits+(bits
>>3 )) & 030707070707;
bits += (bits>> 6) ;
bits += (bits
>>12 ) ;
return (bits+(bits
>>24 )) &0x3f;
908 :
デフォルトの名無しさん :02/07/30 21:06
そだね
909 :
デフォルトの名無しさん :02/08/03 17:28
立っているビットのうち最下位のビットだけを取り出す方法 #define GETLSBBIT(x) ((x) & (-(x))) /* いい名前が考えつかんが... */ 例) x = 10010 -x = 01110 ; 01101 + 1 x & -x = 00010 先輩伝授。勉強になったなー。(wai_flgで使える)
素数を求める世界最速プログラム for C++ #include <iostream> #include <functional> #include <algorithm> using namespace std; template <unsigned int Val> struct UintType { enum { value = Val }; }; template <bool Val> struct BoolType { enum { value = Val }; }; template <unsigned int PrimeNum> struct GetPrime; template <unsigned int PrimeCount> struct NextPrimeSub1; template <unsigned int Rest> struct NextPrimeSub3 { template <unsigned int PrimeCount, unsigned int Cand, unsigned int PrimeNum> struct set_state : NextPrimeSub1<PrimeCount - 1> ::template set_state<Cand, PrimeNum + 1> {}; }; template <> struct NextPrimeSub3<0> { template <unsigned int PrimeCount, unsigned int Cand, unsigned int PrimeNum> struct set_state : NextPrimeSub1<PrimeNum + PrimeCount> ::template set_state<Cand + 2, 0> {}; }; template <bool Over> struct NextPrimeSub2 {}; template <> struct NextPrimeSub2<true> { template <unsigned int PrimeCount, unsigned int Cand, unsigned int PrimeNum> struct set_state : UintType<Cand> {}; }; template <> struct NextPrimeSub2<false> { template <unsigned int PrimeCount, unsigned int Cand, unsigned int PrimeNum> struct set_state : NextPrimeSub3<(Cand % GetPrime<PrimeNum>::value)> ::template set_state<PrimeCount, Cand, PrimeNum> {}; };
素数を求める世界最速プログラム for C++ (続き) template <unsigned int PrimeCount> struct NextPrimeSub1 { template <unsigned int Cand, unsigned int PrimeNum> struct set_state : NextPrimeSub2<(GetPrime<PrimeNum>::value * 3 > Cand)> ::template set_state<PrimeCount, Cand, PrimeNum> {}; }; template <> struct NextPrimeSub1<0> { template <unsigned int Cand, unsigned int PrimeNum> struct set_state : UintType<Cand> {}; }; template <unsigned int PrimeNum> struct GetPrime : NextPrimeSub1<PrimeNum - 1> ::template set_state<GetPrime<PrimeNum - 1>::value + 2, 0> {}; template <> struct GetPrime<0> : UintType<2> {}; template <> struct GetPrime<1> : UintType<3> {}; #define PRIME(n) (GetPrime<n>::value) static unsigned int prime_array[] = { PRIME(0), PRIME(1), PRIME(2), PRIME(3), PRIME(4), PRIME(5), PRIME(6), PRIME(7), PRIME(8), PRIME(9), PRIME(10), PRIME(11), PRIME(12), PRIME(13), PRIME(14), PRIME(15), PRIME(16), PRIME(17), PRIME(18), PRIME(19), PRIME(20), PRIME(21), PRIME(22), PRIME(23), PRIME(24), PRIME(25), PRIME(26), PRIME(27), PRIME(28), PRIME(29), PRIME(30), PRIME(31), PRIME(32), PRIME(33), PRIME(34), PRIME(35), PRIME(36), PRIME(37), PRIME(38), PRIME(39), PRIME(40), PRIME(41), PRIME(42), PRIME(43), PRIME(44), PRIME(45), PRIME(46), PRIME(47), PRIME(48), PRIME(49), }; enum { n_prime_array = sizeof prime_array / sizeof *prime_array }; struct PutUint : unary_function<unsigned int, void> { void operator()(unsigned int val) { cout << val << endl; } }; int main() { for_each(prime_array, prime_array + n_prime_array, PutUint()); return 0; } マクロアセンブラでこーゆーネタがあったらしいけど・・・。
スマソ、タブが欠けた。
>>913 当時は洩れ自身は消防だったから(消防にすらなってなかったかも)、
実は何に載っていたのかは知らない。ちなみに、911はg++では通ったけど、
VC6やBCCでは通るかどうか。つーか、実験中に何回もコンパイラが死んだ・・・
>>914 VC6ではエラーが一杯出てきて無理ですた。やる気が無いので直す気も無い。
916 :
デフォルトの名無しさん :02/08/16 20:15
>911 見た感じ小さいほうから素数を50個列挙するプログラムっぽいけど、 ”小さいほうから50個”と静的に決まってるんだったら unsigned int prime_array[] = { 2, 3, 5, 7, ... (省略), } と書くのと変わらないと思う。
ってか、クラス名きしょい
age
919 :
デフォルトの名無しさん :02/08/23 05:24
--i++
age
うわ、感動。まだこのスレを保持していただいていたとは…… ゆっくり読ませていただきます。有難うございます>みなさま
922 :
デフォルトの名無しさん :02/10/10 06:03
すいません質問です。
過去に、ビット数をカウントする技がありましたが、
int right_shift(int n) //←signedに注目
{ return n
>>1 ;}
signedの右シフトは
if (right_shift(-1) == -1)
が保証されるということでいいんでしょうか?
ちなみにVCとBCCで試したら両方とも真になりました。
924 :
デフォルトの名無しさん :02/10/10 06:13
よくない。VC++もBCCも同じCPUだからあまり検証になってないな。
ちなみにint nをunsigned nに変更したら、両方ともfalseです。 この辺は言語仕様で決まってないのかな。
>>924 そうですか。といっても違うCPUなんて持ってないし。困った。
確かにこの結果だけを鵜呑みにしてたら、 後でとんでもないことになりそう。
928 :
デフォルトの名無しさん :02/10/10 06:33
929 :
デフォルトの名無しさん :02/10/10 06:36
>>928-929 ありがとうございます。
じゃあ、処理系毎に算術シフトになるかどうかの切り分けを
入れる必要がありますね。
まず、2の補数表現の符号付整数がサポートされていて算術シフトが定義されているなら、 -1の算術右シフトは-1だ そして、符号付整数の表現方法は 昔は別の表現もあったが 今は2の補数でないチップはまず無い -a = not(a)+1 任意の負数は全ビットの1の補数に1を加算したもの=2の補数 でないチップは博物館か、よほど古いシステムでしか残っていない。 そんな環境ではC言語で右算術シフトなんてコ洒落たものは使えないだろう
右辺が2以上でも-1ダヨネ? if ((-1 >> n) == -1) n:2〜31
ダヨネー?ダヨネー?
935 :
デフォルトの名無しさん :02/10/15 09:29
そろそろ次スレ立てて。
まだはやい
物凄く息の長いスレだね
938 :
デフォルトの名無しさん :02/10/27 10:28
hoshu
939 :
デフォルトの名無しさん :02/10/28 16:27
940 :
デフォルトの名無しさん :02/11/12 08:44
test
941 :
デフォルトの名無しさん :02/11/20 17:27
次スレ、まだかな? と、ゆー訳で、素数判別1行awkプログラム: awk '{for(a=int(sqrt($1));$1%a>0;a--);print a-1?"N":"Y",a"*"$1/a}'
942 :
デフォルトの名無しさん :02/11/22 23:40
矩形内に点があるかどうかを判定する、トリーキなコードありませんか?
bool PtInRect(BOX b, POINT p) { return !!(rand() % 2); }
p(x,y), b(x1,y1,x2,y2) の時(適当) (x-x1)*(x-x2)<=0 && (y-y1)*(y-y2)<=0 が真なら矩形内(境界線上含む)に点がある。
x<x1 の時、 x-x1<0 かつ x-x2<0 より、(x-x1)*(x-x2)>0 x>x2 の時、 x-x1>0 かつ x-x2>0 より、(x-x1)*(x-x2)>0 x1<x<x2の時、 x-x1>0 かつ x-x2<0 より、 (x-x1)*(x-x2)<0 とりあえず単純に if 使うよりはトリッキーって事で。
>>945-946 全然トリッキーじゃないです。
それはこれでできます。
((x - x1) | (x2 - x) | (y - y1) | (y2 - y)) < 0
理由は符合ビットが立つかどうかを考えれば一目瞭然かと
"< 0" は ">= 0" の間違えです
>>947 それは負数が2の補数表現じゃないと通用しないが
1の補数表現でも通用する、と思ったが、-0が問題か。
951 :
デフォルトの名無しさん :02/11/23 19:01
953 :
デフォルトの名無しさん :02/11/23 21:34
矩形内に点があるかどうかを <, <=, >, >= の演算を行わずに判定する方法はありますか?
勿論、数は実数という条件で・・・
.lt.や.le.を使えば良い(ぉ
>>955 いや、これは表記法の問題ではなくて、
数の大小を比較せずにって事。
なんで大小比較があかんの?
>>957 いや、なんとなく。ただの思いつき。
そんな事できないかなぁ、って思っただけ。
でも、そんな事をやってしまうのがトリッキーって奴では?
実数?浮動小数点形式か?
>>961 とりあえずそれで。
但し処理系依存(機械エプシロン分足して走査する、みたいな)は
嫌だな・・・
符号bitを返す関数signがあるとすれば a<bは、sign(a-b)!=0と同じ。 あとはもう自明なので述べない。
>>963 つーか、それって sign 自体が内部で(0との)大小比較を行っているだけ
だと思うが(メモリ上での操作は別として、意味的に)。。。
しかしコンピュータの中で動く以上、それもまた回答になるのだろう。
ま、こんな問題、あまり深く追求しても仕方ないか。
とりあえず付き合ってくれてありがと。
IEEE754 浮動小数点だったら先頭が符号ビットだから整数キャストで947と同様にいけそうな。
Σ(゚д゚lll)ガーン
/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\ Λ_Λ | 君さぁ こんなスレッド立てるから | ( ´∀`)< 厨房って言われちゃうんだよ | ( ΛΛ つ >―――――――――――――――――――‐< ( ゚Д゚) < おまえのことを必要としてる奴なんて | /つつ | いないんだからさっさと回線切って首吊れ | \____________________/ (-_-) ハヤクシンデネ… (-_-) ハヤクシンデネ… (-_-) ハヤクシンデネ… (∩∩) (∩∩) (∩∩) (-_-) ハヤクシンデネ… (-_-) ハヤクシンデネ… (-_-) ハヤクシンデネ… (∩∩) (∩∩) (∩∩) (-_-) ハヤクシンデネ… (-_-) ハヤクシンデネ… (-_-) ハヤクシンデネ… (∩∩) (∩∩) (∩∩)
埋め
埋め
揉め
産め
多め
止め
戒め
噛め
詰め
決め
爪
埋め
埋め
埋め
埋め
埋め
埋め
埋め
埋め
埋め
埋め
埋め
埋め
埋め
埋め
15分間隔で埋め立て?
998
999
1000でつ
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。