在预处理中填充数组

问题描述

我试图在预处理中用恒定数量的值填充数组。 这是为了能够在这些值中添加MACRO并减少运行时的操作。

我不确定是否有可能这样做。

我的第一种方法

from tkinter import *
import tkinter.messageBox as tmsg
from tkinter import ttk


root = Tk()

root.geometry('450x500')
root.title('my notepad')

fonts = ['lucida','Arial']
fg_col,bg_col = 'black','white'

def darkmode():
    global fg_col,bg_col
    fg_col,bg_col='white','black'

Button(root,text='DARK Theme',bg = 'grey',command=darkmode).pack()

text = Text(root,font =(f'{fonts[0]}',18,'bold'),foreground = fg_col,background=bg_col).pack()


root.mainloop()

尽管这种方法行得通,但我认为这是一个糟糕的解决方案,因为对于每个SIZE,都需要在数组中手动​​添加一个新值。

我使用this post的第二种方法

const float Array[] = { (float)(SIZE - 0) / (float)SIZE,(float)(SIZE - 1) / (float)SIZE };

尽管这似乎是一种更好的方法,但是当我尝试调用#define Array(float,Array,SIZE,i) float Array[SIZE]; \ for(int i = 0; i < SIZE; i++) Array[i] = ( (float)(SIZE - i) / (float)SIZE ) 时,它会返回错误

Array

有比第一个方法更干净的方法吗?

编辑: 感谢您的答复,我犯了一个错误,认为identifier "Array" is undefined. 中变量为n的数组可以是不可更改的/可以由宏替换。当Array[n]的部分调用可变时,使数组也可变。 结论: 我将使用函数在运行时创建并填充数组

解决方法

从一种XMLHttpRequest宏开始,该宏将使用FORLOOP作为分隔符,并根据传递给它的计数,以增加的参数调用函数计数次数。然后创建一个回调函数传递给,,该函数初始化一个元素并将其与另一个宏粘合在一起。看起来可能像这样:

FORLOOP

@edit重命名为#define FORLOOP_1(func,priv) func(0,priv) #define FORLOOP_2(func,priv) FORLOOP_1(func,priv),func(1,priv) #define FORLOOP_3(func,priv) FORLOOP_2(func,func(2,priv) #define FORLOOP_4(func,priv) FORLOOP_3(func,func(3,priv) // add more... #define FORLOOP_IN(func,priv,count) FORLOOP_##count(func,priv) // extra expansion wave to expand count argument #define FORLOOP(func,count) FORLOOP_IN(func,count) // Callback to call from FORLOOP,context is SIZE #define ARRAY_INIT_CB(idx,size) ((float)(size - idx) / (float)size) // Pass SIZE as context and expand up to SIZE #define ARRAY_INIT(size) FORLOOP(ARRAY_INIT_CB,size,size) const float Array[] = { ARRAY_INIT(3) }; /* expands to: const float Array[] = { ((float)(3 - 0) / (float)3),((float)(3 - 1) / (float)3),((float)(3 - 2) / (float)3) }; */ ,将FOREACH重命名为FORLOOP,因为通常FOREACH会为每个参数做一些事情,在这里对我来说forloop是更好的名称,因为它会迭代一些计数。

,

在第二种方法中忽略打字错误,第二种方法 (很可能)将生成运行时代码(或至少不适合填充静态/文件范围数组)。

如果要预填充静态数组而不生成运行时代码,则需要采用第一种方法并生成:

{ (float)(SIZE - 0) / SIZE,(float)(SIZE - 1) / SIZE }

(对于每个给定的SIZE,第二个转换都是毫无意义的。)

当您有一些支持计数的迭代的支持宏时,如果没有这些支持宏(并且如果您想支持大量计数器,那么它们将变得冗长),则可以使用宏简洁地执行此操作,同时可以使用脚本(或C程序) )输出给定SIZE的初始化程序可能是您最好的选择。

然后,您可以将这样一个脚本的结果粘贴到源代码中,或者设置您的构建系统以生成整个c文件,然后让编译器从此处进行选择。