1

カメラ オブジェクトに複数のラベルがあり、メモリを節約しようとしています (メモリが非常に少ない環境)。静的定数配列とマクロを使用した現在のバージョンは次のとおりです。

ヘッダー内:

#define NUM_CAMERAS         6        
static const char* CAM_LABELS[NUM_CAMERAS] = {  "Camera1",
                                                "Camera2",
                                                "Camera3",
                                                "752x480_cam",
                                                "std_cam",
                                                "wide_cam" };
#define CAM_LABEL(id)           id<=NUM_CAMERAS?CAM_LABELS[id-1]:"cam id error"

プログラムでの使用法:

int cam = 3;     
pritnf("Configuring camera id [%d], label: [%s]\n",cam, CAM_LABEL(cam) );

上記は機能しますが、マクロを使用して static const 配列を置き換えたかったので、ヘッダーに次のようなものを追加します。

#define NUM_CAMERAS       6
#define CAM_LABEL1        "Camera1"
#define CAM_LABEL2        "Camera2"
#define CAM_LABEL3        "Camera3"
#define CAM_LABEL4        "752x480_cam"
#define CAM_LABEL5        "std_cam"
#define CAM_LABEL6        "wide_cam"
#define CAM_LABEL(id)     /* myster code */

上記の「id」として整数値を渡し、既知の CAM_LABEL## 値を再作成する方法はありますか? ## 接着マクロのいくつかの組み合わせを試しましたが、その変数値の代わりに、「cam」またはマクロに渡された変数名が入れられました。私はおそらく非常に明白な何かを見逃しています。

前もって感謝します。

4

1 に答える 1

4

私があなたの問題を理解したかどうかはわかりませんが、これは私にとって完璧に機能します:

#include <stdio.h> 

#define CAM_LABEL1        "Camera1"
#define CAM_LABEL2        "Camera2"
#define CAM_LABEL3        "Camera3"
#define CAM_LABEL4        "752x480_cam"
#define CAM_LABEL5        "std_cam"
#define CAM_LABEL6        "wide_cam"

#define CAM(n) CAM_LABEL##n

int main(int argc, const char *argv[])
{
  printf("CAM: [%s], [%s]\n",CAM(2),CAM(3));
}

ただし、これがメモリを節約するのに効果的だとは思いません(これが主な懸念事項のようです)。「Camera1」のすべてのインスタンスが同じポインターに置き換えられるように、コンパイラーが同一の定数文字列を折りたたむという事実を期待しています (そして、文字列自体は一度だけ格納されます)。これは保証されていません。の:

printf("%s, %s\n","Camera1","Camera1");

コンパイラが 2 つの別個の文字列を作成することは正当です。

単一の文字列とオフセット ベクトルを作成することをお勧めします。

const char *cam_labels="Camera1\0Camera2\0Camera3";
const char *cam_labels_offset = "\x00\x08\x10";

#define CAM(x)    (cam_labels+cam_labels_offset[x])
int main(int argc, const char *argv[])
{
  printf("CAM: [%s], [%s]\n",CAM(0),CAM(2));
}

厄介なことが起こるのを避けるために何らかの制御を追加する必要があります (ただし、二重評価のリスクがあります)。文字列の合計の長さが 255 を超える場合は、オフセットを 2 バイトで表す必要があります。

また、オフセットを取得するための小さなルーチンを作成する必要があります。手動でカウントするとエラーが発生しやすくなります。

p をシステムの a (char *) のサイズ、n をラベルの数、s を文字列の長さの合計 (末尾の \0 を含む) とします。

最初のアプローチ (文字列へのポインターの配列を使用するもの) では、格納するために n*p+s バイトが必要になります。2 番目のアプローチ (マクロを使用する) は、実際にはコンパイラーに依存します。

于 2012-06-06T19:18:49.063 に答える