Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Разработка ПО на языке Си для микроконтроллера AT91SAM7S.pdf
Скачиваний:
120
Добавлен:
18.05.2014
Размер:
838.69 Кб
Скачать

Листинг 1. Пример определения переменных различных типов.

unsigned int a = 5; // Целочисленная (беззнаковая) переменная

short b = -16384; // Короткое целое, эквивалентно short int b = -16384;

//Не проинициализированная переменная (начальное значение не указано) //(значение в общем случае может быть любым)

unsigned char byteValue;

float temperature = 36.6; //Вещественная переменная (одинарной точности)

const unsigned channel = 4; // Целочисленная беззнаковая константа

1.2Оператор sizeof

Как можно заметить, разные типы данных в общем случае занимают разный размер в памяти. Для автоматического определения этого размера «с помощью» компилятора в языке Си определён оператор sizeof, который применяется как к типам, так и к самим переменным этих типов и позволяет узнать размер, который они занимают в памяти (в байтах). Пример его использования приведён в листингах 2 и 8.

Листинг 2. Пример использования оператора sizeof.

// Переменная,

проинициализированная

числом, равным объёму памяти,

который занимает переменная типа int

 

 

const unsigned

char integerSize = sizeof (int);

// = 4

// Переменная, проинициализированная числом, равным объёму памяти, который занимает переменная integerSize

const unsigned int sizeOfByte = sizeof (integerSize); // = 1

1.3Константы

Вязыке Си зарезервировано ключевое слово const, позволяющее создать «переменную», значение которой невозможно изменить после её инициализации (т. е. константу). Инициализация (т. е. присвоение начального значения) константы должна производиться одновременно с созданием переменной, т. к. позже сделать это будет невозможно, а её значение может оказаться случайным. Так, в листинге 1 описана константа channel, равная 4. В

5

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

Использование констант позволяет сделать исходный текст понятнее, защищает программиста от собственных ошибок (невозможно случайно изменить переменную, которая объявлена константой), а также помогает компилятору оптимизировать программный код. Кроме того, константы обычно размещаются в ПЗУ, что позволяет не держать их в ОЗУ.

1.4Определение и описание переменных

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

Определение переменной – это указание имени и типа переменной с

выделением памяти для её хранения.

Описание (объявление) переменной – указание имени и типа переменной, определённой где-то в другом месте. Описание переменной не выделяет память, а лишь сообщает компилятору о том, что где-то определена переменная с конкретным типом и именем.

Описания переменных обычно используются в случаях, когда необходимо сослаться на внешнюю переменную (см. п. 1.5), определённую ниже по тексту в текущем файле, либо вообще в другом исходном файле. Такие описания делаются с использованием ключевого слова extern.

1.5Классы памяти переменных

Взависимости от того, где (в каком месте программы: в функции, или вне неё) и как (с использованием каких ключевых слов) определена (или описана) переменная, она относится к одному из возможных классов памяти.

Классы памяти в Си – это понятие, определяющее как долго хранится переменная в памяти и откуда к ней можно обратиться (см. табл. 4).

В листинге 3 показан пример использования переменных, относящихся к различным классам памяти.

6

Таблица 4. Классы памяти переменных

Класс

памяти

Ключевое

Место

Описание

переменной

слово

определения

 

 

 

 

 

Автоматический

<нет>

внутри

Локальные переменные. Видны только в этой

 

 

 

функции

функции. Уничтожаются при выходе из функции

 

 

 

 

(т. е. не сохраняют значения между вызовами

 

 

 

 

функции).

Статический

static

внутри

Локальные переменные. Видны только в этой

 

 

 

функции

функции. При выходе из функции не

 

 

 

 

уничтожаются. Сохраняют свои значения между

 

 

 

 

вызовами функции.

 

 

static

вне функций

Глобальные переменные. Создаются до входа в

 

 

 

 

функцию main (см. п. 2.2). Существуют всё

 

 

 

 

время выполнения программы. Видны только в

 

 

 

 

том файле, в котором определены.

Внешний

 

<нет>

вне функций

Глобальные переменные. Создаются до входа в

 

 

 

 

функцию main (см. п. 2.2). Существуют всё

 

 

 

 

время выполнения программы. Доступны в

 

 

 

 

файле, в котором определены, ниже определения.

 

 

 

 

Если необходимо сослаться на внешнюю

 

 

 

 

переменную, определённую ниже по тексту в

 

 

 

 

текущем файле, либо в другом файле, то

 

 

 

 

необходимо сделать описание этой переменной с

 

 

 

 

использованием ключевого слова extern.

Листинг 3. Пример работы с переменными, относящимися к различным классам памяти

//Объявление глобальной переменной value (определение идёт ниже).

//Внешний класс памяти.

extern short value;

// Определение функции (подпрограммы) void func (void)

{

//Объявление целочисленной переменной с

//одновременной инициализацией нулём. Автоматический класс памяти. int i = 0;

//Переменная статического класса памяти. Начальное значение = 3. static short staticValue = 3;

//Инкремент. Каждый новый вызов функции func()

//Будет приводить к увеличению значения переменной. ++staticValue;

//Здесь значения staticValue при каждом вызове func() будут равны:

7

//4, 5, 6, ... и т.д.

//Присваивание глобальной переменной нового значения value = 5;

//Присваивание нового значения локальной переменной i = value;

//Инкремент

++i;

// Здесь i всегда будет равно 6

}

//Определение глобальной переменной value. Внешний класс памяти. short value = 10;

//Выполнение программы начинается с функции main

int main (void)

{

// <--

Здесь

значение value пока равно 10

func();

// вызов функции (подпрограммы)

// <--

Здесь

value уже равно 5

func();

//

вызов функции

(подпрограммы)

func();

//

вызов функции

(подпрограммы)

//<-- Отсюда невозможно напрямую обратиться

//к переменной staticValue, определённой внутри функции

//func(), тем не менее эта переменная существует и её

//значение в данной точке выполнения равно 6

}

8