Переменные в C#
В общем случае, вне зависимости от языка программирования, переменной является именованная область памяти в которой хранятся какие-либо данные приложения. При работе над какой-либо программой мы так или иначе задействуем в работе переменные различного типа. В этой статье мы рассмотрим какие переменные бывают в C# и попробуем написать ещё одно приложение, демонстрирующее полученные нами знания в C#.
Описание переменной в C#
В самом общем случае, переменная в C# определяется следующим образом:
то есть вначале идёт тип переменной, а затем — её имя. Про типы переменных мы поговорим позднее, а пока рассмотрим правила именования переменных в C#. Итак, имя переменной в C#:
- должно начинаться либо с буквы, либо с символа подчеркивания («_»)
- не должно быть ключевым словом C#
- не должно содержать символов пунктуации и пробелов.
При этом следует учитывать, что язык C# регистрозависимый, то есть переменные:
это две разные переменные.
И, хотя переменной можно давать любое имя, всё же имена должны отражать суть того для чего эта переменная предназначена. Например, вот такой код можно считать плохо оформленным:
Во-первых, имя переменной не отражает сути. Во-вторых, переменная состоит из одной заглавной буквы, а, по правилам хорошего тона в C# локальным переменным следует давать имена с маленькой буквы. Правильнее было бы сделать вот так:
И здесь мы подходим к следующей части статьи о переменных в C# — присвоение значений и инициализация переменных в C#.
Присвоение значений и инициализация переменных в C#
Для присвоения значения переменной мы используем следующую конструкцию:
то есть, в отличие от того же Delphi, в C# математический символ = используется именно для присвоения значения переменно. Так, например, в коде выше мы присвоили переменной name значение «Вася Пупкин». При этом, мы можем в любой момент времени изменить значение переменной, например, так:
В C# мы можем сразу при объявлении переменной присвоить ей значение — инициализировать переменную, например, вот так:
Каким вариантом работы с переменными воспользоваться — решать только вам.
Неявно типизированные локальные переменные
Язык C# имеет статическую типизацию. Это означает, что переменная, или возвращаемое значение функции связывается с типом в момент объявления и тип не может быть изменён позже. Например, в C# мы не сможем сделать следующее:
так как изначально мы определили, что переменная name имеет тип string .
Однако, начиная с версии C# 3.0 стало возможным определять неявно типизированные локальные переменные. Это не в коем случае не означает, что для переменной не будет определен тип, просто тип переменной определяется компилятором при инициализации переменной.
Для того, чтобы объявить неявно типизированную переменную в C# используется ключевое слово var . Например, в приведенном ниже фрагменте кода обе переменные будут эквивалентны и иметь один и тот же тип:
В отличие от обычных переменных (с явно указанным типом), неявно типизированные переменные должны быть сразу инициализированы. Так, следующим код приведет к ошибке:
Пустые переменные
Начиная с версии 7.0 язык C# поддерживает пустые переменные. Это временные фиктивные переменные, которые намеренно не используются в коде приложения. Пустые переменные эквивалентны переменным, которым не присвоены значения.
Так как пустая переменная по сути всего одна и этой переменной может даже не выделяться память, пустые переменные помогают расходовать память более экономно.
Эти переменные делают код яснее, повышают его читаемость и упрощают его поддержку.
В C# пустая переменная определяется символом нижнего подчеркивания «_».
Использование пустых переменных — это отдельная тема о которой мы ещё успеем поговорить. Пока же приведу небольшой код в котором используется пустая переменная:
По сути, последняя строка — всего лишь «заглушка» позволяющая держать окно консоли открытым пока пользователь не нажмет кнопку Enter, однако сам по себе метод ReadLine() возвращает строку (string) введенную пользователем. И так как нам эта строка абсолютно не требуется мы передаем её в пустую переменную.
Итого
Сегодня мы разобрались с тем, что из себя представляют переменные, как объявляются и инициализируются переменные в C#, а также затронули такие интересные моменты языка C# как объявление неявно типизированных и пустых переменных.
Как присвоить переменной текстовое значение c
На этом шаге мы рассмотрим особенности реализации такой программы .
В следующем примере мы научимся отображать диалоговое окно с полем ввода. С помощью такого окна в программу можно вводить данные, которые программа сможет использовать.
Диалоговое окно с полем ввода отображается так же просто, как и диалоговое окно с сообщением. Правда, для отображения окна с нолем ввода нам придется прибегнуть к средствам языка Visual Basic . Дело в том, что в языке С# нет встроенных средств для отображения окна с полем ввода. Зато такое окно можно отобразить с привлечением средств языка Visual Basic . Технология .Net Framework позволяет нам прибегнуть к помощи библиотеки Visual Basic при написании программного кода на языке С# . Чтобы воспользоваться этой возможностью, мы должны подключить пространство имен Microsoft.VisualBasic . Если пространство подключено, то в программе будет доступен класс Interaction , в котором есть статический метод InputBox() . Этот метод отображает диалоговое окно с полем ввода, а результатом возвращает текст, введенный пользователем. Небольшой пример программы, в которой использованы описанные выше утилиты для отображения диалогового окна с нолем ввода, представлен в примере ниже.
При запуске программы сначала появляется окно, представленное на рисунке 1.
Рис.1. Диалоговое окно с полем ввода
Окно имеет название Давайте познакомимся. , определяемое в программе, и текст Как Вас зовут? , также определяемый в программе. В поле диалогового окна следует ввести текст и щелкнуть кнопку ОК (см. рисунок 1). После этого появляется диалоговое окно с сообщением, причем сообщение содержит текст, введенный ранее пользователем в поле предыдущего диалогового окна. Как может выглядеть окно с сообщением, показано на рисунке 2.
Рис.2. Диалоговое окно с сообщением, содержащим введенный пользователем текст
Теперь проанализируем программный код, который позволяет получить такие результаты. В начале программы подключаются пространства имен Microsoft.VisualBasic и System.Windows.Forms (рисунок 3). Первое из них необходимо для использования статического метода InputBox() из класса Interaction , отображающего окно с полем ввода, а второе пространство имен необходимо для использования статического метода Show() из класса MessageBox .
Рис.3. Текст программы и ссылки
Напомним, что мало добавить в программный код инструкции подключения пространств имен. Необходимо также добавить соответствующие ссылки в проект. Для этого следует в меню Project ( Проект ) выбрать команду Add Reference ( Добавить ссылку ) и в открывшемся окне выбрать строки с названиями подключаемых пространств имен.
В главном методе программы есть команда string name . Этой командой объявляется переменная name , относящаяся к текстовому типу string . Проще говоря, значением переменной name может быть текст.
Переменная — это блок памяти, к которому обращаются по имени (название переменной). Переменную удобно представлять в виде ячейки с надписью на дверце. В эту ячейку можно что-то положить (записать значение) или посмотреть, что там находится (прочитать значение). У каждой переменной есть тип. Тип переменной влияет на объем памяти, выделяемой под переменную, а также на то, какие значения можно записывать в переменную и какие операции с этой переменной можно выполнять.
Каждая переменная в языке С# должна быть объявлена. Для этого указывается тип переменной и ее название. В данном случае в качестве идентификатора типа указано ключевое слово string , означающее, что переменная является текстовой: значением такой переменной разрешается присвоить текст. Объявлять переменные можно фактически в любом месте программы (главного метода), но обязательно до того, как переменная первый раз используется.
Идентификатор string является псевдонимом (или синонимом) для инструкции System.String . Это обращение к классу String из пространства имен System . Если пространство имен System подключено, то вместо идентификатора string можно использовать название класса String .
Класс String предназначен для реализации текста. Текст реализуется в виде объекта класса String . Но то, как выше описывался способ реализации переменных, относится к базовым типам, а не к объектам. Другими словами, способ реализации объектов сложнее, чем было описано выше. Тем не менее пока что это не столь важно, и мы можем думать о текстовой переменной как об обычной переменной базового типа. Базовые типы данных, классы и объекты обсуждаются позже.
Для отображения диалогового окна с полем ввода из класса Interaction вызывается статический метод InputBox() . Аргументами методу передается текст «Как Вас зовут?» (первый аргумент) и «Давайте познакомимся. » (второй аргумент). Первый аргумент метода определяет текст, отображаемый в диалоговом окне сверху над полем ввода, в то время как второй аргумент задает название окна.
Метод InputBox() возвращает результат. Это позволяет отождествлять инструкцию вызова метода с некоторым значением. Для метода InputBox() возвращаемое значение — это введенный пользователем в поле диалогового окна текст. Данное значение присваивается переменной name . Поэтому в результате выполнения команды
В C# оператором присваивания является символ равенства =. Выражение вида переменная=значение обрабатывается так: в переменную, указанную слева от оператора присваивания, записывается значение, указанное справа от оператора присваивания.
Name already in use
csharp_for_beginners / c3.md
- Go to file T
- Go to line L
- Copy path
- Copy permalink
1 contributor
Users who have contributed to this file
- Open with Desktop
- View raw
- Copy raw contents Copy raw contents
Copy raw contents
Copy raw contents
ГЛАВА 3. Типы данных, литералы
В этой главе рассматриваются три основополагающих элемента С#: типы данных, литералы и переменные. В целом, типы данных, доступные в языке программи рования, определяют те виды задач, для решения которых можно применять данный язык. Как и следовало ожидать, в C# предоставляется богатый набор встроенных типов дан ных, что делает этот язык пригодным для самого широкого применения. Любой из этих типов данных может служить для создания переменных и констант, которые в языке C# называются литералами.
О значении типов данных
Типы данных имеют особенное значение в С#, посколь ку это строго типизированный язык. Это означает, что все операции подвергаются строгому контролю со стороны компилятора на соответствие типов, причем недопустимые операции не компилируются. Следовательно, строгий кон троль типов позволяет исключить ошибки и повысить на дежность программ. Для обеспечения контроля типов все переменные, выражения и значения должны принадлежать к определенному типу. Такого понятия, как «бестиповая» переменная, в данном языке программирования вообще не существует. Более того, тип значения определяет те опера ции, которые разрешается выполнять над ним. Операция, разрешенная для одного типа данных, может оказаться не допустимой для другого.
ПРИМЕЧАНИЕ В версии C# 4.0 внедрен новый тип данных, называемый dynamic и приводящий к отсрочке контроля типов до времени выполнения, вместо того чтобы производить подобный контроль во время компиляции. Поэтому тип dynamic является исключением из обычного правила контроля типов во время компиляции. Подробнее о типе dynamic речь пойдет в главе 17.
Типы значений в C#
В C# имеются две общие категории встроенных типов данных: типы значений и ссы лочные типы. Они отличаются по содержимому переменной. Если переменная от носится к типу значения, то она содержит само значение, например 3,1416 или 212. А если переменная относится к ссылочному типу, то она содержит ссылку на значение. Наиболее распространенным примером использования ссылочного типа является класс, но о классах и ссылочных типах речь пойдет далее в этой книге. А здесь рассма триваются типы значений.
В основу языка C# положены 13 типов значений, перечисленных в табл. 3.1. Все они называются простыми типами, поскольку состоят из единственного значения. (Иными словами, они не состоят из двух или более значений.) Они составляют основу системы типов С#, предоставляя простейшие, низкоуровневые элементы данных, которыми можно оперировать в программе. Простые типы данных иногда еще называют при митивными.
Таблица. 3.1. Типы значений в C#
| Тип | Значение |
|---|---|
| bool | Логический, предоставляет два значения: “истина” или “ложь” |
| byte | 8-разрядный целочисленный без знака |
| char | Символьный |
| decimal | Десятичный (для финансовых расчетов) |
| double | С плавающей точкой двойной точности |
| float | С плавающей точкой одинарной точности |
| int | Целочисленный |
| long | Длинный целочисленный |
| sbyte | 8-разрядный целочисленный со знаком |
| short | Короткий целочисленный |
| uint | Целочисленный без знака |
| ulong | Длинный целочисленный без знака |
| ushort | Короткий целочисленный без знака |
В C# строго определены пределы и характер действия каждого типа значения. Исходя из требований к переносимости программ, C# не допускает в этом отношении никаких компромиссов. Например, тип int должен быть одинаковым во всех средах выполнения. Но в этом случае отпадает необходимость переписывать код для кон кретной платформы. И хотя строгое определение размерности типов значений может стать причиной незначительного падения производительности в некоторых средах, эта мера необходима для достижения переносимости программ.
ПРИМЕЧАНИЕ Помимо простых типов, в C# определены еще три категории типов значений: перечисления, структуры и обнуляемые типы. Все они рассматриваются далее в этой книге.
В C# определены девять целочисленных типов: char, byte, sbyte, short, ushort, int, uint, long и ulong. Но тип char применяется, главным образом, для пред ставления символов и поэтому рассматривается далее в этой главе. Остальные восемь целочисленных типов предназначены для числовых расчетов. Ниже представлены их диапазон представления чисел и разрядность в битах.
| Тип | Разрядность в битах | Диапазон представления чисел |
|---|---|---|
| byte | 8 | 0-255 |
| sbyte | 8 | -128-127 |
| short | 16 | -32 768-32 767 |
| ushort | 16 | 0-65 535 |
| int | 32 | -2 147 483 648-2 147 483 647 |
| uint | 32 | 0-4 294 967 295 |
| long | 64 | -9 223 372 036 854 775 808-9 223 372 036 854 775 807 |
| ulong | 64 | 0-18 446 744 073 709 551 615 |
Как следует из приведенной выше таблицы, в C# определены оба варианта различ ных целочисленных типов: со знаком и без знака. Целочисленные типы со знаком от личаются от аналогичных типов без знака способом интерпретации старшего разряда целого числа. Так, если в программе указано целочисленное значение со знаком, то компилятор C# сгенерирует код, в котором старший разряд целого числа использу ется в качестве флага знака. Число считается положительным, если флаг знака равен 0, и отрицательным, если он равен 1. Отрицательные числа практически всегда представ ляются методом дополнения до двух, в соответствии с которым все двоичные разряды отрицательного числа сначала инвертируются, а затем к этому числу добавляется 1.
Целочисленные типы со знаком имеют большое значение для очень многих алго ритмов, но по абсолютной величине они наполовину меньше своих аналогов без знака. Вот как, например, выглядит число 32 767 типа short в двоичном представлении.
Если установить старший разряд этого числа равным 1, чтобы получить значение со знаком, то оно будет интерпретировано как -1, принимая во внимание формат до полнения до двух. Но если объявить его как значение типа ushort, то после установки в 1 старшего разряда оно станет равным 65 535.
Вероятно, самым распространенным в программировании целочисленным типом является тип int. Переменные типа int нередко используются для управления цикла ми, индексирования массивов и математических расчетов общего назначения. Когда же требуется целочисленное значение с большим диапазоном представления чисел, чем у типа int, то для этой цели имеется целый ряд других целочисленных типов. Так, если значение нужно сохранить без знака, то для него можно выбрать тип uint, для больших значений со знаком — тип long, а для больших значений без знака — тип ulong. В качестве примера ниже приведена программа, вычисляющая расстояние от Земли до Солнца в дюймах. Для хранения столь большого значения в ней использует ся переменная типа long.
Вот как выглядит результат выполнения этой программы.
Очевидно, что этот результат нельзя было бы сохранить в переменной типа int или uint.
Самыми мелкими целочисленными типами являются byte и sbyte. Тип byte представляет целые значения без знака в пределах от 0 до 255. Переменные типа byte особенно удобны для обработки исходных двоичных данных, например байтового по тока, поступающего от некоторого устройства. А для представления мелких целых зна чений со знаком служит тип sbyte. Ниже приведен пример программы, в которой переменная типа byte используется для управления циклом, где суммируются числа от 1 до 100.
Результат выполнения этой программы выглядит следующим образом.
В приведенном выше примере программы цикл выполняется только от 1 до 100, что не превышает диапазон представления чисел для типа byte, и поэтому для управ ления этим циклом не требуется переменная более крупного типа.
Если же требуется целое значение, большее, чем значение типа byte или sbyte, но меньшее, чем значение типа int или uint, то для него можно выбрать тип short или ushort.
Типы для представления чисел с плавающей точкой
Типы с плавающей точкой позволяют представлять числа с дробной частью. В С# имеются две разновидности типов данных с плавающей точкой: float и double. Они представляют числовые значения с одинарной и двойной точностью соответственно. Так, разрядность типа float составляет 32 бита, что приближенно соответствует диапа зону представления чисел от 5Е-45 до 3,4Е+38. А разрядность типа double составляет 64 бита, что приближенно соответствует диапазону представления чисел от 5Е-324 до 1,7Е+308.
В программировании на С# чаще применяется тип double, в частности, потому, что во многих математических функциях из библиотеки классов С#, которая одновре менно является библиотекой классов для среды .NET Framework, используются чис ловые значения типа double. Например, метод Sqrt(), определенный в библиотеке классов System.Math, возвращает значение типа double, которое представляет собой квадратный корень из аргумента типа double, передаваемого данному методу. В при веденном ниже примере программы метод Sqrt() используется для вычисления ра диуса окружности по площади круга.
Результат выполнения этой программы выглядит следующим образом.
В приведенном выше примере программы следует обратить внимание на вызов ме тода Sqrt(). Как упоминалось выше, метод Sqrt() относится к классу Math, поэтому в его Вызове имя Math предшествует имени самого метода. Аналогичным образом имя класса Console предшествует имени метода WriteLine() в его вызове. При вызове некоторых, хотя и не всех, стандартных методов обычно указывается имя их класса, как показано в следующем примере.
В следующем примере программы демонстрируется применение нескольких три гонометрических функций, которые относятся к классу Math и входят в стандартную библиотеку классов С#. Они также оперируют данными типа double. В этом примере на экран выводятся значения синуса, косинуса и тангенса угла, измеряемого в пределах от 0,1 до 1,0 радиана.
Ниже приведена лишь часть результата выполнения данной программы.
Для вычисления синуса, косинуса и тангенса угла в приведенном выше примере были использованы стандартные методы Math.Sin(), Math.Cos() и Math.Tan(). Как и метод Math.Sqrt(), эти тригонометрические методы вызываются с аргументом типа double и возвращают результат того же типа. Вычисляемые углы должны быть указаны в радианах.
Десятичный тип данных
Вероятно, самым интересным среди всех числовых типов данных в C# является тип decimal, который предназначен для применения в финансовых расчетах. Этот тип имеет разрядность 128 бит для представления числовых значений в пределах от 1Е-28 до 7,9Е+28. Вам, вероятно, известно, что для обычных арифметических вычислений с плавающей точкой характерны ошибки округления десятичных значений. Эти ошиб ки исключаются при использовании типа decimal, который позволяет представить числа с точностью до 28 (а иногда и 29) десятичных разрядов. Благодаря тому что этот тип данных способен представлять десятичные значения без ошибок округления, он особенно удобен для расчетов, связанных с финансами.
Ниже приведен пример программы, в которой тип decimal используется в кон кретном финансовом расчете. В этой программе цена со скидкой рассчитывается на основании исходной цены и скидки в процентах.
Результат выполнения этой программы выглядит следующим образом.
Обратите внимание на то, что значения констант типа decimal в приведенном выше примере программы указываются с суффиксом m. Дело в том, что без суффикса m эти значения интерпретировались бы как стандартные константы с плавающей точ кой, которые несовместимы с типом данных decimal. Тем не менее переменной типа decimal можно присвоить целое значение без суффикса m, например 10. (Подробнее о числовых константах речь пойдет далее в этой главе.)
Рассмотрим еще один пример применения типа decimal. В этом примере рассчи тывается будущая стоимость капиталовложений с фиксированной нормой прибыли в течение ряда лет.
Вот как выглядит результат выполнения этой программы.
Обратите внимание на то, что результат выполнения приведенной выше програм мы представлен с точностью ДО целого ряда десятичных разрядов, т.е. с явным избыт ком по сравнению с тем, что обычно требуется! Далее в этой главе будет показано, как подобный результат приводится к более «привлекательному» виду.
В C# символы представлены не 8-разрядным кодом, как во многих других языках программирования, например C++, а 16-разрядным кодом, который называется унико дом (Unicode). В уникоде набор символов представлен настолько широко, что он охва тывает символы практически из всех естественных языков на свете. Если для многих естественных языков, в том числе английского, французского и немецкого, характерны относительно небольшие алфавиты, то в ряде других языков, например китайском, употребляются довольно обширные наборы символов, которые нельзя представить 8-разрядным кодом. Для преодоления этого ограничения в C# определен тип char, представляющий 16-разрядные значения без знака в пределах от 0 до 65 535. При этом стандартный набор символов в 8-разрядном коде ASCII является подмножеством уни кода в пределах от 0 до 127. Следовательно, символы в коде ASCII по-прежнему оста ются действительными в С#.
Для того чтобы присвоить значение символьной переменной, достаточно заклю чить это значение (т.е. символ) в одинарные кавычки. Так, в приведенном ниже фраг менте кода переменной ch присваивается символ X.
Значение типа char можно вывести на экран с помощью метода WriteLine(). Например, в следующей строке кода на экран выводится значение переменной ch.
Несмотря на то что тип char определен в C# как целочисленный, его не следует путать со всеми остальными целочисленными типами. Дело в том, что в C# отсутству ет автоматическое преобразование символьных значений в целочисленные и обратно.
Например, следующий фрагмент кода содержит ошибку.
Ошибочность приведенного выше фрагмента кода объясняется тем, что 88 — это целое значение, которое не преобразуется автоматически в символьное. При попытке скомпилировать данный фрагмент кода будет выдано соответствующее сообщение об ошибке. Для того чтобы операция присваивания целого значения символьной пере менной оказалась допустимой, необходимо осуществить приведение типа, о котором речь пойдет далее в этой главе.
Логический тип данных
Тип bool представляет два логических значения: «истина» и «ложь». Эти логиче ские значения обозначаются в C# зарезервированными словами true и false соот ветственно. Следовательно, переменная или выражение типа bool будет принимать одно из этих логических значений. Кроме того, в C# не определено взаимное преобра зование логических и целых значений. Например, 1 не преобразуется в значение true, а 0 — в значение false.
В приведенном ниже примере программы демонстрируется применение типа bool.
Эта программа дает следующий результат.
В приведенной выше программе обнаруживаются три интересные особенно сти. Во-первых, при выводе логического значения типа bool с помощью метода WriteLine() на экране появляется значение «True» или «False». Во-вторых, самого значения переменной типа bool достаточно для управления оператором if. Для это го не нужно, например, записывать оператор if следующим образом.
И в-третьих, результатом выполнения оператора отношения является логическое значение. Именно поэтому в результате вычисления выражения 10 > 9 на экран вы водится значение «True.» Кроме того, выражение 10 > 9 следует заключить в скобки, поскольку оператор + имеет более высокий приоритет, чем оператор >.
Некоторые возможности вывода
До сих пор при выводе с помощью метода WriteLine() данные отображались в формате, используемом по умолчанию. Но в среде .NET Framework определен до статочно развитый механизм форматирования, позволяющий во всех деталях управ лять выводом данных. Форматированный ввод-вывод подробнее рассматривается далее в этой книге, а до тех пор полезно ознакомиться с некоторыми возможностями форма тирования. Они позволяют указать, в каком именно виде следует выводить значения с помощью метода WriteLine(). Благодаря этому выводимый результат выглядит более привлекательно. Следует, однако, иметь в виду, что механизм форматирования поддерживает намного больше возможностей, а не только те, которые рассматривают ся в этом разделе.
При выводе списков данных в предыдущих примерах программ каждый элемент списка приходилось отделять знаком +, как в следующей строке.
Конечно, такой способ вывода числовой информации удобен, но он не позволяет управлять внешним видом выводимой информации. Например, при выводе значения с плавающей точкой нельзя определить количество отображаемых десятичных раз рядов. Рассмотрим оператор
который выводит следующий результат.
В одних случаях такого вывода может оказаться достаточно, а в других — он про сто недопустим. Например, в финансовых расчетах после десятичной точки принято указывать лишь два десятичных разряда.
Для управления форматированием числовых данных служит другая форма метода WriteLine(), позволяющая встраивать информацию форматирования, как показано ниже.
В этой форме аргументы метода WriteLine() разделяются запятой, а не знаком +. А форматирующая строка состоит из двух элементов: обычных печатаемых символов, предназначенных для вывода в исходном виде, а также спецификаторов формата. По следние указываются в следующей общей форме:
где argnum — номер выводимого аргумента, начиная с нуля; width — минимальная ширина поля; fmt — формат. Параметры width и fmt являются необязательными. Если во время выполнения в форматирующей строке встречается спецификатор формата, то вместо него подставляется и отображается соответствующий аргумент, обозначаемый параметром argnum. Таким образом, местоположение спецификатора формата в форматирующей строке определяет место отображения соответствующих данных. Параметры width и fmt указывать необязательно. Это означает, что в своей простейшей форме спецификатор формата обозначает конкретный отображаемый аргумент. Например, спецификатор <0>обозначает аргумент arg0, спецификатор <1>— аргумент arg1 и т.д.
Начнем с самого простого примера. При выполнение оператора
получается следующий результат.
Как видите, значение 28 подставляется вместо спецификатора <0>, а значение 29 — вместо спецификатора <1>. Следовательно, спецификаторы формата обозначают ме сто в строке, где отображаются соответствующие аргументы (в данном случае — зна чения 28 и 29). Кроме того, обратите внимание на то, что дополнительные значения разделяются запятой, а не знаком +.
Ниже приведен видоизмененный вариант предыдущего оператора, в котором ука зывается ширина полей.
Выполнение этого оператора дает следующий результат. В феврале 28 или 29 дней.
Как видите, неиспользуемые части полей заполнены пробелами. Напомним, что минимальная ширина поля определяется параметром width. Если требуется, она мо жет быть превышена при выводе результата.
Разумеется, аргументы, связанные с командой форматирования, не обязательно должны быть константами. Ниже приведен пример программы, которая выводит та блицу результатов возведения чисел в квадрат и куб. В ней команды форматирования используются для вывода соответствующих значений.
Результат выполнения этой программы выглядит следующим образом.
В приведенных выше примерах сами выводимые значения не форматировались. Но ведь основное назначение спецификаторов формата — управлять внешним видом выводимых данных. Чаще всего форматированию подлежат следующие типы данных: с плавающей точкой и десятичный. Самый простой способ указать формат данных — описать шаблон, который будет использоваться в методе WriteLine(). Для этого ука зывается образец требуемого формата с помощью символов #, обозначающих разряды чисел. Кроме того, можно указать десятичную точку и запятые, разделяющие цифры. Ниже приведен пример более подходящего вывода результата деления 10 на 3.
Выполнение этого оператора приводит к следующему результату.
В данном примере шаблон #.## указывает методу WriteLine() отобразить два десятичных разряда в дробной части числа. Следует, однако, иметь в виду, что метод WriteLine() может отобразить столько цифр слева от десятичной точки, сколько по требуется для правильной интерпретации выводимого значения.
Рассмотрим еще один пример. Оператор
дает следующий результат.
Для вывода денежных сумм, например, рекомендуется использовать спецификатор формата С.
Результат выполнения этого фрагмента кода выводится в формате денежных сумм, указываемых в долларах США.
Форматом С можно также воспользоваться, чтобы представить в более подходя щем виде результат выполнения рассматривавшейся ранее программы расчета цены со скидкой.
Вот как теперь выглядит результат выполнения этой программы.
В C# литералами называются постоянные значения, представленные в удобной для восприятия форме. Например, число 100 является литералом. Сами литералы и их назначение настолько понятны, что они применялись во всех предыдущих примерах программ без всяких пояснений. Но теперь настало время дать им формальное объяс нение.
В С# литералы могут быть любого простого типа. Представление каждого литерала зависит от конкретного типа. Как пояснялось ранее, символьные литералы заключают ся в одинарные кавычки. Например, ‘а’ и ‘%’ являются символьными литералами. Целочисленные литералы указываются в виде чисел без дробной части. Например, 10 и -100 — это целочисленные литералы. Для обозначения литералов с плавающей точкой требуется указывать десятичную точку и дробную часть числа. Например, 11.123 — это литерал с плавающей точкой. Для вещественных чисел с плавающей точкой в C# допускается также использовать экспоненциальное представление. У литералов должен быть также конкретный тип, поскольку C# является строго ти пизированным языком. В этой связи возникает естественный вопрос: к какому типу следует отнести числовой литерал, например 2,123987 или 0.23? К счастью, для от вета на этот вопрос в C# установлен ряд простых для соблюдения правил. Во-первых, у целочисленных литералов должен быть самый мелкий целочислен ный тип, которым они могут быть представлены, начиная с типа int. Таким образом, у целочисленных литералов может быть один из следующих типов: int, uint, long или ulong в зависимости от значения литерала. И во-вторых, литералы с плавающей точкой относятся к типу double.
Если вас не устраивает используемый по умолчанию тип литерала, вы можете явно указать другой его тип с помощью суффикса. Так, для указания типа long к литералу присоединяется суффикс l или L. Например, 12 — это литерал типа int, a 12L — ли терал типа long. Для указания целочисленного типа без знака к литералу присоединя ется суффикс u или U. Следовательно, 100 — это литерал типа int, a 100U — литерал типа uint. А для указания длинного целочисленного типа без знака к литералу при соединяется суффикс ul или UL. Например, 984375UL — это литерал типа ulong. Кроме того, для указания типа float к литералу присоединяется суффикс F или f. Например, 10.19F — это литерал типа float. Можете даже указать тип double, при соединив к литералу суффикс d или D, хотя это излишне. Ведь, как упоминалось выше, по умолчанию литералы с плавающей точкой относятся к типу double.
И наконец, для указания типа decimal к литералу присоединяется суффикс m или М. Например, 9.95М — это десятичный литерал типа decimal.
Несмотря на то что целочисленные литералы образуют по умолчанию значения типа int, uint, long или ulong, их можно присваивать переменным типа byte, sbyte, short или ushort, при условии, что присваиваемое значение может быть представлено целевым типом.
Вам, вероятно, известно, что в программировании иногда оказывается проще поль зоваться системой счисления по основанию 16, чем по основанию 10. Система счисле ния по основанию 16 называется шестнадцатеричной. В ней используются числа от 0 до 9, а также буквы от А до F, которыми обозначаются десятичные числа 10, 11, 12, 13, 14 и 15. Например, десятичному числу 16 соответствует шестнадцатеричное число 10. Вследствие того что шестнадцатеричные числа применяются в программировании до вольно часто, в C# разрешается указывать целочисленные литералы в шестнадцате ричном формате. Шестнадцатеричные литералы должны начинаться с символов 0х, т.е. нуля и последующей латинской буквы «икс». Ниже приведены некоторые приме ры шестнадцатеричных литералов.
Управляющие последовательности символов
Большинство печатаемых символов достаточно заключить в одинарные кавычки, но набор в текстовом редакторе некоторых символов, например возврата каретки, вы зывает особые трудности. Кроме того, ряд других символов, в том числе одинарные и двойные кавычки, имеют специальное назначение в С#, поэтому их нельзя исполь зовать непосредственно. По этим причинам в C# предусмотрены специальные управ ляющие последовательности символов, иногда еще называемые константами с обратной косой чертой (табл. 3.2). Такие последовательности применяются вместо тех символов, которых они представляют.
Таблица 3.2. Управляющие последовательности символов
| Управляющая последовательность | Описание |
|---|---|
| \a | Звуковой сигнал (звонок) |
| \b | Возврат на одну позицию |
| \f | Перевод страницы (переход на новую страницу) |
| \n | Новая строка (перевод строки) |
| \r | Возврат каретки |
| \t | Горизонтальная табуляция |
| \v | Вертикальная табуляция |
| \0 | Пустой символ |
| ‘ | Одинарная кавычка |
| « | Двойная кавычка |
| \ | Обратная косая черта |
Например, в следующей строке кода переменной ch присваивается символ табу ляции.
А в приведенном ниже примере кода переменной ch присваивается символ оди нарной кавычки.
В С# поддерживается еще один тип литералов — строковый. Строковый литерал представляет собой набор символов, заключенных в двойные кавычки. Например сле дующий фрагмент кода:
представляет собой текстовую строку. Образцы подобных строк не раз встречались в приведенных выше примерах программ.
Помимо обычных символов, строковый литерал может содержать одну или не сколько управляющих последовательностей символов, о которых речь шла выше. Рас смотрим для примера программу, в которой используются управляющие последова тельности \n и \t.
Результат выполнения этой программы приведен ниже.
В приведенном выше примере программы обратите внимание на то, что для пере хода на новую строку используется управляющая последовательность \n. Для выво да нескольких строк совсем не обязательно вызывать метод WriteLine() несколько раз — достаточно вставить управляющую последовательность \n в тех местах удли ненной текстовой строки (или строкового литерала), где должен происходить переход на новую строку. Обратите также внимание на то, как в текстовой строке формируется знак кавычек.
Помимо описанной выше формы строкового литерала, можно также указать бук вальный строковый литерал. Такой литерал начинается с символа @, после которого следует строка в кавычках. Содержимое строки в кавычках воспринимается без изме нений и может быть расширено до двух и более строк. Это означает, что в буквальный строковый литерал можно включить символы новой строки, табуляции и прочие, не прибегая к управляющим последовательностям. Единственное исключение составля ют двойные кавычки («), для указания которых необходимо использовать две двой ные кавычки подряд («»). В приведенном ниже примере программы демонстрируется применение буквальных строковых литералов.
Результат выполнения этой программы приведен ниже.
Следует особо подчеркнуть, что буквальные строковые литералы выводятся в том же виде, в каком они введены в исходном тексте программы.
Преимущество буквальных строковых литералов заключается в том, что они позво ляют указать в программе выводимый результат именно так, как он должен выглядеть на экране. Но если выводится несколько строк, то переход на новую строку может на рушить порядок набора исходного текста программы с отступами. Именно по этой причине в примерах программ, приведенных в этой книге, применение буквальных строковых литералов ограничено. Тем не менее они приносят немало замечательных выгод во многих случаях, когда требуется форматирование выводимых результатов.
И последнее замечание: не путайте строки с символами. Символьный литерал, на пример ‘X’, обозначает одиночную букву типа char. А строка, состоящая из одного символа, например «X», по-прежнему остается текстовой строкой.
Более подробное рассмотрение переменных
Переменные объявляются с помощью оператора следующей формы:
где тип — это тип данных, хранящихся в переменной; а имя_переменной — это ее имя. Объявить можно переменную любого действительного типа, в том числе и опи санных выше типов значений. Важно подчеркнуть, что возможности переменной опре деляются ее типом. Например, переменную типа bool нельзя использовать для хра нения числовых значений с плавающей точкой. Кроме того, тип переменной нельзя изменять в течение срока ее существования. В частности, переменную типа int нельзя преобразовать в переменную типа char.
Все переменные в C# должны быть объявлены до их применения. Это нужно для того, чтобы уведомить компилятор о типе данных, хранящихся в переменной, прежде чем он попытается правильно скомпилировать любой оператор, в котором использу ется переменная. Это позволяет также осуществлять строгий контроль типов в С#. В С# определено несколько различных видов переменных. Так, в предыдущих при мерах программ использовались переменные, называемые локальными, поскольку они объявляются внутри метода.
Задать значение переменной можно, в частности, с помощью оператора присваи вания, как было не раз продемонстрировано ранее. Кроме того, задать начальное зна чение переменной можно при ее объявлении. Для этого после имени переменной ука зывается знак равенства (=) и присваиваемое значение. Ниже приведена общая форма инициализации переменной:
где значение — это конкретное значение, задаваемое при создании переменной. Оно должно соответствовать указанному типу переменной. Ниже приведены некоторые примеры инициализации переменных.
Если две или более переменные одного и того же типа объявляются списком, разде ляемым запятыми, то этим переменным можно задать, например, начальное значение.
В данном примере инициализируются только переменные b и с.
В приведенных выше примерах в качестве инициализаторов переменных исполь зовались только константы, но в C# допускается также динамическая инициализация переменных с помощью любого выражения, действительного на момент объявления переменной. Ниже приведен пример краткой программы для вычисления гипотенузы прямоугольного треугольника по длине его противоположных сторон.
Результат выполнения этой программы выглядит следующим образом.
В данном примере объявляются три локальные переменные: s1, s2 и hypot. Две из них (s1 и s2) инициализируются константами, А третья (hypot) динамически ини циализируется вычисляемой длиной гипотенузы. Для такой инициализации исполь зуется выражение, указываемое в вызываемом методе Math.Sqrt(). Как пояснялось выше, для динамической инициализации пригодно любое выражение, действительное на момент объявления переменной. А поскольку вызов метода Math.Sqrt() (или лю бого другого библиотечного метода) является действительным на данный момент, то его можно использовать для инициализации переменной hypot. Следует особо под черкнуть, что в выражении для инициализации можно использовать любой элемент, действительный на момент самой инициализации переменной, в том числе вызовы методов, другие переменные или литералы.
Неявно типизированные переменные
Как пояснялось выше, все переменные в C# должны быть объявлены. Как прави ло, при объявлении переменной сначала указывается тип, например int или bool, а затем имя переменной. Но начиная с версии C# 3.0, компилятору предоставляется возможность самому определить тип локальной переменной, исходя из значения, ко торым она инициализируется. Такая переменная называется неявно типизированной. Неявно типизированная переменная объявляется с помощью ключевого слова var и должна быть непременно инициализирована. Для определения типа этой перемен ной компилятору служит тип ее инициализатора, т.е. значения, которым она инициа лизируется. Рассмотрим такой пример.
В данном примере переменная е инициализируется литералом с плавающей точкой, который по умолчанию имеет тип double, и поэтому она относится к типу double. Если бы переменная е была объявлена следующим образом:
то она была бы отнесена к типу float.
В приведенном ниже примере программы демонстрируется применение неявно типизированных переменных. Он представляет собой вариант программы из предыду щего раздела, измененной таким образом, чтобы все переменные были типизированы неявно.
Результат выполнения этой программы оказывается таким же, как и прежде.
Важно подчеркнуть, что неявно типизированная переменная по-прежнему остает ся строго типизированной. Обратите внимание на следующую закомментированную строку из приведенной выше программы.
Эта операция присваивания недействительна, поскольку переменная s1 относится к типу double. Следовательно, ей нельзя присвоить десятичное значение. Единствен ное отличие неявно типизированной переменной от обычной, явно типизированной переменной, — в способе определения ее типа. Как только этот тип будет определен, он закрепляется за переменной до конца ее существования. Это, в частности, означает, что тип переменной s1 не может быть изменен по ходу выполнения программы.
Неявно типизированные переменные внедрены в C# не для того, чтобы заменить собой обычные объявления переменных. Напротив, неявно типизированные перемен ные предназначены для особых случаев, и самый примечательный из них имеет отно шение к языку интегрированных запросов (LINQ), подробно рассматриваемому в главе 19. Таким образом, большинство объявлений переменных должно и впредь оставаться явно типизированными, поскольку они облегчают чтение и понимание исходного тек ста программы.
И последнее замечание: одновременно можно объявить только одну неявно типи зированную переменную. Поэтому объявление
является неверным и не может быть скомпилировано. Ведь в нем предпринимается попытка объявить обе переменные, s1 и s2, одновременно.
Область действия и время существования переменных
Все переменные, использовавшиеся в предыдущих примерах программ, объяв лялись в самом начале метода Main(). Но в C# локальную переменную разрешается объявлять в любом кодовом блоке. Как пояснялось в главе 2, кодовый блок начинает ся открывающей фигурной скобкой и оканчивается закрывающей фигурной скобкой. Этот блок и определяет область действия. Следовательно, всякий раз, когда начинается блок, образуется новая область действия. Прежде всего область действия определяет видимость имен отдельных элементов, в том числе и переменных, в других частях про граммы без дополнительного уточнения. Она определяет также время существования локальных переменных.
В C# к числу наиболее важных относятся области действия, определяемые классом и методом. Рассмотрение области действия класса (и объявляемых в ней переменных) придется отложить до того момента, когда в этой книге будут описываться классы. А до тех пор будут рассматриваться только те области действия, которые определяют ся методом иди же в самом методе.
Область действия, определяемая методом, начинается открывающей фигурной скобкой и оканчивается закрывающей фигурной скобкой. Но если у этого метода име ются параметры, то и они входят в область действия, определяемую данным методом.
Как правило, локальные переменные объявляются в области действия, невидимой для кода, находящегося вне этой области. Поэтому, объявляя переменную в опреде ленной области действия, вы тем самым защищаете ее от доступа иди видоизменения вне данной области. Разумеется, правила области действия служат основанием для ин капсуляции.
Области действия могут быть вложенными. Например, всякий раз, когда создается кодовый блок, одновременно образуется и новая, вложенная область действия. В этом случае внешняя область действия охватывает внутреннюю область. Это означает, что локальные переменные, объявленные во внешней области действия, будут видимы для кода во внутренней области действия. Но обратное не справедливо: локальные перемен ные, объявленные во внутренней области действия, не будут видимы вне этой области.
Для того чтобы стала более понятной сущность вложенных областей действия, рас смотрим следующий пример программы.
Как поясняется в комментариях к приведенной выше программе, переменная х объявляется в начале области действия метода Main(), и поэтому она доступна для всего последующего кода в пределах этого метода. В блоке условного оператора if объявляется переменная у. А поскольку этот кодовый блок определяет свою собствен ную область действия, то переменная у видима только для кода в пределах данного блока. Именно поэтому строка line у = 100;, находящаяся за пределами этого блока, закомментирована. Если удалить находящиеся перед ней символы коммента рия (//), то во время компиляции программы произойдет ошибка, поскольку пере менная у невидима за пределами своего кодового блока. В то же время переменная х может использоваться в блоке условного оператора if, поскольку коду из этого блока, находящемуся во вложенной области действия, доступны переменные, объявленные в охватывающей его внешней области действия.
Переменные могут быть объявлены в любом месте кодового блока, но они становят ся действительными только после своего объявления. Так, если объявить переменную в начале метода, то она будет доступна для всего остального кода в пределах этого метода. А если объявить переменную в конце блока, то она окажется, по существу, бес полезной, поскольку не будет доступной ни одному коду.
Если в объявление переменной включается инициализатор, то такая переменная инициализируется повторно при каждом входе в тот блок, в котором она объявлена. Рассмотрим следующий пример программы.
Ниже приведен результат выполнения этой программы.
Как видите, переменная у повторно инициализируется одним и тем же значением -1 при каждом входе во внутренний цикл for. И несмотря на то, что после этого цик ла ей присваивается значение 100, оно теряется при повторной ее инициализации.
В языке C# имеется еще одна особенность соблюдения правил области действия: не смотря на то, что блоки могут быть вложены, ни у одной из переменных из внутренней области действия не должно быть такое же имя, как и у переменной из внешней об ласти действия. В приведенном ниже примере программы предпринимается попытка объявить две разные переменные с одним и тем же именем, и поэтому программа не может быть скомпилирована.
int i; float f; i = 10; f = i; // присвоить целое значение переменной типа float
// Продемонстрировать неявное преобразование типа long в тип double. using System;
Как присвоить переменной текстовое значение c
Для хранения данных в программе применяются переменные . Переменная представляет именнованную область памяти, в которой хранится значение определенного типа. Переменная имеет тип, имя и значение. Тип определяет, какого рода информацию может хранить переменная.
Перед использованием любую переменную надо определить. Синтаксис определения переменной выглядит следующим образом:
Вначале идет тип переменной, потом ее имя. В качестве имени переменной может выступать любое произвольное название, которое удовлетворяет следующим требованиям:
имя может содержать любые цифры, буквы и символ подчеркивания, при этом первый символ в имени должен быть буквой или символом подчеркивания
в имени не должно быть знаков пунктуации и пробелов
имя не может быть ключевым словом языка C#. Таких слов не так много, и при работе в Visual Studio среда разработки подсвечивает ключевые слова синим цветом.
Хотя имя переменой может быть любым, но следует давать переменным описательные имена, которые будут говорить об их предназначении.
Например, определим простейшую переменную:
В данном случае определена переменная name, которая имеет тип string . то есть переменная представляет строку. Поскольку определение переменной представляет собой инструкцию, то после него ставится точка с запятой.
При этом следует учитывать, что C# является регистрозависимым языком, поэтому следующие два определения переменных будут представлять две разные переменные:
После определения переменной можно присвоить некоторое значение:
Так как переменная name представляет тип string, то есть строку, то мы можем присвоить ей строку в двойных кавычках. Причем переменной можно присвоить только то значение, которое соответствует ее типу.
В дальнейшем с помощью имени переменной мы сможем обращаться к той области памяти, в которой хранится ее значение.
Также мы можем сразу при определении присвоить переменной значение. Данный прием называется инициализацией:
Отличительной чертой переменных является то, что в программе можно многократно менять их значение. Например, создадим небольшую программу, в которой определим переменную, поменяем ее значение и выведем его на консоль:
Консольный вывод программы:
Константы
Отличительной особенностью переменных является то, что мы можем изменить их значение в процессе работы программы. Но, кроме того, в C# есть константы. Константа должна быть обязательно инициализирована при определении, и после определения значение константы не может быть изменено
Константы предназначены для описания таких значений, которые не должны изменяться в программе. Для определения констант используется ключевое слово const , которое указывается перед типом константы:
Так, в данном случае определена константа NAME , которая хранит строку «Tom». Нередко для название констант используется верхний регистр, но это не более чем условность.
При использовании констант надо помнить, что объявить мы их можем только один раз и что к моменту компиляции они должны быть определены. Так, в следующем случае мы получим ошибку, так как константе не присвоено начальное значение:
Кроме того, мы ее не сможем изменим в процессе работы программы:
Таким образом, если нам надо хранить в программе некоторые данные, но их не следует изменить, они определяются в виде констант. Если же их можно изменять, то они определяются в виде переменных.