Бьерн Страуструп. Язык программирования С++. Специальное издание (2011) (1004033), страница 28
Текст из файла (страница 28)
Например: Глава 4. Типы и объявления 128 //глобальная переменная х коЫ ~'() ( шгх; х=/г //локальная х скрывает глобальную х // присваивание локальной х ( !пг х; х = 2з ) // скрывает первую локальную х // присваивание второй локальной х // присваивание первой локальной х //взять адрес глобальной х шг*р= ах; Сокрытие имен неизбежно в больших программах. В то же время, программист может и не заметить, что какое-то имя оказалось скрыто. Из-за того, что такие ошибки редки и нерегулярны, их трудно обнаруживать.
Следовательно„ сокрытие имен желательно минимизировать. Хотите проблем — используйте г или х в качестве глобальных имен, или в качестве локальных в функциях большого размера. Доступ к скрытому глобальному имени осуществляется с помощью операции:: (опероция разрешения области видимости — зсоре гезо!ийоп орегагог). Например: (пг хг // скрывает глобальную х // присваивание глобальной х // присваивание локальной х Не существует способа обращения к скрытому локальному имени. Область видимости имени начинается в точке обьявления, точнее, сразу после декларатора, но перед инициализирующим выражением. Из этого следует, что имя можно использовать в качестве инициализатора самого себя.
Например: шгх; коЫ/3 () ( шгх=х; Это не запрещено, просто глупо. Хороший компилятор предупредит о попытке чтения неинициализированной переменной (в5.9[9)). В принципе, в блоке можно обращаться с помощью одного и того же имени к разным переменным, даже не используя операции::. Вот пример на эту тему: гоЫ (2 ( ) тгхГ 2( :: =2; х=2; // ...
) // извращение: инициализируем х ее собственным // (непроинициализированнылд значением 4.9. Объявления 129 (пг х=11; ю!г( 14 ( ) ( 1пгу = х; Ыгх = 22; у=х; // используется глобальная х: у=!1 /У используется локальная х: у=22 Считается, что имена аргументов функции обьлвлены в самом внешнем блоке, относяи(емся к функции, так что следующий пример ю!и( 15 ( 1пг х) ( !пг х; ) // ег ог (ошибка) компилируется с ошибкой, ибо имя х дважды определено в одной и той же области видимости. Отнесение такой ситуации к ошибочным позволяет избегать коварных ошибок.
1пг а; аоиЫе йь /У означает (п( а = 0; //означает ь(оиЫе ь( = 0.0; Локальные переменные (иногда называемые также автоматическими обьектами — ашотабс оо)ес(л) и объекты, создаваемые в свободной памяти (динамические обьекты или объекты, созданные на куче — Ьеар о!уес(л), по умолчанию не инициализируются. Например: юЫ ('() ( (пг х; У... ) //х не имеет точно определенного значения Элементы массивов и члены структур инициализируются по умолчанию или не инициализируются в зависимости от того, являются ли соответствующие объекты статическими. Для пользовательских типов можно самостоятельно определить инициализацию по умолчанию (910.4.2). Сложные объекты требуют более одного инициализирующего значения. Для инициализации массивов (95.2.1) и структур (95.7) в стиле языка С используются списки инициализирующих значений ((п(г(а1(~ег йлм), ограниченные фигурными скобками. Для инициализации пользовательских типов применяются конструкторы, которые используют обычный функциональный синтаксис, когда через запятую перечисляются их аргументы (92.5.2, З10.2.3).
4.9.5. Инициализация Если инициализирующее выражение присутствует в объявлении, то оно задает начальное значение объекта. Если же оно отсутствует, то глобальные объекты (В4.9.4), объекты, объявленные в пространстве имен 68.2) и статические локальные объекты (97.1.2, 910.2.4) (совокупно называются статическшпи объектами — л(або о(уесц) автоматически инициализируются нулевым значением соответствующего типа.
Например: Глава 4. Типы и объявления 130 Обратите внимание на то, что в объявлениях пустая пара круглых скобок ( ) всегда означает функцию (87.1). Например: !пг а(1 = (1, 2); У инициолкзатор.иассива Ро!пз г (1, 2) г У инициализация в функционал»кол~ стиле (вызов конструктора) !пс)'() г )объявление функции 4.9.6. Объекты и леводолустиалые выражения (1ча!це) Разрешено выделять память под неименованные объекты и использовать их, и можно осуществлять присваивания странно выглядящим выражениям (например, *р(а+!01=7). В результате возникает потребность в названии для «чего-то в памяти». Так мы приходим к фундаментальному определению объекта: обьект— это непрерывный блок памяти. Соответственно, леводопустимое выражение (!иа!ие) — это выражение, ссылающееся на объект.
Исходным смыслом 1ца!пе (от английского 1ел иа1пе) является «нечто, что может стоять в левой части операции присваивания». На самом деле, не каждое 1на(пе может стоять в левой части операции присваивания, ибо некоторые 1«а1пе ссылаются на константы (55.5). Те 1«а!пе, которые были объявлены без модификаторов сопя(, называются модифицируеммми !га!ие. Приведенное простое и низкоуровневое понятие объекта не следует путать с высокоуровневыми понятиями классовых объектов и объектов полиморфных типов (5 ! 5.4.3).
Если программист не указал ничего иного 67.1.2, 810.4.8), объявленный в функции объект создается в точке его определения и существует до момента выхода его имени из области видимости (810.4.4). Такие объекты принято называть автоматическими объектами.
Объекты, объявленные глобально или в пространствах имен, или с модификатором малс в функциях нли классах, создаются и инициализируются в работающей программе лишь однажды и живут до тех пор, пока программа не завершит работу (010.4.9). Такие объекты принято называть статическими. Элементы массивов и нестатические члены классов и структур живут ровно столько, сколько живут содержащие их объекты. Используя операции пе»г и де!еге, можно самостоятельно управлять временем жизни объектов (86.2.6).
4.9.7. Ключевое слово дурее!е1 Объявление, начинающееся с ключевого слова гурег!еу; определяет новое имя для типа, а не новую переменную какого-либо сушествуюшего типа. Например: ГуредеГ сйаг* Рсйаг; Рсйаг р1, р2; Ур! и р2 типа сйаг" сйаг* РЗ=р1» Вводимые таким образом имена часто являются короткими синонимами для типов с неудобоваримыми именами. Например, можно ввести для типа ипз!япед сйаг (особенно при его частом использовании) более короткий синоним, исйаг: гуреде! ипз(дпед сйаг исйаг; Часто (уреде!'используется для того, чтобы ограничить прямое обращение к целевому типу единственным местом в программе. Например: 4.10. Советы гуреДеГ1лг 1лг32« гуре«1е~ злогг глг1 6 г Если теперь использовать тип 1лг32 всюду, где нужны большие целые, то программу будет легко портировать на системную платформу, для которой з1гсоГ'Плг) равен 2.
Действительно, нужно лишь дать новое определение для!лг32: Гуред«З'!олд ГлГ32; Хорошо это или плохо, но с помощью 0релег'вводятся лишь новые синонимы существующих типов, а ие сами новые типы. Следовательно, эти синонимы можно использовать параллельно именам существующих типов. Если же требуются новые типы, имеющие схожую семантику и/или представление, то следует присмотреться к перечислениям 64.8) и классам (глава 1О). 4.10.
Советы 1. Сужайте область видимости имен; 84.9.4. 2. Не используйте одно и то же имя и в текущей области видимости, и в объемлющей области видимости; 84.9.4. 3. Ограничивайте объявление одним именем; 84.9.2. 4. Присваивайте короткие имена локальным и часто используемым переменным; глобальным и редко используемым — длинные; 84.9.3. 5. Избегайте похожих имен; 84.9.3. 6.
Придерживайтесь единого стиля именования; 84.9.3. 7. Внимательно выбирайте имена таким образом, чтобы они отражали смысл, а не представление; 84.9.3. 8. Применяйте гуре4еУ для получения осмысленных синонимов встроенного типа в случаях, когда встроенный тип для представления переменных может измениться; 84.9.7.
9. Синонимы типов задавайте с помощью 0ре4ей новые типы вводите с помощью перечислений и классов; 84.9.7. 10. Помните, что любое объявление должно содержать тип явно (никаких «неявных гль>); 54.9.1. 11. Без необходимости не полагайтесь на конкретные числовые коды символов; 84.3.1, вС.6.2.1. 12. Не полагайтесь на конкретные размеры целых; 84.6. 13. Без необходимости не полагайтесь на диапазон значений чисел с плавающей запятой; 84.6. 14.
Предпочитайте тип йг типам злогг 1лг и 1ол» 1лг, 84.6. 15. Предпочитайте тип ИолЫе типам Яааг и !олй 4олЫе; 84.5. 16. Предпочитайте тип слог типам з18ле4 сйаг и лляйле4 сйаг; вС.3.4. 17. Избегайте необязательных предположений о размерах объектов: 84.6. 18. Избегайте арифметики беззнаковых типов; 84.4. Глава 4. Типы и объявления Относитесь с подозрением к преобразованиям из з(янеФ в ияз(вней( и обрат- ным преобразованиям; 9С.6.2.6. Относитесь с подозрением к преобразованиям из типов с плавающей запятой в целые; 9С.6.2.6. Относитесь с подозрением к преобразованиям из более широких типов в бо- лее узкие (например, из (пг в ейа«); 9С.6.2.6. 19. 20.
21. 4.11. Упражнения (*2) Запустите программу «Не1!о, аког!сИ» (93.2). Если эта программа не ком- пилируется, обратитесь к 9В.3.1. (*1) Для каждого объявления из 94.9 выполните следующее: если объявление не является определением, переделайте его в определение; если же объявле- ние является определением, напишите для него соответствующее объявле- ние, не являющееся одновременно и определением.