在标题中定义变量,而不是在C中定义函数(非全局)

在标题中定义变量,而不是在C中定义函数(非全局),c,header,struct,C,Header,Struct,当我尝试比较这两个不同的代码时,在.map文件中看不到任何内存更改。 这里有“良好实践”可遵循吗?我应该还是不应该把变量放在标题中? 请注意,我可以有多个PIDUpdate()函数,我可以有两个(如果这有什么区别的话) 标题->main.c中没有变量的第一个示例 static int16_t PIDUpdate(int16_t target, int16_t feedback) // Valve { static float pTerm, iTerm, dTerm; static float P

当我尝试比较这两个不同的代码时,在.map文件中看不到任何内存更改。 这里有“良好实践”可遵循吗?我应该还是不应该把变量放在标题中? 请注意,我可以有多个PIDUpdate()函数,我可以有两个(如果这有什么区别的话)

标题->main.c中没有变量的第一个示例

static int16_t PIDUpdate(int16_t target, int16_t feedback) // Valve
{
static float pTerm, iTerm, dTerm;
static float PID;
int16_t CurrentError;
static float LastError, SumError;
uint16_t tick;
static uint16_t elapsed;
float Kp = 0.1, Ki = 0.1, Kd = 0.1;

Kp = (float) pGain/10000.0;
Ki = (float) iGain/10000.0;
Kd = (float) dGain/10000.0;

....
if(elapsed = tick - timestamp, elapsed < TRACKING_PERIOD)
    goto leave;

timestamp = tick;

CurrentError = target - feedback;

pTerm = Kp * CurrentError;

// Calculate the Integral State with appropriate Limiting
....
iTerm = Ki * SumError;

dTerm = Kd * (LastError - CurrentError);

LastError = CurrentError;

PID = pTerm + iTerm + dTerm;

control = PID;
....
    leave:
return (control);
      }
现在,主.c代码与上面的.h文件结合在一起

static int16_t PIDUpdate(int16_t target, int16_t feedback) // Valve
{
pid_object _PID_t;
StaticPid_object _StatPID_t;

_PID_t.Kp = (float) pGain/10000.0;
_PID_t.Ki = (float) iGain/10000.0;
_PID_t.Kd = (float) dGain/10000.0;

if(_StatPID_t.elapsed = _PID_t.tick - _StatPID_t.timestamp, _StatPID_t.elapsed < TRACKING_PERIOD)
    goto leave;

_StatPID_t.timestamp = _PID_t.tick;

_PID_t.CurrentError = target - feedback;

_PID_t.pTerm = _PID_t.Kp * _PID_t.CurrentError;

// Calculate the Integral State with appropriate Limiting
....

_PID_t.iTerm = _PID_t.Ki * _StatPID_t.SumError;

_PID_t.dTerm = _PID_t.Kd * (_StatPID_t.LastError - _PID_t.CurrentError);

_StatPID_t.LastError = _PID_t.CurrentError;

_PID_t.PID = _PID_t.pTerm + _PID_t.iTerm + _PID_t.dTerm;

_StatPID_t.control = 255-_PID_t.PID; // Make it work oposite to Heater

     leave:
return (_StatPID_t.control);
     }
static int16\u t PIDUpdate(int16\u t target,int16\u t feedback)//阀门
{
pid_对象_pid_t;
静态PID_对象_StatPID_t;
_PID_t.Kp=(浮动)pGain/10000.0;
_PID_t.Ki=(浮动)iGain/10000.0;
_PID_t.Kd=(浮动)dGain/10000.0;
如果(_StatPID_t.appeased=_PID_t.tick-_StatPID_t.timestamp,_StatPID_t.appeased<跟踪周期)
去离开;
_StatPID\u t.timestamp=\u PID\u t.tick;
_PID\u t.CurrentError=目标-反馈;
_PID_t.pTerm=_PID_t.Kp*_PID_t.CurrentError;
//计算具有适当极限的积分状态
....
_PID_t.iTerm=_PID_t.Ki*_StatPID_t.sumr;
_PID_t.dTerm=_PID_t.Kd*(_StatPID_t.LastError-_PID_t.CurrentError);
_StatPID\u t.LastError=\u PID\u t.CurrentError;
_PID_t.PID=_PID_t.pTerm+_PID_t.iTerm+_PID_t.dTerm;
_StatPID\u t.control=255--u PID\u t.PID;//使其在加热器现场工作
离开:
返回(_StatPID_t.control);
}

代码在哪里并不重要-在
.h
.c
中,但是如果在多个文件中包含定义静态变量的头文件,则每个文件都有不同的实例。这里重要的是这是否是您想要的。

您的代码在哪里并不重要-在
.h
.c
中,但是如果您在多个文件中包含定义静态变量的头文件,则每个文件都有不同的实例。这里重要的是这是否是您想要的。

实际上,您只在main.h中定义数据类型。实际上那里没有任何变量(即使它看起来像缩进)

我想说,在typedef中包含
static
是疯狂的,没有理由这样做

传统上,在使用foo.c、bar.c和baz.c的程序中,foo.h文件具有需要在foo.c外部查看的全局变量的数据类型、函数声明和
extern
版本。bar.h和baz.h也是如此

福安

外部的、内部的、全局的

富科

int一些全球的


因此,当您的程序链接时,
foo.c
提供了
一些全局
,而
bar.c
baz.c
将知道它是什么。

实际上,您只是在main.h中定义了数据类型。实际上那里没有任何变量(即使它看起来像缩进)

我想说,在typedef中包含
static
是疯狂的,没有理由这样做

传统上,在使用foo.c、bar.c和baz.c的程序中,foo.h文件具有需要在foo.c外部查看的全局变量的数据类型、函数声明和
extern
版本。bar.h和baz.h也是如此

福安

外部的、内部的、全局的

富科

int一些全球的


所以当你的程序被链接时,
foo.c
提供了
一些全局的
,而
bar.c
baz.c
将知道它是什么
是一个定义,它将为变量
foo
extern int foo分配存储空间
是一个声明,表示变量
foo
的存储已经给出。您可以将定义放入头文件中,但如果链接包含该头文件的多个源文件,则可能会出现重新定义错误。通常,如果需要的话,我们只在头文件中添加声明,并在相应的源文件中定义变量。其他源文件将在链接阶段看到它们。

注意
intfoo
是一个定义,它将为变量
foo
extern int foo分配存储空间
是一个声明,表示变量
foo
的存储已经给出。您可以将定义放入头文件中,但如果链接包含该头文件的多个源文件,则可能会出现重新定义错误。通常,如果需要的话,我们只在头文件中添加声明,并在相应的源文件中定义变量。其他源文件将在链接阶段看到它们。

您想实现什么?在现代,你究竟为什么要使用静态局部变量?20年前这是个坏消息。现在您只需保证在整个过程中只能有一个PID控制器。顺便说一句,
\u t
后缀通常是为typedef保留的,而不是为变量名保留的。在函数的局部变量上使用
前缀是很奇怪的。大多数C编码标准使用
\uu
来表示私有(而不是公共)函数或全局变量。多亏了tomlogic,Im处于学习过程中;)David,对于需要记住其值的可重用函数,你有更好的建议吗?你想实现什么?在现代,你究竟为什么要使用静态局部变量?20年前这是个坏消息。现在您只需保证在整个过程中只能有一个PID控制器。顺便说一句,
\u t
后缀通常是为typedef保留的,而不是为变量名保留的。在函数的局部变量上使用
前缀是很奇怪的。大多数C编码标准使用
\uu
来表示私有(而不是公共)函数或全局变量。多亏了tomlogic,Im处于学习过程中;)David,对于一个需要记住其值的可重用函数,你有更好的建议吗?谢谢,这很有教育意义。为什么在typedef中有static是疯狂的?它使我的函数能够记住这些变量值,而无需在函数中创建新的静态变量(保存备忘)
static int16_t PIDUpdate(int16_t target, int16_t feedback) // Valve
{
pid_object _PID_t;
StaticPid_object _StatPID_t;

_PID_t.Kp = (float) pGain/10000.0;
_PID_t.Ki = (float) iGain/10000.0;
_PID_t.Kd = (float) dGain/10000.0;

if(_StatPID_t.elapsed = _PID_t.tick - _StatPID_t.timestamp, _StatPID_t.elapsed < TRACKING_PERIOD)
    goto leave;

_StatPID_t.timestamp = _PID_t.tick;

_PID_t.CurrentError = target - feedback;

_PID_t.pTerm = _PID_t.Kp * _PID_t.CurrentError;

// Calculate the Integral State with appropriate Limiting
....

_PID_t.iTerm = _PID_t.Ki * _StatPID_t.SumError;

_PID_t.dTerm = _PID_t.Kd * (_StatPID_t.LastError - _PID_t.CurrentError);

_StatPID_t.LastError = _PID_t.CurrentError;

_PID_t.PID = _PID_t.pTerm + _PID_t.iTerm + _PID_t.dTerm;

_StatPID_t.control = 255-_PID_t.PID; // Make it work oposite to Heater

     leave:
return (_StatPID_t.control);
     }