Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 以不同类型访问数组成员的正确方法?_C_Arrays_Casting_Unions - Fatal编程技术网

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

C 以不同类型访问数组成员的正确方法?,c,arrays,casting,unions,C,Arrays,Casting,Unions,我有大量的uint16\u t 它的大多数成员是uint16\u t,但有些是int16\u t,有些是uint8\u t 你会怎么处理 顺便说一下,我试过: 指针: 使用两个指针,一个int16\u t*和另一个uint8\u t*,这两个指针都初始化到数组的开头,以访问数组的成员int16\u t和uint8\u t (这在一开始是可行的,但后来在程序中,其他东西改变了指针的值时,我遇到了问题,所以我不相信它。) 具有联合的类型定义 在文件.h中: typedef union { ui

我有大量的
uint16\u t

它的大多数成员是
uint16\u t
,但有些是
int16\u t
,有些是
uint8\u t

你会怎么处理


顺便说一下,我试过:

  • 指针:

    使用两个指针,一个
    int16\u t*
    和另一个
    uint8\u t*
    ,这两个指针都初始化到数组的开头,以访问数组的成员
    int16\u t
    uint8\u t

    (这在一开始是可行的,但后来在程序中,其他东西改变了指针的值时,我遇到了问题,所以我不相信它。)

  • 具有联合的类型定义

    在文件.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[];
    
    在文件.c中:

    ram_params_t ram_params[] = {0};
    
    (那真是太棒了。)

  • 铸造

    (我没有走多远。)


  • 其他类型的数组元素必须与
    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;
    }
    

    您尝试的问题是#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];
    

    我也看不出你的尝试有什么错。我想我可能会这样做,而不是使用并集。

    您如何知道哪些元素属于哪些类型?你能给我们看一下试演吗?如果它们必须是单个数组,那么这似乎是最明智的方法。为什么要这样做?为什么不只使用两个其他类型的变量呢?这似乎很容易出错,而且无法维护?>为什么要这样做?--因为阵列(在嵌入式系统中)是与外部世界共享的。外部系统可以访问该阵列,并且只能访问该阵列。数据的类型多种多样。>您如何知道哪些元素属于哪些类型?--按索引。我知道索引3处的成员是一个int16_t,索引5处的成员是一对字节。>我看不出你的尝试有任何错误#1--直到今天,我也没有发现,其中一个指针中的值发生了变化,损坏了数组中的数据。指针在启动时设置一次。我如何确保在运行一年后仍能正确设置,而无需重置?它就是不可靠。我想我必须周期性地检查它的值。你的指针被破坏是程序中其他东西出错并破坏内存的标志。实际上,我建议您重试#1并调试您的程序,否则您可能最终会遇到另一个神秘的故障。>您的指针损坏表明您的程序中有其他错误,正在破坏内存。-是的,绝对是!我找到它并修好了。但这是对依赖指针的危险性的警钟。“我们应该小心地从经验中摆脱出来,只保留其中的智慧,并停在那里,以免我们像坐在热炉盖上的猫一样。她再也不会坐在热炉盖上了,这很好,但她也再也不会坐在冷炉盖上了。”-马克Twain@Davide安德里亚:有趣。我使用的编译器不是这样的。我想你必须解决编译器的奇怪行为。
    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];