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

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

< Лекция 3 || Лекция 4: 123456 || Лекция 5 >
Указатели

Указатели в языке Си объявляются при помощи символа "*":

int * pInt;  
      

Здесь переменная pInt - это указатель на int или, проще, адрес переменной целого типа. Доступ к значению, хранящемуся по адресу указателя, производится через разыменование:

*pInt=6;  
      

Забавно, что если написать обе строки (объявление указателя и присваивание) подряд, то получится синтаксически правильный фрагмент, но по смыслу он ошибочен. Объявлением указателя мы выделили память под сам указатель, т.е. под адрес некоторого объекта. Однако память под сам объект не выделена, и поэтому записывать значение 6 некуда.

При помощи оператора "&" можно получить адрес уже существующей переменной. Следующий пример демонстрирует, как можно установить указатель pint на переменную varlnt типа int:

int * pint; 
int varint; 
pint = &varInt;  
      

После этого уже можно выполнять присваивание *plnt=6;. Теперь значение 6 попадет в память переменной varint.

Указатель, "не указывающий никуда", в языке Си называется Null. Это единственная неарифметическая константа. Иногда она представлена как NULL.

Сами по себе указатели не являются сложными типами с точки зрения обращения к ним. Их значением является адрес некоторого программного объекта. Как правило, они указывают на некоторый тип, который в свою очередь уже может иметь сложную составную структуру. Специфика работы с указателями заключается в том, что, например, префиксная или постфиксная операция ++ будет изменять значение указателя на 1, 2, 4 или некоторую другую величину в зависимости от длины (количеств байт, отведенных для представления) того типа, на который указывает этот указатель.

Еще одной и наиболее важной проблемой указателей является несогласованность времени жизни указателя (адреса объекта) и программного объекта, на который он указывает.

Например, функция сохраняет адрес некоторой своей локальной переменной в глобальном указателе. По выходу из функции памяти объекта уже нет. Она может быть перераспределена каким угодно образом, а адрес, где "все это" лежало до сих пор, существует и может быть использован для обращения.

Ошибки подобного рода очень трудно обнаружить, поскольку до некоторого времени поведение программы с дефектами такого вида может быть весьма правдоподобным. Это происходит до тех пор, пока "отданная" память никем не переопределялась, а потом такая программа "вдруг" перестает работать.

Строки

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

Задать значение массиву символов простым присваиванием нельзя, необходимо пользоваться инициализацией, функциями ввода данных или функциями копирования. В разделе 3.5 рассмотрен пример подобной функции My_Strcpy. Следует помнить, что строковые константы в Си выделяются в двойных апострофах, а символьные, занимающие один байт, - в одиночных.

Объединения

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

Пример определения типа объединения:

union Big Word
{
  long Bg long; 
  char *Bg chart [4] ;
}
      

А переменная X_Var такого типа определяется следующим образом:

union Dig Word X_Var;  
      

Данные типа union Big_Word занимают память, необходимую для размещения наибольшего из своих элементов, и могут рассматриваться как аналог вариантной записи в языке Паскаль.

Константы

Константы в языке Си могут иметь одинаковые значения при различных формах своего представления. В особенности это относится к числовым значениям.

10, 012 и 0xA в языке Си будут соответствовать одному и тому же значению 10 или в двоичной форме 1010. Просто числовые константы, начинающиеся с цифры 0, считаются в Си заданными в восьмеричной форме представления, а с префиксом 0х - шестнадцатеричными.

Вещественные числа также можно записывать в различных формах 12.5, 1.2e1, 125e-1, где символ "е" или "Е" используется для отделения мантиссы числа от порядка. Предполагается, что вещественная константа всегда положительна, а предшествующий ей знак "минус", если указан, рассматривается как унарная операция смены знака.

Еще следует обратить внимание на символьные константы. Они записываются в одиночных кавычках: 'A', 'a', ' + ', '-' и т.п. В случае необходимости можно определить символ его кодом в таблице '\12' или '\xA', задавая после обратной наклонной черты номер символа в восьмеричной или шестнадцатеричной системе.

Ранее говорилось, что следует различать символы и строки символов, которые задаются двойными кавычками. Так, константе "A" будет соответствовать строка из двух символов: собственно 'A' и '\0', т.е. к байту символа будет добавлен второй байт с нулевым значением для представления признака конца строки.

< Лекция 3 || Лекция 4: 123456 || Лекция 5 >