Отличие форматов "%d" и "%zd" на языке C Печать
Добавил(а) microsin   

Отличие между "%d" и "%zd" в языке C заключается в том, для какого типа данных они предназначены и как обрабатывают потенциальное различие в размере типа int и size_t.

Формат "%d". Назначение: для типа int (знаковое целое, обычно 4 байта).

Возможная проблема: если вы передаёте значение типа size_t (беззнаковое, обычно 8 байт на 64-битных системах) в printf с использованием "%d", то:

  - Произойдёт неопределённое поведение (Undefined Behavior, UB), так как тип не соответствует спецификатору.
  - На 64-битной системе size_t больше int, как следствие printf прочитает только часть байтов, и результат будет некорректным (например, большие числа обрежутся или станут отрицательными).

Формат "%zd" (введён в C99). Назначение: специально для типа size_t (беззнаковый результат `sizeof`, индексы массивов и т.д.).

Преимущество:

  - Автоматически подстраивается под реальный размер size_t (4 или 8 байт).
  - Безопасен и портабелен.
  - Гарантирует корректный вывод значений size_t без обрезания или неопределённого поведения.

Пример различий:

#include < stdio.h>
#include < stddef.h>

int main() {
size_t x = 4000000000; // больше 2^31-1 (на 64-битной системе)

printf("%d\n", x); // Ошибка: может вывести отрицательное число или 0
printf("%zd\n", x); // Правильно: 4000000000

return 0; }

Другие похожие спецификаторы:

"%zu" — для size_t (беззнаковый вывод, z + u).
"%td" — для разности указателей (ptrdiff_t, знаковый).
"%zd" — знаковый вариант для ssize_t (нестандартный) или для size_t, если вы хотите знаковое представление (редко бывает нужно).

Какой формат когда использовать?

- Всегда используйте "%zd" или "%zu" для вывода значений, связанных с sizeof, strlen, индексами в size_t, длинами контейнеров в безопасном коде.
- "%d" — только для обычных чисел int, когда вы точно знаете, что значение помещается в int и не является size_t.

Игнорирование этого различия — частая причина трудноуловимых ошибок при переносе кода между 32-битными и 64-битными платформами.

[Ссылки]

1. Секреты printf.
2. IAR EWB ARM: форматированный вывод printf библиотеки DLIB.
3. Выравнивание в printf по правой стороне выводимого числа.
4. Проблемы с printf и sprintf. | avr-troubleshooting-faq