0

iterationによって値を出力する必要がある変数 (配列には存在しない) のリストがあります。これらの変数は、末尾に付いている数字を除いて同じ名前です。

以下は変数名です。

int mem_size0;
int mem_size1;
int mem_size2;
...
...
int mem_sizen;

そのような変数の総数は、別の変数によって与えられますmem_size_entries。これらの変数は別のツールによって生成され、これらの変数の値を何らかの反復で出力する必要があります。いくつかのマクロを使用してこれを行うことは可能ですか?

4

3 に答える 3

2

vim を使用します。

たとえば、すべての変数に対して次の行を繰り返したいとします。

something mem_sizen0 something;

その行の先頭に移動して、次のキーを押します。

qa (start recording macro)
yy (copy line)
p (paste line in new line)
wwwhh (move to the 0)
ctrl+a (increase 0 by 1)
q (finish repeating macro)
30@a (repeat this 30 times, if this is the amount you need)
于 2012-04-12T01:32:43.933 に答える
1

これらの変数がすべて順番に宣言されている場合、(保証はされていませんが) メモリ内の連続した場所を占有する可能性があります。これはすべての (またはすべての) コンパイラで機能するとは限りませんが、少なくとも試してみる価値はあります:

int mem_size0;
int mem_size1;
int mem_size2;
...
...
int mem_sizen;

const int *const start = &mem_size0;
const int *const end   = &mem_size0 + (mem_size_entries);

for (const int *p = start; p < end; p++)
{
    /* Do stuff with p... */
    printf("%i\n", *p);
}
于 2012-04-12T01:35:30.753 に答える
1

おそらく、生成されたコードを次のように編集できます。

int mem_size0;
int mem_size1;
int mem_size2;
...
...
int mem_sizen;

になります:

union {
struct {
int mem_size0;
int mem_size1;
int mem_size2;
...
...
int mem_sizen;
} s;
int mem_array[mem_size_entries];
} u;

これで、 の要素を反復処理できますu.mem_array

perlこれは、シェル スクリプト (またはスクリプト)を使用してかなり簡単に実行できます。トリッキーな部分は、いつ到達したmem_sizenか、またはその後の行を認識することです。これは私にとってはうまくいくようです:

#!/usr/bin/env perl
use strict;
use warnings;

my($seen, $done) = (0, 0);
while (<>)
{
    if (/mem_size0/)
    {
        print "struct { union {\n";
        $seen = 1;
    }
    if ($seen && !$done && !/mem_size/)
    {
        print "} s; int mem_array[mem_size_entries]; } u;\n";
        $done = 1;
    }
    print $_;
}

与えられた入力:

int mem_size0;
int mem_size1;
int mem_size2;
int mem_sizen;

mem_sizeこれらの宣言の後に空白行 (または を含まないその他の行) を付けます。

スクリプトは次の出力を生成します。

struct { union {
int mem_size0;
int mem_size1;
int mem_size2;
int mem_sizen;
} s; int mem_array[mem_size_entries]; } u;

それほど難しくなく、よりきれいにレイアウトできます。次に、配列を反復処理できますu

for (int i = 0; i < mem_size_entries; i++)
    printf("%d: %d\n", i, u.mem_array[i]);

これの欠点は、初期化子が元のコードに表示されないことです。ただし、Perl を使用すると、存在する数を認識し、初期化を見つけて、このスキームに適合するように編集することが容易にできます。基本的に、これはプログラムの生成された出力を「高水準言語」のソース コードとして扱い、それをコンパイル可能な C コードに「コンパイル」します。

于 2012-04-12T02:17:48.873 に答える