2013-08-30 3 views
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); 

Если я работаю над кодом, я получаю вывод, как показано ниже.Тип литой адрес в C

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. Почему нет изменения адреса, если мы делаем typecast в (IOM_FIXED_PIA *) после ввода типа (CM_IOM_PIA *)?
  3. В общем, если у нас есть листинг, у нас есть изменение адреса?
+0

Правильно ли это утверждение: 'typedef char CM_IOM_PIA [IOM_PIA_SIZE];'. Я имею в виду, может ли one'typedef' 'char' type использовать тип массива? –

+1

@nishant: Да, это так. Это определяет 'CM_IOM_PIA' как синоним массива' char' длины 'IOM_PIA_SIZE'. –

+2

Возможно, вам понравится читать указатель arithmetic. – alk

ответ

1

Фактически, тип casting не изменяет адрес вашей переменной, он изменяет способ интерпретации вашей переменной переменной. Адрес не изменяется, потому что ваша переменная может быть на 8 бит, 32 или 64 бита, она всегда начинается с того же адреса. Но если у вас есть массив и поверг его в типе Differente, когда вы будете interate на нем ваша программа будет itererate на маленького размера, например:

char* array; 
int*  i; 

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

у вас будет 4 * 8bits, так что вы будете имеют 32 бита, которые могут быть записаны как int, но если вы перейдете на ваш int-массив, вы выйдете из памяти, потому что программа будет ходить sizeof (int), поэтому вы превысите выделение памяти.

Надеюсь, я помог вам.

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

будет выдавать 1 и 4 (вероятно, при условии sizeof (int) == 4). Математика адреса с использованием sizeof исходных типов.

+0

И ваш ответ, и Hulor's должны быть объединены. – Medinoc

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.

1
typedef char CM_IOM_PIA [IOM_PIA_SIZE]; 

Является ли указатель на символ 256 байт В C при добавлении одного к указателю он вырастет размером данных указателей. Если это был 32-разрядный целочисленный указатель данных + 1, то указывалось на следующее целое число, поэтому указатель начинался с 4 байтов. В вашем конкретном случае, так как размер структуры составляет 256 байт указателя хода 256 байт каждый раз, когда вы добавить 1.

(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, чтобы выполнить математическую операцию перед отливом.

+0

не могли бы вы избрать. Я не получил это – venkysmarty

+0

некоторые изменения, чтобы сделать его более понятным – ColdCat

1

Это происходит из-за отсутствующие скобки в

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

после того приведения типов.

Смежные вопросы