Смущенный о расширении макроса C и целочисленной арифметике
8431 просмотра
4 ответа
Возможный дубликат:
загадка (в 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?
Ответы (4)
12 плюса
Посмотрите на эту строку:
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++)
Если вы хотите определить константу без знака в макросе, используйте обычный суффикс ( u
for unsigned
, ul
for unsigned long
).
7 плюса
sizeof
возвращает количество байтов в формате без знака. Вот почему вам нужен актерский состав.
Подробнее здесь .
Автор: Skurmedel Размещён: 04.06.2009 11:563 плюса
Относительно вашего вопроса о
#define AA (-64)
См. Определение и расширение макроса в C preprocessor
:
Объектно-подобные макросы традиционно использовались как часть хорошей практики программирования для создания символических имен для констант, например
#define PI 3.14159
... вместо жесткого кодирования этих чисел в коде. Однако и C, и C ++ предоставляют директиву const, которая обеспечивает еще один способ избежать констант жесткого кодирования во всем коде.
Константы, определенные как макросы, не имеют ассоциированного типа. Используйте, const
где это возможно.
1 плюс
Отвечая только на один из ваших подвопросов:
Чтобы «определить константу в макросе» (это немного неаккуратно, вы не определяете «константу», просто делаете некоторую хитрость замены текста), которая не имеет знака, вы должны использовать суффикс «u»:
#define UNSIGNED_FORTYTWO 42u
Это вставит unsigned int
литерал везде, где вы печатаете UNSIGNED_FORTYTWO
.
Аналогично, вы часто видите (например, в
#define FLOAT_PI 3.14f
Это вставляет float
(т. Е. «Одинарную точность») литерал с плавающей точкой, куда бы вы ни вводили FLOAT_PI
код.
Вопросы из категории :
- c Как вы форматируете unsigned long long int, используя printf?
- c What are the barriers to understanding pointers and what can be done to overcome them?
- c Как реализовать продолжения?
- c Как вы передаете функцию в качестве параметра в C?
- c Как получить список каталогов в C?
- c В чем разница между #include <filename> и #include "filename"?
- macros Источники для изучения макросов схемы: определение синтаксиса и правила синтаксиса
- macros Являются ли шаблоны C ++ просто замаскированными макросами?
- macros Какая польза от do while (0), когда мы определяем макрос?
- macros Смущенный о расширении макроса C и целочисленной арифметике
- macros Получение имени класса c ++ программным путем
- macros Escaping a # symbol in a #define macro?
- c-preprocessor Предупреждение компилятора «Нет новой строки в конце файла»
- c-preprocessor Как проверить ОС с помощью директивы препроцессора?
- c-preprocessor Зачем использовать явно бессмысленные операторы do-while и if-else в макросах?
- c-preprocessor Как сделать символьную строку из значения макроса C?
- c-preprocessor Преобразовать токен препроцессора в строку