Читаем Программирование. Принципы и практика использования C++ Исправленное издание полностью

Глобальная область видимости (global scope). Часть текста, не входящая ни в одну другую область видимости.

Пространство имен (namespace scope). Именованная область видимости, вложенная в глобальную область видимости или другое пространство имен (раздел 8.7).

Область видимости класса (class scope). Часть текста, находящаяся в классе (раздел 9.2).

• Локальная область видимости (local scope). Часть текста, заключенная в фигурные скобки, { ... }, в блоке или функции.

• Область видимости инструкции (например, в цикле for).


Основное предназначение области видимости — сохранить локальность имен, чтобы они не пересекались с именами, объявленными в другом месте. Рассмотрим пример.


void f(int x)  // функция f является глобальной;

               // переменная x является локальной в функции f

{

  int z = x+7; // переменная z является локальной

}


int g(int x)   // переменная g является глобальной;

               // переменная x является локальной в функции g

{

  int f = x+2; // переменная f является локальной

  return 2*f;

}


Изобразим это графически.



Здесь переменная x, объявленная в функции f(), отличается от переменной x, объявленной в функции g(). Они не создают недоразумений, потому что принадлежат разным областям видимости: переменная x, объявленная в функции f(), не видна извне функции f(), а переменная x, объявленная в функции g(), не видна извне функции g(). Два противоречащих друг другу объявления в одной и той же области видимости создают коллизию (clash). Аналогично, переменная f объявлена и используется в функции g() и (очевидно) не является функцией f().

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


int max(int a, int b) // функция max является глобальной;

                      // а переменные a и b — локальными

{

  return (a>=b) ? a : b;

}


int abs(int a)        // переменная a, не имеющая отношения

                      // к функции max()

{

  return (a<0) ? –a : a;

}


Функции max() и abs() принадлежат стандартной библиотеке, поэтому их не нужно писать самому. Конструкция ?: называется арифметической инструкцией if (arithmetic if), или условным выражением (conditional expression). Значение инструкции (a>=b)?a:b равно a, если a>=b, и b — в противном случае. Условное выражение позволяет не писать длинный код наподобие следующего:


int max(int a, int b) // функция max является глобальной;

                      // а переменные a и b — локальными

{

  int m; // переменная m является локальной

  if (a>=b)

    m = a;

  else

   m = b;

  return m;

}


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

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


// здесь переменные r, i и v не видны

class My_vector {

 vector v;           // переменная v принадлежит области

                          // видимости класса

public:

 int largest()

 {

  int r = 0;              // переменная r является локальной

                          // (минимальное неотрицательное целое число)

  for (int i = 0; i

    r = max(r,abs(v[i])); // переменная i принадлежит

                          // области видимости цикла

                          // здесь переменная i не видна

  return r;

 }

                          // здесь переменная r не видна

}


// здесь переменная v не видна

int x;           // глобальная переменная — избегайте по возможности

Перейти на страницу:

Похожие книги

Programming with POSIX® Threads
Programming with POSIX® Threads

With this practical book, you will attain a solid understanding of threads and will discover how to put this powerful mode of programming to work in real-world applications. The primary advantage of threaded programming is that it enables your applications to accomplish more than one task at the same time by using the number-crunching power of multiprocessor parallelism and by automatically exploiting I/O concurrency in your code, even on a single processor machine. The result: applications that are faster, more responsive to users, and often easier to maintain. Threaded programming is particularly well suited to network programming where it helps alleviate the bottleneck of slow network I/O. This book offers an in-depth description of the IEEE operating system interface standard, POSIX (Portable Operating System Interface) threads, commonly called Pthreads. Written for experienced C programmers, but assuming no previous knowledge of threads, the book explains basic concepts such as asynchronous programming, the lifecycle of a thread, and synchronization. You then move to more advanced topics such as attributes objects, thread-specific data, and realtime scheduling. An entire chapter is devoted to "real code," with a look at barriers, read/write locks, the work queue manager, and how to utilize existing libraries. In addition, the book tackles one of the thorniest problems faced by thread programmers-debugging-with valuable suggestions on how to avoid code errors and performance problems from the outset. Numerous annotated examples are used to illustrate real-world concepts. A Pthreads mini-reference and a look at future standardization are also included.

David Butenhof

Программирование, программы, базы данных