トリッキーなコード

このエントリーをはてなブックマークに追加
1
独りよがりのためのスレッド
大体トリッキーなコードを書く奴に限って
致命的なバグを出したりするんだけど、
書きたいもんはしょうがない。
2:2001/02/26(月) 21:51
サンプルまでに有名な奴を1つ

#define swap(a,b) a^=b^=a^=b
3デフォルトの名無しさん:2001/02/26(月) 22:06
>>2
すげー! あ、いやまじで。メモッとこ
4デフォルトの名無しさん:2001/02/26(月) 22:11
そして3は浮動小数点演算に上記のマクロを使用して氏んだ
5:2001/02/26(月) 22:30
>>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
>>6
Perlだと普通じゃない?
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を開け、さもなくば逝ってよし」
103:2001/02/27(火) 01:07
>>4
またまたお得情報! うん、確かに使えない

>>5
ASSERTって何? namcoの戦車ゲーム? でもスペル違うな〜
あ、いやまじで疑問。
118:2001/02/27(火) 01:12
確かにperlじゃ普通かも
ごめん宇津だし脳
12デフォルトの名無しさん:2001/02/27(火) 01:23
>>10

ASSERTの使い方については、
『Writing Solid Code』という本を読むといいよ。
1310:2001/02/27(火) 01:31
>>12
えーとswap(a,a)だとaが0になっちゃうってこと?
でaが0なもんでエラーになっちゃうってこと?
ちょっと実験してみます。

http://www.microsoft.com/japan/developer/library/vccore/_core_the_assert_macro.htm
とかですか? 他の言語でもきっと大差ないよね?
1413:2001/02/27(火) 01:40
実験してわかったぴょん
swap(a,a)のように本マクロで同一変数を使用した場合、
a^a の結果が a に代入されるため、結果 a==0 になってしまう
Cって奥が深いぴょん
15デフォルトの名無しさん:2001/02/27(火) 01:47
お礼になるか分からないけど最近作った駄作だぴょん
#define bitchack(a,b) (a>>b)&1
aのb番目(0〜)のbitが勃っていたら1、勃っていなかったら0
16デフォルトの名無しさん:2001/02/27(火) 02:09
bitcheck?
>>15
1715:2001/02/27(火) 02:26
>>16
bitcheckぴょん
ついでに出てきた駄作ぴょん
#define bitset(a,b) a|=(1<<b)
#define bitreset(a,b) a&=~(1<<b)
代入したくなかったら=を捨てるぴょん
18: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:2001/02/27(火) 09:52
>>20
あ、なるほど
?:の優先順位のバグがちょっと気になるけど、
簡単なswitchを書くならこちらの方が見やすいかもね。
効率が悪くなるのが残念だけど。
22デフォルトの名無しさん:2001/02/27(火) 10:09
>21
コンパイラの最適化を信じなさい(笑)
23デフォルトの名無しさん:2001/02/27(火) 10:31
>>1
キボーンは、こんな感じでちゅか。

switch(c) {
  case 0:
    /* 0 */
    ....;
    if (0)
    case 1:
      /* 1 */
      ....;
    /* 0,1 */
    ....;
    break;
  default:
    /* others */
    break;
}
24デフォルトの名無しさん:2001/02/27(火) 10:37
トリッキーなコードに浸っているようでは所詮厨房
25デフォルトの名無しさん:2001/02/27(火) 10:52
トリッキーコードに浸って厨房っぷりをはっきするスレッドでは。
26デフォルトの名無しさん:2001/02/27(火) 11:32
>>24
いいから、なんか出せ!
27デフォルトの名無しさん:2001/02/27(火) 11:34
大昔・・・、
FORTRANで、いかに短い行数(=パンチカードの枚数)で、万年カレンダー等の
プログラムを作れるかを競ってたなぁ〜。

結構ロジック・アルゴリズムの勉強にはなったよ。
28:2001/02/27(火) 11:35
>>23
exactly!だだ出来ればブロックで囲むとなお可。

>>24
25の言うとおり、厨房ぶり満載のスレッド。
1で書いたけど、実際仕事でトリッキーなコードを書く奴に
ろくな奴がいないのは承知。でも書きたいんだよ
29デフォルトの名無しさん:2001/02/27(火) 11:35
Z80のアセンブラで最速かつ最短の乗除算ルーチンを…
30:2001/02/27(火) 11:37
>>27
それと、N88BASICで1行プログラミングとかね。
31名無しさん@お腹いっぱい。:2001/02/27(火) 12:29
>>31
1 end
32デフォルトの名無しさん:2001/02/27(火) 14:41
>>23
申し訳ないけどif(0)のあたりが意味不明だぴょん
誰か解説お願いだぴょん
てゆーか、今まさにそのコードを使ってみたいぴょん

・・・あ、やっぱ四の五の言わずに実験してみるぴょん
33デフォルトの名無しさん:2001/02/27(火) 14:51
>>32ぴょん
実験しても、理解しにくいと思いまちゅ。

gotoだと見た目にトリッキーさに欠けるから、if(0)を使ってるだけでちゅ。
使うのは、砂場のお遊びまでにしといてくだちゃい。
3424:2001/02/27(火) 16:16
ポインタから0か1のbool型に変換したい時に普通
b = (ptr != NULL)
なんて書くところを
b = !!ptr
と書くのはどう?
トリッキーでもないけど読みやすさの点から結構気に入った書き方
35: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
うわ、面白い!!
テストしてみよ、どう動くんだろう。

俺厨房。糞コードマンセー
3724: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再起動させたほうが早かったんだよね。
4236:2001/02/27(火) 17:24
ちゃんと動くじゃん、仕事で使ってみたいな。
やっぱ、書き直しか?

つーか、上司が糞だから通りそうで嫌だな。
43: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だけど。
46デフォルトの名無しさん:2001/02/27(火) 18:15
>>39
ごめん。Pascalだとあんまりトリッキーなのは、書かせてもらえないの(藁
47:2001/02/27(火) 18:28
42ではないが>>44
if(0)で次の1文がとばせるんですが、
switchのcaseで飛んできたものは実行される、という訳です。
上から順次実行してきた場合はとばされるけど、
case宛にjumpしてきたコードは実行される。
言葉にすると難しいな。やっぱ42さんお願い
48デフォルトの名無しさん:2001/02/27(火) 18:39
>>44
普通に>>35でわかりやすい例が挙がってるじゃん。読めよ
49デフォルトの名無しさん:2001/02/27(火) 18:39
>>47
ありがとうございました。
解かりました。
if(0)を FOR文等に変えてみてもトリッキ−な事できますね。
50: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のマシンコード};
54デフォルトの名無しさん:2001/02/27(火) 19:31
>>53
ベーマガの投稿プログラムかよ(ワラ
55:2001/02/27(火) 19:31
>>53
そんな事出来るの?コンパイラ依存でなくて?
実験実験。ブルースクリーン出そうだが。
5653:2001/02/27(火) 19:35
昔の話しで環境依存だとおもう。
最近のはデータセクションにコードは置けないだろうから。
57デフォルトの名無しさん:2001/02/27(火) 19:40
>>56
たぶん、エントリーポインタ書き換えればいけるよъ( ゚ー^)
58:2001/02/27(火) 19:42
>>56
考えてみればそうだね。
今エントリポイントを操作して頑張ってたけど、
どうあがいてもプログラムロード即死亡。
コードセクションにデータをおければいいんだが。
59デフォルトの名無しさん:2001/02/27(火) 20:05
コードってゆうか
#define "debug.c"
debug.cの中にはデバッグ用のソースが入っている。
60デフォルトの名無しさん:2001/02/27(火) 20:13
>>59

#include じゃなくて?
61デフォルトの名無しさん:2001/02/27(火) 21:05
#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;
}

63デフォルトの名無しさん:2001/02/28(水) 00:19
なんか、このスレに一人だけ素の厨房がいるな
64デフォルトの名無しさん:2001/02/28(水) 02:00
キミのことかね?
65デフォルトの名無しさん:2001/02/28(水) 04:20
#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動作確認しました。
動いた。
71デフォルトの名無しさん:2001/02/28(水) 15:23
>>62
error C2007: #define の後に識別子が必要です。
72デフォルトの名無しさん:2001/02/28(水) 15:27
>>70
隣家オプション求む
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;
鬱だ。
76デフォルトの名無しさん:2001/02/28(水) 22:18
char main=-61;

動いちゃったぴょん
Linuxならふつーに動くッぽいぴょん
77デフォルトの名無しさん:2001/02/28(水) 22:44
トリッキーの極みと言えば、やっぱり(67の様な)オブジェクトコードの埋め込みや、
自己書き換えだと思うけど、誰か本格的にやってる人いない?
78デフォルトの名無しさん:2001/02/28(水) 23:05
>>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(); /* 実行 */
}
80デフォルトの名無しさん:2001/02/28(水) 23:35
>>79
何に使うの。具体例を。

 if ( 用途が無い ) return 屑コード;
8179:2001/02/28(水) 23:39
これができて何が嬉しいかというと、普通のファイルに関数そのものを置ける事。
DOSのsmallモデルとかの、実行ファイルのサイズに制限のある環境で、
擬似的にオーバレイが可能になるとか。
他に利点無かったかな・・・
82デフォルトの名無しさん:2001/02/28(水) 23:45
  ∩ ∩
 (゜∇゜) ピョピョ
 (   )
  ⊥⊥
8379:2001/02/28(水) 23:46
まあ、処理系依存なんだけど、大抵の環境で同じ様な事が出来る筈。
TEXTセグメントに納まらなくなった場合とかに、アセンブラで書いて小さくする手間が省ける。
アセンブラを直接弄らない事で、ある意味移植性は高くなる。(藁
84デフォルトの名無しさん:2001/02/28(水) 23:46
(cond
((用途が無い?) '屑コード)
((実用にはならないけど面白い?) 'そうだね)
(else '何かあるの?))
85デフォルトの名無しさん:2001/02/28(水) 23:47
>>79
func2()がfunc1()よりも後ろに置かれてるという保証はあるの?
8685:2001/02/28(水) 23:49
ごめん。わかってるみたいね。
87デフォルトの名無しさん:2001/02/28(水) 23:49
>>85
引き算したり比較したりしてうまいことやる。

if ( func1 < func2 )
{
...
}
else
{
...
}
8879:2001/02/28(水) 23:51
>>85
だからー、79で
>関数のサイズは、コンパイラが出力するMAPファイルやアセンブラ出力で関数の
>位置関係から算出します。
と書いてあるだろが。
ちゃんと読んでね。
89デフォルトの名無しさん:2001/03/01(木) 00:00
if文などの条件演算におけるXOR表現
(a < 0 != b < 0)
…この程度常識っすかね?
9079:2001/03/01(木) 00:01
まあ、今となってはあまり意味が無いか。
ゲームボーイなどの携帯ゲーム機ではいまだに有効な筈・・。
91>89:2001/03/01(木) 00:05
たしかその式はC言語では違法だった様な。コンパイラが警告ださない?
非ゼロ同士が一致するかは保障されてない筈。
でも大抵の環境で有効かな?
アセンブラ出力見ればはっきりするけど。
92デフォルトの名無しさん:2001/03/01(木) 00:11
>>84
面白い=トリッキーコード≠屑コード。

"The International Obfuscated C Code Contest"なんて
どこが面白いでちゅか?
93>91:2001/03/01(木) 00:11
んなわけねーだろ。
関係演算子の値は、常に0か1だ。
9491>93:2001/03/01(木) 00:15
あ、そうかも。式の値に対しての真偽値のことと間違えてた。
しまん
95デフォルトの名無しさん:2001/03/01(木) 00:36
// MSVC has for scope bug.
#if defined(_MSC_VER)
# define for if(0);else for
#endif
96デフォルトの名無しさん:2001/03/01(木) 01:05
多分トリツキーなことになると思うのでここで質問。

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
9996:2001/03/01(木) 01:23
>>97
やはり、printfの引数の数が鬼門ですね・・・
引数の数にあわせてdefineを代えるのも面倒(ごめんなさい)。
ここをトリックで切り抜ける方法がなんかないもんでしょかね。
10097>99:2001/03/01(木) 01:26
だからー、全体を括弧で囲めば、dprintf一個でも良いの。
dprintf(("p:%lx ->n:%lx\n", (long)p, (long)n));
10196:2001/03/01(木) 01:28
>>98
素ゥ晴らしい! 君は英雄だ!
ありがとう! 2chって素敵
10297>98:2001/03/01(木) 01:33
負けた。
実行されないコードがコンパイラによって削除されるかが鍵だなー。
10397:2001/03/01(木) 01:37
あ、普通削除されるか・・
10496:2001/03/01(木) 01:38
>>102
コンパイラの最適化で消えてなくなるようです。
(今 .s を出力して確かめてみた)
まさに実用的なマーベラストリックですね。
105デフォルトの名無しさん:2001/03/01(木) 01:43
>>97
Cよちよちの初心者です。お世話になります。

#define d1printf(t, a)

上の','とaの間にある半角スペースは、ある種のトリックでしょうか。
「コピペ」の言葉が、ちょっと気になったものですから・・・。
10697>105:2001/03/01(木) 01:49
空白は全然、なんの関係もないです。
みたまんまのマクロです。
107デフォルトの名無しさん:2001/03/01(木) 01:53
97じゃないけど、()のなかの空白は気にしなくてもいいよ。
108襴様:2001/03/01(木) 01:54
>>105
定説です。
109105:2001/03/01(木) 01:57
>>97
ありがとうございます。出直してきます。
110外付けSCSI:2001/03/01(木) 02:32
#ifndef DEBUG
#define DB(x)
#else
#define DB(x) x
111デフォルトの名無しさん:2001/03/01(木) 03:24
>>98
うわーかっこいい!サイコーだぴょん。
ん?・・・ちょっと待つぴょん

#ifdef DEBUG
#define debug
#else
#define debug 1?(void)0:
#endif

とすると、printfだけじゃななくてもどんな関数
(一時的なロギング関数とか)でもオッケーだぴょん。
こんな感じだぴょん
debug hoge();
112デフォルトの名無しさん:2001/03/01(木) 06:52
>>111
110さんのが、トリックを使わずに、可読性・汎用性も高く
副作用も少ない、すばらしい書き方の見本ではないのかな。

トリックをすべて否定している訳では無いよ。
113デフォルトの名無しさん:2001/03/01(木) 10:28
98のは昔のDOS処理系のLSI-C試食版やTurboCでも期待通り展開される。
114デフォルトの名無しさん:2001/03/02(金) 08:44
>>110
括弧つけるのが面倒だぴょん
生意気言ってごめんだぴょん
115デフォルトの名無しさん:2001/03/02(金) 11:59
>>114
デバッグ用のコードがシンプルでなければ・・・、
 デバッグ用のコードのデバッグをやるはめになる恐れがある。

まーふぃー(嘘)
116デフォルトの名無しさん:2001/03/02(金) 16:28
今でもよく使うトリック。

char* GetHogehogeFilename()
{
static char filename[_MAX_PATH + 1];
.....(hoge hoge).....
return filename;
}
117デフォルトの名無しさん:2001/03/02(金) 16:53
>>116
これはトリックというのか?
リエントラントでないのでsage
118デフォルトの名無しさん:2001/03/02(金) 16:56
トリックというより、単なる糞コードだな。
119デフォルトの名無しさん:2001/03/02(金) 17:57
>>117
> リエントラントでないのでsage
うむ。でも便利。Windowsだと怖いが。
120デフォルトの名無しさん:2001/03/02(金) 18:12
Windowsだとなぜ怖い?
どんなOSだろうと使い方間違えればすぐにバグの原因になるコードだと
思うけど。
121デフォルトの名無しさん:2001/03/02(金) 18:20
>>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では
何か違うの?
124デフォルトの名無しさん:2001/03/02(金) 21:03
最近のは知らないんだけど
昔のstrtokとかいうのも、そんな実装じゃなかったっけ?
125デフォルトの名無しさん:2001/03/02(金) 21:12
私にはレベルが高すぎて理解できないので、
どなたか教えてください。

>>98さんの
#define debug_printf 1 ? (void) 0 : printf
>>111さんの
#define debug 1?(void)0:
の行と、

#define debug
の違いを詳しく。
126125:2001/03/02(金) 21:15
↑失礼、記入漏れあり。訂正いたします。

#define debug
の違いを詳しく。
   ↓
#define debug_printf
#define debug
の違いを詳しく。
127デフォルトの名無しさん:2001/03/02(金) 22:40
自分でcppだけ実行して展開してみろ>125
128125:2001/03/02(金) 23:00
今、Cの本しか無いんです。
ヒントだけでもいいですから、教えてください。>>127さん
129デフォルトの名無しさん:2001/03/02(金) 23:27
自分で調べることが大切だ、ということを教えているのだよ。
130デフォルトの名無しさん:2001/03/02(金) 23:56
>>128
b=( a>0 ? 3 : 0 );
たとえばこれ、分かりますか?
多分Cの本には載ってるぴょん
131125:2001/03/02(金) 23:57
>>129
それはわかります。
Cの本で"プリプロセッサ”の章も調べた上でお聞きしているのです。

例えば、その本の中で、
グローバル変数の実体宣言と外部宣言のマクロを使った説明があるのですが、
(以下、引用)
#ifdef  GLOBAL_VALUE_DEFINE
#define  GLOBAL
#else
#define  GLOBAL extern
#endif

でマクロ定義して、GLOBAL_VALUE_DEFINEの定義/未定義によって、
GLOBALの置換文字列を空文字列またはexternにします。(以下、略)

つまり、上記での「空文字列」のやり方と何が違うのかと。お願い致します。
132125:2001/03/03(土) 00:07
>>130
3項演算子ですね。
代入演算子より優先順位は高いので、括弧は不要でしょう。
133デフォルトの名無しさん:2001/03/03(土) 00:10
>>131
あんまり変わらないぴょん
なんであんなふうになってるかというと
printfには引数があるからだぴょん
134125:2001/03/03(土) 00:20
>>133
ふむふむ、なんとなく。ありがとう。
135125:2001/03/03(土) 00:41
>>133
じゃあ、これでもいいって事ですか?

#ifdef DEBUG
#define debug
#else
#define debug //
#endif
136デフォルトの名無しさん:2001/03/03(土) 00:49
>#define debug //
"//"自体が#define行のコメント子になっちゃうでしょ。
137125:2001/03/03(土) 01:05
>>136
コメント>マクロ という事ですか。ふーむ。奥が深い。
138125:2001/03/03(土) 01:31
もう少しおつきあい下さい。
これなら、どぉ?

#ifdef DEBUG
#define debug
#else
#define debug /##/
#endif
139125:2001/03/03(土) 01:33
やっぱ、だめ臭いな。
140デフォルトの名無しさん:2001/03/03(土) 01:48
もうこのスレから出てってくれ>125
141フォルトの名無しさん:2001/03/03(土) 02:21
>>96
VC++6.0ならこれでOKみたい。
#ifdef DEBUG
#define debug_printf printf
#else
#define debug_printf
#endif
142>141:2001/03/03(土) 02:31
それが通らないコンパイラは存在しないだろう。
ただし引数が評価されるために副作用があるけどな。
143>138:2001/03/03(土) 02:37
まあ好き好きだから、それを使っとけ。
このようなコードでも、君の書いた通りには動くことだし。

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版との動作の差がなくなると思うのだが・・・
(なんの副作用もなければ最適化で消えると思うし)
145デフォルトの名無しさん:2001/03/03(土) 03:30
#ifdef DEBUG
#define debug
#else
#define debug 1? 0:
#endif

gccで問題なく実行できたぴょん
146デフォルトの名無しさん:2001/03/03(土) 03:32
四の五の言わずにまずトライ&エラーの精神を持つべきだぴょん
失敗は成功のおっぱいだぴょん
147デフォルトの名無しさん:2001/03/03(土) 03:36
148デフォルトの名無しさん:2001/03/03(土) 03:42
>>146
トライアンドエラーもよいけど、
たまには言語の仕様とか勉強して
理論的にプログラム書こうね!
149デフォルトの名無しさん:2001/03/03(土) 03:51
>>147 はどうやらVC++で
for ( i = 0; ... )
{
}
と書けるようにするテクニックを紹介してるみたいだ。
150デフォルトの名無しさん:2001/03/03(土) 03:55
>>149
for (int i = 0; ...) でしょ.
Watcom もこれできないんだよな−
151138>143:2001/03/03(土) 04:51
もう一回だけチャンスを。

#ifdef DEBUG
#define debug
#else
#define debug if(0)
#endif

>>140
なんかすごいの出してくれたら、そうします。
152デフォルトの名無しさん:2001/03/03(土) 05:08
>>151
すばらしいぴょん
それが正道っぽいぴょん
いつのまにかそんなにトリッキーじゃなくなってるぴょん・・・
153151:2001/03/03(土) 05:13
>>152
全てはあなたのお陰です。ありがとう。
154デフォルトの名無しさん:2001/03/03(土) 05:25
>>151
なんだ、まだやってたのか。
この場合は三項演算子を使うのが定石であって、
それ以外の解は存在しないんだって。
151ではこれが正しく動かないだろ?

if (...)
 debug printf(...);
else
 ...
155151:2001/03/03(土) 05:36
>>154
机上では、動くはずなんですけど。それより、
定石を破るのが「トリック」なのでは・・・?
156151:2001/03/03(土) 05:37
だめだね。ごめん>>155
157151:2001/03/03(土) 05:38
訂正:
だめだね。ごめん>>154
158デフォルトの名無しさん:2001/03/03(土) 05:44
これだったらどうだろう?

#define debug if(1) ; else
159151:2001/03/03(土) 05:51
「どっか逝け」の声は、もう十分に聞こえております。 が、
まだ煮え切らないので。

if-else のネストだけが問題なら、

#define debug while(0)

で、だめ?
160デフォルトの名無しさん:2001/03/03(土) 06:03
>>158-159
moe ? printf("ハァハァ") : debug printf("逝ってよし!");
だめだめ。
161デフォルトの名無しさん:2001/03/03(土) 06:36
あと、
debug printf("ヽ(´ー`)ノ") , debug printf("やっぱり氏のう");
だめだめ。
162!151:2001/03/03(土) 07:20
3項演算子でなくても
#define debug_printf 0 && printf
でどう?
163デフォルトの名無しさん:2001/03/03(土) 07:30
1 + debug_printf("だめだめ\n");
164151:2001/03/03(土) 08:17
>>163
ちょっと一眠りして、ひとつ考えてみたんですけど
まだつきあってくれます?
165151:2001/03/03(土) 08:23
とりあえず書きますので、また駄目出しお願いします。

#ifdef DEBUG
#define debug
#else
#define debug 0 &&
#endif
166151:2001/03/03(土) 09:20
>>163さん以外の方でも結構ですので、どなたか
>>165の「だめだめパターン」を教えてください。
167151: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"ってメッセージです。
環境のせいでしょうか。
168151:2001/03/03(土) 10:48
訂正:

上記、#define DEBUG の記述をコメントアウトしたときに、
コンパイラがエラーを返します。 ごめんなさい。
169デフォルトの名無しさん:2001/03/03(土) 11:17
もうこのスレ 151 にあげるから気が済むまでおやりなさい
170:2001/03/03(土) 11:25
さすがにかなりウザいと思い始めたり。

仕方ないので新しいネタ。
自分自身をファイルなどで読み込むことなく、
自分自身を表示するプログラムを書いてみそ。

ちなみに「可能です」。
わからない人は下の答え(たぶんすぐ誰かが書くだろう)を見ないで、
しばらく考えてみてはどうでしょう。面白い(かもしれない)よ

ちなみにN88BASICなら
10 LIST
ですね。
171:2001/03/03(土) 11:31
>>170
#include "hoge.h"

--hoge.h
int main(void){printf("#include \"hoge.h\"");return 0;}

こういうのはやめてね(涙)。
172151:2001/03/03(土) 12:04
振り返ってみると、確かに「荒らし」のごとくの連続書き込み。

151は、これをもちまして永遠に2chから去ることとなりました。
ご迷惑をおかけしました皆様方には、お詫び申し上げます。さようなら。
173デフォルトの名無しさん:2001/03/03(土) 15:56
>>170
> 10 LIST

system .... cat .... "What?" .... finish->face
174好評なのに絶版:2001/03/03(土) 16:42
printf("main=0x%x\n",main);
175デフォルトの名無しさん:2001/03/03(土) 17:23
なんか有澤誠が出てきそうなネタだな>不動点プログラム
176デフォルトの名無しさん:2001/03/03(土) 17:43
177好評なのに絶版:2001/03/03(土) 23:06
>>176
これって何か役に立つの?
取り立ててすごいわけでもなく、毒にも薬にもならない。
たとえば、自分の中の関数名一覧をとりだせちゃうとか、
そういうのだったらいろいろ応用(?)も効くと思う。
178デフォルトの名無しさん:2001/03/03(土) 23:24
>>170
ネタが高度すぎてだれも付いてこられないもよん。
179デフォルトの名無しさん:2001/03/03(土) 23:36
>>170
子プロセスでシェルを起動して、ソースファイルを
typeとかcatに渡すってのは?
180デフォルトの名無しさん:2001/03/03(土) 23:39
>>179
ファイルを読んじゃ駄目ってんだから、たぶん反則だとおもうぴょん
181:2001/03/04(日) 01:03
>>178
高度なパズルで、トリッキーなコードとは無関係だったからかも。
昔ソースコードに感染するウィルスを考えていたときに作ったんだけどね。

>>179
180さんの言われるとおり反則ですね〜。頑張って下さい。
182デフォルトの名無しさん:2001/03/04(日) 01:40
埋め込みオブジェクトコードの話題キボン
183デフォルトの名無しさん:2001/03/04(日) 01:58
文字コードを利用する奴はなんか反則っぽいのでいや。
昔、FORTRANですごいの見たことあるんだけど思い出せない。
184デフォルトの名無しさん:2001/03/04(日) 02:48
void call_func(void *func, ...)
{
func(...);
}
というような関数は実装できますか?
185デフォルトの名無しさん:2001/03/04(日) 03:00
キャストしておしまい>184
186デフォルトの名無しさん:2001/03/04(日) 03:01
>>184
だいたい出来るぴょん
187デフォルトの名無しさん:2001/03/04(日) 03:03
>184
関数ポインタ使え!
188デフォルトの名無しさん:2001/03/04(日) 03:12
>>184
void mick( int a )
{ printf("%d\n",a); }
void jack( void b() ,int a)
{ b(a); }
main()
{ jack( mick, 8 ); }

もっとかっこよく実装できるはずだがそこは諸兄に任せるぴょん
189:2001/03/04(日) 03:17
どういうときに効果的に使えるんだろう。
関数を引数に渡したくなったことはないけど、
もしかしたら綺麗にプログラミングするときに便利かもね

>>183
とりあえず文字コード(0x22とか)に頼らなくても作れます。
現在printfを使わないでやるのに挑戦中です。
(要するにcoutなどを使ってみる)
190デフォルトの名無しさん:2001/03/04(日) 03:34
>>189
>関数を引数に渡したくなったことはないけど
基本的に関数に引渡す値は、構造体に入れておけば
引数を渡しまわせるので、実地においてその辺りで
悩むケースは稀だと思うぴょん
191:2001/03/04(日) 03:45
>>190
悩むことは無くても、効果的に使用できる状況は知っておきたいね。
知らなくても美しく(かつ読みやすく(笑))書くことは出来ると思うけど。
192デフォルトの名無しさん:2001/03/04(日) 07:15
>>191
引数を渡すパターンも>>188で示してるつもりだぴょん
でも可変引数はこのパターンだと確かにちょっときついぴょん
トリッキーでも美しくもないのでsageるぴょん
193デフォルトの名無しさん:2001/03/04(日) 07:41
>>170
>自分自身をファイルなどで読み込むことなく、
>10 LIST
ワラタヨ! イイカラスーパートリッキナコタエダシテミセロ サイテンシテヤッカラ
194デフォルトの名無しさん:2001/03/04(日) 08:29
大して面白くはないな

#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);}
195デフォルトの名無しさん:2001/03/04(日) 08:38
訂正。無駄なことをしていた。

#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);}
196デフォルトの名無しさん:2001/03/04(日) 09:37
>>195
デタウンコ、マタコンパイルシテミタノカー
ウンコノゲンリョウト、コンペアシテミタノカー
..... < 10 LIST
197デフォルトの名無しさん:2001/03/04(日) 10:27
>>170
イイカラ、ハヤクコタエダシテミセロ
198Ken:2001/03/04(日) 11:19
やあみんな。
http://www.acm.org/classics/sep95/
の Stage I なんか、どうだい?
199デフォルトの名無しさん:2001/03/04(日) 12:12
>>198
ヘイ!ケン ソンナノココニカクト スキールヨリモラールガオチール
200: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;}
201デフォルトの名無しさん:2001/03/04(日) 12:47
>>200
イイヨ リカイシヤスイ イイコタエ
モスコシ トリッキナモンダイ ダシテクレ
202:2001/03/04(日) 13:27
>>201
問題考えるの簡単じゃないんだよ。
もう少し引っ張れると良かったんですが。

アセンブラレベルとかだったらトリッキーなコード多そうだけど、
ついてこれない人が大部分だろうし。

ちょっと考えてみます。誰かネタふって(笑)
c=a++ + + + + + ++a;
203:2001/03/04(日) 13:46
ちょっと思いついた問題。休日の午後だというのに厨房だな俺。

ビット数を求める最短のプログラムを書け、ってのはどうでしょう。
32bitの問題として、例えば5ならビット数は2(0101)って感じです。

あ〜ちなみにこのスレッドは
「こんなトリッキーなコードを書いたよ」
とか、
「この冗長なコードをトリッキーに出来ないかな」
とか、そういった話題も大歓迎です。
本来はそっちが目的だったし。
204デフォルトの名無しさん:2001/03/04(日) 13:54
>>189
SPMDプログラミングモデルで他ノードに対して関数呼び出しさせるときとか。
あ、クラスタなどでの並列プログラミングの話ね。
205デフォルトの名無しさん:2001/03/04(日) 14:23
>>202
ワルイコトシタ... スマンナ ジカンガ アレバ キョウリョクスル
c=a++ + + + + + ++a;

maximal munch ノ モンダイダナ
...ト コタエテシマウト マタワルイノデ オイトク
206: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);
208207: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: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);
}
これは自分で考えるとすると結構ハードだと思うのですが。
かくいう俺も独自で思いついたのはありません。
210デフォルトの名無しさん:2001/03/04(日) 15:13
>>209
条件から「最短のプログラムを書け」を削除しなきゃ。
211デフォルトの名無しさん:2001/03/04(日) 15:22
ライシュウマデ モーコラレナイノデ マァ'スゴーク'カンタンナヤツヲ ヒトツ オワビニ

Z80アセンブラデ ジサツプログラムヲ ツクレ
 メモリクウカンハ 0-FFFFh スベテ RAM
 ソノルーチンヲ ヨブト RAMエリア スベテ 0クリア
 ルーチンハ リロケータブル デアルコト
 スグ コタエラレルヤツハ カクナ

Z80ナラ ニーモニックヒョウグライ ナントカナルダロ
212:2001/03/04(日) 15:30
>>210
exactry。時間最短にしときましょか(笑)

>>211
Z80じゃなきゃ無理なのかな?
x86で出来ないかなぁ。
213:2001/03/04(日) 15:32
>>212
>exactry
ウツダシノウ
214デフォルトの名無しさん:2001/03/04(日) 16:26
>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
216デフォルトの名無しさん:2001/03/04(日) 17:58
と思ったらあったね。add [eax],al が 00h,00h
217デフォルトの名無しさん:2001/03/04(日) 19:01
>>215, 216
16bitモードの時、[bx+si]のModR/Mが00だったので
32ビットモードだとレジスタに'e'が付くだけだと思い込んでました
鬱だ
218:2001/03/04(日) 20:18
>>215
eaxとesiが0だったら、メモリを荒らすことなく
ずっとぐるぐる動き続けることができるのでは?
状況がわかりにくいので「自殺プログラム」って
何をするべきなのかわからないのですが。
219デフォルトの名無しさん:2001/03/04(日) 21:49
>>203

int numofbits(unsigned int n)
{
static const int bits[] = {
0, 1, 1, 2,
(途中省略)
30, 31, 31, 32,
};

return bits[n];
}

すいません。くだんねーのでsageます。
220デフォルトの名無しさん:2001/03/04(日) 22:04
>>218
自分のプログラムも含めてクリアする。つまり自殺。って事では。

>>219
一番最速!しかも、たぶん一番最小(34byte程度のテーブルなら)。
しかし、スレ趣旨から外れてるのは確かに。でもよく使うよね。
221デフォルトの名無しさん:2001/03/04(日) 22:09
>>220
ゴメソ。テーブルの数はまちがいじゃん。鬱・・・。
222:2001/03/04(日) 22:21
>>219
いや素晴らしい、ワラタ
マジで最速ですな。

>>220
自分のプログラムをクリアするだけ?
他のアドレスもクリアするんでしょ?
自分自身を先のアドレスへコピーして、
今までの自分を0でクリアする、そういうプログラムの事なのかな?
この場合はメモリが循環していないと駄目だよね。むーん
223デフォルトの名無しさん:2001/03/04(日) 23:53
>>203
int count(int a)
{
int ret=0;
for(;a;a>>=1)ret+=a&1;
return ret;
}
挑戦してみたぴょん。でももうちょっと削れそうだぴょん
224223:2001/03/04(日) 23:57
致命的なバグを発見したぴょん
でも秘密にしとくぴょん
225:2001/03/05(月) 00:05
>>223
サンクス。限度まで削って……
int ret=a&1;
while(a) ret+=(a>>=1)&1;
return ret;
あまりかわらんなぁ。
226:2001/03/05(月) 00:07
>>224
言われて気付いた ^^;
トリッキーなコードは書くべきじゃないね(笑)
227デフォルトの名無しさん:2001/03/05(月) 00:36
>>225
気のせいか処理が長くなってる気がするぴょん
228:2001/03/05(月) 00:37
>>223
最終案
do ret+=a&1;
while(a>>=1);
これだと可読性もあるし、ベストかもしれない。

テーブルもループも使わず、>>209の様な形で
かっこよくかつ短くビット数を得るトリッキーなコード
誰か考えてくれないかなぁ。
229デフォルトの名無しさん:2001/03/05(月) 00:46
>>228
渋くて速くてかっこいいぴょん
で、答が落ち着いたところでデバッグしとくぴょん
int count( unsigned int a )

つーか、この時間たぶん誰も見てないぴょん・・・
230デフォルトの名無しさん:2001/03/05(月) 01:56
うむ。処理系によってはちゃんと動く場合もあるかもね。
231デフォルトの名無しさん:2001/03/05(月) 01:59
>>230
処理系依存の処理ってどこ?
っていうか何に対してコメントしてるの?
232デフォルトの名無しさん:2001/03/05(月) 02:07
>>231
unsignedについてのコメントと思われるぴょん
右シフト時、処理系によって符号の扱いが違うかもしれない
ということ(0埋めか符号そのままか)だぴょん
unsignedにしとけば符号は関係ないので常に0埋めとなるぴょん
233お手軽な奴をひとつ:2001/03/05(月) 03:46
int numofbits(unsigned bits) {
return bits ? numofbits(bits / 2) + bits % 2 : 0;
}
234:2001/03/05(月) 06:26
>>233
いいねぇ。いかにもfc.comp.lang.cっぽい書き方が通っぽい。
たかがbitcheckでスタックを結構喰うのが難点だけど、
読みやすくていいんじゃないでしょうか。

>>230
unsigned/signedの右シフトなら、ANSI-Cではしっかりと仕様が決まってます。
signedの場合、最上位ビットは必ずそのまま設定されるはずですよ。
235デフォルトの名無しさん:2001/03/05(月) 06:27
あんま出番がないのでさみしいから・・・。

>>222
>他のアドレスもクリアするんでしょ?
Yes

>自分自身を先のアドレスへコピーして、
そんな事はしなくていいですよ。

>今までの自分を0でクリアする
一番最後にね。ヒント。

>この場合はメモリが循環していないと駄目だよね。
そう。処理中にNMI要求もない事が条件。
237:2001/03/05(月) 07:05
>>236
なるほど、意外と複雑じゃ無いみたいですね。
書けないこともなさそう。98emuでも入れて、
その中で試しに書いてみようかな。
俺はx86系アセンブリをあまり書いたことがないから
トリッキーに美しく書くのは無理だろうけど。

俺はライフゲームの無限生成パターンみたいなのを
想像していて、例えば mov [next eip],code みたいに
次々と自分自身を変更するコードを考えてた。
238デフォルトの名無しさん:2001/03/05(月) 07:23
自己書き換えは実行のみ可能なセグメントではエラーになるよ
>237
239:2001/03/05(月) 07:29
>>238
だからPC-9801(というかdos)を想定してました。
(確かにeipという書き方で誤解を生みますね)
code/dataセグメントが分かれてしまう環境では
自殺プログラムって原理的に不可能ですよね?

自殺プログラムが作れる条件は多分
・メモリが巡回している
・全ての領域に書き込み可能
なんじゃないのかな?
240デフォルトの名無しさん:2001/03/05(月) 08:35
>>239
Winだろうが別にdataセグメントにコード置いたってかまわないし
codeセグメントにwrite属性付けることも可能ですよ
241:2001/03/05(月) 12:23
>>240
へえ、知らなかった、tnxっす。
実はセグメント周りは弱いんだよね。
コンパイラオプションでも調べてみます。
さすがにメモリ巡回はしていないよね?
242デフォルトの名無しさん:2001/03/05(月) 12:44
243: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;
}
某本からの転載です
244デフォルトの名無しさん:2001/03/06(火) 00:51
>>243
基本原理はおんなじっぽいぴょん
disasしたら0xaaaaaaaaとか出てきたから
割り算とかはこれらの数字を作るためのトリックっぽいぴょん
245デフォルトの名無しさん:2001/03/06(火) 17:50
CSVファイル(とか)を作るコード。

do{
&nbsp;&nbsp;&nbsp;/* なんか処理する */
}while(!((終了条件) || (fputc(',', fp), 0)));
246職人志願:2001/03/06(火) 18:43
#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
>>246
enumで定義しろ。enumで。
250デフォルトの名無しさん:2001/03/06(火) 20:10
> 定数宣言に#defineなんて使うのですか?
> constじゃなくて?
フツーでしょ。
constは、このデータはいじりません宣言でしかないだけでしょ。
定数宣言じゃないですよ。
と言うか、もしかして君、そうしてるの?
251デフォルトの名無しさん:2001/03/06(火) 21:05
247じゃないけど、const派だなぁオレは。デバッガでも追いやすいし。
つか、普通は最適化で直埋めされるから速度も問題ないし…。
252デフォルトの名無しさん:2001/03/06(火) 21:22
読みにくいコードコンテストみたくなってきたな
253coder:2001/03/06(火) 21:27
gotoを使わないための苦肉の策。

while(0)
{
...
if (...) break;
...
if (...) break;
...
}

割と普通?

gotoは使わない!ってんじゃないけど、
インデント的に嫌いなもんで。
254デフォルトの名無しさん:2001/03/06(火) 21:31
>>246
職人への道のりは、かなり遠く感じるぞ。
まずは言語より、考え方の勉強だな。
255デフォルトの名無しさん:2001/03/06(火) 21:42
>>253
coderさん、Pro? それともネタ?
256coder:2001/03/06(火) 21:47
>>255
間違えた。
これじゃ何もしないじゃん。(苦笑)

じゃあ、こんな感じかな。

while(1) {
 ...
 if (...)break;
 ...
 break;
};

一応、Proです。^o^v
257デフォルトの名無しさん:2001/03/06(火) 21:56
>>256
プロのcoderさんなので、お聞きします。
ネストが2重以上になった時のいい方法、教えて。
258246:2001/03/06(火) 21:58
>>248
どうもすみません。
数字の部分は既に定義が決められているので
tbl[] = { {START_A,"START_A"},
       {END_B,"END_B"},
       {STOP_C,"STOP_C"},
としてやってみます。

>>254
すみません。精進します。
259デフォルトの名無しさん:2001/03/06(火) 22:03
>>256
無限ループは危険だと思うぴょん。有限ループがいいと思うぴょん。
do{}while(0);とかはどうかぴょん。
260coder:2001/03/06(火) 22:10
>>257
break(2);
ってやりたくなる時ですか?

基本的には2重以上にネストしないように見直しますが、
どうしても必要になったのなら、ためらいなくgotoを使います。
もしくは、ネストの内側でreturn。(←あまり薦められない)
あ、やっぱり別関数にするかな。

要するに状況に応じて対処します。(あたりまえ)

ちなみに、Proって言ってもGAME関係です。
納期・効率が優先される世界なので、一般的ではないかも。
#故に「トリッキー」に惹かれてきたわけですが。
261デフォルトの名無しさん:2001/03/06(火) 22:13
できれば個性は語尾ではなく、内容で示していただけると幸いです。
全く内容のない書き込みなら、語尾だけで個性を表すことも仕方ないと
思いますが、わりと良い内容を書かれているだけに残念です。

老婆心によるお節介なので、sage。
262coder:2001/03/06(火) 22:14
>>259さん
コードを見直してみたらそのようにやっていました。^_^;;

それで、while(0)って。。(恥&言い訳)
26379: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;
}
264デフォルトの名無しさん:2001/03/06(火) 22:34
>>259
初心者ですが、・・・do{}while(0); は、有限ループなの?
do先に一回{}無条件実行、while(継続条件式)って思ってましたが。説明お願い。
265259:2001/03/06(火) 22:53
>>264
有限ループである。
何故ならば、継続条件式が偽であるため、
継続せずに終わるからである。   だぴょん
266デフォルトの名無しさん:2001/03/06(火) 23:02
>>265
回らない条件ループ。シュール。だったら、while(0)をタイプする意味はなあに?

>>261なんか無視していいよ。だってここは2chだもの みつを
267259:2001/03/06(火) 23:09
>>266
while(0)を入れないとコンパイル通らないからだぴょん
てゆーかそもそも do{〜;}while() ってゆー構文だし、
一度だけ回るループとか思ってほしいぴょん
268デフォルトの名無しさん:2001/03/06(火) 23:19
ああ、261が言ってるのって'ぴょん'とかって発言してるやつ(ら?)のことか・・だもん
269SAGE:2001/03/06(火) 23:21
1回しか通らないんじゃループとは言わねぇ!

…という突っ込みは無しですか?(^^;)
270デフォルトの名無しさん:2001/03/06(火) 23:31
ループには展開されないよ。>269
アセンブラの出力でも見れば?
271デフォルトの名無しさん:2001/03/06(火) 23:36
switch(val)
{
 case 0:
  return TRUE;
  break;
 case 1:
  return FALSE;
  break;
}

return する場合でも break を入れる律儀な俺。
break 入れてる?

スレ違い?
272デフォルトの名無しさん:2001/03/06(火) 23:37
警告出るから入れない>271
273デフォルトの名無しさん:2001/03/06(火) 23:44
>>263
こういうのってfar呼出しになるからDOSだと効率悪いね。
特にポインタ渡すような関数は。
コードをheapにコピーして置けばnearで呼べるかな?
274デフォルトの名無しさん:2001/03/07(水) 00:07
>>263
素直にインラインアセンブラ使えばいいんでないの?
275デフォルトの名無しさん:2001/03/07(水) 00:19
DSEGにコード追い出せるのが利点とか。>274
あと実行時に変更ができる?
まあ、inline-asmでもできるか。
276デフォルトの名無しさん:2001/03/07(水) 03:24
あたりまえすぎるが

bool f = false ;
:
if(pushed)
foo = !foo ;
:

マジでこれ仕事で使っていたが上司に「鳥キーな事してるね」
いわれたアル. フツーあるよね!?
277: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: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: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を効率的に使ういい場面を知っている人は教えてください。
280デフォルトの名無しさん:2001/03/07(水) 03:55
unionを使うところって、OOPならポリモーフィズムを使うべきところが
ほとんどだから、それで正しいんじゃないかな。
281デフォルトの名無しさん:2001/03/07(水) 04:16
276が意味不明。も少し詳しい説明きぼん
282: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; とするしか選択がない(藁
284デフォルトの名無しさん:2001/03/07(水) 06:59
Boolでなくboolだ。これだからPascal野郎は…。
285デフォルトの名無しさん:2001/03/07(水) 06:59
>>279
非公開メンバは普通 protected にする
private は身内にすら見せないから不便
286=283=284なんで。:2001/03/07(水) 06:59
287デフォルトの名無しさん:2001/03/07(水) 07:07
>>285
おまえC++も質問の意図もまったくわかってねえよ。
逝ってよし
288デフォルトの名無しさん:2001/03/07(水) 07:33
非公開メンバは普通 vrivateにする
private は身内にすら見せないから便利
289デフォルトの名無しさん:2001/03/07(水) 08:38
>>288
typo?
290デフォルトの名無しさん:2001/03/07(水) 09:34
yes
291276: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で二分探索の方が普通だと思うな。
295285=288=アホ:2001/03/07(水) 11:48
privateメンバとpublicメンバの話をしているのはよくわかった。
で、private継承とpublic継承は知ってるか?
285で反応している>>279の質問は、protected継承の話なんだが。
292もアホに反応するなよ。
296デフォルトの名無しさん:2001/03/07(水) 11:49
>>279
private/protectedな継承は外部に対してスーパークラスの
インターフェイスを隠したい時に使えますね。(んなこた解ってるって?)
他の言語なら継承を用いずにコンポジションで実現しなければならない
場面で利用出来そうです。
JavaのStackクラスなんかは失敗例で、コンポジションを使うべき、
或いはprotectedな継承が使えれば良かったケース。

# 用語の使い方からC++屋じゃないことは明らか(藁
297デフォルトの名無しさん:2001/03/07(水) 11:54
C++でprivateメンバの実装が見えちゃうって事自体は、
Cとの互換性を保つために仕方がないと割りきったんじゃないかなぁ。
要は、スタックにオブジェクトを確保するためにデータメンバが必要で、
インラインで呼び出すために、privateメソッドのインターフェースも必要と。
298デフォルトの名無しさん:2001/03/07(水) 11:56
>296
多分、>>279はprivate継承の意義はその通りだと知っているはず。
でも、protected継承の意義が不明ということだと思う。
この辺は、Effective C++に詳しいね。
299デフォルトの名無しさん:2001/03/07(水) 11:57
>296
気が付かなかった。
Vectorのインタフェース丸見えですな。
300297:2001/03/07(水) 12:47
>>292-293はfriendの事だって気付かなかった・・・俺ってバカだ。
うーむむ、俺も「friendにだけなら許す」という
アクセス属性が欲しいと思った事が何回かあるし。

別のキーワードを嫌った面もあるだろうけど、
特に、演算子のオーバーロードで多用される点からも、
「friendはメンバ関数の一種として扱え」って事かな?
301デフォルトの名無しさん:2001/03/07(水) 12:51
javaのStackクラスはあくまでVectorクラスの拡張ですよ。
302:2001/03/07(水) 13:28
一般的でないために質問がわかりにくかったみたいですまないです。
こういう腐ったことを考えるのこそ、まさにオタの厨房ですな。

>>298
tnx。早速本屋で立ち読みします
303296:2001/03/07(水) 13:40
>>298
protectedな継承なら、それをさらに継承したクラスからも外部には
非公開の親の親の機能を使えるじゃないですか。
通常のStackの外部インターフェイスとしてはinsertElementAt()
みたいなメソッドは不要なはずですが(だと思ってるけど)、Stackを
継承してStackの途中の要素に対してアクセスする何かを作る時、
privateな継承だとStackのpublic/protectedなインターフェイスしか
使えないっしょ。

だからといってprivate/protectedな継承がいいといっているわけじゃない。
コンポジションで代用出来るから敢えて必要な機能じゃないよね。
304292:2001/03/07(水) 13:47
>>295

なんとなく反応しちまったよ。スマソ
305デフォルトの名無しさん:2001/03/07(水) 13:49
トリッキーっつーか、C++になってないか? > スレ
306296:2001/03/07(水) 13:52
ごめんよー
307デフォルトの名無しさん:2001/03/07(水) 13:54
publicじゃない継承はコンポジションみたいなもんなんだからコンポジション
したときにその変数をprivate/protectedにするかの選択ができるように
private/protected継承ができるんじゃないの?

俺のトリッキーコード
既存のクラスライブラリがあって、そのライブラリのソースコードには触れられなくて
でもあるメンバ変数にアクセスしたかったとき
#define private public
#include <XXXXXXX.h>
とやったぞ
308:2001/03/07(水) 13:56
>>305
すまないです。C++スレで質問すべきでした。
309296:2001/03/07(水) 14:02
>>307
>publicじゃない継承はコンポジションみたいなもんなんだからコンポジション
>したときにその変数をprivate/protectedにするかの選択ができるように
>private/protected継承ができるんじゃないの?
そのとおり

>#define private public
>#include <XXXXXXX.h>
有名だよね。
でもそのクラスをさらに拡張しようとする人は泣くかもね(藁
元の設計意図は大事に&元の設計はきちんと(藁藁

このへんで抜けます。
310本題外れまくりの298:2001/03/07(水) 15:01
>302の1
あ、Effective C++に載っているのは
「public継承はis-aという意味である」
「private継承はhas-aの代替手段である」
「protected継承の意味は知らん」
って事だけです。
まあ、よほどの達人以外、買って損はしない本だと思うけど。
311: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);
313デフォルトの名無しさん:2001/03/08(木) 00:08
わりとふつーっぽい>312
314デフォルトの名無しさん:2001/03/08(木) 00:15
ふつーナリか。。。(ショボン
315デフォルトの名無しさん:2001/03/08(木) 00:43
原典⇒原点
ということで、減点
316デフォルトの名無しさん:2001/03/08(木) 01:01
>>315
 イスラム原典
 ハンムラビ法典
 信長の野望 (原典版)
317デフォルトの名無しさん:2001/03/08(木) 01:12
>>312
.2s
っての初めてみました。
2文字までって事?
文字列引数の長さ調整ができたのか〜
318: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("曜日です");
全然トリッキーじゃないけど、参考までに
319デフォルトの名無しさん:2001/03/08(木) 16:19
>>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*はあんまり意味なし。+にすればもっと簡単。
322トリッキーの1:2001/03/08(木) 22:36
sprintfの様な関数を使わずには無理かな?
標準関数だから使っても問題なしなんだけれど、
やはりオーバーヘッドなどを考えてしまう厨房な俺。
323デフォルトの名無しさん:2001/03/08(木) 23:38
printfはそんなにオーバーヘッドかい?>322
324トリッキーの1:2001/03/08(木) 23:53
自分で作るとなるとかなりのオーバーヘッドになりそうで。
%sなどをサーチしてそこに文字列を代入する手間を考えると、
結構な労力が必要かと思われます。

暇を見て後でdisassembleしてみます。
325トリッキーの1:2001/03/09(金) 04:36
>>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
暗号を解除するプログラムが暗号ですね。
330デフォルトの名無しさん:2001/03/10(土) 19:03
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
>>2の意味がわかりません。。。
336デフォルトの名無しさん:2001/03/25(日) 19:17
オタッキーなコード・・・・・・
もぇっもぇっ、さくらたん、とか、アニメ落ち、とか
コメントに書いてあるのだろうか。
337デフォルトの名無しさん:2001/03/26(月) 13:10
>>336
そうだよん
あとデバッグメッセージかな
OutputDebugString("こりすたん。。。ハァハァ")
338335:2001/03/27(火) 00:09
>>335 誰か教えて!
339プリプリ博士:2001/03/27(火) 00:30
>>335
>>2は、aとbを入れ替えるマクロ、らしいぞ!
ゴ〜
340デフォルトの名無しさん:2001/03/27(火) 02:59
というか、swapという単語を辞書で引けって感じ・・・(^^;

ちなみに、>>2のマクロはa==bの時はデータ異常になるという蟲持ち。
341335:2001/03/27(火) 03:30
>>339 >>340 SWAPの意味はわかるけど、なんで>>2 でできるの?
342340:2001/03/27(火) 03:35
>>342
自分のスキルアップのためにも、人に聞く前に自分で計算してみな?

と、ごまかしておこう
昔、手書きで計算してみて納得したけど、もう忘れたよ(^^;;;
343プリプリ博士:2001/03/27(火) 04:56
>>340
問題があるのは値が a==b のときではなく
swap(a,a)のように同じ変数を入れたとき、らしいぞ!
ゴ〜
344デフォルトの名無しさん:2001/03/27(火) 08:42
a==bだと0になっちまうだろ。
345SAGE: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)
346デフォルトの名無しさん:2001/03/27(火) 11:42
344も0になるかどうかやってみれ
347デフォルトの名無しさん:2001/03/27(火) 17:29
>>343
xor eax, eax
348デフォルトの名無しさん:2001/03/28(水) 00:15
>>347
それは0になるが、それがどうした?
349347:2001/03/28(水) 11:46
ふつうのコードでしょ。
a^=b^=a^=b
も理解できるはず。
a==bの場合は大丈夫。
&a==&bのときは両方0
>>343としたのは間違い。
スマン
350デフォルトの名無しさん:2001/03/28(水) 12:20
4 名前:デフォルトの名無しさん投稿日:2001/02/26(月) 22:11
そして3は浮動小数点演算に上記のマクロを使用して氏んだ
351優しい名無しさん:2001/03/28(水) 15:45
^= ってなーに?
352SAGE:2001/03/28(水) 16:12
>>351
歯痛的lonely話
353デフォルトの名無しさん:2001/03/28(水) 19:24
そもそも生のSwapなんてするか?
使うのはソートの時くらいじゃないの?
354デフォルトの名無しさん:2001/03/28(水) 21:28
新しいネタきぼーん!!!
355351:2001/03/28(水) 21:56
>>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クリアするよりも、何クロックか速いんだよね。
358デフォルトの名無しさん:2001/03/29(木) 03:17
>>356 1010 ^ 0001 = 1010
↑お前が間違っとるやんけ。
>>355 は (a,b) の変移を1行で書いたのだろ。
359デフォルトは名無しさん:2001/03/29(木) 16:34
goto文をつかわずにネストの深いfor文から抜け出す方法
360デフォルトの名無しさん:2001/03/29(木) 16:50
↑return
361デフォルトの名無しさん:2001/03/29(木) 16:57
↑longjmp(藁
362デフォルトの名無しさん:2001/03/29(木) 17:05
↑終了フラグでネスト毎にブレーク(w
363347:2001/03/29(木) 17:06
↑throw
364347:2001/03/29(木) 17:07
↑throw
365359:2001/03/29(木) 18:30
協議の結果、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
369デフォルトの名無しさん:2001/03/30(金) 02:19
ここはプログラムっぽいのならなんでもいいのかな?
echo10回実行のシェルスクリプトってこう書くよね

#!/bin/sh
foo=1
while [ "$foo" -le 10 ]
do
echo hogehoge
foo=$(($foo+1))
done

これをスマートに出来るかな?
bashなんでrepeat命令は無しです
370デフォルトの名無しさん:2001/03/30(金) 04:20
#!/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
373371:2001/03/30(金) 09:43
これは間違い。スマソ。
374デフォルトの名無しさん:2001/03/30(金) 09:47
>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
376368:2001/03/30(金) 12:46
>>374
そっか、じゃあ
 LD HL,LDIRの次
とすれば完璧!
377デフォルトの名無しさん:2001/03/30(金) 14:41
>>369
コピペです。ちょっとすっきり

#!/bin/sh
for i in 'seq 10'; do echo hogehoge; done
378デフォルトの名無しさん:2001/03/30(金) 18:18
可変個の引数を取るshスクリプトで、引数それぞれに処理を行うとき、

while [ $# -gt 0 ]
do
  処理 $1
   :
  shift
done

これって常識?
379デフォルトの名無しさん:2001/03/30(金) 23:24
こういうリスト操作を考えたんだけど・・・
すでに前例があるのか知ってる人いない?

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} */
380デフォルトの名無しさん:2001/03/31(土) 09:22
>>378
常識つーか、普通だと思うが。
381デフォルトの名無しさん:2001/03/31(土) 16:52
>>379
一つの関数で、リストへの追加と削除を済ましてしまうという
ところがミソにゃのか!?

ただ、あらかじめprev,nextメンバは自分自身を指すようでない
とダメっぽいので

typedef struct DLList_
{
struct DLList_ *prev, *next;
DLList_(){
prev = next = this ;
}
} DLList;

とすると、より(他人が見て)分かりやすいにょ。(C++になるけど)
382デフォルトの名無しさん:2001/03/31(土) 19:00
>>381
そーゆー事。
もちろん要素が単独の場合、それらの prev,next は自分自身を
指す事を想定しています。
383381:2001/04/01(日) 00:05
>>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
スパンキーなコード
387デフォルトの名無しさん:2001/04/07(土) 12:06
オタッキーなコード < all
388デフォルトの名無しさん:2001/04/07(土) 12:39
>>387
リダイレクトの向きが
389デフォルトの名無しさん:2001/04/07(土) 12:55
>>384, >>386, >>387
http://mentai.2ch.net/test/read.cgi?bbs=prog&key=983059592&ls=50
デ キミ ノ サイノウ ヲ ジュウニブン ニ ハッキシテネ!
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
なにげに>>366より>>392のが速くないか?
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
>>392
精度落ちるじゃん。
399392: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の精度を保っている。
402392:2001/04/12(木) 10:27
>>401
あぁ、演算結果は5bitでも
「4bit同士の足し算」って所が問題なのか。
それはまったく そのとーりです。
403弱い者の味方、:2001/04/12(木) 15:43
月光仮面おじさん登場!!!
ホームページを作ったものの、まったくアクセスが上がらな
くて悩んでいる人のためにお役に立ちましょう。
効率よく宣伝できる共有宣伝掲示板を18個設置しました。
全部宣伝して回ればなんと1,000以上の掲示板にカキコしたこ
とになり即、効果が期待できます。さらに共有掲示板の隠し
リンクを発見してそれらも全部宣伝して回ると計2,000以上の
掲示板にカキコしたことになり、さらにアクセスアップを期
待できます。もう、今日からアクセスが無くて悩むことは無
いです。今すぐここからアタックアタック!!

http://home9.highway.ne.jp/cym10262/
404デフォルトの名無しさん:2001/04/12(木) 16:05
トリッキーじゃない。ばいばい。
405デフォルトの名無しさん:2001/04/13(金) 18:30
>>357

キャリーフラグがクリアされると思われ
406デフォルトの名無しさん:2001/04/14(土) 21:10
宿題でもいいからなんかネタないかなぁ
407デフォルトの名無しさん:2001/04/14(土) 21:46
408デフォルトの名無しさん:2001/04/14(土) 21:59
こ、これは・・・!
すごいな。
どうやってこんなの考えられるんだろう・・・
ソースを貼り付けられないのが残念だ。
409デフォルトの名無しさん:2001/04/14(土) 22:02
すげえ、
410デフォルトの名無しさん:2001/04/14(土) 23:29
>>407
1シーケンスポイント内で複数の副作用が
起きているように見えるのは気のせいか?
411410: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のトランスレータ使った方がいいかも。
(スクリプト〜のスレにリンクあります)
417416:2001/05/03(木) 02:23
ヒープベースでいいなら、インスタンスのチェインを作ったり、
マクロで変換したり色々楽する方法はあるけど、
純粋なCの使い方じゃないんだろうなあ・・
↑に追加するなら、あと、
・コンパイラが型保障してくれない。
これが痛い。どうしても(void*)使いまくる事になるからね。
418416:2001/05/03(木) 02:30
よって完全を喫したい場合、デバッグ時などで
メソッド関数の入り口で
if (self->classid == 〜)
とかする必要がある。
利点は
・OO(風)実装の質加減を自分で決定できる。
・Cは言語仕様が小さいので環境を選ばない。
・どうせ(void*)主体なのでC++の様な大掛かりなtemplateは必要ない。
ぐらいかな。
419416:2001/05/03(木) 02:45
欠点追加
・インライン展開してくれない。(inlineキーワードが使えない)
アクセサとか、なにも考えずに定義できない。
gccやVisualC++ならCでも__inline__使えるので、
使えない処理系毎にマクロで切り分けるはめに・・
・本質と関係無いコードの量が多くなる。
モチベーションが低下する。しょうがないんだけど。
思考するための言語の使い方としては最悪。
だから純粋にOO可能な言語でプロトタイプ作って
C移行やるのがベストかも。(どうしてもやるなら)
420416:2001/05/03(木) 03:01
純粋OO言語→Cのトランスレーターがあればそれ使うのが一番良い。
(ありがちな問題として「純粋OO言語」のライブラリ群をどうやって
Cへ変換するるかだけど、それぐらい無かったら自分で作る。)
やっぱりCで自分で書くのは疲れるよ。無茶するのは健康に悪い。
421416: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->直呼びに変換する。
422416: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の自動デストラクト
}
もちろんハンドルを保持すればデストラクトを持ち越す事ができる。
この辺は実際に使って有効だった手法。
423414:2001/05/03(木) 03:56
>>414 みたいなのは、C++コンパイラが買えなかった頃
LSI-C試食版でC++に憧れつつやってました(厨房だ

>>415
第一引数を構造体にするのは安上がりにC++気分が味わえて実用的ですよね。
424414:2001/05/03(木) 03:56
>>416-422
ぐわっ。なんかすごいです。ここまですれば実戦でつかってもメリット多かも
>>422 なんかはC++でもブロックを越えて、半自動的にヒープの
オブジェクトをデストラクトするのに便利かも、ですね

一般的には言語にない機能をカバーしようとしてトリッキーになってしまう
ことが多い気がします。
むかーしの雑誌で、例外未サポートのC++コンパイラ(ワラ)でTRY/CATCHマクロ
を実装する(大域jumpをつかう)記事が出てたけどトリッキーだった。

私はC++使ってるとgarbage collectionがないせいでトリッキーになることが
多々あります。頭悪いのかも。
自分で書いたcollection classにひたすら参照カウンタを上げ下げする
コードを追加してるとなんのクラスを書いてるのか分からなくなってきます。
425デフォルトの名無しさん:2001/05/03(木) 19:44
>>416 なんか凄い参考になった気がするのでage
426デフォルトの名無しさん:2001/05/04(金) 04:02
オトッキー
427: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
>>429
自分でコンパイラを描く。
431デフォルトの名無しさん:2001/05/26(土) 00:02
schemeにあるよ>define
432429:2001/05/26(土) 00:08
>>430
前はそれやってました
(自作プリプロセッサもどきでコンパイル前にマクロ置き換え)

でも、この間事故でえらい目にあったので
なるべく標準的な機能を使いたいんだ
433デフォルトの名無しさん:2001/05/26(土) 00:11
defineある言語に乗り換えれば?>432
434429:2001/05/26(土) 00:16
>>433
ネーチブなJavaVMが載ってるマシンで動かすものなので
Java以外で動かすのはもったいないのだ。
435デフォルトの名無しさん:2001/05/26(土) 00:23
定数のdefineならインターフェイスに書けば?
他のdefineは目的によっては不可能じゃない?
436429:2001/06/02(土) 01:48
>>435
ありがとう。インターフェイスの勉強してきました。早速使ってみます。
トリッキーな手法があるかなーと思って期待してたんだけどね。
437デフォルトの名無しさん:2001/06/02(土) 09:04
ネーチブなJavaVMってJavaChipかいな。興味津々

>>436
普通に定数使いたいんなら、finalで十分じゃない。

>>435 さんの方法が悪いって訳じゃないけど
めんどくさいからって、定数だらけのinterfaceを
implementsするってのは良くないと思うよ
# JavaCCがやってたけど

ttp://java-house.etl.go.jp/ml/archive/j-h-b/025751.html#body
438デフォルトの名無しさん:2001/06/02(土) 11:05
このスレタイトル、どうしても取り憑きーなコードに見えてしまうぞ。
バグが取り憑いたコードならいくらでもあるのだが。
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
>>439
カンドーしたよ。こんど真似しよっと。
441デフォルトの名無しさん:2001/06/03(日) 21:26
漏れの感覚だと -1,0,1 の三状態を使うなあ
a=-a で済むし
442439:2001/06/05(火) 05:55
>>441
すみません。そっちの方がかっこいいですね・・・
修行しなおしてきます。次は負けん!
443デフォルトの名無しさん:2001/06/07(木) 09:57
あと 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
>>444
それって
http://www.ioccc.org/
↑ここのパクリじゃないの?
447デフォルトの名無しさん:2001/06/10(日) 19:22
思いっきりパクリやん
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
452デフォルトの名無しさん:2001/06/10(日) 22:32
>>451
それじゃ意味ナイーン
453デフォルトの名無しさん:2001/06/10(日) 22:50
>>452
どうちて?

lui r0,r1,1
xor r2,r1,r2
とコストは変わらんでしょ。

X86ならXORの圧勝だが。
454デフォルトの名無しさん:2001/06/10(日) 23:38
>>446

パクリつーか、iocccに応募した本人みたいよ。
455デフォルトの名無しさん:2001/06/11(月) 01:22
sub 1,a という概念自体に強い衝撃を覚えたよ(ワラ
結果は 1 に代入されるんだろうか…これも時代かねえ

>>453
x86 ならじゃなくて逆に mips くらいなもんなんじゃないの?
456デフォルトの名無しさん:2001/06/11(月) 01:27
>>455
大丈夫?
457デフォルトの名無しさん:2001/06/11(月) 02:08
i386 でも最適化すれば高々二倍の差しかなさげだ

[a=1-a] ⇔ [a=a^1]
DEC EAX ⇔ XOR AL,1
NEG EAX

まあコンパイラがこんなコードを吐くとは思えんが
458デフォルトの名無しさん:2001/06/11(月) 04:30
そろそろ前みたいにトリッキーなコード希望age
459デフォルトの名無しさん:2001/06/11(月) 05:55
ていうかキミが提供してちょ>458
460デフォルトの名無しさん:2001/06/11(月) 06:06
>>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の 公式(曜日の算出)
462デフォルトの名無しさん:2001/06/11(月) 09:08
>>461
>((13*$month+8)/5) + $day) % 7
イカス!
これそんなにメジャーだったんだね。知らなかった。
463デフォルトの名無しさん:2001/06/11(月) 14:05
>>455
IA-64でも同コスト
464デフォルトの名無しさん:2001/06/12(火) 00:56
>>463
最近の RISC は大体そうなんかな?
ていうか、何に使われてるチップ?
465IA-64:2001/06/12(火) 02:35
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
>>468
もうちっとだけヒントください
473デフォルトの名無しさん:2001/07/14(土) 15:33
>>486
つーかANSIの範囲で書けるなら書いてみてくれ
474デフォルトの名無しさん:2001/07/14(土) 20:30
>>470
それってどういう局面で必要になるの?
475デフォルトの名無しさん:2001/07/15(日) 10:11
>>474
DOSとかでマルチスレッドもどき管理するとき。
スレッド切り替えは陽に呼んでやる必要があるんだけどね。
476デフォルトの名無しさん:2001/07/16(月) 02:29
>>470,475
デバッグに役立ちそう。イタダキマス。
そんなにトリッキーでもないような。
477475:2001/07/16(月) 15:18
へっだ
int _cre_tsk( void (*)(void), int ); /* タスクの登録 */
void _sta_tsk( void ); /* タスクの起動 */
void _wai_tsk( void ); /* タスクの切換 */
478475:2001/07/16(月) 15:19
本体その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 );
}
479475:2001/07/16(月) 15:20
本体その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();
}
480475:2001/07/16(月) 15:21
使用例。
#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 を
数え上げることができるのがコード書くときに楽。あんまりトリッキー
じゃないのでスレ違いっぽいのは確か(可読性も高いよね)。

 例えばドキュメント、ページ、その中の画像オブジェクト、というような
階層状の構造をもつ何かを編集するソフトで、特定の画像ファイルの消去等
の際には、ドキュメント→ページ→画像オブジェクト、アンドゥバッファ中
の画像オブジェクト、クリップボード上の画像オブジェクト、などいろんな
ところを見なくちゃならないでしょ。そういうときに「全ての画像オブジェ
クト」ってのを用意して手抜きするわけです。
483デフォルトの名無しさん:2001/07/20(金) 01:15
>>481
a ^= b ^= ( a ^= b ) ;
整数型のスワップならこうだろう。
って、昔はアセンブラなんかでは良く使った手だな…。
484デフォルトの名無しさん:2001/07/20(金) 23:44
>>483
アセンブラなら直接交換する命令を使ったが。
そんなのもないやつ?
485デフォルトの名無しさん:2001/07/20(金) 23:48
>>484
レジスタペアには使えなかったりとか。
486481:2001/07/21(土) 13:05
>>483
>>2で超がいしゅつ
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 するという事で

シフトと論理演算だけで出来ない訳じゃないけど厳しいねえ
489デフォルトの名無しさん:2001/07/21(土) 14:47
×最初に16bit左シフト
○最初に16bit右シフト
490488:2001/07/21(土) 15:18
全然ダメ 488 は間違いね 恥ずかしい・・・
491デフォルトの名無しさん:2001/07/21(土) 15:23
>>487
どういうことだかわからないんだけど、こうしたいっていう具体例を
挙げてもらえる?
492488: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;
}
493488:2001/07/21(土) 15:36
ええと課題は
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));
こんな感じ?検算してないけど。
条件文入ってるからダメか。
497496:2001/07/21(土) 15:54
result=(short)((h&0x7fff)|(h>>30)|(((h&0x7fffffff)>0x7fff)*0x7fff));
の間違いでした
498494:2001/07/21(土) 15:58
>>496,497
内容の確認はしてないけど、その手なら MIPS でも分岐命令は
出なさそう。

出題者の意図次第ですが、>>492 さんの解答がいいところを突いて
る予感はします。これも内容確認してませんが(w
499デフォルトの名無しさん:2001/07/21(土) 16:07
>>498
492はちっとなげーし、なによりインラインアセンブラは歓迎されねーだろ
500488: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は有りだよね
501497:2001/07/21(土) 17:08
>>500
わりい。ちょっと直す。
result=(short)((h&0x7fff)|((h>>31)<<15)|(((h&0x7fffffff)>0x7fff)*0x7fff));
これでだいじょぶかな?
502488:2001/07/21(土) 17:19
確かに条件判断 >0x7fff は分岐に展開されないから 利用せて貰うと

これが c でもアセンブラ並なコードが出た
return (short)( ( ( ( (x>>31) ^ 0x7fff)^x)
           & (-( abs(x) > 0x7fff)) )
        ^ x);


>>501 まだダメ 負数だとオーバー時 -1 になってしまうよ
クリップだから -$8000 にならないと
503497:2001/07/21(土) 17:24
>>502
あはは。寝ぼけてた。ごめん。・・・旅に出ます。
504488:2001/07/21(土) 17:38
a xor b and c xor b
は cが1なら a xor b xor b = a cが0なら b

という事でビット毎の代入パターン

( (x>>31) ^ 0x7fff は 0x7fff+(x<0)
505494:2001/07/21(土) 17:43
>>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 がどう展開されるかもコンパイラ&プロセッサ次第。

たぶん、「算術&論理演算だけで片付ける」ってのが、
出題者の意図だとは思うが。
506488:2001/07/21(土) 18:01
たぶん、CPUがx86系で 条件判断が入ると遅いという事じゃないのかな?

それとも命令数を数えてコーデングしてて、分岐が入るとメンドクサイから
嫌だとか


条件によって代入とか 条件によって次命令スキップなんて
命令を備えてるCPUも多いんだけどね。
507487:2001/07/21(土) 18:38
スマソ
x86系でPCMのクリッピングに使います。

たしかにアセンブラレベルじゃMMXやcmovcc使えばいいし、
Cコンパイラでもgccとかは自動的にcmovcc使ってくれるのでよいのだが。

それとはちょっと別に「分岐を起こさせずに」ってのは、実質的な
意味よりも、>>505 の言うように「算術&論理演算だけで片付ける」
ってのでの方法をちょっと知ってみたかっただけなので・・・。
508デフォルトの名無しさん:2001/07/21(土) 18:45
せっかくだからガンガントリッキーに攻めようぜ
509デフォルトの名無しさん:2001/07/21(土) 19:18
今の所 >>502
(short) ( ( ( ( (x>>31) ^ 0x7fff)^x ) & (-( abs(x) > 0x7fff)) ) ^ x)

これが一番綺麗だね
510デフォルトの名無しさん:2001/07/21(土) 19:30
でも >>502のコードは条件が入ってて
 こいつが setcc al に展開される
 その後 eaxを使うと パーシャルレジスタストール に引っかからないのかな?

まあパーシャルレジスタストールなんて数年したら
そんな事もあったなあなんてレベルの話なんだろうけど
511デフォルトの名無しさん:2001/07/21(土) 19:37
速度はこのスレじゃ関係ないでしょ
 いかにトリッキーかのスレなんだから
512デフォルトの名無しさん:2001/07/21(土) 19:41
>>511
いや、いかにトリッキーかというのはあとから付いてくるものだよ。
なんつーか、「こんな方法があったのか!」っていうヒザポンな
解法をみんなで思いつくのが本来の趣旨 のような。
わき道にずれてごめんsage
513デフォルトの名無しさん:2001/07/21(土) 19:53
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)
515デフォルトの名無しさん:2001/07/21(土) 20:44
せめてこういうふうに書いて欲しいな

//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("三角形の秘密はね、");
517デフォルトの名無しさん:2001/07/21(土) 21:10
フェルマーの定理でも証明するつもりか? >>516
518487:2001/07/21(土) 22:19
PCMのクリッピングなんで、+32767〜-32768からはずれた、
あまり大きな数値や小さな数値は絶対に入ってこないので、
数値を最初に32768を足して、unsigned int 32->unsigned int 16 の
飽和変換を行ってからまた 32768 を引こうかと思ったんだけど
unsigned int 32->unsigned int 16 の飽和はどうしようか・・・
教えて君ですまんそ
519487:2001/07/21(土) 22:20
あ、なんでもないです518は忘れてください
520デフォルトの名無しさん:2001/07/21(土) 22:47
一応、条件演算子無しで書いてみた。
short clip16(int x) {
 int f=(x>>31);
 x ^= f;
 x = (((-(x&-0x8000))>>31) | x) & 0x7FFF;
 x ^= f;
 return (short)x;
}
521デフォルトの名無しさん:2001/07/21(土) 22:50
>>518
 ええとね、PCMのクリッピングで悩む必要はないよ。
 44.1Kだから1秒に およそ9万回しかクリッピング処理は回って来ないからさ
 それより、その処理本体で悩んだ方がいいと思う
522デフォルトの名無しさん:2001/07/23(月) 20:17
皆さん凄いですね。
フリーソフトの作家さんが、セミコロンを使わないでCのプログラムを
書いて遊んでいたのを思い出しました。
523デフォルトの名無しさん:2001/07/24(火) 02:31
>>522
そんなことできるのかー。

Perlなら簡単そうだけど、Cで出来るのか。
524デフォルトの名無しさん:2001/07/24(火) 03:13
trigraphつかえばできそうだけどそうじゃないのかな
525デフォルトの名無しさん:2001/07/24(火) 03:15
ううーん
すべての
式;
はif(式){}で置き換えられるとして
変数宣言はどうするんだ
526デフォルトの名無しさん:2001/07/24(火) 03:18
変数は引数でもつかってりゃいいか

void sub(char *msg)
{
if(msg = "Hello world!\n", printf(msg), 0) {}
}

int main()
{
if(sub(0), 0) {}
}
527526:2001/07/24(火) 03:20
あmainのreturn書いてないやw
returnが書けないのか・・・
まぁ関数から値を返すときは関数に変数のポインタを渡せばいいけど
mainにreturnが書けないのはイタイ
528デフォルトの名無しさん:2001/07/24(火) 03:36
>>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をクラスオブジェクトに見立てて利用したい時
530デフォルトの名無しさん:2001/07/29(日) 19:00
・・・
>>529 どこがトリッキーなんだ?
531デフォルトの名無しさん:2001/07/29(日) 19:55
ウイッキーなコード
532デフォルトの名無しさん:2001/07/30(月) 00:44
 add word ptr[ptr+0xxh], reg
ptr:
 jmp 0xxxxh
533デフォルトの名無しさん:2001/07/30(月) 04:44
アセンブラ覚えたいょぅ
534デフォルトの名無しさん:2001/07/30(月) 06:26
>>533 Delphiでもやってみたら? 俺は あれのCPU窓で覚えたよ。
535デフォルトの名無しさん:2001/07/30(月) 13:23
>>534
VCだろ!
536デフォルトの名無しさん:2001/07/30(月) 17:22
>>535
VCってなに?VirtualCall?
537デフォルトの名無しさん:2001/07/30(月) 19:43
XCHG EAX,ECX
JECXZ LABEL
538デフォルトの名無しさん:2001/07/30(月) 21:27
>>536
ビタミンCにきまってるdaro!
539デフォルトの名無しさん:2001/07/31(火) 00:54
>>536 正解!詳細を知りたければ、エロゲー板へどうぞ!
540デフォルトの名無しさん:2001/08/08(水) 03:00
ヴォヤッキーなコード
541 :2001/08/08(水) 03:09
JECXZって80386以降か。
よくそんなニーモニック知ってるのぅ。
542デフォルトの名無しさん:2001/08/08(水) 08:17
TEST EAX,EAX
JZ LABEL
と較べてフラグを保存できる上、1バイト小さい。
543デフォルトの名無しさん:2001/08/10(金) 03:00
あげ
544デフォルトの名無しさん:2001/08/23(木) 21:58
2分木を再帰やスタックを使わないでトラバースする方法って
無いでしょうか?(昔どこかでできるという様な話を聞いたんですが)
545544:2001/08/24(金) 00:24
ちなみに、葉に親ノードを専用に保持する領域を作ったり、
紐付き2分木の様なnullポインタを使う方法では無いらしいです。
どなたかご存じないでしょうか。
546デフォルトの名無しさん:2001/08/24(金) 01:11
>>544
rootをarr[1]に入れて、arr[k]の左の子をarr[2k]、右の子をarr[2k+1]に
入れておいて arr[] を一気に舐める、というようなやり方のことかな?
547546:2001/08/24(金) 01:15
えーと、rootがarr[0]で、arr[2k+1] と arr[2k+2] に子ノードを
置いてもいいんだけど、コードが読みにくくなっちゃうので
俺は546のように置いている。
548544:2001/08/24(金) 02:04
>>546
いえ、配列を使う(実質スタックですよね?)のでは無く、
左右のどっちかのノードの書き換えのみで行なう様な感じだったと
思うのですが・・
普通にやると、片方のノードはループに書き換えられますが、
もう片方を辿る時に、例えば左辺を親ノードと入れ替えるとか、
そんな感じのコードになると予想しています。
理屈ではできそうなんですけど。
549546:2001/08/24(金) 02:17
>>548
トラバースするときにえっちらおっちらコピーするわけじゃなくて、
最初から配列に組んじまえばいいんですよ。
(要素の数が劇的に変わったり、左右のバランスが悪いときには
 メモリ効率が落ちるが)
左右の子へのポインタを2つとも持たなくていい分、効率がいいこともあるよ。
(要素へのポインタの配列で組むと、ポインタ一個分しか節約にならんけどね)
550デフォルトの名無しさん:2001/08/24(金) 02:19
>>549
結局ヒープソートの基礎以上の内容ではなさげだが……?
551デフォルトの名無しさん:2001/08/24(金) 04:04
ノードには印がつけられるとし、最初はすべてのノードが無印だとします。
ノードをたどりながら印をつけ、そのノードを訪れたとして出力する。
ツリーの末端まできたらそのノードは削除する。
スタックが使えないのでバックトラックできないので、
その後ふたたびルートから繰り返す。
が、印のついていないノードにきた場合は印をつけ、
そのノードを訪れたとして出力する。
ノードが無くなったらトラバースの出力は終わり。
552デフォルトの名無しさん:2001/08/24(金) 08:33
>>544
そのアルゴリズム、読んだ覚えがあるけど
どこで読んだか思い出せない・・・(鬱
確か goto をやたら使っていた様な気がするけど違うかなぁ。
553552:2001/08/24(金) 09:10
あと、Knuth が紹介していたような気もする・・・
554デフォルトの名無しさん:2001/08/24(金) 13:20
>>551
んなのはトラバースとはいわんだろ。
555544: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] );
}

これで配列コピー。
上のレベルを見る限りあんまりトリッキーでもないかな...
がいしゅつだったらスマソ。
557デフォルトの名無しさん:2001/08/25(土) 16:19
>>556
それは単に、Cの代入演算子の挙動を理解(つーか誤解)した、という意味に過ぎないのでは?
558デフォルトの名無しさん:2001/08/25(土) 16:58
未だに構造体の代入拒む奴いるよな
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
>>559
分岐ナシソートか。
562デフォルトの名無しさん:2001/08/25(土) 22:17
ソノシートsage
563556:01/08/26 14:19
>>557
ありゃ、普通でした?
char配列の場合、なかなかトリッキーなstrcpyができるなぁと思ったんですが。
言われてみればたしかに代入演算子の挙動を理解(誤解なの?)したに過ぎないですね
564544: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
おー。こんなことできるのか。
567デフォルトの名無しさん:01/08/28 02:14 ID:mHosmIv.
>>564
そりゃー、昔のゴミ集めの連鎖辿りでは常套手段だったべさ。
>>2の手法で、一つのpointer fieldで双方向鎖の実装もあったべさ。
実記憶のみで総100Kbyteとかの時代の話だべ。
568デフォルトの名無しさん:01/08/28 02:19 ID:9IU/Y/5o
>>565-566
case文ってのがブロックのなかにあっても通用するってのが
目から鱗だったよ。
569デフォルトの名無しさん:01/08/28 03:22 ID:PVHMotjs
ただのラベルだからな
570デフォルトの名無しさん:01/08/29 01:34 ID:GIhJkjc.
>>567
こういうの聞いてると昔のコードって
みんなトリッキーなコードになるかも。
571デフォルトの名無しさん:01/08/29 01:44 ID:gasQtqoY
昔のプログラマは偉かったっていうことだ。
572デフォルトの名無しさん:01/08/29 01:47 ID:Mf58huQg
565のはたしかにすごいが、かけてもかきたくねー。
573デフォルトの名無しさん:01/08/29 03:06 ID:hol8O3eY
こういうのは、タイトなループだから、
書きたくなくても書かなければならない部類だと思う。

bcopyのsourceは、word境界に揃えたり軒並凄い事になっている。
i960のマニュアルに載っていたb*(), str*()のsample assemblerも面白かった。
574a:01/08/29 09:41 ID:UHzULLbQ
>>565
どうもコードを追う事が出来ない…
これをちゃんと構造化して書くとどうなるの?
575a: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だー!
580jjdd: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]
582 ◆JJ4mnGoc :01/08/29 18:03 ID:nyQPz1bE
うわ、動きやがる。スゲ気持ち悪い。
#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');
}
}
583デフォルトの名無しさん:01/08/29 21:17 ID:MU40CPSs
>>582
if の条件を変えても(例えば if(1) とかでも)、同じ結果が出るね…。
if の条件は無視されるけど {} のブロック構造は生きてて、
case の実行が止められるって事なんだろうな…。
 582 が意図してた事とはちょっと違うのかもしれないけど、勉強になったよ。
584デフォルトの名無しさん:01/08/30 00:12 ID:C3TsWUik
>>583
blockにlocal変数があると、compilerは面倒だなー。C++だと悲惨だ。
585デフォルトの名無しさん:01/08/30 00:26 ID:1Hb4haos
?
586デフォルトの名無しさん:01/08/30 00:36 ID:MsZQr7Hg
>>582

げ、マジでコンパイル通るね。
いい勉強になったよ。さんくす。
587デフォルトの名無しさん:01/08/30 01:17 ID:xkEeQIkg
>>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;
}
588デフォルトの名無しさん:01/08/30 08:08 ID:wH4PBT6g
>>587
{ } をなくすととたんに普通のコードに見えてくるなぁ(^^;
589デフォルトの名無しさん:01/08/31 10:20 ID:jo6IzfKs
>>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目だけを交換する、という感じで。
ボトルネックになりかねないところなので
速度優先で行きたいんすけど、当方厨房なのでご教授願います。
591デフォルトの名無しさん:01/08/31 23:39 ID:7xETyOKM
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取ったりするやつです)
どなたか教えてくださると助かります。
既出っぽいですけど。
593デフォルトの名無しさん:01/09/01 00:29 ID:X4g2r2K6
>>592
確か
 n & (n - 1) == 0
じゃなかったっけ?
594デフォルトの名無しさん:01/09/01 00:48 ID:fRlPzhIU
>>593
その公式つかって、二進数で数字を表したときの1の個数を
調べる方法あったよね。
かーにはん・りっちーの本に載ってたはずなんだが、
読んでも見つからないし、思い出せない。

だれかおしえてくらはい。
595デフォルトの名無しさん:01/09/01 02:02 ID:3D0QdnKM
>>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 が定数の場合には、コンパイラが頑張って
最適化してくれるから、そこそこの出力が得られる。

アセンブラでガリガリ書くのは私の手に負えんので、できる人お願い。
596デフォルトの名無しさん:01/09/01 11:22 ID:nFNRRApE
>>594
int bitcount(unsigned n)
{
 int cnt;
 for (cnt = 0; n; n &= n - 1)
  cnt++;
 return cnt;
}
597デフォルトの名無しさん:01/09/01 15:31 ID:4WaMM0is
>>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
>>591 >>595 >>597 ありがとうございました。
煽られるかと思ったんですが、質問してよかったです。
599592:01/09/01 23:45 ID:cxkeoCoY
>>593
多分それです。
ありがとう
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
601デフォルトの名無しさん:01/09/02 12:05 ID:sAGvjp0g
>>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
604デフォルトの名無しさん:01/09/03 07:49 ID:fdEwavAE
>>600
バーヤ
605てぃむぽ:01/09/07 09:18

 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
つべこべ言わずにやれったらやれ!
>>602
このスレでの登場回数3回目だね!
>>613
だからプリプロセッサ使えって・・・
616デフォルトの名無しさん:01/09/08 20:00
Unixに展開コマンドあるよ。
cpp ← C プリプロセッサ

cpp sample.c >> sample.txt

とすれば、展開後のソースが sample.txt で得られる。
>>101
VC++なら _RPTF系を使う。
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
ボクにもやらせて。えっとね
↓ ドンキー任天ード
↑ コレッキリーにシヨーヨ        ……オレモナー
630aeg:01/09/13 23:35
age
6317行の504:01/09/20 17:24
頭の中であのマクロが展開出来ないようでは展開したものを見ても多分
分からないと思うので、作者に代わって大意を述べると、

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のどれに
なっても構わないし、厳密にはこれで異常終了するような実装でも
構わなかったはずです。
632 ◆CrX8cL0k :01/09/21 23:51
最近使ってみた(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;
6351:01/09/27 03:00
その画像ならココ
http://www.f2.dion.ne.jp/~impact14/
>>635
トリッキーの1さんを利用するのは許せない
>>632
どういう意味があるの?
int n = 0;
char *ps, sz[] = "a\0bcde\0fgh\0";

while(sz[n])
  n += strlen( (printf("%s\n", ps = &sz[n]), ps) ) + 1;
639504 of 7行:01/10/01 11:44
>>376
LDIRを使う方法の場合
LD HL,LDIRの次
(LDDRを使う場合はLDDRの前になる)
は必須です。しかも問題の条件からこれをリロケータブルにやらないと
いけません。その部分もきちんと考えるとどうなります?

※LDIRの動作はLDIの動作の後、BCレジスタが0でなければ、PCをDECします。
(説明書などにはBC=0となるまでLDIの動作を繰り返す、のように記述されて
いるかも知れませんがそれは不正確です。ハードウエア的にトレースして
見れば分かります。)
よってHLレジスタの値が中途半端な所にある場合、LDIRの命令のところまで
消去したところで実行される命令がNOPになるので(Z80では書き換えられた
命令は即実行に影響します)その続きの命令が実行されてしまいます。
640504 of 7行:01/10/01 13:07
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
新ネタということで、7行スレより移動してきました
http://pc.2ch.net/test/read.cgi/tech/984182993/589-593

1ソース多言語で"Happy 2ch world!"を出力する
・コンパイルのワーニングは無視してかまわない
・"Happy 2ch world!"以外はなるたけ出さない
・プログラムの長さは1レスまで
・実行可能な言語を示す
  (DOS窓とMS系OSのコマンドラインなどは1つとして数える)

例:DOS窓+C言語

rem (){printf("Happy 2ch world!\n");return 0;} main(){ /*
echo Happy 2ch world!
rem */
rem ();return 0;}


元ネタ(f77,c,/bin/shの3つ)
http://www.ioccc.org/1986/applin.c
#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?もう一個は?
650:01/11/04 23:49
オリジナリティ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脱落では。・・
653:01/11/05 00:06
えーと、ミスです(涙)
Perl, C, DOSのつもりだったけど、
Perl, C通らないね ^^;
出直してきます
perlは、
=begin
=end
じゃなくて、
=任意のアルファベットだけからなる文字列
=cut
だったはずっすよ。
655:01/11/05 01:13
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を共存させれたら、褒める。
褒めてつかわす。

あげ
6607行の60です:01/11/06 06:47
トリッキーの1さん、こないだはどーもでした(笑

>>659
(DEFINE /* (lambda () (display "Hello world")));*/)
(/*);*/){ printf("Hello world."); return 0; }

誉めて使わせ
661660:01/11/06 06:48
あー、LISPじゃなくて、Schemeね。
662660:01/11/06 07:07
main付け忘れた(鬱

(DEFINE /* (lambda () (display "Hello world")));*/)
(/*);*/){ printf("Hello world."); return 0; } main() { DEFINE(); return 0; }
663:01/11/08 18:18
>>660 = 60of7L
こちらこそどうもでした、また会いましょう(笑)

……というレスをはやく付けようと思っていたんですが、
このレスだけで書き込むと内容がスレ違いだし、
何か一緒に書き込むネタがないか…と考えていました(笑)。
結局思いつかなかったんですが。

C++のtemplateを使ってトリッキーな事が出来ないかな、とか考えていたんですが、
普通に書いても結構トリッキーになってしまうので、余り「これ!」っていうネタは
無いですね。

誰かテンプレートのトリッキーな使い方をしたことのある人はいませんか?
>>663
どこかのスレに、フィボナッチの数列を求めるサンプルがあったけど。
これってトリッキーかな
665:01/11/08 21:27
templateを使ってフィボナッチ数列を求めるって事ですか?
例えばchar型やlong型で??
発想力がないのでtemplateの説明みたいなコードしか思い浮かばないけれど、
実物みたいですね。
666デフォルトの名無しさん:01/11/08 21:45
666ゲットぅ!

おーい母さん今夜はリッキーだ!
>>663
なんでgoogleで調べない? ふぃぼなっちの綴りがわかんない
とかじゃないだろうな?
http://pc.2ch.net/test/read.cgi/tech/996640937/320-
フィボナッチなtempleteってーとこの辺か。
669:01/11/09 00:40
>>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
677飽和演算:01/12/27 22:02
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
>>682
つーか、サンプルの例が悪すぎ。
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
知ってる人も多いだろうが
http://www.pro.or.jp/~fuji/mybooks/cdiag/
取りあえずこれ読んどけ。いや読んでください。個人的に目黒寄生虫館物語と並ぶ名著と。
思わず吹き出してしまうと言う珍しいプログラミング関連書籍。スレ趣旨にもマッチ(藁
これ読んで笑えれば初級は脱却。
687デフォルトの名無しさん:02/01/11 15:03
第八章が秀逸
漏れ、目黒寄生虫館の館長のサイン持ってるよ。
689原点回帰:02/01/12 12:08
スレ読み返してみたけど、
>>2 #define swap(a,b) a^=b^=a^=b ネタで、
b=a-b;a-=b;b+=a;
とか
b=a/b;a/=b;b*=a;
なんてのもあるね(藁

>>686 ネタなら、 ttp://www.pro.or.jp/~fuji/mybooks/cdiag/cdiag.8.2.html
マジすげー。唖然とした。
690デフォルトの名無しさん:02/01/13 04:27
>>689
エディタの機能について言及してるが、この人は本当に
エディタを使いこなしテイルのだろうか?
今時これしきの字下げをマクロで組めないような
エディタを使っている時点で藤原氏の底も知れるな。


などと擁護してみるテスト。おれだってこんなソース見たら逃げるっちゅーの
691デフォルトの名無しさん:02/01/13 06:01
Tricky ("code")
藤原の本は悪書に認定されてるんで初心者に勧めないように。
つーか、自ら
http://www.pro.or.jp/~fuji/mybooks/cdiag/appendix.b.htmlの「UNIX流Cプログラミング入門 」の書評で
> プログラミング言語の本は、コンピュータ関連の本の中では寿命の長い方ですが、それでも出版されてから5年程度が寿命です。
> いつ出版された本かは必ず確認して買いましょう。
と書いてる。
693686:02/01/13 15:10
>>690

いや10年前の本だってう゛ぁ(藁 DOSならVzEditorとかの時代?
そういう意味からも鵜呑みには出来ないけど、
この本読んで面白がるのは中級者以上だから、ちゃんと情報の取捨選択は出来る筈。
あくまで読み物だからね。
つかトリッキーなコードってよりクソなコードだったっぽ。スマソ(藁
694Trrykiy code:02/01/13 16:07
void main()
{
 a:
 goto b;
 c:
 goto a;
 b:
 goto c;
}
       ∧_∧ Assembler派としては
       ( ´Д`) 正直、C言語にビットローテート演算子がホスィ・・・
      /    \ ついでにビットスキャン演算子もホスィ
   _  | |  ∬ | |_..∬
  |\ ̄ ̄ ̄旦 ̄ ̄ 旦.\
 ./..\\          \  
/   \|================| 
\    ノ             \
  \                .\
    \               ..\_
      """"""""""""""""""″″′
696デフォルトの名無しさん:02/01/14 23:32
>>695
ローテートはマクロでどうにでもなるかと
ビットスキャンとは?
あるビットを読みたいとか?

a &= 0x04;
>>696
1引いてもとの数とandを取る
> ローテートはマクロでどうにでもなるかと
いや、演算子として実装された方が、コンパイラが上手く最適化してくれるという意味。

> ビットスキャンとは?
ビットフィールドを順方向(または逆方向)に見ていって、最初に立つビット位置を見つけること。
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飽和演算等が可能
704トリッキーの1:02/01/24 02:18
このスレがまだ生きていたとは……感謝です。
ネタがなくて申し訳ないですが。
>>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がわからないんだけど。誰か説明して
>>714
lispやるとわかるでしょう。
C++において[]演算子のオーバーロードができることから、
リンクリストを扱うtemplateクラスを作って
item[-1]; // 前の要素
item[1]; // 次の要素
とか。
もちろん添字に当たる引数はsignedな型にしておく。
717711:02/03/01 11:06
>>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};
>>717
さほどトリッキーに見えん
普通にAdd,Del,Mul,Dev書くよりもメリットなさそうだが。
タイプ量が減るってメリットはありそうだが
>>671
結構驚いた。
なんでこうなるんだ?
#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;}

のほうが少ないよん。メリット無しだね。
723711:02/03/01 23:28
>>722
例で書いただけだかんね。実際に使う場合は、
#define HOGE(Funk,Opr) void Funk(){\
/*略*/
c = a Opr b;\
/*略*/
}
ってな具合に使うから、タイプ量が減る。
724711:02/03/02 11:00
あと、似たようなコードを書かずに済むから、バグも減る。
>721
1+(-1) = 0
>>725
端折らないで途中も書いてー
a=1+-+-+-+-+-+-+-+1;
a=1+( -( -( -(-(- ( - ( -1) ))))));
a=1+(-1)
1+・・・・+1; の最初の+は演算子として残って、
それ以外の+は消えちゃうわけですか・・・?

むむ・・・・あ、+-の間に0を補間していけばいいのか。
>>723
テンプレート使えばいいではないか
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
739sage:02/03/08 13:23
ドンキーコングがトリッキーコードを書く。
ケンタッキーのチキン(鳥)を食べながらコーラを飲む。
トリッキーコーラ
お〜い山田くん
742デフォルトの名無しさん:02/03/08 16:08
現存する最古の(?) Cコンパイラーのソース(last1120c)の
ospaceはトリッキーだな。
http://cm.bell-labs.com/cm/cs/who/dmr/primevalC.html

これもトリッキー
http://www.konica.co.jp/showroom/goody/
744デフォルトの名無しさん:02/03/11 09:08
>>743
笑った
746厨房:02/03/11 18:01
>>742
ダウソロードしました
goto文を見つけてビクーリしました
取り憑き仲人とは?
748デフォルトの名無しさん:02/03/12 09:46
>>734
UNIX の icode か?
>>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
>>750
>>709-710 でガイシュツ
別スレ「プログラムの高速化について語る」より、float → int 変換
http://pc.2ch.net/test/read.cgi/tech/1011918364/96-99
保守
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を得るにはほとんどこれしかないけどね
>>777-778
それなに?
>>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 は引数なしで
定義するのが普通ですな。
>>786 >>96-
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のプロトタイプ宣言て事??
800795:02/04/07 04:30
>>796
こうすることで、変数 n に収めた文字がコードに変換されると思ったらしい。
まぁC は初体験だったらしいので…(何だかエチ-表現だ)

>>799
おおむね正解。
ローカル関数っつーより、ローカル(な)プロトタイプ宣言と言った方が正しいかと。
801795:02/04/07 05:13
こう書いたのとほぼ同意になるんだったっけ?

 #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/
よりコピペ
>>808
 なるほど、後半は >>209のやり方のアレンジかな
810NIH3T3: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
>>812
num が 0 の時どうすんの?
numが0でも問題無いが?
へえ? 今だと変わった環境だな >>822 log(0) で例外出ないのか
824デフォルトの名無しさん:02/04/18 23:32
>>816
 世の中色んな環境がありますし、要求があります。

 浮動小数点をサポートしてない環境でも>>811は動きます

また、分岐命令は分岐予測に失敗すると十数命令分ペナルティを払うようなCPUだって
あるので、分岐命令を使わない>>808方が速かったりしますしね。

たとえば、マイクロ秒のタイマーが必要な場合に命令数を数えて時間を作ったりしますが
そんな時に実行時間が一定の関数があればそれを入れたり出来る事もあります

>>823
VCでコンパイルして実行してみたけど、きっちり1が帰ってきたYO!
ライブラリ関数内部で0ならリターンしてるんじゃない?
>>824
そんなに頻繁に必要桁数求めるかぁ?
>>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
837836:02/04/19 21:19
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
「必要の無いところでも最適化する」奴は使えん
「必要の無いところでも最適化できる」奴なら同意だが
839836:02/04/19 23:58
コピペついでに古い問題をもう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は最近どうしてるんだ(笑)
848845:02/05/02 02:58
あ、
誤:CALL SUB
正:CALL (HL)
849デフォルトの名無しさん:02/05/04 21:41
age
850デフォルトの名無しさん:02/05/13 13:20
保全age
851age:02/06/04 13:44
age
switch(1)
{
age("保守保守");
case 1:
}
つーか、このスレ過去の遺物だから保守要らない
echo "ホシュ";
いまだに >>2 がよくわからない。
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
>>857
イメージ的によくわかった。サンクス。
ラスタオペレーションキター(゚∀゚)ー!!
>>857
分かりやすい!
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
>>867
それ(・∀・)イイ!!
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
>>865
破壊
何がじゃ
破壊ダー
876デフォルトの名無しさん:02/07/14 00:16
スタックだろうが
eax,ebxの順に入れて
eax,abxの順に取り出したら以下略
自信ないのか
何を破壊するの?
>>878
キカイダー
>>878
eaxとebxレジスタじゃないか?
>>873,876
ちゃんと交換されるが。
882 :02/07/14 00:27
>>869が予言しているので、>>885はがんがれよ。
873赤っ恥
↓がんがれ
xchg eax, ebx
       冫─'  ~  ̄´^-、
     /          丶
    /             ノ、
   /  /ヽ丿彡彡彡彡彡ヽヽ
   |  丿           ミ      
   | 彡 ____  ____  ミ/        
   ゝ_//|    |⌒|    |ヽゞ        
   |tゝ  \__/_  \__/ | |
   ヽノ    /\_/\   |ノ  _____
    ゝ   /ヽ───‐ヽ /  /
     ヽ   ヽ──'   /  < ン?
       \      ̄ ,/   \_____
         / ⌒\ \  
         |  \ \\   
         |    |\ v' ))  
         |   /⌒ー'‖ 
         |  /   イ  ||  
         |    / |  ||        
         \_/  (__つ
遅かった・・・鬱
888赤っ恥873:02/07/14 00:37
あー、それ以前の全く見ずに書いてたよ。
それなら納得。
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)

だけで大分速くなりそう。
898871:02/07/14 03:15
皆様レスどうも!勉強になります。

>>894
そうです、その通りなのです。
具体的には、dataが3桁以下ならそのまま出力で、4桁以上のものに
ついては、上位3桁のみを残して、4桁目を四捨五入するのが目的です。
説明不足でした、スマソ。もう一回逝ってきます。

>>896
なるほど、(int)log10で桁数求まりますね。高校数学忘れてる・・・ウツダ
一行コード・・・萌えるなぁ。
しかし浮動小数演算コストも伴う諸刃の剣・・・
899871:02/07/14 03:19
>>897
うわ〜、むちゃくちゃ速くなりました。ありがとうございます!!
>>899
>>896との速度比較もしてみてよ。興味ある。
901871:02/07/14 03:50
速度比較してみました。といっても、下に書いたコード実行しただけですが。
うちの環境(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;
}
902871:02/07/14 03:54
あ、私が最初に書いたコードは約28秒でした。
書き忘れてた、やっぱり逝こう。
903逝って良しの1:02/07/14 11:34
縦に読むと別の動作をするコード。
904age:02/07/20 03:13
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;
>>906
レスがいっぱいに見えるぞ。
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;
}
マクロアセンブラでこーゆーネタがあったらしいけど・・・。
スマソ、タブが欠けた。
>>911
ASCIIのなんだったっけかな。
914911:02/08/16 18:01
>>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
921:02/09/18 21:20
うわ、感動。まだこのスレを保持していただいていたとは……
ゆっくり読ませていただきます。有難うございます>みなさま
922デフォルトの名無しさん:02/10/10 06:03
すいません質問です。
過去に、ビット数をカウントする技がありましたが、

int right_shift(int n) //←signedに注目
{ return n>>1;}

signedの右シフトは
if (right_shift(-1) == -1)
が保証されるということでいいんでしょうか?
923922:02/10/10 06:11
ちなみにVCとBCCで試したら両方とも真になりました。
924デフォルトの名無しさん:02/10/10 06:13
よくない。VC++もBCCも同じCPUだからあまり検証になってないな。
925922:02/10/10 06:15
ちなみにint nをunsigned nに変更したら、両方ともfalseです。
この辺は言語仕様で決まってないのかな。
926922:02/10/10 06:16
>>924
そうですか。といっても違うCPUなんて持ってないし。困った。
確かにこの結果だけを鵜呑みにしてたら、
後でとんでもないことになりそう。
928デフォルトの名無しさん:02/10/10 06:33
http://www.tool-spt.mesc.co.jp/faq/faq/01051275_j.htm
ここ見ると、算術シフトとして保証されてるっぽいが。
929デフォルトの名無しさん:02/10/10 06:36
と思ったら、
http://www.ksworks.org/memo/references/cref.htm
>左シフト、右シフトは一方向シフト。 はみ出したビットは捨てられ、反対側には0がシフトインする。
>負の値は(たいていの処理系は)その符号を保持する算術シフトを用いる(処理系依存)

やっぱ処理系依存だそーです。
930922:02/10/10 06:45
>>928-929
ありがとうございます。
じゃあ、処理系毎に算術シフトになるかどうかの切り分けを
入れる必要がありますね。
まず、2の補数表現の符号付整数がサポートされていて算術シフトが定義されているなら、 -1の算術右シフトは-1だ
そして、符号付整数の表現方法は 昔は別の表現もあったが 今は2の補数でないチップはまず無い

-a = not(a)+1 任意の負数は全ビットの1の補数に1を加算したもの=2の補数

でないチップは博物館か、よほど古いシステムでしか残っていない。 
そんな環境ではC言語で右算術シフトなんてコ洒落たものは使えないだろう
右辺が2以上でも-1ダヨネ?
if ((-1 >> n) == -1)
n:2〜31
ダヨネー?ダヨネー?
>>925
unsignedの場合は決まってる。
935デフォルトの名無しさん:02/10/15 09:29
そろそろ次スレ立てて。
まだはやい
物凄く息の長いスレだね
938デフォルトの名無しさん:02/10/27 10:28
hoshu
939デフォルトの名無しさん:02/10/28 16:27
>>910-911
キタ━━━(゚∀゚)━━━!!
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); }
>>943
すげー!って引数意味ねーじゃん!
945月並みだが:02/11/23 02:14
p(x,y), b(x1,y1,x2,y2) の時(適当)

(x-x1)*(x-x2)<=0 && (y-y1)*(y-y2)<=0

が真なら矩形内(境界線上含む)に点がある。
946一応解説:02/11/23 02:19
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

理由は符合ビットが立つかどうかを考えれば一目瞭然かと
948947:02/11/23 05:05
"< 0" は ">= 0" の間違えです
>>947
それは負数が2の補数表現じゃないと通用しないが
1の補数表現でも通用する、と思ったが、-0が問題か。
951デフォルトの名無しさん:02/11/23 19:01
>>950
次スレ頼むわ
952950:02/11/23 19:08
>>951
いや。お前が立てろや。
953デフォルトの名無しさん:02/11/23 21:34
矩形内に点があるかどうかを

<, <=, >, >=

の演算を行わずに判定する方法はありますか?
954953:02/11/23 21:44
勿論、数は実数という条件で・・・
.lt.や.le.を使えば良い(ぉ
956953:02/11/23 22:38
>>955
いや、これは表記法の問題ではなくて、
数の大小を比較せずにって事。
なんで大小比較があかんの?
958953:02/11/23 22:51
>>957
いや、なんとなく。ただの思いつき。
そんな事できないかなぁ、って思っただけ。
でも、そんな事をやってしまうのがトリッキーって奴では?
>>953
ドット単位で全走査。
960953:02/11/23 22:57
>>959
勿論、数は実数という条件で・・・
実数?浮動小数点形式か?
962953:02/11/23 23:16
>>961
とりあえずそれで。
但し処理系依存(機械エプシロン分足して走査する、みたいな)は
嫌だな・・・
符号bitを返す関数signがあるとすれば
a<bは、sign(a-b)!=0と同じ。
あとはもう自明なので述べない。
964953:02/11/23 23:56
>>963
つーか、それって sign 自体が内部で(0との)大小比較を行っているだけ
だと思うが(メモリ上での操作は別として、意味的に)。。。
しかしコンピュータの中で動く以上、それもまた回答になるのだろう。

ま、こんな問題、あまり深く追求しても仕方ないか。
とりあえず付き合ってくれてありがと。
IEEE754 浮動小数点だったら先頭が符号ビットだから整数キャストで947と同様にいけそうな。
Σ(゚д゚lll)ガーン
971名無しさん:03/01/05 02:09
         / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\
Λ_Λ  | 君さぁ こんなスレッド立てるから          |
( ´∀`)< 厨房って言われちゃうんだよ             |
( ΛΛ つ >―――――――――――――――――――‐<
 ( ゚Д゚) < おまえのことを必要としてる奴なんて         |
 /つつ  | いないんだからさっさと回線切って首吊れ     |
       \____________________/

(-_-) ハヤクシンデネ… (-_-) ハヤクシンデネ… (-_-) ハヤクシンデネ…
(∩∩) (∩∩) (∩∩)

(-_-) ハヤクシンデネ… (-_-) ハヤクシンデネ… (-_-) ハヤクシンデネ…
(∩∩) (∩∩) (∩∩)

(-_-) ハヤクシンデネ… (-_-) ハヤクシンデネ… (-_-) ハヤクシンデネ…
(∩∩) (∩∩) (∩∩)
埋め
埋め
揉め
産め
多め
977いいかげん:03/01/07 23:58
止め
戒め
噛め
詰め
決め
埋め
埋め
埋め
埋め
埋め
埋め
埋め
埋め
埋め
埋め
埋め
埋め
埋め
埋め
15分間隔で埋め立て?
998
999
1000でつ
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。