トップページ⇒tech
142コメント40KB

ちょっとしたテクニークスレッド

■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。NGNG
if( hogehoge == 1 )
を
if( 1 == hogehoge )
と書くと、イコールが一個しかなかったときエラーに
なってくれる。

#罵倒をおそれずかきこめー
0002>1NGNG
その話題ふると 恐い人がやってくるのでsageですぅ
0003名無しさん@お腹いっぱい。NGNG
(define (dbg x . s) (for-each display s) (display x) (newline) x)
0004名無しさん@お腹いっぱい。NGNG
つーか、1(最初の文章)に
>#罵倒をおそれずかきこめー
だけ書いて
2に内容書けばよかったのに・・・


struct hoge {
  char *ptr;
  char str[1];
};
C++だと使いにくいが…
0005名無しさん@お腹いっぱい。NGNG
VC++だと
struct hoge{
 char *ptr;
 char str[0];
}
が出きるから、それに慣れてたせいでgccに移植するときに泣いたことが…
0006名無しさん@お腹いっぱい。NGNG
>4@`5
それって何に使うんですか?純粋に知りたいです。
00074NGNG
つい、例にポインタをいれてしまったので、わかりにくいか。

例えば、文字列のリスト構造を実現する場合に
リストを実現する構造体と、文字列を記憶する配列分の
2回、mallocを呼ぶ必要がある。
ところが、4の形式、つまり構造体の最後のメンバにchar[1]があると、
 p = malloc(sizeof(struct hoge)+strlen(s));
 strcpy(p->str@` s);
という技が使える。
利点はmallocの呼び出し回数が減らせるため、
記憶領域的にも速度的にも有利になる。

もちろん、charに限らず、
「不定長の領域を本体とは別に確保する必要がある場合」に、
使う事が出来る。
00081NGNG
誰も上げないので
あげ
0009>6NGNG
構造体の最後のメンバが可変長のデータを持っている(指しているのではない)
の時に使います。
とくに、生成から消滅までの間固定長だけど、モノによってデータサイズが違う
ときに有効です。
0010名無しさん@お腹いっぱい。NGNG
Shift-JIS 漢字第一バイトの判定

if ( ((c >= 0x81) && (c <= 0x9F)) || ((c >= 0xE0) && (c <= 0xFC)) )

のかわりに

if ( (c >= 0x81) && ( (c <= 0x9F) || ((c >= 0xE0) && (c <= 0xFC)) ) )

の方が、多くの場合速度が速いコードが作れ、オーバーヘッドもほとんどない。
括弧が多いのは、今書いたからなんで、かんべん。

0011このスレおもしろいかもNGNG
//1と2を入れ替える
i := (i - 1) * (-1) + 2;
{
if i = 1 then
 i := 2
eles
 i := 1;
}
2つもコメントを入れてしまった俺は根性なし・・・
0012名無しさん@お腹いっぱい。NGNG
<10
2つ以上の範囲の判定なら、いつでも使えそうですね。
0013名無しさん@お腹いっぱい。NGNG
VBでCombo boxにリストを追加したい時、普通は
Combo1.AddItem リスト項目
とやる。
が、この項目がうん百件とある場合(データベースから拾ってくる等)
AddItemでは偉く時間がかかってしまう。
そこで、APIを使うと速度が向上する。
こんな感じだ。
あらかじめ、Option Explicitで以下のように宣言しておく。

Private Declare Function SendMessage Lib "user32" _
Alias "SendMessageA" _
(ByVal hwnd As Long@` _
ByVal wMsg As Long@` _
ByVal wParam As Long@` _
ByVal lParam As Any) As Long

で、実際の処理部分は、
自分の場合DBにオラクルを使ったので、

Dim ret As Long
Dim cbHwnd As Long
Dim cbitem As String
Dim SQL_TEXT As String

cbHwnd = Combo1.hwnd
Combo1.Clear

SQL_TEXT = "select hoge from TB_hoge "
SQL_TEXT = SQL_TEXT & "where code = 'hoge'"
SQL_TEXT = SQL_TEXT & " ORDER BY hoge"
Set OraDs = OraDatabase.CreateDynaset(SQL_TEXT@` ORADYN_READONLY)

OraDs.MoveFirst
Do Until OraDs.EOF
cbitem = OraDs![hoge] & vbNullString
ret = SendMessage(cbHwnd@` CB_ADDSTRING@` 0@` cbitem)
OraDs.MoveNext
Loop

といった感じになる。
かなりスピードアップするハズ。
お試しアレ。
sendmessageは奥深いよ……。
0014名無しさん@お腹いっぱい。NGNG
常識かもしらんけど。

#define SWAP(a@`b) (a^=b@`b^=a@`a^=b)
0015>11NGNG
i = (1+2) - i;
でええんとちゃうの?
BASIC時代にはしょっちゅう使ったテクだが。
0016名無しさん@お腹いっぱい。NGNG
>15
つーか、それって3-i
0017名無しさん@お腹いっぱい。NGNG
有名かもしれんが、

printf("%0*d\n"@` 4@` 123 );


00186NGNG
>7@` 9
なるほど〜。
WinAPIでパレットいじるときのあれみたいなものですね〜。
どうもありがとうございました。
0019>13NGNG
それ以前に
COMBOやMSFLEXGRIDなんかは

Combo1.Visible = False

処理

Combo1.Visible = True

とするとオーバーヘッドが発生するはずなのになぜかかなりの高速化になる。
0020名無しさん@お腹いっぱい。NGNG
LD BC@`DEを実現する
PUSH DE
POP BC
0021名無しさん@お腹いっぱい。NGNG
ALの符号をAHに拡張する
CBW
0022>20NGNG
mov b@` d
mov c@` e
でいいと思うんだけど。なぜにスタックを使う?
メモリを介さない分、速いだろうとおもうのですが。
002320NGNG
>>22
??言われてみれば、そうだな……。Z80の話だからなあ。
よく覚えてねえや。
じゃあ、これでどうだ
XCHG BC DE を実現する
PUSH BC
PUSH DE
POP BC
POP DE
0024名無しさん@お腹いっぱい。NGNG
inline int IsShiftJIS(unsigned char c)
{
 if(c>=0x81)
 {
  if(c<=0x9F)
   return 1;
  else
  {
   c += 0x20;
   if(c <= 0x1C)
    return 1;
  }
 }
 return 0;
}

こう言うのはやっぱり無駄な努力なんでしょうか。
0025!=22NGNG
どうだ、って、それもaを使って6回LDする方が速いんじゃねーの?
002620NGNG
>>25
かな?
まあ、アキュムレータを使わないでも済む方法、ってことで一つ……。
どっちが早いかは、今手元に資料が無いから分かんないよ。
0027!=22@`25 NGNG
8ビット汎用レジスタ間LDは全部4クロック、PUSH/POPは11+10クロック
だから、スタックは使わない方が基本的に速い。
23のはAレジスタ使わないなら
PUSH BC
LD B@`D
LD C@`E
POP DE
あたりで妥協かな。
0028名無しさん@お腹いっぱい。NGNG
ageてみよう
0029名無しさん@お腹いっぱい。NGNG
>>14
逆の意味で常識。
SWAP(x@` x);
とした場合、何が起こる?
0030名無しさん@お腹いっぱい。NGNG
0と1を入れ替え。

int a = 0;
a = 1 - a;

すげーだろー。
0031名無しさん@お腹いっぱい。NGNG
>30
a^=1; でええやん。

0032名無しさん@お腹いっぱい。NGNG
人差し指と薬指で広げておいて、中指を膣口に忍ばせ、
更に親指はクリトリスを責める!
0033名無しさん@お腹いっぱい。NGNG
0からN-1までをなめるとき、
for (int i = N - 1; i >= 0; --i) {
...
}
みたいに判定を0で行うとほんの少し速くなるかも
#こんなこと気にしながらプログラム書きたくないけど・・・
0034ミトコンドリ子NGNG
アタシはこっちの書き方のほうが好きよ。
for ( int i=N ; --i >= 0 ; ) {...}
Nの表記が長いときに -1 が紛らわしくならないからよ。

0比較のため、というよりはインデックス逆巡回を書くときの
イディオムよね。
0035名無しさん@お腹いっぱい。NGNG
>>33@`>>34
境界判定のための比較が要らなくなるか、
って、アセンブラなら減産して0だった時点でZeroフラグ立つよね。

Cって、
オプティマイズされたオブジェクトなら、意外な方法で高速にしたりするんで、意味無し!

003633NGNG
>>34
>for ( int i=N ; --i >= 0 ; ) {...}
あ、、、きれい・・・いただきます:-)

>0比較のため、というよりはインデックス逆巡回を書くときの
>イディオムよね。
んーでも、比較すべき数値をレジスタにロードしなくて良い分
速いかなぁと・・・CPUによりけりですけど。
おまじないのように上記のようにがんばって書いてました。
「もうちょっと速くなりますように」とお祈りしながら・・・
003733NGNG
>>35
>Cって、
>オプティマイズされたオブジェクトなら、意外な方法で高速にしたりするんで、意味無し!
いや、先の例で、Nが変数のときには
for (int i=0; i < N; ++i) {...}
で、比較部分がほんのちょこっとだけ最適化あまくなるようなきがしません?
まあ、目に見えて速くなるわけではないですが、
藁にもすがりたいときにはおまじないとしてやってます。。。
だめっすかねぇ・・・
0038名無しさん@お腹いっぱい。NGNG
for ( int i=N ; --i >= 0 ; ) {...}  って
for ( int i=N ; i-- ; ) {...} でも可?
0039名無しさん@お腹いっぱい。NGNG
x+=(button==RIGHT)-(button==LEFT);
y+=(button==UP)-(button==DOWN);
(;´Д`)
0040名無しさん@お腹いっぱい。NGNG
すんません
ここの人はアセンブラとかにも詳しいのかな?
便乗質問させてください。

for(int i=N; --i;){}
と
int i=N;
while(i--){}
ではforの方が早くなるんですか?

最適化のあまりよろしく無いコンパイラ(あまり最適化に頼るのもなんなので)
普通程度の最適化がなされるコンパイラ(今時のコンパイラならそのぐらい基本的みたいな)

の両方のケースで教えてください。
0041名無しさん@お腹いっぱい。NGNG
>>40
何故自分で確かめない?
0042名無しさん@お腹いっぱい。NGNG
x=y=z=0;
(;´Д`)
0043名無しさん@お腹いっぱい。NGNG
>>40
ループ回数違うような・・・
あと、iが0になったかどうかだけで判定してますが
Nが負で渡ってきちゃったときとか不安・・・
iのスコープも違ってるし・・・

スピードは同じっぽそう。逆アセンブルして確かめよう。
0044名無しさん@お腹いっぱい。NGNG
自分の目で確かめろ。
アゲてるやつはみんな白痴。
0045名無しさん@お腹いっぱい。NGNG
他人を白痴呼ばわりするのって楽しい?
0046名無しさん@お腹いっぱい。NGNG
>>45
あなたは、そんなこと聞いてどうするの?
0047名無しさん@お腹いっぱい。NGNG
int a@`b@`c;
....;
if(int d=a-b)
{
d+=...;
c+=d;
}
(;´Д`)
0048名無しさん@お腹いっぱい。NGNG
何これ?>47
0049名無しさん@お腹いっぱい。NGNG
>>45
たのしぃでぇ〜す。

酔っぱらい関数きぼん。
0050名無しさん@お腹いっぱい。NGNG
ここおもろい!!わしもかきこ!!

nビットのマスク生成

(1 << n) - 1;
0051名無しさん@お腹いっぱい。NGNG
あらら、sageばっかり・・・
あげちゃえ!
0052名無しさん@お腹いっぱい。NGNG
mvi a@`0
ではなく
xra a
とすると1バイトで済む

メモリを0(等)で埋める歳にはpushを使うと速い

dadで16bitの引き算をするには…
bcとdeをxchgしたい時には…
は当たり前の事か
0053名無しさん@お腹いっぱい。NGNG
bool light0;
…;
(light0?Enable:Disable)(LIGHTING);
(;´Д`)
0054名無しさん@お腹いっぱい。NGNG
CMP AL@`0Ah
SBB AL@`69h
DAS

5バイトの1桁16進バイナリ−ASCII文字変換。
有名だねー。
0055名無しさん@お腹いっぱい。NGNG
CLEAR @`&HBFFFしないでGVRAMにアクセスするルーチンをC000以前に置くには
文字列変数に入れてVARPTR()の値を参考に絶対アドレスの部分を書き換える

って何の話だ
0056名無しさん@お腹いっぱい。NGNG

SJIS2JIS PROC
     sub al@`71h
     and al@`3Fh
     stc
     rcl al@`1
     cmp ah@`7Fh
     cmc
     sbb ah@`1Fh
     cmp ah@`7Fh
     jc @skp
     inc ax
     sub ah@`7Fh-21h
@skp:
     xchg al@`ah
     ret
SJIS2JIS ENDP
0057名無しさん@お腹いっぱい。NGNG
typedef unsigned char BYTE;
typedef struct { BYTE stuff[100]; } BYTE100;

*(BYTE100*)px = *(BYTE100*)py; //memcpy(px@`py@`100)と同じ?
0058名無しさん@お腹いっぱい。NGNG
>>56
よかったらJIS2SJISも書いてくださ〜い。
0059名無しさん@お腹いっぱい。NGNG
int c の b ビット目の on / off

#define BITon(b@`c)  ((c) = ((c)|(0x01<<(b))))
#define BIToff(b@`c)  ((c) = (~(~(c)|(0x01<<(b)))))

ダサイ???
0060名無しさん@お腹いっぱい。NGNG
#define BIToff(b@`c) ((c) = (c) & ~(1 << (b)))
c++ を無意識に使う怖さから、inline にしたほうがいいと思うが。
0061名無しさん@お腹いっぱい。NGNG
>54
6809版
ADDA #$90
DAA
ADCA #$40
DAA

6バイト
0062名無しさん@お腹いっぱい。NGNG

#define BIT_Reverse(b@`c) ((c)=(c)^(1<<(b)))
0063名無しさん@お腹いっぱい。NGNG
なんか、懐かしのテクニークスレッドと化してきたな(ワラ
0064名無しさん@お腹いっぱい。NGNG
>>63
しょうがねぇじゃん。ここに書いてる奴はみんなレベル低いんだから。
0065名無しさん@お腹いっぱい。NGNG
オマエモナーと言われたいM男君が増えてるな
逝ってやらん
0066名無しさん@お腹いっぱい。NGNG
age
0067名無しさん@お腹いっぱい。NGNG
ここにHerrさんいるでしょ。
0068名無しさん@お腹いっぱい。NGNG
#DIV(x@` y) (y ? x / y : 0)

うーん、こんなのは?
望んだ結果が出ないかもしれんけど。
006968NGNG
あ、((y) ? (x) / (y) : 0) だな。
0070名無しさん@お腹いっぱい。NGNG
>>68 何に使うの? 無限大を0に修正する? 用途を示してくんない?
0071名無しさん@お腹いっぱい。NGNG
除算エラーにしたくないのでしょう。
0072>70NGNG
たぶんゼロ除算例外を防止する為でしょう。

でも、その前の段階でyがゼロにならないよう管理すべきだと思ってたから
こんな事はやったことないな。逆に原因不明にするだけじゃん。
0073名無しさん@お腹いっぱい。NGNG
>>72 わしもそう思う。

007470NGNG
ゼロ除算防止なのは、わかる。
オレも72の言うとおりこのマクロの使用では原因不明になるだけじゃないのか
と思う。

でもこういう形で記述すると上手く解決できる問題分野があり、それを
オレが知らないだけかとも思ったワケ。

そこらへん、どうよ >>68

#行列の特異値分解かなにかで 1/ε -> 0 (εは非常に小さい正数)と
置き換える場合とかがあった気がする。でもその場合はこのマクロは
使えないとも思う。
0075名無しさん@お腹いっぱい。NGNG
ビット数をカウントするアルゴリズムでさぁ
0x7777とか、0x33333?とか使うやつあったっしょ
あれってどーゆーのだっけ?
0076名無しさん@お腹いっぱい。NGNG
>>75
そこまで分かってるなら自分で検索すれ!
http://www.st.rim.or.jp/~phinloda/cqa/cqa15.html
007775NGNG
ありがと。(探したけど、見つからなかったの、ゆ・る・し・て)
0078名無しさん@お腹いっぱい。NGNG
ちょっとズレるけどさ、マクロって関数コールのオーバーヘッドを
避けるために多用したりすることってないの?>制御分野のお方。
0079>78NGNG
僕は制御じゃないけど
複雑になりそうな場合マクロをやめて関数にしてpragmaでinline化します。
移植性は下がるけど、可読性のほうが大事なので。
0080名無しさん@お腹いっぱい。NGNG
制御用のクロスコンパイラは実装が貧困すぎて
inlineできないのがあります。
0081名無しさん@お腹いっぱい。NGNG
最近は制御系にもgccとか使われる場合が結構ある。
0082>78NGNG
あるよ。
0083ななしさん@目立ちたがりの厨房NGNG
コメントテク。
通常、
/*
....
*/
と書くが、
/*
....
//*/
と、コメントアウトしておくと、
//*
....
//*/
と、最初の一行に'/'一個追加するだけで、"...."の行が有効になる。

デバッグの時にちょっと便利。
0084名無しさん@お腹いっぱい。NGNG
偶数化:変数 & -2
0085名無しさん@お腹いっぱい。NGNG
>76
ちなみにどんなキーワードで見つけたの?すごい
0086吾輩は名無しさんであるNGNG
ここあとで修正しとく必要があるなーってとこには
/**/を書いときます。
0087名無しさん@お腹いっぱい。NGNG
>>83
頼むからやめてくれ。
008868じゃないけどNGNG
>>68-74
もちろん、y=0にならないように書くのが正しいんだけど、仕事でゲームの
開発をしていると、最悪でも例外がおきないようにしておくのはわりと
大事だったりします。
# ハングるよりは変な場所に表示される方がマシってこと。
008968NGNG
あ、遅レスだけど 71-73@`88 の言う通りですね。
まあこれは 88 の言うように許容できる場合に限るので今考えると特殊な部類に入るかもね…
返す値を 0 じゃなくて自作関数で説明入りエラー吐くようにしておけば 0 割りのトラップもしやすいかもね。
0090名無しさん@お腹いっぱい。NGNG
0が返っても許容できる、じゃなくて、
エラー処理の存在自体が許容できないわけです。ゲームでは。
0091名無しさん@お腹いっぱい。NGNG
ちょっとしたテクニークスって事で
typedef で一度にポインタも定義出来ます

例:
typedef struct { なんとかかんとか} HOGE@`*PHOGE;
0092名無しさん@お腹いっぱい。NGNG
<91
typedefの書式は、識別子の宣言とおなじだからね。
0093名無しさん@お腹いっぱい。NGNG
常識と思うけど大文字化(ASCII 文字セット限定)
c には英文字が入ってると思いねぇ
char to_upper(char c) {
return c & ~0x20;
}
0094名無しさん@お腹いっぱい。NGNG
>>91
const PHOGE
ってやってハマる奴がたまにいる。
0095>>93NGNG
普通のtoupperじゃなんであかんの?
0096Dr.URINGNG
URIのことをかまってくださいー・・・

typedef struct{
  unsigned int Value : 2;
} ROTATE;

void FuncA()
{
  ROTATE st;
  unsigned int p;
  st.Value = 0;
  int i;
  for (i = 0; i < 10; i++)
  {
    p = st.Value++;
    printf("%d\n"@` p);
  }
}
0097名無しさん@お腹いっぱい。NGNG
#define FLAG_CHECK( NUM@` FLAG) ((NUM & FLAG) / FLAG)
#define FLAG_ON( NUM@` FLAG) NUM |= (NUM ^ FLAG)
#define FLAG_OFF( NUM@` FLAG) NUM ^= (NUM & FLAG)

いまどきフラグなんてせこい使い方しないか?
0098ビット操作を最近覚えた人NGNG
>>97
結構便利なんですが、、、
例えばゲームの毒、混乱、眠りなどの状態を表すとか。
0099名無しさん@お腹いっぱい。NGNG
#define FLAG_CHECK(NUM@` FLAG) (!!(NUM & FLAG))
の方が好みだ。
0100名無しさん@お腹いっぱい。NGNG
#define FLAG_CHECK(NUM@` FLAG) (((NUM)&(FLAG))==(FLAG))
0101ビット"猿"ZよかNGNG
ビットフィールド使うなぁ…
■ このスレッドは過去ログ倉庫に格納されています