Найти в Дзене
Библиотека C++ и Python

Понимание Функции printf() в Языке Программирования C++

Оглавление

Что такое C++

C++ — это мультипарадигмальный язык программирования, поддерживающий процедурный, объектно-ориентированный и обобщенный программинг. Хотя C++ предлагает богатый набор средств ввода-вывода через библиотеку iostream, он также сохраняет совместимость с функциями ввода-вывода в стиле языка C. Одна из таких функций — printf(), благодаря простоте и контролю над форматированием, она часто используется в программах на C++.

В этой статье мы рассмотрим функцию printf(), её использование в C++ и некоторые подводные камни и лучшие практики при её включении в ваш код.

Что такое printf()

printf(), что означает "print formatted" или "печатать с форматированием", — это функция, которая отправляет форматированный вывод на stdout (стандартный вывод) или проще говоря в консоль. Она включена в C++ в целях совместимости с C, откуда она произошла. Функция определена в заголовочном файле <cstdio.h>, также известном в C.

Функция printf имеет следующий вид:

int printf ( const char * format, ... );
  • const char * format принимает указатель на строку, которая говорит этой функции, что и как нужно вывести на экран.
  • Далее функция принимает сколько угодно дополнительных параметров. Они будут использоваться в том случае, если format (первый аргумент) содержит упоминания этих самых дополнительных параметров. Тут мы будем передавать числа, строки и переменные, которые могут понадобиться для вывода на экран.
  • Возвращает функция сколько символов было выведено на экран.

Эта функция может показаться довольно сложной, поэтому приведу несколько примеров

#include <stdio.h> int main() {
printf("1. просто строка \n");
printf("2. целое число: %d \n", 1234);
printf("3. дробное число: %f \n", 12.34);
printf("4. Символ: %c \n", 'C');
printf("5. строка: %s \n", "C++");
printf("6. процент: 100%% \n");
return 0; }

Вывод программы:

просто строка
целое число: 1234
дробное число: 12.340000
Символ: C
строка: C++
процент: 100%

Разбор примеров

  • Для вывода строки не требуется ничего особенного - просто передайте строку.
  • Для вывода целого числа используйте %d.
  • Для чисел с плавающей точкой используйте %f.
  • Для символа используйте %c.
  • Для строк используйте %s.
  • Для вывода процента используйте %%.

Базовые примеры использования printf()

Вот простой пример использования printf():

#include <cstdio>
int main() {
int number = 10;
float pi = 3.14159;
printf("Целое: %d\n", number);
printf("Вещественное: %.2f\n", pi);
return 0;
}

Вывод:

Целое: 10
Вещественное: 3.14

В первом вызове %d форматирует целое число number. Во втором вызове %.2f форматирует число с плавающей точкой pi до двух десятичных знаков.

Как видите, в простых случаях работа с printf несложна. Давайте перейдем к более сложным форматированиям:

Код

printf("1. несколько аргументов: %d, %f \n", 1234, 12.34);
printf("2. минимальная ширина: %10d \n", 1234);
printf("3. лидирующие нули: %010d \n", 1234);
printf("4. количество знаков после запятой: %.9f, %.0f \n", 12.34, 12.34);
printf("5. шестнадцатеричное число: %x \n", 1234);

Вывод

несколько аргументов: 1234, 12.340000
выравнивание: 1234
лидирующие нули: 0000001234
количество знаков после запятой: 12.340000000, 12
шестнадцатеричное число: 4d2

Этот пример демонстрирует:

  • Возможность использовать несколько спецификаторов в одной строке.
  • Указание минимальной ширины с использованием числа после %.
  • Использование лидирующих нулей и указание количества цифр после запятой

Спецификаторы формата

Спецификатор формата имеет следующую структуру (в квадратных скобках опциональные модификаторы):

%[флаги][ширина][.точность][размер]тип

Обязательно нужно указать только знак % и тип. Остальное можно опустить если вас устраивает вывод без них.

Тут довольно много различных модификаторов. Некоторые из них мы уже использовали выше, но большинство мы еще не встречали. Давайте пройдемся по каждому из них:

  • тип
  • флаги
  • ширина
  • точность
  • размер

Тип

-2

Флаги

-3

Ширина

-4

Точность

-5

Размер

Модификаторы размера нам нужны, потому что в C нет возможности понять размер переданного аргумента в printf. Давайте посмотри на простой пример, чтобы продемонстрировать о чем я говорю:

long long int x = 10000000000; // десять миллиардов printf("%d\n", x);

Вывод:

1410065408

Дело здесь в том, что printf ожидает int для спецификатора %d. Значение типа long long int просто не влезает, поэтому мы видим не то, что ожидали.

Чтобы решить эту проблему, нужно явно указать размер целого числа, которое нужно вывести:

long long int x = 10000000000; // десять миллиардов
printf("%lld\n", x);

Вывод:

10000000000

Теперь вывод соответствует нашим ожиданиям. Вот таблица возможных типов:

-6

Плюсы и минусы использования функции printf() в C++

Плюсы:

  1. Управление: printf() предоставляет широкие возможности управления форматированием, что может быть полезным для создания таблиц или когда необходим точный контроль над форматированием.
  2. Простота: Для простого вывода строк printf() может показаться более простым, чем iostream, не требуя использования манипуляторов потока или флагов.
  3. Производительность: printf() может быть быстрее в сценариях, где не требуется обширная типобезопасность и расширяемость iostream.

Минусы:

  1. Типобезопасность: printf() не обеспечивает типовую безопасность, что может привести к ошибкам или неопределенному поведению, если спецификаторы формата не соответствуют предоставленным аргументам.
  2. Сложность: Строки формата могут стать сложными и трудными для чтения, что усложняет поддержку и отладку.
  3. Совместимость: printf() — это функция стиля C, и её использование не позволяет в полной мере использовать объектно-ориентированные особенности C++, что может привести к менее идиоматичному коду на C++.
  4. Расширяемость: В отличие от iostream в C++, printf() нельзя напрямую расширить для обработки пользовательских типов данных.

Заключение

Хотя printf() является пережитком C, она остается полезным инструментом в наборе инструментов разработчика C++, особенно при работе со старыми кодовыми базами или когда необходимо быстро выполнить простые задачи форматированного вывода. Однако важно быть осведомленным о потенциальных проблемах с типовой безопасностью и обслуживанием. Библиотека C++ iostream предлагает более типобезопасный и объектно-ориентированный подход к обработке ввода-вывода, который может быть более подходящим для современной разработки на C++.

Когда вы решаете использовать printf(), помните о лучших практиках её использования. Убедитесь, что спецификаторы формата и типы переменных совпадают, остерегайтесь уязвимостей переполнения буфера и предпочитайте возможности и безопасность, предлагаемые стандартной библиотекой C++, где это возможно.

P.S. Ссылки на источники,на которые опирался и брал некоторый текст и таблицу: https://codelessons.dev/ru/printf-in-c-cplusplus/

Наука
7 млн интересуются