|
|
|
| |
Главная Программирование С++ Присваивание значений переменным
Присваивание значений переменным |
Давайте ненадолго вернемся к анализатору выражений. Когда обнаружен оператор присваивания, вычисляется значение части выражения, расположенной справа от знака присваивания, и оно присваивается переменной, находящейся слева от этого знака с помощью функции assign_var(). Однако язык С++ поддерживает разные области видимости, включая глобальную (формально называемую областью видимости пространства имен (namespace scope)) и локальную. Кроме того, локальные области видимости могут быть вложенными. Это важно, так как влияет на способ поиска интерпретатором Mini С++ значений переменных. Для того чтобы понять почему, рассмотрим следующий пример, int count; int main() , { int count, i: count = 100; i = f(); return 0; } int f() { int count; count = 99; return count; } Когда переменной count присваивается значение, как функция assign_var() узнает, на какую переменную ссылка? Имеется в виду глобальная переменная count или одна из локальных переменных count? Ответ прост. В языке С++ локальные переменные обладают большим приоритетом по сравнению с глобальными переменными с тем же именем. Кроме того, локальные переменные не известны за пределами их собственного блока. Для того чтобы понять, как эти правила можно использовать для выполнения присваиваний в только что приведенном примере, рассмотрим ФУНКЦИЮ assign_var (). // Присваивает значение переменной. void assign_var(char *vname, int value) { // Сначала проверяет, не локальная ли это переменная, if(!local_var_stack.empty()) for(int i=local_var_stack.size()-1; i >= func_call_stack.top(); i—) { if(!strcmp(local_var_stack[i].var_name, vname)) % { if(local_var_stack[i].v_type == CHAR) local_var_scack[i].value = (char) else if(local_var_stack[i].v_type == INT) local_var_stack[i].value = value; return; ) } // В противном случае проверяет глобальные переменные, for(unsigned i=0; i < global_vars.size(); i++) if(!strcmp(global_vars[i].var_name, vname)) { if(global_vars[i].v_type == CHAR) global_vars[i].value = (char) value; else if(global_vars[i].v_type == INT) global_vars[i].value = value; return; } throw InterpExc(NOT_VAR); // переменная не найдена } Как уже объяснялось в предыдущем разделе, каждый раз, когда вызывается функция, текущее значение индекса вершины стека локальных переменных (local_var_stack) записывается В стек ВЫЗОВа функций (func_call_stack). Это значит, что любые локальные переменные, определенные в функции, будут помещены в стек над этой точкой. Следовательно, функция assign_var() сначала просматривает стек локальных переменных, начиная от текущего значения вершины и заканчивая значением индекса, сохраненным при последнем вызове функции. Этот механизм гарантирует, что проверяются только локальные переменные функции (он также помогает выполнять рекурсивные функции, поскольку текущее значение вершины стека сохраняется при каждом вызове функции). Следовательно, строка примера count = 100; в функции maino приведет к вызову функции assign_var() для поиска локальной переменной count внутри функции main (). В функции f () оператор count = 99; вызовет функцию assign_var () для поиска переменной count, объявленной в функции f (). Если нет локальной переменной с соответствующим именем, то просматривается список глобальных переменных. Если ни в списке локальных, ни в списке глобальных переменных нет переменной с заданным именем, возникает синтаксическая ошибка. ' Теперь рассмотрим приведенный далее пример объявления переменной во вложенной области видимости, int f() { int count; count = 99; if(n > 0) { int count; // эта переменная count локальная для оператора if count =100 // относится к переменной count в блоке if // } return count; // относится к внешней переменной count } В этом случае внешняя переменная count (объявленная в начальных строках кода функции) помещается в стек local_var_stack первой. Далее в этот же стек попадает переменная count, локальная для блока в операторе if. Таким образом, когда выполняется следующая строка: count = 100 // относится к переменной count в блоке if функция assign_var() ищет переменную count и находит первой, как и должна, ее копию, локально описанную в блоке if. Последнее замечание: в функции interp о при каждом выходе из блока стек local_var_stack укорачивается до размера, который был у него до входа в блок. Этот технический прием позволяет эффективно удалять из стека все переменные, описанные внутри данного блока. Стек iocai_var_stack также укорачивается при каждом возврате из функции, удаляя все переменные и параметры, связанные с этой функцией.
|
Opera Mini для мобильного телефона опера мини русская версия., кредит наличными в кемерово
|
|
|
|