Мегаобучалка Главная | О нас | Обратная связь


Область видимости идентификаторов



2019-11-13 424 Обсуждений (0)
Область видимости идентификаторов 0.00 из 5.00 0 оценок




Дорога в ад программирования вымощена глобальными переменными

С. Макконелл, «Совершенный код»

Понятие области видимости переменной

Областью видимости идентификатора (переменной) называется область программы, в которой на данный идентификатор можно сослаться.

Существуют четыре области видимости идентификатора: область видимости — функция, область видимости — файл, область видимости — блок, и область видимости — прототип функции.

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

Переменные, объявленные вне функции называются глобальными переменными.

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

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

Переменные, объявленные в описаниях функций, имеют областью видимости блок так же, как и параметры функции, и являются локальными переменными. Любой блок может содержать объявления переменных. Если блоки вложены и идентификатор во внешнем блоке имеет такое же имя, как идентификатор во внутреннем блоке, идентификатор внешнего блока «невидим» (скрыт) до момента завершения работы внутреннего блока. Это означает, что пока выполняется внутренний блок, он видит значение своих собственных локальных идентификаторов, а не значения идентификаторов с идентичными именами в охватывающем блоке.

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

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

#include<iostream>

using namespace std;

void a(void); // прототип функции

void b(void);   // прототип функции

void c(void);   // прототип функции

 

int x = 1;     // глобальная переменная

 

void main(void) {

cout << "Глобальная х в main = " << x << '\n';

int x = 3;

cout << "Локальная х в main = " << x << '\n';

{ // начало новой области действия

int x = 5;

cout << "Локальная х в блоке main = " << x << '\n';

} // конец новой области действия

 

a(); /* вызов функции а(); а() имеет локальную переменную х */

b(); /* вызов функции b(); b() исп-ет глобальную переменную х */

c(); /* вызов функции c(); c() использует глобальную переменную х

       и имеет локальную переменную х */

cout << "Локальная х в main = " << x << '\n';

}

 

void a(void){

int x = 10;

cout << "Функция a() локальная переменная х = " << x << '\n';

}

void b(void){

x++;

cout << "Функция b() глобальная переменная х = " << x<< '\n';

}

void c(void){

x *= 3;

cout << "Функция c() глобальная переменная х = " << x << '\n';

int x = 1000;

cout << "Функция c() локальная переменная х = " << x << '\n';

}

 

Программа выведет при запуске:

 

Глобальная х в main = 1

Локальная х в main = 3

Локальная х в блоке main = 5

Функция a() локальная переменная х = 10

Функция b() глобальная переменная х = 2

Функция c() глобальная переменная х = 6

Функция c() локальная переменная х = 1000

Локальная х в main = 3

 

Схематически это можно представить так:

  глобальная область видимости  
main( ) a( ) b( ) c( )

 

Параметры функций

Как было ранее сказано, функции могут использовать формальные параметры. Например, функция stairs, рисующая «ступеньки» из символов *, использует формальный параметр h.

void stairs (int h){

while(h--){

     for(int i = 0; i < h; i++) cout <<'*';

     cout << '\n';

}

}

Если мы вызовем эту функцию следующим образом:

int a = 3;

stairs (a);

cout << a;

то программа, естественно, нарисует «лесенку» из «звездочек», но что станет со значением переменной a? При выполнении третьей строки кода будет выведено число 3, т.е. aпосле инициализации не изменилось. Это происходит потому, что в функцию с помощью формального параметра передали только значение переменной. Т.е. используя псевдонимhмы работаем с копией переменной.

Так, если нам необходимо при передаче двух параметров сделать, чтобы первая переменная уменьшалась на 1, а вторая увеличивалась в 8 раз, то следующая функция, несмотря на кажущуюся простоту, не сработает:

void something(int x, int y) {

x--;

y <<= 3; // умножение на 8 реализовали через побитовый сдвиг

           // влево на 3 разряда

}

Так, при вызове:

int a = 5, b = 14;

something( a, b);

cout << "a = " << a << " b = " << b;

будет видно, что a и b не изменились. Для корректной работы функции необходимо передавать в неё адрес переменной. С операцией взятия адреса мы познакомились в главе, посвященной указателям.

void something(int& x, int& y) {     // теперь правильно

x--;

y <<= 3;

}

Задача №168.  Числа без одинаковых цифр (acmp.ru)

(Время: 1 сек. Память: 16 Мб)

Антон записал ряд натуральных чисел в порядке возрастания: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 и т.д. Затем вычеркнул из него все числа, в которых имеется хотя бы две одинаковых цифры, и получил последовательность: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23 и т.д.

Вам необходимо по заданному N найти N-ое по счету число в получившейся последовательности.

Входные данные

В единственной строке записано натуральное число N (1 ≤ N ≤ 10000).

Выходные данные

В единственную строку нужно вывести N-ое по счету число без одинаковых цифр.

Пример

Ввод Вывод
100 123

Решение

Используем функцию p, которая будет определять, имеются ли в записи числа r одинаковые цифры (true если нет и число входит в последовательность, false в противном случае).

#include <iostream>

bool p(int r){

int d[10] = {0,};

while (r){

   if(++d[r % 10] > 1) return 0;

   r /= 10;

}

return 1;

}

int main() {

int n, k;

std::cin >> n;

for(int i = 0; i < n; i += p(++k));

std::cout << k;

}



2019-11-13 424 Обсуждений (0)
Область видимости идентификаторов 0.00 из 5.00 0 оценок









Обсуждение в статье: Область видимости идентификаторов

Обсуждений еще не было, будьте первым... ↓↓↓

Отправить сообщение

Популярное:



©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (424)

Почему 1285321 студент выбрали МегаОбучалку...

Система поиска информации

Мобильная версия сайта

Удобная навигация

Нет шокирующей рекламы



(0.006 сек.)