在C中输入转换地址

时间:2013-08-30 09:43:56

标签: c casting structure

typedef struct iomFixedPIA 
{
    UINT16      state;  /* State    */
    UINT16      modStatus;/* Module status*/
} IOM_FIXED_PIA;

#define IOM_PIA_SIZE 256 /* Size of PIA per IO module */

typedef char CM_IOM_PIA [IOM_PIA_SIZE]; /* PIA for one module */

printf("Actual PIA address from PIA offset = %x  modid: %d and pPIA: %x \n",
       CI856_CM_ADRS(CI856_PIA_OFFSET), pParMsg->modId,
       ((CI856_CM_ADRS(CI856_PIA_OFFSET)) + pParMsg->modId) );

pMod->pPIA = (IOM_FIXED_PIA *)
             ((CM_IOM_PIA *) (CI856_CM_ADRS(CI856_PIA_OFFSET)) + pParMsg->modId);
// question here ^^

printf(" pMod PIA= %x  \n", pMod->pPIA);

如果我运行上面的代码,我会得到如下输出。

Actual PIA addres from PIA offset = 300051c modid: 1 and pPIA: 300051d
pMod PIA= 300061c and POA= 3007020

我的问题是。

  1. 当我们输入种姓类型(CM_IOM_PIA *)时,为什么我们看到300061c而不是300051d的价值?
  2. 如果我们在输入强制转换(CM_IOM_PIA *)后对(IOM_FIXED_PIA *)进行类型转换,为什么地址没有变化?
  3. 一般情况下,如果我们进行类型转换,我们的地址是否有变化?

5 个答案:

答案 0 :(得分:1)

实际上,类型转换不会更改变量的地址,它会更改计算机解释变量的方式。地址不会改变因为,你的变量可以是8位,32位或64位,它总是从同一个地址开始。但是如果你有一个数组并以不同的类型进行投射,当你对它进行交互时,你的程序会以最小的尺寸迭代,例如:

char*    array;
int*     i;

array = malloc(sizeof(char) * 4);
i = (int*)array;

你将拥有4 * 8bits,所以你将拥有32位,可以转换为int,但是如果你在int数组上进行迭代,你将会内存不足,因为程序将按sizeof(int)行走,所以你将超出你的记忆分配。

我希望我帮助过你。

答案 1 :(得分:1)

typedef char CM_IOM_PIA [IOM_PIA_SIZE];

指向256字节的char的指针 在C中,当你向指针添加一个时,它会增长指针数据的大小。如果是32位整数数据指针+ 1指向下一个整数,那么指针前进4个字节。在特定情况下,当结构大小为256字节时,每次添加1时指针移动256字节。

(CM_IOM_PIA *) is a 256 char pointer so (CM_IOM_PIA *) +1 point to your address + 256 => 300061c 

这只是运算符优先级的问题,在添加之前进行强制转换,因此它增长了256而不是1.简单修复了如果在(CI856_CM_ADRS(CI856_PIA_OFFSET)) + pParMsg->modId周围添加括号以在强制转换之前执行数学运算。

答案 2 :(得分:1)

这是由于

中缺少大括号
(CI856_CM_ADRS(CI856_PIA_OFFSET)) + pParMsg->modId);
添加后进行类型转换。

答案 3 :(得分:0)

char *foo = NULL;
int *bar = NULL;
printf("%p %p\n", foo+1, bar+1);

将输出1和4(可能,假设sizeof(int)== 4)。使用原始类型的sizeof地址数学。

答案 4 :(得分:0)

要在printf()中获取相同的地址,而不是:

pMod->pPIA = (IOM_FIXED_PIA *)
         ((CM_IOM_PIA *) (CI856_CM_ADRS(CI856_PIA_OFFSET)) + pParMsg->modId);

做的:

pMod->pPIA = (IOM_FIXED_PIA *)
         ((CM_IOM_PIA *) ((CI856_CM_ADRS(CI856_PIA_OFFSET)) + pParMsg->modId));

在第二个printf()

因此,添加+ pParMsg->modId将基于(CI856_CM_ADRS(CI856_PIA_OFFSET))的类型完成,该类型基于类型CM_IOM_PIA与OP相关联。