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

Опр. Инициализация – это определение переменной, совмещенное с присваиванием ей конкретного значения.

Опр. Определение переменной – это объявление, совмещенное с выделением памяти для размещения значений переменной.

Опр. Объявление переменной – это информация об имени и типе переменной, которая используется компилятором при синтаксическом анализе выражений программы.

Опр. Описание переменной – это либо объявление, либо определение, либо инициализация.

Замечания:

Переменная может быть использована в программе только после ее определения или инициализации.

В программах С/С++ допускается произвольное число объявлений переменной, но только одно ее определение. Именованные константы описываются только в форме инициализации. Обобщенная синтаксическая форма описания переменной в программе имеет вид:

[Спецификатор][Квалификатор]Тип список_переменных;

Где тип – один из допустимых типов данных. Квалификаторы – это const и volatile – cv-qualifiers, спецификаторы – это спецификаторы хранения extern, static, register, auto, список_переменных – это список из допустимых идентификаторов, разделенный запятыми, возможно с начальными значениями переменных и обязательно для констант.

Синтаксис определения начальных значений имеет две формы:

1-я форма: идентификатор = начальное_значение;

2-я форма: идентификатор (начальное_значение);

Примеры объявление переменных:

extern int a;

volatile extern long double b;

Примеры определений целочисленных переменных:

char symbol, cc;

extern int a =1;

unsigned char code;

int number, row;

unsigned lоng long_number;

Примеры определений вещественных переменных:

float x, X, cc3, pot_8;

double e, Stop, B4;

Примеры инициализации:

static int I;// По умолчанию = 0;

extern static int j;// По умолчанию = 0;

const volatile char* port = (const volatile char*) 0x30;

const int A(1); // <==> const int A = 1;

Все приведенные примеры являются примерами описания переменных в программе.

1.4.3 Область действия, область видимости, время жизни
переменных

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

По области действия различают локальные и глобальные переменные.

Локальность переменной зависит от места ее определения:

- если переменная определена вне всех блоков программы она будет ГЛОБАЛЬНОЙ, причем область действия будет от точки объявления переменной до конца программы, включая все блоки с их вложениями;

- если переменная определена в блоке, то она будет ЛОКАЛЬНОЙ, причем область ее действия будет от точки объявления переменной до конца блока, включая вложенные блоки.

Время жизни глобальной переменной – время работы программы, время жизни локальной переменной – время активности блока ее определения.

Область действия совпадает с областью видимости, за исключением случая, когда определяется локальная переменная с таким же именем. Говорят, что она маскирует глобальную переменную, исключая блок из области видимости глобальной переменной. Замечание имеет силу и для локальных переменных вложенных блоков, которые тоже могут маскировать переменные внешних блоков.

1.4.4 Статические глобальные и локальные переменные

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

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

Пример1.

int a;

int main()

{

int b;

static int c;

{

int a;

{

a=1; // вложенный блок – видна локальная переменная

}

}

// видна глобальная переменная

return 0;

}

Пример 2.

#include <stdio.h>

int main()

{

extern int a,b; // Глобальные переменные – объявление

printf(“%d %d”, a,b);

return 0;

}

int a=10, b=20; // Глобальные переменные – определение

1.4.5 Спецификатор extern. Внешние переменные

Спецификатор extern играет важную роль в программах, состоящих из нескольких файлов. Программу можно разделить на несколько файлов, выполнить их раздельную компиляцию, а затем отредактировать связи между ними. Для этого нужно сообщить всем файлам программы о глобальных переменных. Лучше всего определить все глобальные переменные в одном файле, а в других объявить их с помощью спецификатора extern. На практике объявление внешних переменных хранят в заголовочных файлах, которые подключаются ко всем файлам программы.

Пример 1:

Первый файл – file1.cpp

int x,y;

void main(void)

{

}

void func1(void)

{

x=1;

}

Второй файл – file2.cpp

extern int x,y;

void func2(void)

{

x=y/2;

}

Пример 2:

Заголовочный файл объявления глобальных переменных myglobal.h:

extern int x,y;

Первый файл – file1.cpp

#include “myglobal.h” // Не обязательно

int x,y;

void main(void)

{

}

void func1(void)

{

x=1;

}

Второй файл – file2.cpp

#include “myglobal.h” // Обязательно

void func2(void)

{

x=y/2;

}

Ø Предельные значения типов С.

Предельные значения констант (и соответствующих переменных) разработчики компиляторов вправе выбирать самостоятельно исходя из аппаратных возможностей компьютера. Однако при такой свободе выбора стандарт языка требует, чтобы для значений типа short и int было отведено не менее 16 бит, для lоng - не менее 32 бит. При этом размер lоng должен быть не менее размера int, а int – не менее short. Предельные значения арифметических констант и переменных для большинства компиляторов, реализованных на IBM PC, приведены в таблице

тип данных размер, бит диапазон значений
unsigned char   0.,.255
char   -128... 127
enum   -32768,., 32767
unsigned int   0 - 65535
short int (short)   -32768...32767
uпsigned short   0,., 65535
int   -32768,., 32767
unsigned lоng   0... 4294967295
lоng   -2147483648... 2147483647
float   3.4E-38,., 3.4E+38
double   1.7Е-308... 1.7E+308
long double   3.4E-4932,., 1.1E+4932

Ø Именованные константы

В языке Cи, кроме переменных, могут быть определены константы, имеющие фиксированные названия (имена). В качестве имен констант используются произвольно выбираемые программистом идентификаторы, не совпадающие с ключевыми словами и с другими именами объектов. Традиционно принято, что для обозначений констант выбирают идентификаторы из прописных букв латинского алфавита и символов подчеркивания.

Первая возможность определения именованных констант - это перечисляемые константы, вводимые с использованием служебного слова enum.

Вторую возможность вводить именованные константы обеспечивают определения такого вида:

const mun uмя_кoнcmcmmы=знaчeнue_кoнcmaнmы;

Примеры:

cоnst double E=2.718282;

cоnst lоng M=99999999;

cоnst F=765;

В последнем определении тип константы не указан, по умолчанию ей приписывается тип int.

Третью возможность вводить именованные константы обеспечивает препроцессорная директива

#define имя_константы значение_константы

Обратите внимание на отсутствие символа "точка с запятой" в конце директивы. В конкретные реализации компиляторов с помощью директив #define включают целый набор именованных констант с фиксированными именами.

Отличие определения именованной константы

cоnst double E=2.718282;

от определения препроцессорной константы с таким же значением:

#define EULER 2.718282 состоит внешне в том, что в определении константы E явно задается ее тип, а при препроцессорном определении константы EULER ее тип определяется "внешним видом" значения константы. Например, следующее определение

#define NEXT 'Z'

вводит обозначение NEXT для символьной константы 'Z'. Это соответствует такому определению:

const char NEXT = 'Z';

Однако различия между обычной именованной константой и препроцессорной константой, вводимой директивой #define, гораздо глубже и принципиальнее. До начала компиляции текст программы на языке Cи обрабатывается специальным компонентом транслятора – препроцессором. если в тексте встречается директива

#define EULER 2.718282

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

double mix = EULER;

d = alfa*EULER;

то препроцессор заменит каждое обозначение EULER на ее значение и сформирует такой текст:

double шix = 2.718282;

d = alfa*2.718282;

Далее текст от препроцессора поступает к компилятору. Константы, определяемые на препроцессорном уровне с помощью директивы #define, очень часто используются для задания размеров массивов.

Итак, основное отличие констант, определяемых препроцессорными директивами #define, состоит в том, что эти константы вводятся в текст программы до этапа ее компиляции. Специальный компонент транслятора - препроцессор обрабатывает исходный текст программы, подготовленный программистом, и делает в этом тексте замены и подстановки.

1.5 Принципы работы препроцессора.

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

Подстановка не выполняется в комментариях и в строковых литералах.

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

FLT__MAX - максимальное число с плавающей точкой типа float;

CHAR_BIT - количество битов в байте;

INT_MIN - минимальное значение для данных типа int.

Чтобы использовать в программе указанные именованные препроцессорные константы, недостаточно записать их имена в программе. Предварительно в текст программы необходимо включить препроцессорную директиву такого вида:

#include <имя_заголовочного_файла> где в качестве имени_заголовочного_файла подставляются:

limits.h - для данных целых типов;

float.h - для вещественных данных.

В заголовочный файл limits.h помещаются, например, такие определения констант:

#define CHAR_BIT 8

#define SHRT_MAX Ox7FFF

#define LОNG MAX Ox7FFFFFFFL

В заголовочном файле float.h находятся директивы, определяющие константы, связанные с представлением данных вещественных типов. Например:

#define FLT_MIN 1.17549435E-38F

#define DBL_MIN 2.2250738585072014E-308

#define DBL_EPSILОN 2.2204460492503131E-16

Итак, записав в тексте своей программы директиву

#include <limits.h>

можно использовать в программе стандартные именованные константы CHAR_BIT, SHRT_MIN и т.д.

Если включить в программу директиву

#include <float.h>

то станут доступными именованные константы предельных значений числовых данных вещественных типов.

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

1.6 Операторы

В этом параграфе определяются все операторы языка Си и приводится таблица их приоритетов.

1.6.1 Знаки операторов

Для формирования и последующего вычисления выражений используются операторы. Для изображения операторов в большинстве случаев используется несколько символов. В табл. 1.4 приведены все знаки операторов, определенные стандартом языка. Операторы в таблице разбиты на группы в соответствии с их рангами.

За исключением операторов «[]», «()» и «?:», все знаки операторов распознаются компилятором как отдельные лексемы. В зависимости от контекста одна и та же лексема может обозначать разные операторы, т.е. один и тот же знак операторы может употребляться в различных выражениях и по-разному интерпретироваться в зависимости от контекста. Например, бинарный оператор & - это поразрядная конъюнкция, а унарный оператор & -это оператор получения адреса.

Операторы ранга 1 имеют наивысший приоритет. Операторы одного ранга имеют одинаковый приоритет. Если в выражении несколько операторов, то они выполняются в соответствии с правилом ассоциативности, либо слева направо (->), либо справа налево (<-). Если один и тот же знак оператор приведен в таблице дважды (например, знак *), то первое появление (с меньшим по номеру, т.е. старшим по приоритету, рангом) соответствует унарной операторы, а второе – бинарной.

Таблица 1.4

Ранг Операторы Ассоциативность
  () [ ] ->. ->
  ! ~ + - ++ -- & * (тип) sizeof <-
  * / % (мультипликативные бинарные) ->
  + - (аддитивные бинарные) ->
  << >> (поразрядного сдвига) - >
  < <= >= > (отношения) ->
  ==!= (отношения) ->
  & (поразрядная конъюнкция "И") ->
  ^ (поразрядное исключающее "ИЛИ") ->
  | (поразрядная дизъюнкция "ИЛИ") ->
  && (конъюнкция "И") ->
  || (дизъюнкция "ИЛИ") ->
  ?: (условный оператор) <-
  = *= /= %= += -= &= ^= |= <<= >>= <-
  , (оператор "запятая") ->

Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: