我有一个变量列表(不存在于数组中),其值必须通过迭代打印。这些变量具有相同的名称,除了末尾附带的数字
说以下是变量名;
int mem_size0;
int mem_size1;
int mem_size2;
...
...
int mem_sizen;
此类变量的总数由另一个变量给出mem_size_entries
。这些变量是由不同的工具为我生成的,我必须通过某种迭代打印这些变量的值。使用一些宏可以做到这一点吗?
使用 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)
If these variables are all declared in order, it seems likely (though not guaranteed) that they would occupy sequential locations in memory. This may not work on all (or any!) compilers, but it's worth a try at least:
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);
}
也许您可以编辑生成的代码,以便:
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
.
这可以通过 shell 脚本(或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 代码。