Смущенный о расширении макроса C и целочисленной арифметике

c macros c-preprocessor

8431 просмотра

4 ответа

8773 Репутация автора

Возможный дубликат:
загадка (в C)

У меня есть пара вопросов относительно следующего фрагмента:

#include<stdio.h>

#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};

int main()
{
int d;

for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
printf("%d\n",array[d+1]);

return 0;
}

Здесь вывод кода не печатает элементы массива, как ожидалось. Но когда я добавляю тип (int), макроопределение ELEMENTS как

 #define TOTAL_ELEMENTS (int) (sizeof(array) / sizeof(array[0]))

Он отображает все элементы массива, как и ожидалось.

  • Как работает этот тип передачи?

Исходя из этого у меня есть несколько вопросов:

  • Означает ли это, если у меня есть некоторые макроопределения как:

    #define AA (-64)

по умолчанию в C все константы, определенные как макросы, эквивалентны со знаком int .

Если да, то

  • Но если мне нужно принудительно заставить некоторую константу, определенную в макросе, вести себя как неподписанный тип int, есть ли какой-нибудь постоянный суффикс, который я могу использовать (я пробовал UL, UD не работал)?

  • Как я могу определить константу в определении макроса, чтобы вести себя как unsigned int?

Автор: goldenmean Источник Размещён: 04.06.2009 11:52

Ответы (4)


7 плюса

17270 Репутация автора

sizeofвозвращает количество байтов в формате без знака. Вот почему вам нужен актерский состав.

Подробнее здесь .

Автор: Skurmedel Размещён: 04.06.2009 11:56

12 плюса

8467 Репутация автора

Посмотрите на эту строку:

for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)

На первой итерации вы проверяете,

-1 <= (TOTAL_ELEMENTS-2)

Оператор size_of возвращает значение без знака, и проверка завершается неудачно (-1 подписано = 0xFFFFFFFF без знака на 32-битных машинах).

Простое изменение в цикле устраняет проблему:

for(d=0;d <= (TOTAL_ELEMENTS-1);d++)
printf("%d\n",array[d]);

Чтобы ответить на другие ваши вопросы: Макросы C расширены в текстовом виде, понятия типов нет. Компилятор C видит ваш цикл так:

for(d=-1;d <= ((sizeof(array) / sizeof(array[0]))-2);d++)

Если вы хотите определить константу без знака в макросе, используйте обычный суффикс ( ufor unsigned, ulfor unsigned long).

Автор: Miroslav Bajtoš Размещён: 04.06.2009 12:09

3 плюса

62536 Репутация автора

Относительно вашего вопроса о

#define AA (-64)

См. Определение и расширение макроса в C preprocessor:

Объектно-подобные макросы традиционно использовались как часть хорошей практики программирования для создания символических имен для констант, например

#define PI 3.14159

... вместо жесткого кодирования этих чисел в коде. Однако и C, и C ++ предоставляют директиву const, которая обеспечивает еще один способ избежать констант жесткого кодирования во всем коде.

Константы, определенные как макросы, не имеют ассоциированного типа. Используйте, constгде это возможно.

Автор: gimel Размещён: 04.06.2009 12:24

1 плюс

335619 Репутация автора

Отвечая только на один из ваших подвопросов:

Чтобы «определить константу в макросе» (это немного неаккуратно, вы не определяете «константу», просто делаете некоторую хитрость замены текста), которая не имеет знака, вы должны использовать суффикс «u»:

#define UNSIGNED_FORTYTWO 42u

Это вставит unsigned intлитерал везде, где вы печатаете UNSIGNED_FORTYTWO.

Аналогично, вы часто видите (например, в ) достаточное количество, чтобы установить точный тип с плавающей точкой:

#define FLOAT_PI 3.14f

Это вставляет float(т. Е. «Одинарную точность») литерал с плавающей точкой, куда бы вы ни вводили FLOAT_PIкод.

Автор: unwind Размещён: 04.06.2009 12:30
Вопросы из категории :
32x32