Как C обрабатывает целочисленные литералы с ведущими нулями и как насчет atoi?
когда вы создаете целое число с ведущими нулями, как с этим справлялся? Он отличается для разных версий C?
в моем случае они просто кажутся отброшенными (но, может быть, это то, что делает printf?):
#include <stdio.h>
int main() {
int a = 005;
printf("%in", a);
return 0;
}
Я знаю, что могу использовать printf для заполнения с 0s, но мне просто интересно, как это работает.
7 ответов
ведущие нули указывают, что число выражается в восьмеричной, или база 8; таким образом, 010 = 8. Добавление дополнительных ведущих нулей не имеет никакого эффекта; как и следовало ожидать в математике, x + 0*8^n = x; нет никакого изменения значения, делая его представление более длинным.
одном месте вы часто видите это в режимы файл Unix; 0755 на самом деле означает 7*8^2+5*8+5 = 493; или с umasks, таких как 0022 = 2*8+2 = 10.
atoi(nptr)
определяется как эквивалент strtol(nptr, (char **) NULL, 10)
, за исключением того, что он не обнаруживает ошибок - как таковой, atoi()
всегда использует decimal (и, таким образом, игнорирует ведущие нули). strtol(nptr, anything, 0)
делает следующее:
строка может начинаться с произвольного количество пробелов (как определено by
isspace(3)
), а затем один необязательно'+'
или'-'
знак. Если база нуль или 16, строка может тогда включить"0x"
префикс и номер будет прочитано в базе 16; в противном случае a ноль базу берется 10 (дес) если следующий символ'0'
, в этом случае принимается 8 (восьмеричной).
поэтому он использует те же правила, что компилятор C.
будьте осторожны!
в данном заявлении 005
является восьмеричной константой.
int a = 005;
в этом случае это не имеет значения, потому что одноразрядная восьмеричная константа имеет то же значение, что и эквивалентная десятичная константа, но в C: 015 != 15
если целочисленный литерал выражен в восьмеричном, десятичном или шестнадцатеричном формате, после его анализа компилятором он просто рассматривается как значение. Как целое число выводится через printf
зависит только от его типа, его значение и спецификаторы формата (и активная локаль).
тот факт, что начальный ноль указывает на восьмеричное число, часто забывается. Я видел, что это вызывает путаницу несколько раз, например, когда кто-то пытался ввести IP-адрес, используя хороший, обычный формат для октетов:
192.168.010.073
и парсер интерпретировал последние 2 октета как восьмеричные числа.
единственное, что хуже, чем неудачное использование ведущих нулей C, чтобы сделать восьмеричное число, - это обработка ведущих нулей Javascript иногда сделайте восьмеричное число (число восьмеричное, если остальные цифры в порядке-меньше 8-десятичного в противном случае). В JavaScript (017 == 15)
но (018 == 18)
.
Я бы предпочел, чтобы была ошибка; на самом деле я бы предпочел полностью отказаться от поддержки восьмеричных букв. По крайней мере, используйте более в вашем лице префикс, например,
0t10 (ocTal 8)
0k17 (oKtal 15)
но я на 35 лет опоздал с моим предложением.
число с ведущим нулем означает восьмеричное кодирование во всех версиях C. So 011 == 9 == 0x9
.
Восьмеричный-это система нумерации, основанная на 8 (вместо 10 для десятичного или 16 для шестнадцатеричного). Так что 011 == 1*8 + 1, 013 == 1*8 + 3
, etc.
вы должны попробовать:
int a = 5;
printf("%03i\n", a);
0 означает "колодка с нулями", 3-требуемая длина вывода.
Edit: Извините, я слишком быстро прочитал Ваш вопрос - теперь я вижу, что вы спросили о чем-то совершенно другом. Однако я оставлю это как есть, как это может быть полезно для кого-то другого.
целые числа не имеют "ведущих нулей" a 5-это 5, Вы можете написать его строковое представление с ведущим 0, если хотите, для этого у вас есть модификаторы printf.
в вашем конкретном случае нули удаляются printf.
Все ведущие нули удаляются компилятором, за исключением начального нуля, который заставляет компилятор рассматривать число как восьмеричное. Для 005 и восьмеричное, и десятичное представления одинаковы и не должны беспокоить вас, но все же, это напрашивается на неприятности, если вы специально не имели в виду восьмеричное представление.
ведущие нули имеют отношение исключительно к строковому представлению целое число. Для печати с ведущими нулями используйте "%03d". Это обеспечит длину поля 3.
В общем случае "%