在C中:如何设置指向作为数组的结构成员的指针?

我应该如何编写代码来示例恰好是结构成员的数组的特定数组索引?以下代码给了我一些问题.
// main.c

void clean_buffers(void); // prototype

struct DEV_STATUS {
    unsigned char ADDR;
    unsigned char DEV_HAS_DATA;
    unsigned char ETH_HAS_DATA;
    unsigned char DATA[20];
};

struct DEV_STATUS g_cmdQueue[60] = {0};

void main(void) {

    clean_buffers();

    while (1) {
        ;// MCU tasks        
    }
}

void clean_buffers(void) {
    unsigned char theCount = 0;
    byte queIdx;
    for (queIdx = 0; queIdx < 59; queIdx++) {
        struct DEV_STATUS *p_struct;
        unsigned char *p_data;
        p_struct = &g_cmdQueue[queIdx];
        p_data = &p_struct->DATA;
        p_struct->ADDR = 0;
        p_struct->DEV_HAS_DATA = 0;
        p_struct->ETH_HAS_DATA = 0;
        theCount = 0;
        while(*(p_data+theCount) != 0) {
            *(p_data+(theCount++)) = 0;
        }
    }    
} // EOF main.c

我在以下行中收到编译器错误“struct / union member expected”:

p_data = &p_struct->DATA;

如果我要访问,例如,结构成员DATA [3]的具体值,我应该如何编写指针?我很困惑,我认为这是p_data =& p_struct-> DATA;定义,我应该能够通过使用*(pdata 3)得到它,但我想我错过了一些东西.

解决方法

您确定要编译您在此处发布的相同代码吗?

如果你的编译器在这一行抱怨

p_data = &p_struct->DATA;

使用“struct / union member expected”消息,您的编译器可能已损坏.

注意,& p_struct-> DATA是C中完全有效的表达式.这个表达式本身绝对没有问题.

这里的问题只是在你的情况下这不是你需要的. & p_struct-> DATA返回一个指向整个数组’DATA’的指针,即unsigned char(*)[20]类型的指针.您正在尝试将此值分配给unsigned char *类型的指针.这在C中是非法的,因为类型完全不同,但传统上C编译器只用“类型不匹配”警告响应它并执行隐式转换(BTW,意味着你的原始代码,虽然“脏”,应该仍然按预期工作).

即使某些编译器决定将此不匹配标记为错误(这很好),它仍然不应该抱怨“struct / union member expected”类型的任何问题.这里没有这样的问题.

附:正如其他人已经说过的,你真正需要的是p_data =& p_struct-> DATA [0],但这仍然无法解释编译器的奇怪行为.可能是’DATA’是在’clean_buffers’定义之前某处定义的宏吗?

已添加10/19/2009:Nate,在您的代码中使用索引theCount访问您的数组.由于您仍在使用索引访问,因此实际上没有理由创建您尝试创建的指针.代码将完美地工作,没有任何额外的指针,只是直接访问DATA字段

theCount = 0;
while (p_struct->DATA[theCount] != 0) {
  p_struct->DATA[theCount++] = 0;

(我可能在这里使用for循环).

如果你真的坚持创建这个指针并且仍然使用索引访问,那么代码应该类似于以下内容(其他人已经建议多次)

p_data = p_struct->DATA; /* or &p_struct->DATA[0] */
...
theCount = 0;
while (p_data[theCount] != 0) {
  p_data[theCount++] = 0;

此外,你可以选择更“异国情调”的变种:)

unsigned char (*p_data)[20]; /* <- note: declared differently */
...
p_data = &p_struct->DATA; /* <- note: your original version */
...
theCount = 0;
while ((*p_data)[theCount] != 0) {
  (*p_data)[theCount++] = 0;

但是,返回到unsigned char * p_data版本,因为您创建了该指针,使用“滑动指针”技术而不是使用索引访问可能更有意义

unsigned char *p_data;
...
p_data = p_struct->DATA; /* or &p_struct->DATA[0] */
...
while (*p_data != 0) {
  *p_data++ = 0;

一如既往,这完全取决于个人喜好.当然,除非你摆脱宏的干扰,否则这一切都无济于事.

相关文章

一.C语言中的static关键字 在C语言中,static可以用来修饰局...
浅谈C/C++中的指针和数组(二) 前面已经讨论了指针...
浅谈C/C++中的指针和数组(一)指针是C/C++...
从两个例子分析C语言的声明 在读《C专家编程》一书的第三章时...
C语言文件操作解析(一)在讨论C语言文件操作之前,先了解一下...
C语言文件操作解析(三) 在前面已经讨论了文件打开操作,下面...