以不同类型访问数组成员的正确方法?

时间:2014-11-14 17:54:50

标签: c arrays casting unions

我有一大堆uint16_t

大多数成员都是uint16_t,但有些成员是int16_t,有些是uint8_t

你会如何处理?


顺便说一句,我试过了:

  1. 指针:

    使用2个指针,一个int16_t*和另一个uint8_t*,两者都初始化为数组的开头,以访问int16_tuint8_t数组的成员

    (最初有效,但我在程序后期遇到了一些问题,其他东西改变了指针的价值,所以我不相信它。)

  2. 使用union进行类型定义。

    在file.h中:

    typedef union {
      uint16_t  u16[NO_OF_WORDS];     // As uint16_t
      int16_t   s16[NO_OF_WORDS];     // As int16_t
      uint8_t   u8[2 * NO_OF_WORDS];  // As uint8_t
    } ram_params_t;
    extern ram_params_t ram_params[];
    

    在file.c中:

    ram_params_t ram_params[] = {0};
    

    (真的被炸了。)

  3. 铸造。

    (我没有那么远。)

2 个答案:

答案 0 :(得分:2)

你的尝试#2的问题在于你制作了一个阵列数组。

要么这样做:

typedef union {
  uint16_t  u16;     // As uint16_t
  int16_t   s16;     // As int16_t
  uint8_t   u8[2];   // As uint8_t
} ram_params_t;
extern ram_params_t ram_params[NO_OF_WORDS];

ram_params_t ram_params[NO_OF_WORDS];

uval16  = ram_params[i].u16;
sval16  = ram_params[i].s16;
uval8_1 = ram_params[i].u8[0];
uval8_2 = ram_params[i].u8[1];

或者你这样做:

typedef union {
  uint16_t  u16[NO_OF_WORDS];     // As uint16_t
  int16_t   s16[NO_OF_WORDS];     // As int16_t
  uint8_t   u8[2 * NO_OF_WORDS];  // As uint8_t
} ram_params_t;
extern ram_params_t ram_params;

ram_params_t ram_params;

uval16  = ram_params.u16[i];
sval16  = ram_params.s16[i];
uval8_1 = ram_params.u8[2*i];
uval8_2 = ram_params.u8[2*i+1];

我认为你的尝试#1也没有任何问题。我认为我可能会这样做,而不是使用工会。

答案 1 :(得分:1)

其他类型的数组元素必须与uint16_t的大小相同才能投射它们。在8位数据的情况下,高8位可能是未定义的,因此我将它们屏蔽掉。

#include <stdio.h>

#define uint16_t    unsigned short
#define int16_t     short
#define uint8_t     unsigned char

int main() {
    uint16_t n;

    // convert uint16_t to int16_t
    n = 0xFFFF;
    printf ("%d\n", (int16_t)n);

    // convert uint16_t to uint8_t
    n = 168;
    printf ("%c\n", (uint8_t)(n & 0xFF));

    return 0;
}

程序输出

-1
¿