Сразу пример , прояcняющий область видимости нескольких разных переменных ii в одном с файле:
Оператор :: это так называемое разрешение области видимости.
#include
#include "stdio.h"
int ii; // глобальная переменная
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int ii=123; // локальная переменная в функции
printf("ii=%d\n",ii);
for(int jj=0;jj<5;jj++)
{
int ii=0; // локальная переменная в цикле в функции
printf("%d %d\n" , ii++ , ::ii++);
}
return a.exec();
}
Вывод:
ii=123
0 0
0 1
0 2
0 3
0 4
Самый интересный момент это применение оператора :: перед ii.
::ii означает использование ii из глобальной области видимости.
Теперь совет всем кто программирует придумайте "уникальное" кодовое слово своим исходникам и обзовите им как свою собственную область видимости, чтобы хоть как-то гарантировать, что названия ваших глобальных переменных, функции и т.д. на совпадет с названиями из других чужих (и даже своих) проектов.
Например выбираем слово ququ.
#include "stdio.h"
int ii=123;
namespace ququ{
int ii=10;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int ii=123;
printf("ii=%d\n",ii);
for(int jj=0;jj<5;jj++)
{
int ii=0;
printf("%d %d %d\n" , ii++ , ::ii++ , ququ::ii++);
}
return a.exec();
}
Вывод:
ii=123
0 123 10
0 124 11
0 125 12
0 126 13
0 127 14
Использование оператора ququ::ii кроме защиты еще подсказывает к какой теме относится переменная ii (на наш взгляд очень удобно).
Кстати говоря классы тоже имеют :: в коде и это тоже по сути то же самое применение.
class A
{
public:
A()
{
ii=99;
printf("constructor A ii=%d\n",ii);
}
~A();
void method1()
{
printf("method1 A ii=%d\n",ii);
}
int ii;
static int si=0;
};
A::~A()
{
printf("destructor A ii=%d\n",ii);
}
// объявление диструктора вынесено из тела класса А
// и поэтому сразу появляется оператор ::
// чтобы понять к какому классу (к какой области видимости)
// относится этот диструктор (метод)
int A::si=0;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
A aaa;
aaa.ii=2;
return a.exec();
}
На наш взгляд все логично и правильно.
В коде есть static int si=0; (переменная класса). Интересно , что static указывает использовать si один раз для всех экземпляров класса, то есть A могут создаваться многократно в коде , а вот si у них будет всегда один и размещен в фиксированной обласьи паияти (это не куча и не стек , это фиксированных блок памяти , создаваемый на стадии линковки).Куча и стек
static можно сразу инициализировать без создания экземпляра класса:
int A::si=0;
Но только не в теле функции, а как глобальную переменную снаружи функций.