netlib.narod.ru< Назад | Оглавление | Далее >

2.3. Константы

Целая константа, например 1234, имеет тип int. Константа типа long завершается буквой l или L, например 123456789L; слишком большое целое, которое невозможно представить как int, будет представлено как long. Беззнаковые константы заканчиваются буквой u или U, а суффикс ul или UL говорит о том, что тип константы — unsigned long.

Константы с плавающей точкой имеют десятичную точку (123.4) или экспоненциальную часть (1e-2), или же и то и другое. По умолчанию считается, что они принадлежат к типу double. Суффикс f или F указывает на тип float, а l или L — на тип long double.

Целое значение может быть представлено в восьмеричной или шестнадцатиричной системе счисления вместо десятичной. Если константа начинается с нуля, считается, что она представлена в восьмеричной системе, если с 0x или 0X, то — в шестнадцатеричной. Например, десятичное целое 31 можно записать как 037 или как 0X1F. Записи восьмеричной и шестнадцатиричной констант могут завершаться буквой L (для указания на тип long) и U (если нужно показать, что константа беззнаковая). Например, константа 0XFUL имеет значение 15 и тип unsigned long.

Символьная константа записывается в виде символа, обрамленного одиночными кавычками, например 'x'. В выражениях символьная константа рассматривается как целое число, равное коду данного символа в наборе символов компьютера. Например, символьная константа '0' на машине, использующей кодировку ASCII, имеет значение 48, которое никакого отношения к числу 0 не имеет. Когда вместо числового значения (например, 48) мы пишем '0', программа становися независимой от конкретного значения кода символа и более простой для чтения. Символьные константы могут участвовать в операциях над числами точно так же, как и любые другие целые, хотя чаще всего они используются для сравнения с другими символами.

Некоторые символы в символьных и строковых константах представляются как управляющие последовательности, например \n (символ новой строки); такие последовательности изображаются двумя символами, но обозначают один. Кроме того, можно непосредственно указать восьмеричный код символа, написав

    '\ooo'

где ooo — одна, две или три восьмеричные цифры (0...7). Можно использовать шестнадцатиричную запись

    '\xhh'

где hh — одна или две шестнадцатеричные цифры (0...9, a...f, A...F). Таким образом, мы могли бы написать

    #define VTAB '\013' /* вертикальная табуляция в ASCII */
    #define BELL '\007' /* звуковой сигнал в ASCII */

или в шестнадцатиричном виде:

    #define VTAB '\xb' /* вертикальная табуляция в ASCII */
    #define BELL '\x7' /* звуковой сигнал в ASCII */

Ниже приводится полный набор управляющих последовательностей:


\a

звуковой сигнал

\\

обратная наклонная черта

\b

возврат на позицию назад (забой)

\?

знак вопроса

\f

переход на новую страницу

\'

апостроф

\n

новая строка

\"

двойная кавычка

\r

возврат каретки

\ooo

восьмеричный код

\t

горизонтальная табуляция

\xhh

шестнадцатиричный код

\v

вертикальная табуляция

 

 


Символьная константа '\0' — это символ с нулевым кодом, так называемый null-символ. Запись '\0' вместо числа 0 используют чтобы подчеркнуть символьную природу выражения, хотя и в том и в другом случае запись обозначает нуль.

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

    #define MAXLINE 1000
    char line[MAXLINE+1];

или

    #define LEAP 1  /* 1 для високосного года */
    int days[31+28+LEAP+31+30+31+30+31+31+30+31+30+31];

Строковая константа, или строковый литерал, — это последовательность символов, заключенных в двойные кавычки, как, например,

    "Я строковая константа"

или

    ""  /* пустая строка */

Кавычки не входят в строку, а служат только ее ограничителями. Также как и в символьные константы, в строки можно включать управляющие последовательности. Например, \" используется для включения в строку символа двойной кавычки. Строковые константы конкатенируются («склеиваются») во время компиляции; например, запись двух строк

    "Здравствуй, " "мир!"

эквивалентна записи одной следующей строки:

    "Здравствуй, мир!"

Указанное свойство позволяет разбивать длинные строки на части и располагать эти части на отдельных строчках исходного кода программы.

Фактически строковая константа — это массив символов. Во внутреннем представлении строки в конце обязательно присутствует нулевой символ '\0', поэтому памяти для строки требуется на один байт больше, чем число символов, расположенных между двойными кавычками. Это означает, что на длину задаваемой строки нет ограничений, но чтобы определить ее длину, требуется просмотреть всю строку. Функция стандартной библиотеки strlen(s) возвращает дину строки s без учета завершающего ее символа '\0'. Ниже приводится наша версия этой функции:

  /* strlen: возвращает длину строки s */
  int srtlen(char s[])
  {
      int i;

      i = 0;
      while (s[i] != '\0')
          ++i;
      return i;
  }

Функция strlen и некоторые другие функции для работы со строками объявлены в стандартном заголовочном файле <string.h>.

Будьте внимательны и помните о различии между символьной константой и строкой, содержащей один символ: 'x' не то же самое, что "x". Запись 'x' означает целое число, равное коду буквы x в наборе символов, используемом в вашей системе, а запись "x" задает массив символов, который содержит два символа — букву x и '\0'.

В Си имеется еще один вид констант — константа перечисления. Перечисление — это список целых констант, например:

    enum boolean { NO, YES };

Если значения констант явно не заданы, то первое имя в перечислении (enum) имеет значение 0, следующее 1, и т.д. Если определены не все значения, то нумерация будет автоматически продолжена от последнего определенного значения. Приведем два примера:

    enum escapes { BELL = '\a', BACKSPACE = '\b', TAB = '\t',
                   NEWLINE = '\n', VTAB = '\v', RETURN = '\r' };

    enum months { JAN = 1, FEB, MAR, APR, MAY, JUN,
                  JUL, AUG, SEP, OCT, NOV, DEC };
                /* FEB равно 2, MAR равно 3 и т.д. */

Имена в перечислении должны отличаться друг от друга и от имен в других перечислениях. Значения, присваиваемые именам в перечислении могут совпадать.

Оператор enum предоставляет удобный способ присваивания имен константам, причем в отличие от #define значения констант могут генерироваться автоматически. Хотя разрешается объявлять переменные типа enum, компилятор не обязан контроллировать,входят ли присваиваемые этим переменным значения в их тип. Но сама возможность такой проверки часто делает enum лучше, чем #define. Кроме того, отладчик получает возможность печатать значения переменных типа enum в символьном виде.


netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz