C Language                
            Форматированный вход / выход
        
        
            
    Поиск…
Печать значения указателя на объект
 Чтобы напечатать значение указателя на объект (в отличие от указателя функции), используйте спецификатор преобразования p . Он определяется только для печати void -pointers, поэтому для распечатки значения не- void -pointer он должен быть явно преобразован («casted *») в void* . 
#include <stdlib.h> /* for EXIT_SUCCESS */
#include <stdio.h>  /* for printf() */
int main(void)
{
  int i;
  int * p = &i;
  printf("The address of i is %p.\n", (void*) p);
  return EXIT_SUCCESS;
}
 Использование <inttypes.h> и uintptr_t 
 Другой способ печати указателей на C99 или более поздней версии использует тип uintptr_t и макросы из <inttypes.h> : 
#include <inttypes.h> /* for uintptr_t and PRIXPTR */
#include <stdio.h>    /* for printf() */
int main(void)
{
  int  i;
  int *p = &i;
  printf("The address of i is 0x%" PRIXPTR ".\n", (uintptr_t)p);
  return 0;
}
 Теоретически не может быть целочисленного типа, который может содержать любой указатель, преобразованный в целое число (поэтому тип uintptr_t может не существовать). На практике это действительно существует. Указатели на функции не должны быть конвертируемыми в тип uintptr_t хотя они чаще всего являются конвертируемыми. 
 Если тип uintptr_t существует, то intptr_t тип intptr_t . Непонятно, почему вы когда-либо хотели обрабатывать адреса как целые числа. 
Предварительная стандартная история:
 До C89 во время K & R-C не было никакого типа void* (ни заголовок <stdlib.h> , ни прототипы, и, следовательно, нет int main(void) notation), поэтому указатель был отброшен до long unsigned int и напечатан с использованием модификатор длины lx / спецификатор преобразования. 
Пример, приведенный ниже, предназначен только для информационных целей. В настоящее время это неверный код, который очень хорошо может спровоцировать печально известное Undefined Behavior .
#include <stdio.h> /* optional in pre-standard C - for printf() */
int main()
{
  int  i;
  int *p = &i;
  printf("The address of i is 0x%lx.\n", (long unsigned) p);
  return 0;
}
Печать разницы значений двух указателей на объект
 Вычитание значений двух указателей на объект приводит к значению целого числа * 1 . Таким образом, он будет напечатан с использованием, по крайней мере, спецификатора преобразования d . 
 Чтобы убедиться, что существует такой тип, достаточно широкий, чтобы провести такую «разницу между указателями», так как C99 <stddef.h> определяет тип ptrdiff_t . Чтобы напечатать ptrdiff_t используйте модификатор t длины. 
#include <stdlib.h> /* for EXIT_SUCCESS */
#include <stdio.h> /* for printf() */
#include <stddef.h> /* for ptrdiff_t */
int main(void)
{
  int a[2];
  int * p1 = &a[0], * p2 = &a[1];
  ptrdiff_t pd = p2 - p1;
  printf("p1 = %p\n", (void*) p1);
  printf("p2 = %p\n", (void*) p2);
  printf("p2 - p1 = %td\n", pd);
  return EXIT_SUCCESS;
}
Результат может выглядеть так:
p1 = 0x7fff6679f430
p2 = 0x7fff6679f434
p2 - p1 = 1
 Обратите внимание, что результирующее значение разности масштабируется по размеру типа, на который указывает вычитаемая точка, int здесь. Размер int для этого примера равен 4. 
* 1 Если два указателя, которые нужно вычесть, не указывают на один и тот же объект, поведение не определено.
Спецификации преобразования для печати
| Спецификация конверсии | Тип аргумента | Описание | 
|---|---|---|
| i,d | ИНТ | печатает десятичные числа | 
| u | unsigned int | печатает десятичные числа | 
| o | unsigned int | отпечатки восьмеричные | 
| x | unsigned int | печатает шестнадцатеричный, строчный | 
| X | unsigned int | печатает шестнадцатеричный, верхний регистр | 
| f | двойной | печатает float с точностью по умолчанию 6, если не задана точность (нижний регистр используется для специальных чисел nanиinfилиinfinity) | 
| F | двойной | prints float с точностью по умолчанию 6, если точность не задана (верхний регистр используется для специальных номеров NANиINFилиINFINITY) | 
| e | двойной | печатает float с точностью по умолчанию 6, если точность не задана, используя научную нотацию с использованием мантиссы / экспоненты; индекс нижнего регистра и специальные номера | 
| E | двойной | печатает float с точностью по умолчанию 6, если точность не задана, используя научную нотацию с использованием мантиссы / экспоненты; индекс верхнего регистра и специальные числа | 
| g | двойной | использует либо fлибоe[см. ниже] | 
| G | двойной | использует FилиE[см. ниже] | 
| a | двойной | печатает шестнадцатеричный, строчный | 
| A | двойной | печатает шестнадцатеричный, верхний регистр | 
| c | голец | печатает один символ | 
| s | символ * | печатает строку символов до терминатора NULили усекает до длины, заданной точностью, если указано | 
| p | недействительным * | печатает значение void-pointer; неvoid-указатель должен быть явно преобразован ( «слепок») кvoid*; указатель на объект, а не указатель функции | 
| % | н / | печатает символ % | 
| n | int * | напишите количество байт, напечатанных до сих пор в intуказывает. | 
 Обратите внимание, что модификаторы длины могут быть применены к %n (например, %hhn указывает, что следующий указатель преобразования n применяется к указателю на знак signed char соответствии с ISO / IEC 9899: 2011 §7.21.6.1 ¶7). 
 Обратите внимание, что преобразования с плавающей запятой применяются к типам float и double из-за правил рассылки по умолчанию - §6.5.2.2. Вызовы функций, ¶7 . Обозначение многоточия в деклараторе прототипа функции приводит к тому, что преобразование типа аргумента останавливается после последнего объявленного параметра. Продвижение аргументов по умолчанию выполняется по завершающим аргументам. ) Таким образом, такие функции, как printf() передаются только double , даже если указанная переменная имеет тип float . 
 В форматах g и G выбор между обозначениями e и f (или E и F ) документируется в стандарте C и в спецификации POSIX для printf() : 
Двойной аргумент, представляющий число с плавающей запятой, должен быть преобразован в стиле
fилиe(или в стилеFилиEв случае спецификатора преобразованияG), в зависимости от преобразованного значения и точности. ПустьPравно точности, если отличная от нуля, 6, если точность опущена, или 1, если точность равна нулю. Тогда, если преобразование со стилемEбудет иметь показательX:
- Если P> X> = -4, преобразование должно быть со стилем
f(илиF) и точностьюP - (X+1).- В противном случае преобразование должно быть со стилем
e(илиE) и точностьюP - 1.
Наконец, если не используется флаг «#», любые конечные нули должны быть удалены из дробной части результата, а символ десятичной точки должен быть удален, если не осталось дробной части.
Функция printf ()
 Доступ через функцию <stdio.h> , функция printf() является основным инструментом, используемым для печати текста на консоли в C. 
printf("Hello world!");
// Hello world!
Обычные, неформатированные массивы символов могут быть напечатаны самим собой, помещая их непосредственно между круглыми скобками.
printf("%d is the answer to life, the universe, and everything.", 42);
// 42 is the answer to life, the universe, and everything.
int x = 3;
char y = 'Z';
char* z = "Example";
printf("Int: %d, Char: %c, String: %s", x, y, z);
// Int: 3, Char: Z, String: Example
 Альтернативно, целые числа, числа с плавающей запятой, символы и т. Д. Могут быть напечатаны с использованием escape-символа % , за которым следует символ или последовательность символов, обозначающих формат, известный как спецификатор формата . 
 Все дополнительные аргументы функции printf() разделяются запятыми, и эти аргументы должны быть в том же порядке, что и спецификаторы формата. Дополнительные аргументы игнорируются, а неверно введенные аргументы или отсутствие аргументов приводят к ошибкам или неопределенному поведению. Каждый аргумент может быть либо буквальным значением, либо переменной. 
 После успешного выполнения количество напечатанных символов возвращается с типом int . В противном случае отказ возвращает отрицательное значение. 
Модификаторы длины
 Стандарты C99 и C11 определяют следующие модификаторы длины для printf() ; их значения: 
| Модификатор | Модифицирует | Относится к | 
|---|---|---|
| чч | d, i, o, u, x или X | char,signed charилиunsigned char | 
| час | d, i, o, u, x или X | short intилиunsigned short int | 
| L | d, i, o, u, x или X | long intилиunsigned long int | 
| L | a, A, e, E, f, F, g или G | double(для совместимости сscanf(); undefined в C90) | 
| Л.Л. | d, i, o, u, x или X | long long intилиunsigned long long int | 
| J | d, i, o, u, x или X | intmax_tилиuintmax_t | 
| Z | d, i, o, u, x или X | size_tили соответствующий типssize_t(ssize_tв POSIX) | 
| T | d, i, o, u, x или X | ptrdiff_tили соответствующий целочисленный тип без знака | 
| L | a, A, e, E, f, F, g или G | long double | 
Если модификатор длины появляется с любым спецификатором преобразования, отличным от указанного выше, поведение не определено.
 Microsoft указывает некоторые модификаторы длины и явно не поддерживает hh , j , z или t . 
| Модификатор | Модифицирует | Относится к | 
|---|---|---|
| I32 | d, i, o, x или X | __int32 | 
| I32 | o, u, x или X | unsigned __int32 | 
| I64 | d, i, o, x или X | __int64 | 
| I64 | o, u, x или X | unsigned __int64 | 
| я | d, i, o, x или X | ptrdiff_t(то есть__int32на 32-битных платформах,__int64на 64-битных платформах) | 
| я | o, u, x или X | size_t(то естьunsigned __int32на 32-битных платформах,unsigned __int64на 64-битных платформах) | 
| л или L | a, A, e, E, f, g или G | long double(В Visual C ++, хотяlong doubleявляется отдельным типом, он имеет то же внутреннее представление, что иdouble). | 
| l или w | c или C | Широкий характер с функциями printfиwprintf. (lc,lC,wcилиwCявляется синонимом функцийCвprintfиcфункциямиwprintf.) | 
| l или w | s, S или Z | Широкосимвольная строка с функциями printfиwprintf. (wSтипаls,lS,wsилиwSявляется синонимомSв функцияхprintfи сsв функцияхwprintf.) | 
 Обратите внимание, что спецификаторы преобразования C , S и Z и модификаторы I , I32 , I64 и w length являются расширениями Microsoft. Обработка l в качестве модификатора для long double а не double , отличается от стандарта, хотя вам будет трудно определить разницу, если long double имеет другого представления из double . 
Флаги формата печати
 Стандарт C (C11 и C99 тоже) определяет следующие флаги для printf() : 
| Флаг | Конверсии | Имея в виду | 
|---|---|---|
| - | все | Результат преобразования должен быть оставлен по полю в поле. Преобразование является правильным, если этот флаг не указан. | 
| + | числовое число | Результат подписанного преобразования всегда начинается со знака ('+' или '-'). Преобразование начинается со знака только тогда, когда отрицательное значение преобразуется, если этот флаг не указан. | 
| <space> | числовое число | Если первый символ подписанного преобразования не является признаком или если подписанное преобразование не приводит к символам, в результат должен быть префикс <space>. Это означает, что при появлении флагов<space>и '+' флаг<space>игнорируется. | 
| # | все | Указывает, что значение должно быть преобразовано в альтернативную форму. Для преобразования o, оно должно увеличивать точность, если и только если необходимо, чтобы заставить первую цифру результата быть нулевой (если значение и точность равны 0, выводится один 0). Для спецификаторов преобразованияxилиXненулевой результат должен иметь префикс0x(или0X). Для спецификаторов преобразованияa,A,e,E,f,F,gиGрезультат всегда должен содержать знак радиуса, даже если никакие цифры не следуют за символом radix. Без этого флага в результате этих преобразований появляется символ радиуса, только если после него следует цифра. Для спецификаторов преобразованияgиGконечные нули не должны удаляться из результата, как обычно. Для других спецификаторов преобразования поведение не определено. | 
| 0 | числовой | Для d, i, o, u, x, X, a, A, e, E, f, F, g и G спецификаторов преобразования, ведущие нули (после любого указания знака или основания) используются для заполнения поля ширину, а не выполнение пробела, за исключением того, что при преобразовании бесконечности или NaN. Если появляются флаги «0» и «-», флаг «0» игнорируется. Для спецификаторов преобразования d, i, o, u, x и X, если задана точность, флаг «0» игнорируется. ⌦ Если появляются флаги '0' и <apostrophe>, символы группировки вставляются перед нулевым заполнением. Для других преобразований поведение не определено. ⌫ | 
Эти флаги также поддерживаются Microsoft с тем же значением.
 Спецификация POSIX для printf() добавляет: 
| Флаг | Конверсии | Имея в виду | 
|---|---|---|
| ' | i, d, u, f, F, g, G | Целочисленная часть результата десятичного преобразования должна быть отформатирована тысячами символов группировки. Для других преобразований поведение не определено. Используется символ неденежной группировки. |