% p против% x в формате String - PullRequest
       0

% p против% x в формате String

0 голосов
/ 03 февраля 2019

Привет, я немного запутался в строковых форматах на C. Может кто-нибудь объяснить мне, что выводит каждый отпечатанный текст здесь?

printf("%p", pointer);
printf("%x", pointer);
printf("%x", &pointer);

Ответы [ 2 ]

0 голосов
/ 03 февраля 2019

%p означает «напечатать указатель». Вы должны передать ему указатель, который был преобразован в void *.%x означает «вывести unsigned int в шестнадцатеричном формате». Вы должны передать ему unsigned int;неверно передавать указатель.

Предположим, у нас есть:

char *pointer = "Hello";
char array[]  = "World";

Тогда в:

printf("%p", (void *) pointer);
printf("%p", (void *) array);

Значение pointer будетнапечатан некоторым образом, определяемым реализацией.(Он должен показать вам адрес, который хранится в pointer.)

Во втором printf массив array будет преобразован в указатель на свой первый элемент, и значение этогоуказатель будет напечатан в соответствии с реализацией.

Обратите внимание, что я вставил приведение к (void *).Это правильный способ использования %p.

In:

printf("%x", (unsigned) pointer);
printf("%x", (unsigned) array);

Значение pointer будет преобразовано в unsigned int.Результат этого преобразования определяется реализацией.Это не должно удивлять, но может отличаться от того, что вы видите с %p.Кроме того, unsigned int может быть слишком узким, чтобы содержать полное значение указателя, и в этом случае некоторая информация будет потеряна.

После этого преобразования первый оператор напечатает значение в шестнадцатеричном формате (безведущий «0x», тогда как использование %p часто включает ведущий «0x»).Второй оператор снова преобразует array в указатель на свой первый элемент, затем преобразует его в unsigned int, а затем выводит его в шестнадцатеричном формате.

Если unsigned int достаточно широк, это возможно,даже не исключено, что значения, напечатанные этим методом, будут отображать те же шестнадцатеричные значения, как показано методом %p, но вы не можете полагаться на это.

Обратите внимание, что при печати их с использованием %x без преобразованияк unsigned имеет поведение, не определенное стандартом C - ошибка передавать указатель для спецификации %x.Вы должны преобразовать это сначала.Ваш исходный код без преобразования может привести к тому, что значение будет напечатано из некоторых произвольных данных, не связанных с указателем, или оно могло вызвать прерывание вашей программы, или оно могло бы распечатать правильный адрес, или это могло бы сделатьчто-то еще - поведение не определено.

In:

printf("%x", (unsigned) &pointer);
printf("%x", (unsigned) &array);

Адрес pointer, а не его значение, будет преобразован в unsigned int и затем напечатан вшестнадцатеричное.Это почти наверняка будет отличаться от результата печати pointer.

Для &array адрес массива будет преобразован в unsigned.В отличие от предыдущих операторов, array не преобразуется в указатель на его первый элемент.Это потому, что & является специальным оператором, который подавляет это преобразование.Он возвращает адрес массива.

Адрес массива «совпадает» с адресом его первого элемента, потому что в памяти массив начинается там, где начинается его первый элемент.Однако указатели могут иметь разные представления, и возможно, что преобразование &array в unsigned int может дать другое значение, чем преобразование array в unsigned int.Тем не менее, в большинстве реализаций C они выдают одно и то же значение, поэтому вы увидите тот же результат для printf("%x", (unsigned) &array);, что и для printf("%x", (unsigned) array);.

0 голосов
/ 03 февраля 2019

первый - для указателей, а второй - для целых, даже если результат очень часто будет одинаковым.И это все объясняет.Если вы хотите напечатать указатель %p, если целое число %x.

Все остальные обсуждения неверны, так как использование неправильного спецификатора формата вызывает UB.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...