Г. Шилдт - С# 3.0 Полное руководство. 2010 (1160798), страница 18
Текст из файла (страница 18)
Переменные могут быть объявлены в любом месте кодового блока, но они становятся действительными только после своего объявления. Так, если объявить переменную в начале метода, то она будет доступна для всего остального кода в пределах этого метода. А если объявить переменную в конце блока, то она окажется, по существу, бесполезной, поскольку не будет доступной ни одному коду. Если в объявление переменной включается инициализатор, то такая переменная инициализируется повторно при каждом входе в тот блок, в котором она объявлена. Рассмотрим следующий пример программьс // Продемонстрировать время существования переменной.
оэ1пд Яуэсеш; сталя Уаггп Епешо ( алатас иогб Нагл() ( гпт х; лог(х = О( х < 3( х++) 1пг у = -1( // Переменная у инициализируется // при каждом входе в блок. Сопэо1е.ыгглеъьпе("у равно: " + у); // Здесь // всегда выводится -1 у = 100; Сопэо1е.иггоеъъпе("у теперь равно: " ь у)( ) ) Ниже приведен результат выполнения этой программы. у равно: -1 у теперь равно: 100 у равно: -1 у теперь равно: 100 84 Часть ). Язык С() у равно: -1 у теперь равно: 100 Как видите, переменная у повторно инициализируется одним и тем же значением -1 при каждом входе во внутренний цикл ког.
И несмотря на то, что после этого цикла ей присваивается значение 100, оно теряется при повторной ее инициализации. В языке С(т имеется еще одна особенность соблюдения правил области действия: несмотря на то, что блоки могут быть вложены, ни у одной из переменных из внутренней области действия не должно быть такое же имя, как и у переменной из внешней области действия. В приведенном ниже примере программы предпринимается попытка объявить две разные переменные с одним и тем же именем, и поэтому программа не может быть скомпилирована. /* В этой программе предпринимается попытка объявить во внутренней области действия переменную с таким же самым именем, как у и переменной, определенной во внешней области действия.
*** Эта программа не может быть скомпилирована. *** */ пвкпч Зуэсеш) с1аав Невсчаг ( вкас1с голд Мако(1 ( ьлс соппст ког(сопок = О) соппс < 10) сопле = сопок+1) ( Сопво1е.нгккеъ1пе("Это подсчет: " + сопок); 1пк сопок) // Неверно!!! Гог(попас О) соппк < 2) сопок++) Сопяо1е.ыг1кеъьпе("В этой программе есть ошибка!" ) ) ) ) Если у вас имеется некоторый опыт программирования на С или С++, то вам должно быть известно, что на присваивание имен переменным, объявляемым во внутренней области действия, в этих языках не существует никаких ограничений.
Следовательно, в С и С++ объявление переменной соппс в кодовом блоке, входящем во внешний цикл уог, как в приведенном выше примере, считается вполне допустимым. Но в С и С++ такое объявление одновременно означает сокрытие внешней переменной. Разработчики СФ посчитали, что такого рода сокрытие имен может легко привести к программным ошибкам, и поэтому решили запретить его. Преобразование и приведение типов В программировании нередко значения переменных одного типа присваиваюгся переменным другого типа. Например, в приведенном ниже фрагменте кода целое значение типа 1пс присваивается переменной с плавающей точкой типа 11оас.
Глаза 3, уипн давних, литералы н лерененнне 85 хпс 1) 01оат Г) 1 = 10; Г = х; // присвоить целое значение переменной типа 11оас Если в одной операции присваивания смешиваются совместимые типы данных, то значение в правой части оператора присваивания автоматически преобразуется в тип в левой его части. Поэтому в приведенном выше фрагменте кода значение переменной 1 сначала преобразуется в тип 11оас, а затем присваивается переменной х. Но вследствие строгого контроля типов далеко не все типы данных в С() оказываются полностью совместимыми, а следовательно, не все преобразования типов разрешены в неявном виде. Например, типы )ооо1 и Ьпс несовместимы.
Правда, преобразование несовместимых типов все-таки может быть осуществлено путем приведения. Приведение типов, по существу, означает явное их преобразование. В этом разделе рассматривается как автоматическое преобразование, так и приведение типов. Автоматическое преобразование типов Когда данные одного типа присваиваются переменной другого типа, неявное преобразование типов происходит автоматически при следующих условиях; ° оба типа совместимы; ° диапазон представления чисел целевого типа шире, чем у исходного типа. Если оба этих условия удовлетворяются, то происходит рааииряющее преобразование. Например, тип Ьпс достаточно крупный, чтобы вмещать в себя все действительные значения типа )тусе, а кроме того, оба типа, 1пс и )хуле, являются совместимыми целочисленными типами, и поэтому для них вполне возможно неявное преобразование.
Числовые типы, как целочисленные, так и с плавающей точкой, вполне совместимы друг с другом для выполнения расширяющих преобразований. Так, приведенная ниже программа составлена совершенно правильно, поскольку преобразование типа 1опп в тип боцЫе является расширяющим и выполняется автоматически. // Продемонстрировать неявное преобразование типа 1опч // в тип боцЫе. цвхпч Яувлеи) с1авв Ьтоп ( всасьс чо1л) Махп() ( 1опд Ь; боцЫе О) Ь = 100128285Ьл 0 = Ьл Сопвоге.игьлег.хпе("1, и 0: " Ь 1, Л " " Ь 0); ) Если тип 1опс может быть преобразован в тип г)оцЫе неявно, то обратное преобразование типа х)оцЫе в тип 1опс неявным образом невозможно, поскольку оно не является расширяющим. Следовательно, приведенный ниже вариант предыдущей программы составлен неправильно. 86 Часть!. Язык С№ // *** Эта программа не может быть скоипилироввна.
*** ив100 эувтеж) о1ввв ЬкоО всасьо тоьд Мвьп() ( 1ооч ьн к)оиЫе пт 0 = 100123285.0) т, = 0) // Неверно!!! Сопво1е.ыт1кеьцпе ("т. и 0: " + 1. Ь " " + О) ) Помимо упомянутых выше ограничений, не допускается неявное взаимное преобразование типов к)ес1ата1 и г1оаг или боцЫе, а также числовых типов и с)тат илн )тоо1. Кроме того, типы е)твт и )ооо1 несовместимы друг с другом. Приведение несовместимых типов Несмотря на всю полезность неявных преобразований типов, они неспособны удовлетворить все потребности в программировании, поскольку допускают лишь расширяющие преобразования совместимых типов. А во всех остальных случаях приходится обращаться к приведению типов. Приведение — это команда компилятору преобразовать результат вычисления выражения в указанный тип.
А для этого требуется явное преобразование типов. Ниже приведена общая форма приведения типов. (целевой тип) выражение Здесь целевой тип обозначает тот тип, в который желательно преобразовать указанное выражение. Рассмотрим для примера следующее объявление переменных: боиЫе х, у) Если результат вычисления выражения х/у должен быть типа 1пг., то следует записать: (1вь) (х / у) Несмотря на то что переменные х и у относятся к типу с(оцЫе, результат вычисления выражения х/у преобразуется в тип ьпс благодаря приведению.
В данном примере выражение х/у следует непременно указывать в скобках, иначе приведение к типу упс будет распространяться только на переменную х, а не на результат ее деления на переменную у. Приведение типов в данном случае требуется потому, что неявное преобразование типа с(оцЫе в тип 100 невозможно. Если приведение типов приводит к тл/жаюв(ему в))еобразованию, то часть информации может быть потеряна, Например, в результате приведения типа 1000 к типу 100 часть информации потеряется, если значение типа 1000 окажется больше диапазона представления чисел для типа ъпс, поскольку старшие разряды этого числового значения отбрасываются.
Когда же значение с плавающей точкой приводится к целочисленному, то в результате усечения теряется дробная часть этого числового значения. Так, если присвоить значение 1,23 целочисленной переменной, то в результате в ней останется лишь целая часть исходного числа (1), а дробная его часть (0,23) будет потеряна. Глава 3. Типы данных, литералы и переменные 87 В следующем примере программы демонстрируется ряд преобразований типов, требующих приведения. В этом примере показан также ряд ситуаций, в которых приведение типов приводит к потере данных.
// Продемонстрировать приведение типов. ия1пп 5увсепп с1аяя Саяспеио ( ягаслс чола иахп() ( бопЬ1е х, у( ЬУГЕ Ьх тпг 17 сьаг сьх п1пс пх вьогг я; 1опд 17 х 10.07 у = 3.07 // Приведение типа бопьуе к типу 1пг, // дробная часть числа теряется.