结构与C中的数组问题

时间:2018-05-28 14:00:35

标签: c struct embedded

编辑: 使用包含模拟EEPROM功能的Microchip引导加载程序 我按照他们的例子声明了一个结构,除了我包含一个数组而不是int somevar&eeVars传递给ezbl.h中显示的代码 问题是sizeof总是产生2,所以只有我的数组的第一个成员由EZBL_ModifyROM编写。如果我在*的最后一行添加EZBL_WriteROMObj,则sizeof会给出正确的结果并写入所有内容。

要测试数组的ezbl.h if语句始终返回false。我已经使用没有结构的数组,结构中的数组(如下所示),结构中的int somevar和结构中的2个int变量进行了测试。

原样,唯一适用于始终为false if语句的情况是单个int somevar。通过将*取消引用添加到else案例中,一切正常。是否有理由测试阵列?是否需要2个案例?

例如,此代码应打印" 65535"在第一次通电时," 10"下一个上电,如果已经写入了数组中的所有值,则每次后续上电都会增加1。

EZBL_AllocFlashHole(emuEEData, 3072, 0x800, -1);
struct
{
 int MY_LUT[101];
} eeVars;

int main(void) {

EZBL_ReadROMObj(&eeVars, EZBL_FlashHoleAddr(emuEEData)); //read the stored data

printf("%d", MY_LUT[10]);

if(eeVars.MY_LUT[10] == 0xFFFF) //check if any values present
{
int i = 0;
for (i=0;i<101;i++)
{MY_LUT[i] = 10;}
}
else
{
MY_LUT[10] = MY_LUT[10] + 1;
}

EZBL_WriteROMObj(EZBL_FlashHoleAddr(emuEEData),&eeVars); //write the data
}

有问题的ezbl.h代码

#define EZBL_WriteROMObj(destPgmAddr, srcRAMObjPtr)                                                  
{                                                                                               
    EZBL_NVMKey = 0x03DF;                                                                       
    if(__builtin_types_compatible_p(typeof (srcRAMObjPtr), void*)) //always returns false
/* regular pointer case */   \
    EZBL_ModifyROM((destPgmAddr), (srcRAMObjPtr), sizeof(*srcRAMObjPtr));                   
    else /* array case  */ 
EZBL_ModifyROM((destPgmAddr), (srcRAMObjPtr), sizeof(srcRAMObjPtr));   

}

void EZBL_ModifyROM(unsigned long destPgmAddr, void *srcData, unsigned   int byteLen);

1 个答案:

答案 0 :(得分:-1)

如果传入数组,则

sizeof以字节为单位返回数组的大小,如:

int MY_LUT[101];
printf("%d", sizeof(MY_LUT)); //prints 101 * sizeof(int)

如果要传入一个指向包含数组的结构的指针,那么要获取结构的完整大小,您可以取消引用它:

#define EZBL_WriteROMObj(destPgmAddr, srcRAMObjPtr)\
{\
  printf("%d", sizeof(*srcRAMObjPtr));\
}  
...
struct
{
 int MY_LUT[101];
} eeVars;
...
EZBL_WriteROMObj(addr, &eeVars);

如果您知道您的结构只包含数组而没有其他内容,那么您可以使用sizeof(srcRAMObjPtr->MY_LUT)获得数组的大小,但这会使代码变得不那么灵活,为什么这样做只需简单取消引用指针?

EZBL_WriteROMObj宏似乎试图确定传递的参数是否是数组,但这是错误的,因为void*struct eevars*或任何其他指针的类型不同。使用GNU扩展检查参数是否为数组的更好方法是:

#define EZBL_WriteROMObj(destPgmAddr, srcRAMObjPtr)\
{\                                            
    if(__builtin_types_compatible_p(typeof(srcRAMObjPtr), typeof(&(srcRAMObjPtr)[0])))\
    {\
        /* regular pointer case */ \
        printf("%d\n", sizeof(*srcRAMObjPtr));\
        EZBL_ModifyROM((destPgmAddr), (srcRAMObjPtr), sizeof(*srcRAMObjPtr));\
    }\
    else /* array case  */ \
    {\
        printf("%d\n", sizeof(srcRAMObjPtr));\
        EZBL_ModifyROM((destPgmAddr), (srcRAMObjPtr), sizeof(srcRAMObjPtr));\
    }\
}

这样,您可以传递指向结构的指针或数组:

struct
{
    int MY_LUT[101];
} eeVars;
...
EZBL_WriteROMObj(addr, &eeVars);
/* or: */
EZBL_WriteROMObj(addr, eeVars.MY_LUT);