Если переменная определяется в том же самом операторе, то спецификатор extern игнорируется.




Правила преобразования типов

В первую очередь происходит преобразование операндов, принадлежащих к типам char, unsigned char или short, к целочисленному типу данных int.

  • char расширяется либо с помощью 0, либо знаком в зависимости от правил «по умолчанию» для этого типа данных;
  • unsigned char расширяется с помощью 0;
  • signed char расширяется с помощью знака;

Стоит отметить, что short, unsigned short или enum при выполнении операции преобразования типов не меняются.

Затем любые два операнда становятся либо int, либо float, double или long double.

Существуют следующие правила преобразования типов:

    1. если один из операндов имеет тип long double, то другой преобразуется к типу long double;
    2. если один из операндов имеет double, то другой преобразуется к типу double;
    3. если один из операндов имеет тип float, то другой преобразуется к типу float;
    4. если один из операндов имеет типunsigned long, то другой преобразуется к типу unsigned long;
    5. если один из операндов имеет тип long, то другой преобразуется к типу long;
    6. если один из операндов имеет тип unsigned, то другой преобразуется к типу unsigned.

В ином случае оба операнда должны иметь тип int.

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

Область действия, область видимости и время жизни идентификаторов

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

Таким образом, класс памяти и область действия зависят не только от объявления, но ещё и от места его размещения в листинге. Иными словами, объявление переменной всегда, кроме типа и класса памяти, явным образом задаёт область её действия.

В C определено две области действия переменной: локальная и глобальная. Если переменная имеет локальную область действияэто значит, что она определена внутри блока и область её действия ограничена точкой объявления и концом блока, включая все уровни вложенности. Если же переменная имеет глобальную область действия, то это значит, что переменная объявлена вне какого-либо блока и область её действия ограничена точкой объявления и концом файла.

Под областью видимости идентификатора понимается часть текста программы, из которой допустим обычный доступ к связанной с идентификатором областью памяти. Как правило, область видимости совпадает с областью действия, за исключением ситуации, в которой во вложенном блоке объявлена переменная, имеющая такой же идентификатор. В таком случае внешняя относительно этого блока переменная является невидимой внутри такого блока, несмотря на то, что этот блок входит в её область действия. Даже в таком случае, у программиста существует возможность обращения к этой переменной: если она глобальная, то к ней можно обратиться используя операцию доступа к области видимости «::».

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

Классы памяти

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

Существует 4 класса памяти:

1. автоматический;

2. внешний;

3. статический;

4. регистровый.

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

Для глобальных переменных этот спецификатор не используется, так как они не привязаны к какому-то конкретному блоку, а для локальных переменных устанавливать его в явном виде большого смысла не имеет.

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

Если переменная определяется в том же самом операторе, то спецификатор extern игнорируется.

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

Модификатор static может быть применён и к глобальным переменным, однако такие переменные будут видны только в том модуле, в котором они описаны. Иными словами, глобальная переменная будет иметь внутреннюю привязку и будет видна исключительно в том файле, в котором она объявлена. Из другого файла к static global variable обратиться нельзя.

Спецификатор четвёртого класса памяти, при его использовании, указывает на то, что компилятор, по возможности, должен разместить её в регистре, а не в основной памяти. В том случае, если компилятор не может разметить переменную в регистре, он привязывает её к классу auto. Условия, которые необходимы для того чтобы компилятор мог сделать переменную регистровой основываются на том, что регистры должны быть не заняты и, по мнению компилятора, это не должно привести к увеличению издержек.

К регистровым переменным не применима функция взятия адреса, так как они не имеют фактического адреса основной памяти. В результате это приведёт к ошибке компиляции.

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



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2020-06-05 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: