Мне нужно объяснение. Я искал ответ, но не нашел его.Указатель void на функцию
Проблема заключается в следующем: Я работаю над упражнениями из книги: «Программирование для инженеров» А.Р. Брэдли Глава 7 Вот часть кода:
struct _fifo {
unsigned capacity;
unsigned head;
unsigned tail;
void * data[0];
};
fifo newFifo(int capacity) {
// The capacity of a circular buffer is one less than one
// would think: if the user wants a given capacity, the
// required array is one cell larger.
capacity++;
fifo q = (fifo) malloc(sizeof(struct _fifo) + capacity * (sizeof(void *)));
q->capacity = (unsigned) capacity;
q->head = 0;
q->tail = 0;
return q;
}
int putFifo(fifo q, void * e) {
if ((q->head+1) % q->capacity == q->tail) // full?
return -1;
q->data[q->head] = e;
q->head = (q->head+1) % q->capacity;
return 0;
}
typedef void (*printFn) (void*);
int printFifo(fifo q, printFn f) {
unsigned i;
for (i = q->tail; i != q->head; i = (i+1) % q->capacity) {
f(q->data[i]);
}
return 0;
}
static void printLong(void * e) {
// %ld tells printf to print a long integer
printf("%ld", (long) e);
}
int main() {
fifo longq;
longq = newFifo(3);
printFifo(longq, printLong);
return 0;
}
Мой вопрос заключается в следующем: функция printLong я передаю пустой указатель е так делает бросок (длинный) е делает этот адрес е? почему я получаю значение данных, а не адрес, напечатанный?
, например, если я делаю это я получаю адрес напечатанный не значение:
typedef void (*printFn) (void*);
static void printLong (void * e) {
printf("%ld", (long) e);
}
int printL (void* l, printFn f) {
f(l);
}
int main()
{
long a = 5;
long* l = &a;
printf("%ld\n", *l);
printL(l, printLong);
return 0;
}
но если я бросил
*(long*) e
я получу значение. Как первая часть кода печатает значение, а не адрес? Думаю, я ничего не вижу, поэтому я смущен. Пожалуйста, помогите :)
Не печатайте значения указателя. Используйте '% p' для вашего спецификатора формата и просто отправьте указатель. Если вы хотите напечатать длинный указатель на указатель на длинный, используйте% ld и разыщите указатель после соответствующего приведения, но убедитесь, что он содержит длинный адрес или вы идете в UB. Есть ли какая-то конкретная причина, по которой вы не просто объявляете 'long *' для вашего типа параметра? – WhozCraig
Представлен ли этот пример кода с префиксом «Не пишете такой код»? Можете ли вы включить код из «newFifo»? Я пытаюсь определить, является ли «void * data [0]» оверлейным взломом или если он был взломан. В любом случае, происходит хитроумная хитрость, которая заставляет меня думать, что книге может понадобиться добавление экзотермического окисления. – kfsone
Я действительно, действительно надеюсь, что этот код не взят из книги ... «Программирование потенциальным инженером»? – Lundin