1
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. 当我们在上面键入 caste 以键入 (CM_IOM_PIA *) 时,为什么我们看到的值是 300061c 而不是 300051d?
  2. 如果我们在类型转换 (CM_IOM_PIA *) 之后对 (IOM_FIXED_PIA *) 进行类型转换,为什么地址没有变化?
  3. 一般来说,如果我们进行类型转换,地址是否会发生变化?
4

5 回答 5

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之前添加括号以进行数学运算,则很简单。

于 2013-08-30T10:14:19.813 回答
1

这是由于缺少大括号

(CI856_CM_ADRS(CI856_PIA_OFFSET)) + pParMsg->modId);

添加后的类型转换。

于 2013-08-30T10:22:20.670 回答
1

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

char*    array;
int*     i;

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

您将拥有 4 * 8 位,因此您将拥有 32 位,可以将其转换为 int 但如果您在 int 数组上进行迭代,您将耗尽内存,因为程序将通过 sizeof(int) 所以您将超出您的内存分配。

我希望我对你有所帮助。

于 2013-08-30T09:56:46.323 回答
0
char *foo = NULL;
int *bar = NULL;
printf("%p %p\n", foo+1, bar+1);

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

于 2013-08-30T10:00:10.687 回答
0

要在两个printf()s 中获得相同的地址,而不是这样做:

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))与 OP 相对应的类型来完成,其中它是基于 type 完成的CM_IOM_PIA

于 2013-08-30T10:13:23.500 回答