Что такое printf
Перейти к содержимому

Что такое printf

  • автор:

Форматированный вывод. Функция printf

В первом уроке мы научились выводить на экран произвольную строчку. Но это самое простое, что может сделать функция printf . Давайте теперь подробнее разберемся, как она устроена и как работает.

Общий синтаксис функции printf следующий:

Общий синтаксис функции printf

Рис.1. Общий синтаксис функции printf.

У функции printf есть один обязательный параметр – строка, заключенная в двойные кавычки. Эту строку еще называют формат-строкой .

Напоминаю, что параметрами называется то, что мы записываем рядом с именем функции в круглых скобках.

Кроме обязательной строки форматирования есть и необязательные параметры. Они пишутся через запятую после формат-строки.

Формат-строка.

  • символы, которые выводятся на экран без изменений
  • escape-последовательности
  • спецификаторы формата

Еscape-последовательности

С этой группой символов мы уже встречались в первом уроке. Символ \n . Он, как вы наверное помните, переносит выводимый текст на новую строку. Есть и другие эскейп-последовательности (иногда можно встретить название управляющие последовательности). Любая такая последовательность начинается с символа обратный слеш \ .

Часто используемые escape-последовательности: \n — новая строка
\t — горизонтальная табуляция. Сдвигает выводимые данные вправо на ближайшую позицию табуляции. Обычно используется для выравнивания текста внутри строки.
\’ — вывод символа ‘
— вывод символа »
\\ — вывод символа \

Как видите, последние три последовательности нужны лишь для того, чтобы вывести на экран символы «»», «’» и «\». Дело в том, что если эти символы просто записать в формат-строку, то они не отобразятся на экране, а в некоторых случаях программа и вовсе не скомпилируется. Интерес представляет символ ? . Вообще говоря, для него также имеется escape-последовательность \? . При этом, вывести данный символ можно и без добавления обратного слеша. Следующая программа иллюстрирует работу escape-последовательностей.

#include int main(void)

Хотя escape-последовательности состоят из нескольких символов, но в потоке вывода они воспринимаются как цельный символ, который имеет своё собственное значение. Итого, используя управляющие последовательности мы можем влиять на то, как данные будут выводиться на экране.

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

Спецификаторы формата всегда начинаются с символа % , и предназначены для вывода на экран значений переменных и выражений. Для каждого типа данных есть свой спецификатор формата. Ниже записаны основные из них.

Основные спецификаторы формата: %d, %i — целые числа
%f, %g — вещественные числа
%c — символы

Есть и другие спецификаторы формата. Мы познакомимся с ними тогда, когда они нам понадобятся. Сами спецификаторы формата на экран не выводятся. Вместо них выводятся данные, которые передаются в функцию printf после строки форматирования. Функция printf работает следующим образом. Все символы, заключенные в двойные кавычки, кроме управляющих последовательностей и спецификаторов формата, выводятся на экран. Спецификаторы формата во время вывода заменяются на значения, указанные после формат-строки. Причем, если используется несколько спецификаторов формата, то первый спецификатор заменяется на первое значение, расположенное после формат строки, второй – на второе, и т.д. Посмотрим на примерах.

printf("%d\t%d\n%d",10,20,30);

Вывод Листинг 2.

Рис.2 Вывод Листинг 2.

printf("pervoe slagaemoe: %d\nvtoroe slagaemoe:%d\nsumma: %d\n",10,20,30);

Вывод Листинг 3.

Рис.3 Вывод Листинг 3.

printf("%d + %d = %d\n", 20, 10, 20+10);

Вывод Листинг 4.

Рис.4 Вывод Листинг 4.

printf("%d + %d %c %d\n", 10, 20, '=', 20+10);

Вывод Листинг 5.

Рис.5 Вывод Листинг 5.

На следующей картинке показан принцип работы функции printf .

Принцип работы функции printf.

Рис.6 Принцип работы функции printf.

  • количество спецификаторов формата должно совпадать с количеством данных для вывода
  • спецификаторы формата должны точно соответствовать типам выводимых данных
#include int main(void) < int z = 4; float b = 5.4; printf("%f\n",z); // нарушено 2 правило // переменная z целого типа, а команда форматирования %f предназначена для // вывода переменных типа float printf("%d\n",z, b); //нарушено 1 правило // нет команды форматирования для переменной b. return 0; >

Напишем небольшую программу, которая иллюстрирует использование спецификаторов формата.
#include int main(void)

Модификаторы формата.

Обратите внимание, что вещественные числа через спецификатор %f выведены с шестью знаками после запятой. У вас на компьютере может быть выведено как больше, так и меньше знаков. Обычно такая точность не нужна. К счастью, этим можно управлять. Для этого предназначены модификаторы формата . Модификаторы формата записываются между символом % и буквой используемого типа. На рисунке ниже представлена спецификатор формата с использованием модификатора формата.

Модификатор формата

Рис.7 Модификатор формата

Первое число обозначает ширину поля, выделяемого для записи числа. Второе число обозначает точность, с которой мы хотим вывести данное вещественное число. В примере на картинке под вещественное число мы выделяем 8 символов и хотим видеть 3 знака после запятой. Если указанного в ширине количества позиций нам не хватает для вывода числа, то ширина поля увеличивается автоматически, до минимально-возможного количества позиций. У первого числа может спереди еще стоять знак минус, например %-8.3f . Этот минус говорит о том, что необходимо выровнять число по левому краю используемой области. Для иллюстрации описанных возможностей модификаторов формата, напишем небольшую программу.

#include int main(void)< int a=777; // никаких модификаторов нет, //вывод использует минимальную ширину поля printf("|%d|\n", a); // ширина 8 позиций, выравнивание по левому краю printf("|%-8d|\n", a); // ширина 8 позиций, выравнивание по правому краю printf("|%8d|\n", a); // число позиций 2, но в числе 777 больше двух цифр // поэтому область расширяется до минимально-возможной ширины printf("|%2d|\n", a); float b=150.5; // никаких модификаторов нет, выведет используя минимальную ширину поля // и стандартную точность 6 знаков printf("|%f|\n", b); // ширина 8 позиций, выравнивание по левому краю, 3 знака после запятой printf("|%-8.3f|\n", b); // ширина 8 позиций, 2 знака после запятой, выравнивание по правому краю printf("|%8.2f|\n", b); // число позиций 4,точность 3 знака после запятой, но этого мало // поэтому ширина поля увеличивается до минимально-возможного значения printf("|%4.3f|\n", b); return 0; >

Результат работы данной программы представлен на рисунке ниже.

Вывод Листинг 8.

Рис.8 Вывод Листинг 8.

Я специально поставил вокруг каждого числа прямые черточки, что можно было увидеть, что означает ширина поля для вывода и как работает выравнивание по левому краю. В этом шаге вы познакомились только с самыми основными возможностями функции printf . Но даже этих возможностей вполне хватит, чтобы данные, которые выводит ваша программа выглядели презентабельно. Да, чуть не забыл. Мы решили одну из задач, которая стояла перед нами в начале урока.

#include int main(void)
Сохрани в закладки или поддержи проект.

Практика

Решите предложенные задачи. Для удобства работы сразу переходите в полноэкранный режим Исследовательские задачи для хакеров:

  1. Теперь вы можете увидеть, как выглядит мусор, который хранится в переменной после её объявления. Для этого объявите переменную любого типа и выведете её значение на экран использую функцию printf .
  2. Найдите в стандарте языка, в справочной системе компилятора полный список escape-последовательностей. Попробуйте использовать их в вашей программе. Разберитесь как они работают.
  3. Выясните, что произойдет, если в формат-строку функции printf вставить \c , где c — любой символ, не входящий в список escape-последовательностей. [K&R]
  4. Разберитесь с тем, как работает модификатор точности для целых чисел.
  5. Попробуйте вывести символы «»», «’», «\» и «?» без использования escape-последовательностей.
  6. Изучите как работает спецификатор %e
  7. Скомпилируйте и выполните сделующую программу:
#include #include int main(void) < char one = '?'; char two = '\?'; printf("Compare chars: %d - %d\n", one, two); if (one == two)< printf("It's equal!\n\n"); >else < printf("It isn't equal!\n\n"); >char tree[] = "?"; char four[] = "\?"; printf("Compare strings: %s - %s\n", tree, four); if (strcmp(tree, four) == 0) < printf("It's equal!\n"); >else < printf("It isn't equal!\n"); >return 0; >

Дополнительные материалы

  1. Ранее я говорил, что тип double называется типом двойной точности, и что он в некотором смысле лучше, чем тип float . Запустите следующую программу, чтобы убедиться в этом.
#include int main(void)< int z = 1/10; float x = 1.0/10.0; double y = 1.0/10.0; printf("int:\n%d\n\n", z); printf("float:\n4\t--\t%.4f\n10\t--\t%.12f\n16\t--\t%.16f\n\n", x,x,x); printf("double:\n4\t--\t%.4f\n10\t--\t%.12f\n16\t--\t%.16f\n", y,y,y); return(0); >

int printf(const char *format, arg-list)

Функция printf() записывает в stdout аргументы из списка arg-list под управлением строки, на которую указывает аргумент format.

Строка, на которую указывает format, состоит из объектов двух различных назначений. Во- первых, это символы, которые сами должны быть выведены на экран. Во-вторых, это специфика­торы формата, определяющие вид, в котором будут выведены аргументы из списка arg-list. Спе­цификаторы формата состоят из символа процент, за которым следует код формата. Команды форматирования приведены в таблице. Количество аргументов должно точно соответство­вать количеству спецификаторов формата, причем следовать они должны в одинаковом порядке. Например, следующий вызов функции printf()

printf («Hi %с %d %s», ‘с’, 10, «there!»);

приведет к выводу «Hi с 10 there!».

Таблица: Команды форматирования для printf()

Код Формат
Символ типа char
%d Десятичное число целого типа со знаком
%i Десятичное число целого типа со знаком
Научная нотация (е нижнего регистра)
Научная нотация (Е верхнего регистра)
%f Десятичное число с плавающей точкой
%g Использует код %е или %f — тот из них, который короче (при использовании %g используется е нижнего регистра)
%G Использует код %Е или %f — тот из них, который короче (при использовании %G используется Е верхнего регистра)
Восьмеричное целое число без знака
%s Строка символов
%u Десятичное число целого типа без знака
Шестнадцатиричное целое число без знака (буквы нижнего регистра)
Шестнадцатиричное целое число без знака (буквы верхнего регистра)
Выводит на экран значение указателя
%n Ассоциированный аргумент — это указатель на переменную целого типа, в которую помещено количество символов, записанных на данный момент
%% Выводит символ %

Если количество аргументов меньше, чем количество команд форматирования, то вывод не­определен. Если же количество аргументов больше, чем команд форматирования, то лишние ар­гументы отбрасываются.

Функция printf() возвращает количество действительно выведенных символов. Возврат отрица­тельной величины означает ошибку.

Команды форматирования могут содержать модификаторы, означающие ширину поля, точ­ность и флаг выравнивания влево. Переменная целого типа, помещенная между символом про­цент и командой форматирования, работает как спецификатор минимальной ширины поля, запол­няя поле вывода пробелами или нулями так, чтобы обеспечить указанную минимальную ширину. Если строка или число больше, чем этот минимум, они будут полностью выведены. По умолча­нию заполнение производится пробелами. При выводе числовых переменных, если надо исполь­зовать заполнение нулями, помещается нуль перед спецификатором минимальной ширины поля. Например, %05d будет дополнять числа, состоящие из менее чем 5 цифр, нулями до пяти цифр.

Результат использования модификатора точности зависит от типа модифицируемой команды форматирования. Чтобы использовать модификатор точности, надо поместить десятичную точку и точность вслед за ней после количества выводимых десятичных знаков. Например, %10.4f озна­чает вывод числа шириной минимум 10 символов с четырьмя знаками после точки. Однако при использовании совместно со спецификаторами g или G модификатор точности задает максималь­ное количество отображаемых значащих цифр.

Когда модификатор точности применяется к целым числам, он указывает минимальное коли­чество отображаемых цифр. (При необходимости отображаются предшествующие нули.)

Когда модификатор точности применяется к строкам, число после десятичной точки указывает максимальную длину поля. Например, %5.7s выводит строку длиной не менее пяти и не более семи символов. Если строка длиннее, чем максимальная ширина поля, то последние символы будут урезаны.

По умолчанию вывод производится с выравниванием вправо. Это значит, что если ширина поля больше, чем выводимые данные, то данные будут размещены на правом краю поля. Можно задать режим выравнивания влево, вставив знак минус сразу после знака процент. Например, %-10.2f прижмет влево в десятизнаковом поле число с плавающей точкой с двумя знаками после запятой.

Имеется два спецификатора формата, позволяющих printf() отображать целые числа типа short и long. Эти спецификаторы могут применяться совместно со спецификаторами типа d, i, о, u, х и X. Спецификатор l «говорит» printf() о том, что далее следуют данные типа long. Например, %ld означает, что нужно вывести long int. Спецификатор h указывает printf(), что нужно отобразить short int. Следовательно, %hu указывает, что данные имеют тип short unsigned int.

Хоть это и не оговорено в стандарте (да это и не нужно), модификатор l может также предше­ствовать спецификаторам типа с плавающей точкой е, Е, f, g и G, указывая, что далее следует переменная double. L используется для указания long double.

Спецификатор n помещает количество выведенных до сих пор символов в переменную целого типа, на которую указывает аргумент, соответствующий спецификатору. Например, следующий фрагмент кода выводит число 15 после строки «this is a test».

int i;
printf («this is a test %n», &i);
printf(«%d», i);

Символ # имеет особое значение, когда используется с некоторыми спецификаторами формата функции printf(). Если поставить # перед спецификаторами a, g, G, f, е или Е, то десятичная точка будет ставиться даже в отсутствие цифр после запятой. Если поставить # перед специфика­тором формата х, то шестнадцатиричное число будет выведено с префиксом 0х. Использование # со спецификатором о приводит к выводу префикса 0. С другими спецификаторами формата сим­вол # использоваться не может.

Спецификаторы минимальной ширины поля и точности могут быть представлены для printf() не только в виде констант, но и с помощью аргументов. Это делается с помощью символа *, который служит указателем места. При считывании форматной строки функция printf() проводит соответствие между символами * и аргументами в том порядке, в каком они встречаются.

Данная программа отображает на экране то , что указано в комментариях :
#include
int main ( void )
{
/* выводит выровненное по левому краю «this is a test» в 20-символьном поле
*/
printf ( «%-20s» , «this is a test» ) ;
/* выводит вещественное значение с 3 цифрами после запятой в 10-символьном поле. В результате работы увидим » 12.235″
*/
printf ( «%10.3f» , 12.234657 ) ;
return 0 ;
}

Что такое printf

Для вывода на консоль в языке программирования Си зачастую применяется функция printf() . Но если с выводом простой строки особых проблем не возникает, то при выводе данных других типов есть свои особенности.

Формальное определение функции printf выглядит следующим образом:

printf(строка_форматирования, список_аргументов)

Первый параметр представляет строку, которая может содержать произвольный текст в двойных кавычках. Например:

#include int main(void)

Кроме стандартного текста мы можем передавать в строку специальные группы символов, которые называются управляющими последовательностями. Наиболее распространенные из них:

  • \n : перевод на новую строку
  • \t : табуляция
  • \r : возврат каретки (курсора) в начало строки
  • \\ : обратный слеш
  • \’ : одинарная кавычка
  • \» : двойная кавычка

#include int main(void)

The book "The C Programming Language" Brian Kernighan, Dennis Ritchie

Спецификации преобразования

Спецификации преобразования позволяют задать формат вывода различных типов данных. Формальное определение спецификаций преобразования выглядит следующим образом:

% флаги ширина_поля.точность модификатор спецификатор

Из этих компонентов обязательными являются только два % и спецификатор .

Какие спецификаторы мы можем использовать:

  • %c : для вывода отдельных символов (тип char)
  • %s : для вывода строк
  • %d : для вывода целых чисел со знаком (тип int)
  • %i : для вывода целых чисел со знаком (тип int)
  • %u : для вывода целых положительных чисел (тип unsigned)
  • %f : для вывода чисел с плавающей точкой (float, double)
  • %F : для вывода чисел с плавающей точкой в верхнем регистре (float, double)
  • %e : для вывода экспоненциального представления чисел с плавающей точкой (float, double)
  • %E : для вывода экспоненциального представления чисел с плавающей точкой в верхнем регистре (float, double)
  • %g : для вывода чисел используется более короткий из форматов %e или %f
  • %G : для вывода чисел используется более короткий из форматов %E или %F
  • %o : для вывода восьмеричных чисел без знака
  • %x : для вывода шестнадцатеричных чисел
  • %X : для вывода шестнадцатеричных чисел в верхнем регистре
  • %% : для вывода знака процента

Применим несколько спецификаторов:

#include int main(void)

Значения для спецификаторов передаются через аргумент, который идет вторым параметром в функции printf.

x = 71.898598 x = 7.189860e+001 symbol = r number = 23 Hello Word 2013

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

float r = 71.8986; printf("x = %4.2f \n", r); // 71.90

Здесь спецификация преобразования представляет строку «%4.2f», где «4» — ширина поля (для вывода числа будут использоваться 4 цифры), а «2» — точность (2 цифры в дробной части).

Модификаторы позволяют конкретизировать выводимое значение. Используются следующие модификаторы:

  • h : для вывода значений short int
  • l : для вывода значений long int и unsigned long int
  • ll : для вывода значений long long int и unsigned long long int
  • L : для вывода значений long double
short r = 7100; printf("x = %hd", r);

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

printf("Name=%s \t Age=%d \t Weight=%3.2f", "Tom", 23, 63.3456);

Первый спецификатор в строке форматирования — «%s», и для него значение будет поставляться первым аргументом — строкой «Tom». Второй спецификатор — «%d», для него значение берется из второго аргумента — числа 23. И так далее.

Дополнительно можно использовать флаги, которые дополнительно позволяют управлять форматированием вывода:

  • — : указывает, что выравнивание будет идти от левого края (по умолчанию используется выравнивае справа).
  • + : если выводимое значение имеет знак (+ или -), то оно выводится. Без данного флага знак выводится только в случае отрицательного значения.
  • пробел : вставляет пробел на месте знака перед положительными числами
  • # : при использовании со спецификаторами «o», «x», «X» значение числа выводится с предшествующими символами 0, 0x или 0X. При использовании со спецификаторами «f», «g», «G» десятичная точка будет выводиться, даже если в числе нет дробной части

Пример использования флагов:

#include int main(void)

8 8 +8 010 8.000000 Tom 38 Tom 38

Типы данных и их вывод

В этом уроке мы познакомимся с особенностями функции printf() и типами данных: целыми и вещественными числами, символами, массивами и строками. Это далеко не все допустимые в C типы. Есть еще указатели, структуры, объединения, перечисления, также в C есть возможность определять собственные типы данных.

Функция printf() и форматированный вывод

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

На прошлом уроке мы выводили строку «Hello World» вот так:

printf("Hello World\n");

Однако то же самое можно было получить так:

printf("%s\n", "Hello World");

Здесь %s — это спецификация строкового формата, т. е. вместо %s будет подставлен следующий аргумент, данные которого должны быть строкой. Вывод целого числа может выглядеть так:

printf("%d\n", 5);

Вместо числа 5 может стоять переменная целочисленного типа. Функция printf() может принимать произвольное число аргументов:

printf("%d %s, %d %s.\n", 3, "dogs", 2, "cats");

При выводе данные подставляются по очередности следования: 3 на место первой спецификации, dogs на место второй и т.д. То есть следует строго соблюдать соответствие форматов и последующих данных.

Под выводимые данные можно выделять больше знакомест, чем необходимо. Для этого между знаком % и буквой формата прописывается целое число, обозначающие ширину поля, например так: %10d. По умолчанию выравнивание происходит по правому краю. Для выравнивания по левому краю перед числом ставится знак минус.

Напишите программу, которая выводила бы на экране данные примерно так, как на картинке. При этом используйте возможность задать ширину поля, а также выравнивание по левому и правому краям.

Пример форматированного вывода

Целочисленные типы

В языке C существует несколько типов целых чисел. Они различаются между собой объемом памяти, отводимым под переменную, а также возможностью присваивания положительных и отрицательных значений. От объема памяти, т. е. от количества выделяемых байтов под переменную, зависит, каким может быть максимально возможное значение, записанное в данную переменную. Следует отметить, что в языке Си объем памяти, выделяемый под конкретный тип, может зависеть от операционной системы.

Так, если под переменную какого-либо целочисленного типа выделяется 2 байта, что составляет 16 бит, и ей можно присваивать только положительные числа и ноль, то эти числа будут в диапазоне от 0 до 65535, т. к. 2 16 = 65536, но одна вариация забирается на нуль. Если же тип допускает отрицательные числа, то диапазон допустимых значений уже будет лежать в пределах от -32768 до +32767.

Часто в программах используется тип int. Вот пример, где происходит объявление и определение (присваивание значений) целочисленных переменных, а также вывод их значений на экран:

#include int main()  int lines, i; int count = 0; lines = 100; i = -1; printf("%5d %5d %5d\n", i, count+10, lines); >

Обратите внимание, что в языке C присваивать значение можно при объявлении переменных.

Обычно под переменную типа int, которая может принимать как положительные так и отрицательные значения, отводится 4 байта, что равно 32-м битам. Отсюда допустимый диапазон значений будет лежать в пределах от -2 147 483 648 до 2 147 483 647. Если в исходном коде на C мы объявим переменную int max, присвоим ей максимально допустимое значение, а потом будем его увеличивать, то сообщений об ошибке не будет ни на этапе компиляции, ни на этапе выполнения.

#include int main()  int max = 2147483647; printf("%d\n", max+1); printf("%d\n", max+2); printf("%d\n", max+10); >

Результат будет таким:

-2147483648 -2147483647 -2147483639

Чтобы понять, почему такое происходит, представьте себе числовую ось не в виде прямой, а в виде окружности. Когда мы достигаем конца, двигаясь например по часовой стрелке, то это значит, что мы пришли в начало. Поэтому, продолжая движение по часовой стрелке, следующее число, которое мы увидим за максимально возможным, – это самое минимальное. Данную особенность языка Си следует иметь в виду при выполнении арифметических действий.

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

#include int main()  int min = -2147483648; printf("%d\n", min-1); printf("%d\n", min-2); printf("%d\n", min-10); >
2147483647 2147483646 2147483638

Помимо типа int в языке программирования C существуют другие (модифицированные) целочисленные типы:

  • short — отводится меньше байтов, чем на int;
  • long — отводится больше байтов, чем на int (не всегда, зависит от системы);
  • unsigned — столько же байт как у int, но без отрицательных чисел; в результате чего знаковый разряд освобождается, и количество положительных значений увеличивается;
  • unsigned short;
  • unsigned long.

При выводе длинных чисел следует дополнять спецификацию формата буквой l перед буквой формата. Например:

printf("%ld\n", i); printf("%15ld\n", i);

Символы

Под символьный тип данных отводится 1 байт памяти. У каждого символа есть соответствующее ему целое число по таблице символов ASCII.

Тип char языка программирования C включает диапазон чисел от -128 до 127. Значения от 0 до 127 могут быть заданы или выведены на экран в виде соответствующих символов (на самом деле не все). Если значение переменной задается в виде символа, то символ заключается в одиночные кавычки, например, так: ‘w’. Также в языке существует тип unsigned char с диапазоном чисел от 0 до 255.

С другой стороны, если переменная задана как int или short и ей присвоено значение в диапазоне, где оно может быть представлено символом, то значение можно вывести как символ. Соответственно целочисленной переменной можно присвоить символ.

Если в программе вы будете использовать целые числа со значениями до 127 или 255 и хотите сэкономить память, то объявите переменную как char или unsigned char.

Получается, что в программе символы — это числа, а числа — символы. Тогда как указать, что мы хотим видеть на экране: символ или число? Для вывода на экран символов используется спецификация формата вида %c.

Так программа, представленная ниже,

#include main()  char ch = 63; unsigned char uch = 'r'; short j = 'b', k = 99; printf("%c == %d\n", ch, ch); printf("%c == %d\n", uch, uch); printf("%c, %c\n", j, k); >

выдает такой результат:

? == 63 r == 114 b, c

Число 63 по таблице символов ASCII соответствует знаку ‘?’. Сначала мы выводим значение переменной ch в формате символа, затем – числа. Тоже самое с переменной uch, однако ее значение было задано через символ, а не число.

Вещественные типы данных

В языке C существует три типа чисел с плавающей точкой: float и double (двойной точности) и long double. Также существует три формата вывода вещественных чисел, причем они не связаны с типами, а связаны с удобством представления числа. Вещественные числа могут иметь высокую точность, очень маленькое или очень большое значение. Если выполнить функции printf() с такими параметрами:

double a = 0.0005; printf("%f\n", a); printf("%g\n", 0.0005); printf("%g\n", 0.00005); printf("%e\n", 0.0005);

, то на экране мы увидим следующее:

0.000500 0.0005 5e-05 5.000000e-04

В первом случае (%f) выводится число в обычном виде. По умолчанию точность представления числа равна шести знакам после точки.

Во втором случае (%g) число выводится как обычно, если количество значащих нулей не больше четырех. Если количество значащих нулей четыре и больше, то число выводится в нормализованном виде (третий случай). Запись 5e-5 означает 5 * 10 -5 , что равно 0.00005. А, например, запись 4.325e+3 является экспоненциальной записью 4.325 * 10 3 , что равно 4325. Если с такой формой представления чисел вы сталкиваетесь первый раз, то почитайте дополнительные источники, например, статью в Википедии «Экспоненциальная запись».

Четвертый формат (%e) выведет число исключительно в нормализованном виде, каким бы это вещественное число ни было.

Если при выводе требуется округлить число до определенной точности, то перед буквой-форматом ставят точку и число-указатель точности. Например, printf(«%.2f», 0.23) выведет на экран 0.23, а не 0.230000. Когда требуется указать еще и поле, то его ширину прописывают перед точкой, например, %10.3f.

Массивы

Переменные, содержащие массивы, в языке программирования C объявляются, например, так:

int arr[5], nums[N]; float f_arr[100]; char str[80];

Если при указании количества элементов используется константа, она должна быть определена до своего использования следующим образом (чаще константы определяют вне функций):

#define N 100

На самом деле #define является командой препроцессора, используемой не только для определения констант. Когда препроцессор обрабатывает исходный файл программы, он подставляет во все места, где была упомянута константа, ее значение.

Индексация массивов в языке программирования C начинается с нуля.

Присваивание значений элементам массивов можно произвести сразу или в процессе выполнения программы. Например:

char vowels[] = 'a', 'e', 'i', 'o', 'u', 'y'>; float f_arr[6]; f_arr[0] = 25.3; f_arr[4] = 34.2; printf("%c, %.2f\n", vowels[4], f_arr[0]);

Когда переменная-массив объявляется и сразу определяется (как в случае vowels), то размер массива можно не указывать, т. к. он вычисляется по количеству элементов, переданных в фигурных скобках.

Строки

В языке программирования С нет отдельного строкового типа данных, хотя формат вывода строки есть (%s). Строки в C – это массивы символов, последний элемент которых является первым (с номером 0) символом в таблице ASCII. В этом месте таблицы стоит «ничто», имеющее символьное обозначение ‘\0’.

С другой стороны, строки — это необычные массивы в том смысле, что работа с ними в языке программирования C несколько отличается от работы с числовыми массивами. В этом мы убедимся позже.

Выше мы объявили и определили массив vowels. Если бы мы его определили вот так:

char vowels[] = 'a', 'e', 'i', 'o', 'u', 'y', '\0'>;
char vowels1[] = "aeiouy";

то он был бы строкой. Во втором случае сами двойные кавычки «говорят» что это строка, и символ окончания строки ‘\0’ записывается в память автоматом.

Массивы символов можно выводить на экран, просто указав имя переменной, а вот с массивами чисел такой номер не пройдет:

printf("%s\n", vowels); printf("%f\n", f_arr); // ошибка

Функция sizeof()

Функция sizeof() языка C принимает в качестве аргумента константу, тип данных или переменную и возвращает количество байт, которые отведено под этот объект в памяти.

При выводе на экран значения, возвращаемого sizeof() используется формат %lu (длинное целое без знака). Примеры:

int a = 10; int b[100]; printf("Integer: %lu \n", sizeof(a)); printf("Float: %lu \n", sizeof(float)); printf("Array of 100 integers: %lu \n", sizeof(b));

Напишите программу, выводящую информацию о количестве байтов, отводимых в памяти под типы данных, которые были изучены на данном уроке. При работе с массивами символов, определяемыми как строковые литералы (в двойных кавычках), обратите внимание, что размер массива больше на единицу, чем количество видимых символов.

Курс с решением части задач:
pdf-версия

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *