В этой статье будут рассмотрены типы переменных в языке С (Си) для микроконтроллеров AVR, объявление переменных, способы задания констант, будет дан обзор арифметических операций языка С, присваивания, инкремента и декремента.
Переменные
Переменные в программировании используются для хранения разнообразных данных. Переменной в общем случае называют область памяти, имеющей имя, которое также часто называют идентификатором.
Определяя для переменной имя мы как бы называем этим же именем и область памяти, куда впоследствии в программе будут записываться значения переменной. С целью улучшения читаемости программы желательно использовать осмысленные названия переменных.
В языке С (Си) к именам переменных предъявляются следующие требования:
- можно использовать строчные и прописные буквы, цифры и символ подчёркивания (в С имеет статус буквы);
- первым символом в имени переменной обязательно должна быть буква;
- не допускается использование пробелов в имени переменной;
- длина имени переменной не ограничена;
- имя переменной не должно совпадать с зарезервированными ключевыми словами языка Си;
- заглавные и строчные буквы в именах переменных различаются, к примеру, переменные a и A – это разные переменные.
Список зарезервированных ключевых слов (которые нельзя использовать в качестве имен переменных), приведен на следующем рисунке.
Чтобы начать пользоваться переменной она обязательно должна быть объявлена. Обычно объявления переменных производятся в начале функций (хороший стиль), но также можно производить их объявление в любом месте тела функции.
При объявлении переменной вы обязательно должны указать ее тип. В зависимости от типа переменной компилятор резервирует ей место в памяти. Наиболее часто используемыми типами данных в языке Си для микроконтроллеров AVR являются char (символьный тип) и int (целочисленный тип).
Типы переменных
Тип char
Символьный тип (char) является самым экономным типом данных в языке С поскольку использует всего один байт (8 бит) в памяти (микроконтроллера). Может быть знаковым (обозначается как "signed char") и беззнаковым ("unsigned char"). Соответственно, в переменной char знакового типа можно хранить значения в диапазоне от -128 до +127, а в переменной беззнакового типа - от 0 до 255.
Фактически, ключевые слова (модификаторы) signed и unsigned в начале объявления типа char интерпретируется как нулевой бит объявляемой переменной. Если unsigned, то все 8 бит интерпретируются как число, поэтому максимальное значение переменной в этом случае составляет 2^8-1=255. Если тип signed, то в этом случае нулевой бит отводится под хранение знака числа (+ (не отображается) или -), соответственно под хранение значения переменной остается всего 7 бит, что соответствует максимальному хранимому значению 127 (128).
Тип int
Переменная целого типа int может быть short (короткой) или long (длинной). При этом модификаторы short и long ставятся после ключевых слов signed или unsigned, поэтому получаем такие типы данных как signed short int, unsigned short int, signed long int, unsigned long int.
Если используется модификатор short, то под хранение переменной целого типа с таким модификатором отводится 2 байта (16 бит). Соответственно, для unsigned short int получаем диапазон хранимых значений от 0 до 65535, а для signed short int - от -32768 до +32767.
При объявлении переменной типа signed short int ключевые слова signed и short можно опускать, поэтому чаще всего при объявлении подобных переменных просто пишут слово int. Вместо int также можно писать просто short, но этим мало кто пользуется, большинство программистов привыкли именно к int.
Переменная типа long int (знаковая (signed) или беззнаковая (unsigned) занимает уже 4 байта (32 бита) в памяти, поэтому диапазоны значений переменных для этих типов будут составлять, соответственно, от -2147483648 до 2147483647 и от 0 до 4294967295.
В языке С существуют еще переменные типа long long int, для хранения которых выделяется 8 байт памяти (64 бита), но вряд ли когда-нибудь в программах для микроконтроллеров у вас возникнет необходимость в использовании столь больших чисел.
Таблица со всеми возможными целыми типами языка С и их параметрами приведена на следующем рисунке.
Объявление переменных
Переменные в языке С объявляют в операторе описания. Оператор описания состоит из спецификации типа и списка имён переменных, разделённых запятой. В конце обязательно ставится точка с запятой.
Объявление переменной имеет следующий формат:
[модификаторы] спецификатор_типа идентификатор [, идентификатор] ...
Модификаторы - ключевые слова signed, unsigned, short, long.
Спецификатор типа - ключевое слово char или int, определяющее тип объявляемой переменной.
Идентификатор - имя переменной.
Примеры объявления переменных:
char s;
int x, y, z;
unsigned long long t;
Инициализация значения переменной при объявлении
Язык С в отличие от многих других языков программирования позволяет при объявлении переменной сразу ее проинициализировать, то есть присвоить ей начальное значение, что, конечно же, удобно для экономии кода программы. Выглядит это, к примеру, следующим образом:
int a = 100;
С помощью данной записи мы объявляем переменную a целого типа и сразу же в нее записываем число 100.
При этом желательно для улучшения читабельности программы не смешивать инициализируемые переменные и просто объявляемые в одной строке.
Константы
В языке С переменную любого типа можно объявить как немодифицируемую, то есть значение которой в дальнейшем невозможно будет изменить – фактически получаем переменную, доступную только для чтения. Сделать это можно с помощью добавления ключевого слова const к спецификатору типа. При этом полный список модификаторов для констант можно не указывать – нужный для них тип определяется исходя из их значения. К примеру:
const long int z = 25;
const x = -50; // подразумевается const int x=-50
const y = 100000; // подразумевается const long int y=100000
Присваивание
Для присваивания в языке С служит знак "=" – не путать со знаком сравнения двух чисел. При использовании данного знака производится вычисление выражение, стоящего справа от знака присваивания, и полученное значение присваивается переменной, стоящей слева от знака присваивания. При этом старое значение переменной стирается и заменяется на новое.
Примеры:
y = 6 + 8; // сложить значения 6 и 8,
// результат присвоить переменной y (записать в переменную y)
c = b + 5; // прибавить 5 к значению, хранящемуся в переменной b,
// полученный результат присвоить переменной c (записать в переменную c)
d = d + 2; // прибавить 2 к значению, хранящемуся в переменной d,
// полученный результат присвоить переменной d (записать в переменную d)
В правой части значение переменной может быть использовано несколько раз, например:
z = x * x + 5 * x;
Арифметические операции
Арифметические операции языка Си представлены в таблице на следующем рисунке.
Примеры:
z = y + 7; // к значению, хранящемуся в переменной y, будет прибавлено число 7,
// полученный результат будет записан в переменную z
k = m * n; // значения переменных m и n будут перемножены,
// результат будет записан в переменную k
t = t - 1; // от значения, хранящегося в переменной t, будет отнято 1
// результат будет записан в переменную t
Дополнительные способы присваивания
Кроме простого оператора присваивания "=", в языке программирования С существует еще несколько комбинированных операторов присваивания: "+=", "-=", "*=<", "/=", "%=". Рассмотрим типичные примеры их использования.
m += n; // то же, что и m = m + n; - сложить m и n
// и поместить результат в переменную m
m -= n; // то же, что и m = m - n; - отнять от m значение n
// и поместить результат в переменную m
m *= n; // то же, что и m = m * n; - умножить m на n
// и поместить результат в переменную m
m /= n; // то же, что и m = m / n; - разделить m на n
// и поместить результат в переменную m
m %= n; // то же, что и m = m % n;
// вычислить целочисленный остаток от деления m на n
// и поместить результат в переменную m
Инкремент и декремент
В тех случаях, когда необходимо изменить значение переменной на 1, вместо стандартных арифметических операций сложения и вычитания часто применяют такие операции как инкремент или декремент – для них в языке С существует удобная и интуитивно понятная форма записи..
Инкремент – операция увеличения значения переменной на 1.
Пример использования:
z++; // значение переменной z будет увеличено на 1
Декремент - операция уменьшения значения переменной на 1.
Пример использования:
z- -; // значение переменной z будет уменьшено на 1
Есть две формы записи этих операций: постфиксная (x++) и префиксная (++x). Если эти операции выполняются совместно с операцией присваивания "=", то первой выполняется префиксная запись.
Примеры:
m = n++;
Допустим, что значение переменной n было равно 7. Тогда в m будет записано значение 7, после чего значение переменной n будет увеличено на 1. Таким образом, в m будет 7, а в n - 8.
m =- -n;
Если значение n было равно 3, то сначала будет выполнено уменьшение n до 2, а затем это значение будет присвоено переменной m. Таким образом, n и m будет присвоено значение 2.
В Вашем примере:
c = b + 5; // прибавить 5 к значению, хранящемуся в переменной b,
// полученный результат присвоить переменной c (записать в переменную b)-
наверное опечатка - полученный результат записать, наверное, все-таки в с, или я не прав?
Да, спасибо. Исправил опечатку
Уважаемый Admin, пытаюсь учится программированию AVR процессоров на языке Си в CvAvr.Не могу понять, почему не правильно работает простейшая программа.
volatile int k=0;
volatile signed int dif=0;
volatile signed int a=0;
volatile signed int b=0;
dif=(a-b)
Ожидаю получить при b>a отрицательный dif, но эта в-на всегда положительна. Пытался подставлять тип signed в выражение, но то же не помогло.
Что я делаю не так?
Добрый вечер, попробуйте использовать полное название типа - signed short int или signed long int, или просто int, без signed. Также попробуйте убрать volatile - для Ардуино эта приставка часто используется, а вот в программах для микроконтроллеров AVR что то особо не припомню ее, не уверен что она будет корректно обрабатываться во всех средах.
Добрый день.
Извините, что напрасно отнял у Вас время. Нашёл свою ошибку. Ограничил величину dif=(a-b) снизу 0.
Поэтому она ниже не шла.
С уважением. Валерий.
Добрый вечер. Да ничего страшного, будем надеяться на ваши дальнейшие успехи в изучении микроконтроллеров