2010-12-26 3 views
2

Функция:указатели в C с #define

#define ASSOC(port) (*(volatile bit_field *) (&port)) 

Вызов функции:

#define SCLK ASSOC(PORTC).bit0 

bit_field определяется как структура, как это:

typedef struct { 
unsigned char bit0 :1, bit1 :1, bit2 :1, bit3 :1, bit4 :1, bit5 :1, 
    bit6 :1, bit7 :1; 
} bit_field; 

у меня нет знаете где & порт определен.

Может кто-нибудь объяснить, как функция читается и как она работает, пожалуйста? Я не очень хорош с указателями, и этот пример, в частности, очень запутан с «*» спереди и в конце и «&» с портом.

Спасибо

ответ

4

port не определен. Это аргумент ASSOC, как вы можете увидеть здесь:

#define ASSOC(port) /* etc. */ 

Кроме того, я предполагаю, что это должно быть char, потому что bit_field имеет 8 бит. & в &port просто служит для получения своего адреса в памяти.

АССОК в свою очередь отбрасывает &port в volatile bit_field *, а затем добавляется * в начале, чтобы указать непосредственно на содержимое полученного указателя.

Следовательно, после вызова ASSOC (порт) вы можете использовать его как структуру типа бит_поля. Например, макрос SCLK даст первый бит PORTC.

+0

Это заняло у меня некоторое время, чтобы понять, но я понял это сейчас. Самая запутанная часть для меня заключалась в том, почему он определял bit_field как переменную указателя (с помощью *). Это потому, что он получает все содержимое созданного им типа typedef bit_field. Затем он умаляет все это [(* (volatile bit_field *) (& port))] с внешним *, потому что, если он этого не сделает, он вернет адрес того, что он передает (PORTC). Таким образом, он упускает из виду все это, поэтому содержимое возвращается, а не адрес .... Я, наконец, понимаю, что указатели лучше :) – milan

1

ASSOC берет то, что я предполагаю, что это char по имени PORTC и дает обратно bit_field с теми же значениями каждого отдельного бита в PORTC.

SCLK возвращает один из битов в поле бит.

Вы принимаете PORTC и передаете его ASSOC в качестве параметра.

2

Определяемый вами макрос ASSOC - это отличное место.

  1. Вы передаете в значении port (в данном случае, это исходит от другого макроса SCLK)
  2. ASSOC принимает адрес port с & оператора
  3. ASSOC слепки адрес port «с до (volatile bit_field *)
  4. ASSOCdereferences (* с) адрес bit_field

Результат - это те же самые биты, с которых вы начали, но можно использовать как структуру bit_field.

+0

Мне потребовалось некоторое время, чтобы понять, но я понял это сейчас. Самая запутанная часть для меня заключалась в том, почему он определял bit_field как переменную указателя (с помощью *). Это потому, что он получает все содержимое созданного им типа typedef bit_field. Затем он умаляет все это [(* (volatile bit_field *) (& port))] с внешним *, потому что, если он этого не сделает, он вернет адрес того, что он передает (PORTC). Поэтому он упускает из виду все это, поэтому содержимое возвращается, а не адрес .... Я, наконец, понимаю, что указатели лучше :) – milan

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