代码之家  ›  专栏  ›  技术社区  ›  nanocat

在C中编译时填充数组

  •  2
  • nanocat  · 技术社区  · 7 月前

    我有一些嵌入式C代码,我想在其中有一个正弦值列表。我在C++中使用一个constexpr函数做了类似的事情,该函数在主循环外返回一个std::数组:

    #include <array>
    #include <cmath>
    
    #define sineListSize 100
    #define sineListAmp 100
    
    constexpr auto makeSineList() {
        std::array<int, sineListSize> list = {};
    
        for (int i=0; i<sineListSize; i++) {
            list[i] = sineListAmp * sin(i * 2 * M_PI / sineListSize);
        }
    
        return list;
    }
    
    auto sineList = makeSineList();
    

    我现在所做的只是一个单独的头文件中的列表,因为它有8192个元素,并且达到了有符号的32位整数限制。很难修改(每当我想更改生成参数时,我都必须生成值并手动复制它们),而且我必须将所有参数保存在注释中。我该如何在C中做这样的事情?

    2 回复  |  直到 7 月前
        1
  •  8
  •   Eric Postpischil    7 月前

    经典的方法是编写一个程序来计算值,并以C数组初始化的格式将其写入输出。作为项目构建过程的一部分,它在构建主机上编译并运行该程序,将其输出定向到头文件。该头文件包含在您的其他源中。

        2
  •  1
  •   dbush    7 月前

    最好的方法是创建一个程序来输出数组声明。你的makefile可以构建这个程序,运行它来生成一个头文件,然后这个头文件就可以包含在你的主程序中。

    例如,给定以下名为sin_list.c的生成程序:

    #include <stdio.h>
    #include <math.h>
    
    #define sineListSize 100
    #define sineListAmp 100
    
    int main()
    {
        printf("int sineList[%d] = {", sineListSize);
    
        for (int i=0; i<sineListSize; i++) {
            int value = sineListAmp * sin(i * 2 * M_PI / sineListSize);
            if (i % 10 == 0) printf("\n    ");
            printf("%d, ", value);
        }
    
        printf("\n};\n");
    
        return 0;
    }
    

    输出结果如下:

    int sineList[100] = {
        0, 6, 12, 18, 24, 30, 36, 42, 48, 53,
        58, 63, 68, 72, 77, 80, 84, 87, 90, 92,
        95, 96, 98, 99, 99, 100, 99, 99, 98, 96,
        95, 92, 90, 87, 84, 80, 77, 72, 68, 63,
        58, 53, 48, 42, 36, 30, 24, 18, 12, 6,
        0, -6, -12, -18, -24, -30, -36, -42, -48, -53,
        -58, -63, -68, -72, -77, -80, -84, -87, -90, -92,
        -95, -96, -98, -99, -99, -100, -99, -99, -98, -96,
        -95, -92, -90, -87, -84, -80, -77, -72, -68, -63,
        -58, -53, -48, -42, -36, -30, -24, -18, -12, -6,
    };
    

    你的makefile看起来像这样:

    main: main.c sin_list.h
        gcc -o main main.c
    
    sin_list.h: sin_list
        ./sin_list > sin_list.h
    
    sin_list: sin_list.c
        gcc -std=gnu99 -o sin_list sin_list.c -lm
    

    然后你的主程序可以使用它:

    #include <stdio.h>
    #include "sin_list.h"
    
    int main()
    {
        printf("sineList[1]=%d\n", sineList[1]);
        printf("sineList[2]=%d\n", sineList[2]);
        return 0;
    }