Опубликован: 05.11.2013 | Доступ: свободный | Студентов: 543 / 46 | Длительность: 11:51:00
Лекция 4:

Язык программирования Си

< Лекция 3 || Лекция 4: 123456 || Лекция 5 >
Соглашения об именах

Мы уже говорили, обсуждая программную документацию, что для текстов программ характерно однократное написание и многократное прочтение. Весьма значимым при чтении текста программы является отделение имен одного класса объектов от других. Проще всего для этого ввести некоторые соглашения об именах, например имена типов и констант писать ТОЛЬКО заглавными буквами, начинать определение имени без знаковых типов и буквы U (unsigned), перечислимых типов - с буквы E (enumeric) и тому подобное. Для этих целей можно воспользоваться следующими определениями:

typedef char   CHAR; /* general text. Range 0..127 */
typedef unsigned char UCHAR; /* extended text. Range 0..255 */
typedef unsigned short BOOL; /* Time efficient Boolean */
typedef unsigned har TBOOL; /* Tiny (space efficient) Boolean */
typedef char   TINY; /* 8 bit. Range (-2^7-1)..(+2^7) */
typedef unsigned char UTINY; /* 8 bit. Range (0)..(+2^8) */
typedef unsigned char TINYBITS; /* 8 bit. For bit manipulation use */
typedef short SHORT; /* 16 bit. Range (-2^15-1)..(+2^15) */
typedef unsigned short USHORT; /* 16 bit. Range (0)..(+2^16) */
typedef unsigned short SHORTBITS; /* 16 bit. For bit manipulation use */
typedef long LONG; /* 32 bit.Range (-2^31-1)..(+2^31)*/
typedef unsigned long ULONG; /* 32 bit.Range (0)..(+2^32) */
typedef unsigned long LONGBITS; /* 32 bit.For bit manipulation use */
typedef int INT; /* Natural machine size integer */  
      

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

Типы, определяемые пользователем

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

Перечислимые:

enum - перечисление констант, например:

enum { Yellow=5, Cyan, Magenta};  
      

или, если следовать правилу использования в именах констант только заглавных букв:

enum { YELLOW=5, CYAN, MAGENTA};  
      

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

typedef enum 
{
  START END FLAG    = 0x0001,  /*  Event  Flag  0  * /
  TEST END FLAG    = 0x0002,  /*  Event  Flag  1  * /
  SYS INIT END    = 0x0004,  /*  Event  Flag  2  */
  CODEC CODE DOWNLOADED =  0x0008,  /*  Event  Flag  3  */
  MODEM CODE DOWNLOADED =  0x0010  /*  Event  Flag  4  */
} E_RUN_FLAG;
  
      

Такое определение перечислимого типа позволяет закодировать значения единицы в разрядах с нулевого по четвертый соответственно. Важно только помнить, что константы типа перечисляются ВСЕГДА в порядке возрастания их значений. И при соблюдении ранее указанных правил наименований если вы где-либо в программе встретите строку определения:

E_RUN_FLAG My_Indicator;  
      

то вы легко догадаетесь, что переменная My_Indicator имеет перечислимый тип.

Ключевое слово void определяет отсутствие типа и используется для "нейтрализации" значения, возвращаемого функцией [9].

Сложные типы

В языке Си определены следующие механизмы для задания сложных типов:

  • массивы;
  • структуры;
  • указатели;
  • строки;
  • объединения.
Массивы

Массивы представляют собой однородную последовательность элементов, каждый из которых характеризуется порядковым номером в данной последовательности. Номер элемента указывается вслед за идентификатором последовательности (идентификатором массива) в квадратных скобках: My_Array[i] , Your_Array[5] и т.п. Самый первый элемент массива имеет порядковый номер 0 (нуль).

Объявление массива в программе в простейшем случае может выглядеть так:

int My_Vector[3] ;  
      

где константа 3 указывает, что последовательность, представляемая массивом, содержит три элемента: My_Vector [0], My_Vector [1], My Vector [2].

При этом следует помнить, что упоминание в программе самого идентификатора массива практически эквивалентно указанию адреса его нулевого элемента.

Записи

Записи (или структуры) представляют собой набор полей, объединенных вместе. Можно работать и с каждым полем отдельно, и со всеми полями, как с записью, вместе.

Вот пример задания структуры:

struct goods 
  {
    char * name; 
    long price; 
    int volume;
  };
      

Здесь goods - имя структурного типа. В этом случае объявление переменной food такого типа будет иметь вид:

struct goods food;  
      

Если же объявить структуру как:

typedef struct 
  {
    char * name; 
    long price; 
    int volume;
  } GOODS;
      

то можно будет объявлять переменные, используя только имя типа:

GOODS food;  
      

Язык Си разрешает присваивание структур (в отличие от присваивания массивов, которое может быть выполнено только поэлементным присваиванием).

При объявлении переменной структурного типа можно проинициализировать ее значение при помощи следующей конструкции:

GOODS food = {"milk", 25.6, 1} ;  
      

Для работы с полями в языке используется составное имя с точкой:

food.price = 27.5;  
      
< Лекция 3 || Лекция 4: 123456 || Лекция 5 >