Различия между строками и символами
Строковая константа "х" — вовсе не то же самое, что и символьная константа ' х'. Одно из различий связано с тем, что ' х' имеет базовый тип (char), но "х" — это производный тип, представляющий собой массив значений char. Второе различие заключается в том, что "х" на самом деле состоит из двух символов — ' х' и ‘\0’ (рис. 4.3).

РИс. 4.3. Символ 'х' и строка "х"
Функция strlen()
В предыдущей главе кратко затрагивалась операция sizeof, которая предоставляет размер типа в байтах. Функция strlen() возвращает длину строки в символах. Поскольку для размещения одного символа требуется один байт, можно было бы предположить, что применительно к строке sizeof и strlen() дадут один и тот же результат, однако это не так. Добавьте в пример кода несколько строк, как показано в листинге 4.3, и вы поймете причину.
122 Глава 4
Листинг 4.3. Программа praise2.с

Если вы используете версию компилятора, не поддерживающую ANSI С, придется удалить следующую строку:
#include
Заголовочный файл string.h содержит прототипы для нескольких функций обработки строк, включая strlen(). Более подробно этот заголовочный файл обсуждается в главе 11. (Кстати, в некоторых системах UNIX, разработанных до появления стандарта ANSI, вместо string.h применяется заголовочный файл strings.h, содержащий объявления строковых функций.)
В общем случае С разделяет библиотеку функций на семейства связанных функций и предоставляет отдельный заголовочный файл для каждого семейства. Например, функции printf() и scanf() принадлежат семейству стандартных функций ввода- вывода и имеют свой заголовочный файл stdio.h. Функция strlen() объединяет вокруг себя ряд других функций обработки строк, таких как функции для копирования и поиска в строках, и это семейство обслуживается заголовочным файлом string.h.
Следует отметить, что в листинге 4.3 длинные операторы printf() представлены с использованием двух методов. Первый метод предусматривает разнесение оператора printf() на две строки. (Вызов можно разделять в промежутках между аргументами, но не в середине строки; т.е. не между кавычками.) Второй метод предполагает применение для вывода одной строки двух операторов printf(). Символ новой строки (\n) присутствует только во втором операторе. После запуска программы возникает следующее взаимодействие с пользователем:
Как вас зовут? Васисуалий Лоханкин
Здравствуйте, Васисуалий. Вы - выдающаяся личность.
Ваше имя состоит из 10 букв и занимает 40 ячеек памяти.
Хвалебная фраза содержит 31 символов и занимает 32 ячеек памяти.
Давайте взглянем, что происходит. Массив name имеет 40 ячеек памяти, и именно об этом сообщает операция sizeof. Однако для размещения имени Васисуалий необходимы только первые 10 ячеек, и об этом информирует функция strlen().
Символьные строки и форматированный ввод-вывод 123
Одиннадцатая ячейка в массиве name содержит нулевой символ, и его присутствие сообщает функции strlen(), когда она должна остановить подсчет. На рис. 4.4 эта концепция иллюстрируется на примере более короткой строки.

Рис. 4.4. Функции strlen() известно, когда остановить подсчет символов
Когда дело доходит до PRAISE, то обнаруживается, что strlen() снова возвращает точное количество символов в строке (включая пробелы и знаки препинания). Операция sizeof дает число, которое на единицу больше количества символов, т.к. она учитывает невидимый нулевой символ, обозначающий конец строки. В коде компьютеру не было указано, какой объем памяти нужно выделить для хранения фразы. Он должен самостоятельно подсчитать количество символов между двойными кавычками.
Как упоминалось в главе 3, стандарты С99 и С11 предполагают использование спецификатора %zd для типа, указываемого в операции sizeof. Это также относится и к типу, возвращаемому функцией strlen(). Для более ранних версий С необходимо знать действительный тип, возвращаемый операцией sizeof и функцией strlen(); обычно им будет unsigned int или unsigned long.
Еще один момент: в предыдущей главе операция sizeof применялась с круглыми скобками, но в этом примере их нет. Используете вы круглые скобки или нет, зависит от того, хотите вы получить размер типа или конкретной величины. Круглые скобки обязательны для типов, но необязательны для отдельных величин. Это значит, что вы будете применять sizeof (char) или sizeof ( float), но также можете использовать sizeof name или sizeof 6.28. Тем не менее, в этих случаях также допускается указание круглых скобок, например, sizeof (6.28).
Читать дальше