让静态函数变量在C中取参数值
Let static function variable take value of parameter in C
我正在编写一个数据混搭函数,其中我正在为一种动态比特破碎机音频过滤器随时间修改音频数据。使用静态变量对我来说很方便,因为它们的值在函数调用之间传递,这有助于我通过在渲染回调中递增等实现一些有趣的基于时间的效果。
例如,一种效果使用 sin 函数随时间调制某些音效。像这样:
void mangle(float * data, int n) {
static bool direction = false;
static float bottom = 0;
static float top = n;
static float theta = 0;
theta += 5;
// data = sin(theta) etc..
所以我希望 theta
初始化一次,然后随着时间的推移进行修改。同样,top 想成为静态变量,因为我稍后也在函数中修改它。此外,top
应采用参数 n
的值,因为 n
根据程序状态而变化。但是当我将 n
分配给 top
时,我得到了编译器错误
Initializer element is not a compile-time constsant
.
有没有办法将参数分配给静态变量?有没有另一种方法可以在没有静态变量的情况下完成我想要的?我知道我可以使用实例变量,但我发现它太多了。
static
变量在程序执行开始前被 初始化,因此您不能使用变量值来初始化 static
变量。您需要一个编译时常量值来初始化 static
变量。
引用C11
标准,章节§6.2.4,对象的存储持续时间(强调我的)
[..] or with the storage-class
specifier static, has static storage duration. Its lifetime is the entire execution of the
program and its stored value is initialized only once, prior to program startup.
但是,您始终可以为static
变量分配一个新值。
也就是说,根据第 §6.7.9 章,初始化 部分,
If an object that has static or thread storage duration is not initialized
explicitly, then
- ...
- if it has arithmetic type, it is initialized to (positive or unsigned) zero
- ...
因此,您无需将 static float
显式 初始化为 0
。您可以在代码后面分配任何值。
您应该做的是创建一个结构来保存调用所需的数据,并将指向该结构的指针传递给函数。如果你想要花哨的话,你可以创建分配、初始化和释放这样一个结构的函数(并且函数的用户永远不需要知道结构的内容是什么。
类似于:
struct mangle_t {
bool direction;
float bottom;
float top;
float theta;
};
struct mangle_t* mangle_open(void)
{
struct mangle_t* m = malloc(sizeof *m);
if (m) {
memset(m, 0, sizeof *m);
}
return m;
}
void mangle_close(struct mangle_t* m)
{
free(m);
}
void mangle(struct mangle_t* m, float * data, int n) {
m->top = n;
m->theta += 5;
}
就将参数分配给静态变量而言,您可以像任何其他变量一样执行分配(但是,不是作为变量声明中的初始化 - 只发生一次)。
在您的例子中,top
是一个 局部静态变量 。
就像全局静态变量和全局变量一样,它们都具有静态存储期,并且在代码启动之前就已经有值了。
您出现类似这种情况的错误原因:
int a;
int b = a; \initializer is not a constant
int main() {
...
}
根据您的目的,使用 top
作为全局变量是正确的方法。
我不确定你是否要初始化 top
一次然后保留它,但如果是这样,我会这样做:
void mangle(float *data, int n) {
static float top = -1; // Assuming that n will never be -1
if (top == -1)
top = n;
// .....
}
如果您不需要在函数调用中保留 top
的值,则无需声明它 static
。
我正在编写一个数据混搭函数,其中我正在为一种动态比特破碎机音频过滤器随时间修改音频数据。使用静态变量对我来说很方便,因为它们的值在函数调用之间传递,这有助于我通过在渲染回调中递增等实现一些有趣的基于时间的效果。
例如,一种效果使用 sin 函数随时间调制某些音效。像这样:
void mangle(float * data, int n) {
static bool direction = false;
static float bottom = 0;
static float top = n;
static float theta = 0;
theta += 5;
// data = sin(theta) etc..
所以我希望 theta
初始化一次,然后随着时间的推移进行修改。同样,top 想成为静态变量,因为我稍后也在函数中修改它。此外,top
应采用参数 n
的值,因为 n
根据程序状态而变化。但是当我将 n
分配给 top
时,我得到了编译器错误
Initializer element is not a compile-time constsant
.
有没有办法将参数分配给静态变量?有没有另一种方法可以在没有静态变量的情况下完成我想要的?我知道我可以使用实例变量,但我发现它太多了。
static
变量在程序执行开始前被 初始化,因此您不能使用变量值来初始化 static
变量。您需要一个编译时常量值来初始化 static
变量。
引用C11
标准,章节§6.2.4,对象的存储持续时间(强调我的)
[..] or with the storage-class specifier static, has static storage duration. Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.
但是,您始终可以为static
变量分配一个新值。
也就是说,根据第 §6.7.9 章,初始化 部分,
If an object that has static or thread storage duration is not initialized explicitly, then
- ...
- if it has arithmetic type, it is initialized to (positive or unsigned) zero
- ...
因此,您无需将 static float
显式 初始化为 0
。您可以在代码后面分配任何值。
您应该做的是创建一个结构来保存调用所需的数据,并将指向该结构的指针传递给函数。如果你想要花哨的话,你可以创建分配、初始化和释放这样一个结构的函数(并且函数的用户永远不需要知道结构的内容是什么。
类似于:
struct mangle_t {
bool direction;
float bottom;
float top;
float theta;
};
struct mangle_t* mangle_open(void)
{
struct mangle_t* m = malloc(sizeof *m);
if (m) {
memset(m, 0, sizeof *m);
}
return m;
}
void mangle_close(struct mangle_t* m)
{
free(m);
}
void mangle(struct mangle_t* m, float * data, int n) {
m->top = n;
m->theta += 5;
}
就将参数分配给静态变量而言,您可以像任何其他变量一样执行分配(但是,不是作为变量声明中的初始化 - 只发生一次)。
在您的例子中,top
是一个 局部静态变量 。
就像全局静态变量和全局变量一样,它们都具有静态存储期,并且在代码启动之前就已经有值了。
您出现类似这种情况的错误原因:
int a;
int b = a; \initializer is not a constant
int main() {
...
}
根据您的目的,使用 top
作为全局变量是正确的方法。
我不确定你是否要初始化 top
一次然后保留它,但如果是这样,我会这样做:
void mangle(float *data, int n) {
static float top = -1; // Assuming that n will never be -1
if (top == -1)
top = n;
// .....
}
如果您不需要在函数调用中保留 top
的值,则无需声明它 static
。