- •Глава 1. Базовые понятия языка
- •1.1 Словарь языка си
- •1.2 Константы и строки
- •1.3 Переменные
- •1.4 Операции
- •1.5 Разделители
- •1.6 Выражения и приведение арифметических типов
- •Глава 2. Введение в программирование на языке си.
- •2.1. Структура и компоненты простой программы
- •2.2. Элементарные средства программирования
- •2.3. Операторы цикла
- •2.4. Массивы и вложение операторов цикла
- •2.5. Переключатели
1.3 Переменные
Каждая переменная перед ее использованием в программе должна быть определена, т.е. для переменной должна быть выделена память. Размер участка памяти, выделяемого для переменной, и интерпретация содержимого зависят от типа, указанного в определении переменной.
В соответствии с типами значений, допустимых в языке Си, рассмотрим символьные, целые и вещественные переменные автоматической памяти. Переменные автоматической памяти существуют в том блоке, где они определены. В наиболее распространенном случае таким блоком является текст основной (main) функции программы.
Простейшая форма определения переменных:
тип список_имен_переменных;
где имена переменных - это выбранные программистом идентификаторы, которые в списке разделяются запятыми;
тип - один из типов.
Определены целочисленные типы:
char - целый длиной не менее 8 бит;
short int- короткий целый (допустима аббревиатура short);
int - целый;
long - длинный целый.
Каждый из целочисленных типов может быть определен либо как знаковый signed либо как беззнаковый unsigned (по умолчанию signed).
Различие между этими двумя типами - в правилах интерпретации старшего бита внутреннего представления. Спецификатор signed требует, чтобы старший бит внутреннего представления воспринимался как знаковый; unsigned означает, что старший бит внутреннего представления входит в код представляемого числового значения, которое считается в этом случае беззнаковым. Выбор знакового или беззнакового представления определяет предельные значения, которые можно представить с помощью описанной переменной. Например, на IBM PC переменная типа unsigned int позволяет представить числа от 0 до 65535, а переменной типа signed int (или просто int) соответствуют значения в диапазоне от -32768 до +32767.
Примеры определений целочисленных переменных:
char symbol, cc;
unsigned char code;
int number, row;
unsigned long long_number;
Обратите внимание на необходимость символа "точка с запятой" в конце каждого определения.
Стандартом языка введены следующие вещественные типы:
float - вещественный одинарной точности;
double - вещественный удвоенной точности;
long double- вещественный максимальной точности.
Значения всех вещественных типов в ЭВМ представляются с "плавающей точкой", т.е. с мантиссой и порядком,
Примеры определений вещественных переменных:
float х, X, ссЗ, pot_8;
double a, Stop, B4;
Инициализация переменных. В соответствии с синтаксисом языка переменные автоматической памяти после определения по умолчанию имеют неопределенные значения. Надеяться на то, что они равны, например, 0, нельзя. Однако переменным можно присваивать начальные значения, явно указывая их в определениях:
тип имя_ переменной=начальное значение;
Этот прием назван инициализацией. В отличие от присваивания, которое, осуществляется в процессе выполнения программы, инициализация выполняется при выделении для переменной участка памяти. Примеры определений с инициализацией:
float pi=3.1415, cc=1.23;
unsigned int. year=1997;
Именованные константы. В языке Си, кроме переменных, могут быть определены константы, имеющие фиксированные названия (имена). В качестве имен констант используются произвольно выбираемые программистом идентификаторы, не совпадающие с ключевыми словами и с другими именами объектов. Традиционно принято, что для обозначений констант выбирают идентификаторы из больших букв латинского алфавита и символов подчеркивания. Такое соглашение позволяет при просмотре большого текста программы на языке Си легко отличать имена переменных от названий констант.
Первая возможность определения именованных констант, это перечисляемые константы, вводимые с использованием служебного слова enum.
Вторую возможность вводить именованные константы обеспечивают определения такого вида:
const тип имя_константы=значение_константы;
Здесь const - квалификатор типа, указывающий, что определяемый объект имеет постоянное значение, т.е. доступен только для чтения;
тип - один из типов объектов;
имя константы -идентификатор;
значение_константы должно соответствовать ее типу. Примеры:
const double Е=2.718282;
const long M=99999999;
const F=765;
В последнем определении тип константы не указан, по умолчанию ей приписывается тип int.
Третью возможность вводить именованные константы обеспечивает препроцессорная директива
#define имя_константы значение константы
Обратите внимание на отсутствие символа "точка с запятой" в конце директивы.
Отличие определения именованной константы
const double Е=2.718282;
от определения препроцессорной константы с таким же значением
#define EULER 2.718282
состоит внешне в том, что в определении константы Е явно задается ее тип, а при препроцессорном определении константы EULER ее тип определяется "внешним видом" значения константы. Например, следующее определение
#define NEXT 'Z'
вводит обозначение NEXT для символьной константы 'Z'. Это соответствует такому определению:
const char NEXT = 'Z';
Однако различия между обычной именованной константой и препроцессорной константой, вводимой директивой #define, гораздо глубже и принципиальнее. До начала компиляции текст программы на языке Си обрабатывается специальным компонентом транслятора - препроцессором. Если в тексте встречается директива
#define EULER 2.718282
а ниже ее в тексте используется имя константы EULER, например, в таком виде:
double mix = EULER;
d = alfa*EULER;
то препроцессор заменит каждое обозначение EULER на ее значение и сформирует такой текст:
double mix = 2.718282;
d = alfa*2.718282;
Далее текст от препроцессора поступает к компилятору, который уже "и не вспомнит" о существовании имени EULER, использованного в препроцессорной директиве #define. Константы, определяемые на препроцессорном уровне с помощью директивы #define, очень часто используются для задания размеров массивов, что будет продемонстрировано позже. Подстановка не выполняется в комментариях и в строковых константах.
Именно с помощью набора именованных препроцессорных констант стандарт языка Си рекомендует авторам компиляторов определять предельные значения всех основных типов данных. Для этого в языке определен набор фиксированных имен, каждое из которых является именем одной из констант, определяющих то или иное предельное значение. Например:
FLT_MAX - максимальное число с плавающей точкой типа float;
CHAR_BIT- количество битов в байте;
INT_МIN - минимальное значение для данных типа int.
Чтобы использовать в программе указанные именованные препроцессорные константы, недостаточно записать их имена в программе. Предварительно в текст программы необходимо включить препроцессорную директиву такого вида:
#include <имя заголовочного _файла>
где в качестве имени заголовочного_файпа подставляются:
limits.h - для данных целых типов;
float.h - для вещественных данных.
#include <limits.h>
#include <float.h>