在c中确定编译时数组中的位置

在c中确定编译时数组中的位置,c,C,在c语言中,有没有办法在编译时确定常量数组中的位置?下面是我尝试做的一个例子: const unsigned char DATA[] = { // Part 1 // hundreds or thousands of values // Part 2 // compiler records this position in the array in PART2 // hundreds or thousands of values // Part 3 // compiler reco

在c语言中,有没有办法在编译时确定常量数组中的位置?下面是我尝试做的一个例子:

const unsigned char DATA[] = {
// Part 1 
// hundreds or thousands of values

// Part 2  
// compiler records this position in the array in PART2
// hundreds or thousands of values

// Part 3  
// compiler records this position in the array in PART3
// hundreds or thousands of values

// ...
};

const unsigned int PART_IDX [] = {
// index to Part 1
0,

// index to Part 2
PART2,

// index to Part 3
PART3,

// ...
};
我可以在运行时计算索引,但宁愿让它们已经计算好,因为数组是常量。我可以制作一个程序来分析源代码,计算每个部分中的元素数量,并在part_IDX中插入数据,但我真的希望编译器在编译时这样做。这样,如果数据被插入或删除,或者部分被添加或删除,编译器仍然会生成正确的代码。有人知道我怎么做吗?谢谢

编辑: 要澄清,请使用实际数据示例:

const unsigned char DATA[] = {
// Part 1 
0, 1, 2, 3, 4,

// Part 2  
// compiler records this position in the array in PART2 (should be 5)
10, 11, 12, 13, 14, 15, 16,

// Part 3  
// compiler records this position in the array in PART3 (should be 12)
20, 21, 22
};

const unsigned int PART_IDX [] = {
// index to Part 1
0,

// index to Part 2
PART2,   // should be 5, points to 10 in the array

// index to Part 3
PART3,   // should be 12, points to 20 in the array
};

问题是,我可以用什么来代替以//编译器记录此位置开头的行。。。为了让编译器在第2部分和第3部分中记录适当的值,而不是试图强迫C去做它本来不想做的事情,一种更好、更常见的方法是通过编写一个准备数据的程序来为C程序准备数据。也就是说,编写一些其他程序来计算部件中的数据,并编写初始化数据和部件IDX所需的C代码

另一个选择是:

将每个部分的所有数据放在一个单独的“.h”文件中,例如文件“part1.h”、“part2.h”、“part3.h”。 要初始化数据,请将所有这些头文件包含在其初始值设定项列表中。 要计算部件的索引,请使用sizeof计算包含前面部件的代理数组中的元素数。 例如:

“part1.h”包含10、11、12、

“part2.h”包含20、21、

“part3.h”包含30、31、32、33、

C文件是:

const unsigned char DATA[] =
{
    #include "part1.h"
    #include "part2.h"
    #include "part3.h"
};


const unsigned int PART_IDX [] =
{
    0,

    sizeof (const unsigned char []) {
        #include "part1.h"
    } / sizeof (const unsigned char),

    sizeof (const unsigned char []) {
        #include "part1.h"
        #include "part2.h"
    } / sizeof (const unsigned char),
};


#include <stdio.h>


int main(void)
{
    for (int i = 0; i < 3; ++i)
        printf("Part %d begins at index %d with value %d.\n",
            i, PART_IDX[i], DATA[PART_IDX[i]]);
}

与其试图强迫C去做它不想做的事情,一种更好、更常见的方法是通过编写一个准备数据的程序来为C程序准备数据。也就是说,编写一些其他程序来计算部件中的数据,并编写初始化数据和部件IDX所需的C代码

另一个选择是:

将每个部分的所有数据放在一个单独的“.h”文件中,例如文件“part1.h”、“part2.h”、“part3.h”。 要初始化数据,请将所有这些头文件包含在其初始值设定项列表中。 要计算部件的索引,请使用sizeof计算包含前面部件的代理数组中的元素数。 例如:

“part1.h”包含10、11、12、

“part2.h”包含20、21、

“part3.h”包含30、31、32、33、

C文件是:

const unsigned char DATA[] =
{
    #include "part1.h"
    #include "part2.h"
    #include "part3.h"
};


const unsigned int PART_IDX [] =
{
    0,

    sizeof (const unsigned char []) {
        #include "part1.h"
    } / sizeof (const unsigned char),

    sizeof (const unsigned char []) {
        #include "part1.h"
        #include "part2.h"
    } / sizeof (const unsigned char),
};


#include <stdio.h>


int main(void)
{
    for (int i = 0; i < 3; ++i)
        printf("Part %d begins at index %d with value %d.\n",
            i, PART_IDX[i], DATA[PART_IDX[i]]);
}
在c语言中,有没有办法在编译时确定常量数组中的位置

是的。请记住,可以生成C源文件,并相应地改进您的功能,例如编辑

因此,只需生成第二部分,例如,在Linux上使用一些awk或脚本,或者您自己用C编写的简单代码-或一些脚本语言-输出生成的C代码的部分。玩玩。有关灵感,请参阅答案

你可以假设你使用C编译器,也可以考虑编写你的ad-hoc,但是在你的特定情况下,它不值得付出努力。

顺便说一句,我的程序使用了这样的元编程技巧。GCC本身有几十个特殊的代码生成器

如果您生成一些足够复杂的C代码,我建议在内部保留某种类型的代码

在c语言中,有没有办法在编译时确定常量数组中的位置

是的。请记住,可以生成C源文件,并相应地改进您的功能,例如编辑

因此,只需生成第二部分,例如,在Linux上使用一些awk或脚本,或者您自己用C编写的简单代码-或一些脚本语言-输出生成的C代码的部分。玩玩。有关灵感,请参阅答案

你可以假设你使用C编译器,也可以考虑编写你的ad-hoc,但是在你的特定情况下,它不值得付出努力。

顺便说一句,我的程序使用了这样的元编程技巧。GCC本身有几十个特殊的代码生成器


如果你生成了足够复杂的C代码,我建议在内部保留某种类型的代码。

你不知道你希望这个索引计算的信息是什么。什么组成了你的数组的一部分?你需要C还是C++?这不能让三个部分分开吗?编译器是否有义务提供编译?ime访问这些信息?你能举一个例子,说明你希望代码在元素数较少的情况下是什么样子的,比如说5-10吗?@FrançoisAndrieux:计算的基础是一些由插入初始值设定项列表中的行标记或记录的东西,比如MarkerMacroPart2。例如,使用斜杠标记行,数组mi可以用{/MarkerMacroPart1/3,4,5,/MarkerMacroPart2/6,7,8,9,/MarkerMacroPart3/10,11,}初始化。不清楚您希望进行索引计算的信息是什么。什么构成ar的一部分
雷?你需要C还是C++?你不能把这三部分分开吗?编译器有义务提供对这些信息的编译时访问吗?你能举一个例子,说明你希望代码在元素数量较少的情况下是什么样子的吗,比如说5-10?@FrançoisAndrieux:计算的基础将是在初始值设定项列表中插入一些行来标记或记录的东西,比如MarkerMacroPart2。例如,使用斜杠标记行,可以使用{/MarkerMacroPart1/3、4、5、/MarkerMacroPart2/6、7、8、9、/MarkerMacroPart3/10、11、}初始化数组。有趣的技术。我不知道你可以用sizeof。使用define指定数组部分,然后将这些部分合并到单个数组中。您可以使用“定义”为零件创建定义的常量,然后在执行“包含”操作的位置使用定义的常量,而不是包含随后包含的文件。我不是在建议定义常量,因为这些常量的长度有限制,但对于较小的数据集,它可以很好地工作。这非常有效!另一个好处是,每个部分都包含在自己的文件中。我可以对它们重新排序,或者更容易地添加和删除它们。谢谢有趣的技术。我不知道你可以用sizeof。使用define指定数组部分,然后将这些部分合并到单个数组中。您可以使用“定义”为零件创建定义的常量,然后在执行“包含”操作的位置使用定义的常量,而不是包含随后包含的文件。我不是在建议定义常量,因为这些常量的长度有限制,但对于较小的数据集,它可以很好地工作。这非常有效!另一个好处是,每个部分都包含在自己的文件中。我可以对它们重新排序,或者更容易地添加和删除它们。谢谢