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

时间:2012-01-13 15:05:39

标签: c struct size 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;

在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

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

不知何故感觉程序认为PID2_t.pTermuint16_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

3 个答案:

答案 0 :(得分:5)

尝试

PID2_t.pTerm = ((int24_t) PID2_t.Kp) * ((int24_t)PID2_t.CurrentError);

Joachim的评论解释了为什么这样做。在乘法之前,编译器没有将被乘数提升为int24_t,因此存在溢出。如果我们手动推广使用强制转换,则没有溢出。

答案 1 :(得分:1)

我的系统没有int24_t,正如一些评论所说,来自哪里?

在Joachim的评论之后,我写了一个简短的测试:

#include <stdint.h>
#include <stdio.h>

int main() {
        uint16_t a = 2000, b = 57;
        uint16_t c = a * b;
        printf("%x\n%x\n", a*b, c);
}

输出:

1bd50
bd50

所以你得到前2个字节,与int16_t一致。所以问题似乎是你的int24_t未正确定义。

答案 2 :(得分:-1)

正如其他人所指出的,您的int24_t似乎被定义为16位。除了它太小的事实,你应该小心这个类型定义。 stdint.h指定uint_Nt类型恰好是N位。因此,假设您的处理器和编译器实际上没有24位数据类型,那么您将违反标准约定。如果您最终将其定义为32位类型,则将其命名为uint_least24_t更合理,它遵循至少的整数类型模式大到足以容纳N位。区别很重要,因为有人可能希望uint24_t翻转到16777215以上。