我的struct中声明的变量可以具有不同的大小

Chr*_*ian 0 c size struct pic

为什么我问这是因为发生了以下情况:

在标题中定义:

typedef struct PID
{
// PID parameters
uint16_t Kp; // pGain
uint16_t Ki; // iGain
uint16_t Kd; // dGain

// PID calculations OLD ONES WHERE STATICS
int24_t pTerm;
int32_t iTerm;
int32_t dTerm;
int32_t PID;

// Extra variabels
int16_t CurrentError;

// PID Time
uint16_t tick;

}_PIDObject;
Run Code Online (Sandbox Code Playgroud)

在C源:

static int16_t PIDUpdate(int16_t target, int16_t feedback)
{
      _PIDObject PID2_t;

  PID2_t.Kp = pGain2; // Has the value of 2000

      PID2_t.CurrentError = target - feedback; // Has the value of 57

      PID2_t.pTerm = PID2_t.Kp * PID2_t.CurrentError; // Should count this to (57x2000) = 114000
Run Code Online (Sandbox Code Playgroud)

我调试时发生的事情是它没有.我可以在pGain2中定义的最大值(种类)是1140. 1140x57给出64980.

不知何故感觉程序认为PID2_t.pTerm是一个uint16_t.但事实并非如此; 它在结构中声明更大.

已经PID2_t.pTerm在某种程度上得到了价值uint16_t从第一个宣布在结构变量或者是一些错误的计算,我有uint16_tint16_t?如果我在结构外声明它们,这不会发生.

另外,这是我的int def(之前从未出现过问题:

#ifdef __18CXX
typedef signed char int8_t;                 // -128 -> 127               // Char & Signed Char
typedef unsigned char uint8_t;              // 0 -> 255                  // Unsigned Char
typedef signed short int int16_t;           // -32768 -> 32767           // Int
typedef unsigned short int uint16_t;        // 0 -> 65535                // Unsigned Int
typedef signed short long int int24_t;      // -8388608 -> 8388607       // Short Long
typedef unsigned short long int uint24_t;   // 0 -> 16777215             // Unsigned Short Long
typedef signed long int int32_t;            // -2147483648 -> 2147483647 // Long
typedef unsigned long int uint32_t;         // 0 -> 4294967295           // Unsigned Long
#else
#   include <stdint.h>
#endif
Run Code Online (Sandbox Code Playgroud)

dmc*_*dmc 5

尝试

PID2_t.pTerm = ((int24_t) PID2_t.Kp) * ((int24_t)PID2_t.CurrentError);
Run Code Online (Sandbox Code Playgroud)

Joachim的评论解释了为什么这有效.编译器在乘法int24_t之前不会将被乘数提升到,所以存在溢出.如果我们手动推广使用强制转换,则没有溢出.

  • 我以为我会解释,因为我显然把对话与我的假设相混淆,即int是32位.证据是类型定义,它是一个具有int16_t整数的18Cxx PIC.发生的事情是两个16位值被提升为int(签名int16,因为其中一个是)并且相乘,溢出被抛弃.之后,由于赋值,它们被提升到24位(int24_t实际上在此架构上实际上是24位)上面的行通过在乘法之前将两个因子提升到24位来解决这种情况,因此不会产生任何溢出. (2认同)