Учебное пособие (1077022), страница 3
Текст из файла (страница 3)
В данном издании unsafe-режим нерассматривается.Структура – это механизм языка, который представляет собой аналогкласса, но реализован на основе стека. Синтаксически структуры и классыв программе на C# мало различаются. Однако в некоторых случаяхиспользованиеструктурвместоклассовпозволяетповыситьпроизводительность приложения, иногда очень значительно. Например,массив структур хранится в стеке последовательно, обработка такогофрагмента данных не требует дополнительных переходов.
Массивобъектов классов хранится в виде массива указателей, при их обработкенеобходимо выполнить дополнительные переходы по указателям, чтоможет существенно увеличить время обработки данных. Поскольку всовременном варианте языка C# структуры в основном являются17механизмом оптимизации производительности приложений, то в данномиздании они не рассматриваются, их описание можно найти в [1, 2].3.2 Базовые типы данныхБазовые типы данных являются типами-значениями и хранятся встеке.Полная система базовых типов описана в [1]. Ниже будутрассмотрены только наиболее часто используемые типы.У каждого типа есть полное наименование, принятое в CTS, а такжекраткое, используемое в C#.
Допустимы оба варианта наименований, нодля удобства разработчики обычно предпочитают краткие наименования.Целочисленные типы данных представлены в таблице 1.Таблица 1Целочисленные типы данныхНаименованиеНаименованиев C#в CTSОписаниеsbyteSystem.SByteЦелое 8-битное число со знакомshortSystem.Intl6Целое 16-битное число со знакомintSystem.Int32Целое 32-битное число со знакомlongSystem.Int64Целое 64-битное число со знакомbyteSystem.ByteЦелое 8-битное число без знакаushortSystem.UIntl6Целое 16-битное число без знакаuintSystem.UInt32Целое 32-битное число без знакаulongSystem.UInt64Целое 64-битное число без знакаТипы данных с плавающей точкой представлены в таблице 2.Таблица 2Типы данных с плавающей точкойНаименованиеНаименованиеОписание18в C#floatв CTSSystem.Single32-битное число с плавающей точкойодинарной точности, около 7значащих цифр после запятойdoubleSystem.Double64-битное число с плавающей точкойдвойной точности, около 15значащих цифр после запятойdecimalSystem.Decimal128-битное число с плавающейточкой повышенной точности, около28 значащих цифр после запятойВнутреннее представление типа decimal отличается от внутреннегопредставления типов float и double.Описание логического типа представлено в таблице 3.Таблица 3Логический тип данныхНаименованиеНаименованиев C#в CTSboolSystem.BooleanОписаниеМожет принимать значения true илиfalse.В условных операторах C# и Java, как и в Паскале используетсялогический тип.
В классических С и С++ он отсутствует, его рольвыполняет целочисленный тип, но в некоторых современных диалектахС++ логический тип применяется.Описание символьного и строкового типов данных представлено втаблице 4.19Таблица 4Символьный и строковый типы данныхНаименованиеНаименованиев C#в CTSОписаниеcharSystem.CharСимвол UnicodestringSystem.StringСтрока символов UnicodeТип string является не типом-значением, а ссылочным типом.В языке C# ограничителем для символа служит одинарный апостроф,а для строки двойная кавычка. Пример объявления символа и строки:char c = '1';string str = "строка";Корневой тип в CTS – тип System.Object (в C# – object).
От негонаследуются все ссылочные типы и типы-значения. Сам тип objectявляется ссылочным.Большинство базовых типов являются типами-значениями, но типыstring и object стали исключением из этого правила.3.3 Преобразования типовПреобразование типов выполняется аналогично тому, как этопроисходит в С++ и Java с использованием оператора приведения типов –круглые скобки.Пример преобразования переменной типа double в тип int:double d1 = 123.45;int i1 = (int)d1;Оченьчасто,особенноприконсольномвводе,необходимопреобразовать строковое представление числа (введенное с клавиатуры) вчисловой формат. Это можно сделать тремя способами.20Первый состоит в том, что у каждого класса-типа существуетстатический метод Parse, преобразующий строку в числовой тип данных.Пример преобразования типов с использованием метода Parse:int i2 = int.Parse("123");double d2 = double.Parse("123,45");Метод Parse использует настройки локализации операционнойсистемы, в частности для переменной типа double в качестве разделителяцелой и дробной части используется запятая.
Если строка не содержиткорректного представления числа, метод Parse генерирует исключениеFormatException (исключения подробнее рассмотрены ниже).При втором способе вместо метода Parse используется TryParse. Вслучаенеудачногопреобразованияданныйметоднегенерируетисключение, но возвращает логическое значение false. Возвращаемоечисло представляется выходным параметром (out-параметр).Пример использования метода TryParse:int i3;bool result = int.TryParse("123", out i3);Третий способ заключается в применении класса Convert, которыйсодержит большое количество статических методов и может преобразоватьзначения большинства базовых между собой.Пример использования класса Convert:int i4 = Convert.ToInt32("123");Если же строка не содержит корректное представление числа, классConvert, как и метод Parse, генерирует исключение FormatException.3.4 Использование массивовДля объявления массивов в C# используется синтаксис:int[] array;21В языке С++ квадратные скобки должны ставить не после имени типа,а после имени переменной: int array[].
В Java допустимы оба вариантаобъявления.Если необходимо присвоить начальные значения элементам массива,то форма объявления следующая:int[] array = new int[3] {1, 2, 3};Аналогично для строкового типа:string[] strs =new string[3] { "строка1", "строка2", "строка3" };МногомерныемассивывязыкеC#бываютдвухвидов–прямоугольные и зубчатые (jagged).Объявление прямоугольных массивов очень похоже на их объявлениев Паскале.Пример объявления прямоугольного массива:int[,] matrix = new int[2, 2] { { 1, 2 }, { 3, 4 } };или:int[,] matrix = { {1,2}, {3,4} };или:int[,] matrix = new int[2, 2];matrix[0, 0] = 1;matrix[0, 1] = 2;matrix[1, 0] = 3;matrix[1, 1] = 4;Объявление зубчатых массивов похоже на их объявление в языкахС++ и Java.Пример объявления зубчатого массива:int[][] jagged = new int[3][];jagged[0] = new int[3] { 1, 2, 3 };jagged[1] = new int[2] { 4, 5 };jagged[2] = new int[4] { 6, 7, 8, 9 };В случае зубчатого массива каждый подмассив может иметьсобственную размерность.223.5 Консольный ввод-выводСредства консольного ввода-вывода в C# напоминают аналогичныесредства в Java и очень уступают по возможностям консольному вводувыводу в С++.Ввод-вывод в консоль осуществляется посредством класса Console, укоторого предусмотрены статические методы ввода-вывода данных: Console.WriteLine – вывод данных с переводом строки; Console.Write – вывод данных без перевода строки; Console.Read – чтение текущего символа; Console.ReadKey–чтениетекущегосимволаилифункциональной клавиши; Console.ReadLine – чтение строки до нажатия ввода.У класса Console также есть методы для чтения и изменения цветатекста, размеров окна и другие.ДлявводаданныхвконсолисуществуеттолькометодConsole.ReadLine, позволяющий ввести только строковый тип данных, ноне позволяющий вводить числовые типы данных.
Здесь язык C# уступаетпо возможностям консольной библиотеке С++. Поэтому в языке C# приразработке консольных приложений актуальным является преобразованиестрокового типа данных в другие типы.Методы Console.WriteLine и Console.Write имеют большое количествоперегрузок для вывода данных различных типов.Также существует перегрузка для форматированного вывода, когдапервым параметром указывается строка формата, а далее передаетсяпроизвольное количество параметров, которые подставляются в строкуформата.Пример использования метода WriteLine со строкой формата:int p1 = 2;int p2 = 4;23Console.WriteLine("{0} умножить на {1} = {2}", p1, p2, p1*p2);В консоль будет выведено:2 умножить на 4 = 8Фигурныескобкивстрокеформатаозначаютссылкунасоответствующий параметр, причем параметры нумеруются с нуля.
Такимобразом, вместо {0} будет подставлена переменная p1, вместо {1} –переменная p2, вместо {2} – выражение p1*p2.Пример, содержащий форматирование параметра:double d3 = 1.12345678;Console.WriteLine("{0} округленное до 3 разрядов = {0:F3}", d3);В консоль будет выведено:1,12345678 округленное до 3 разрядов = 1,123Выражение {0:F3} означает, что нулевой параметр нужно вывести ввиде числа с плавающей точкой, округлив до 3 знаков после разделителяразрядов.3.6 Основные конструкции программирования языка C#Данный раздел основан на примере 1, приведенном целиком. Вдальнейшем в основном будут даны только фрагменты примеров.usingusingusingusingusingSystem;System.Collections;System.Collections.Generic;System.Linq;System.Text;namespace Structures{class Program{/// <summary>/// Использование основных операторов/// </summary>/// <param name="args"></param>static void Main(string[] args){string str = "строка1";//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// Условия//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//Условный оператор (в отличие от С++ в условии используется логический тип)if (str == "строка1")24{Console.WriteLine("if: str == \"строка1\"");}else{Console.WriteLine("if: str != \"строка1\"");}//Условная операцияstring Result = (str == "строка1" ? "Да" : "Нет");Console.WriteLine("?: Равна ли строка '" + str + "' строке 'строка1' - " + Result);//Оператор switchstring Result2 = "";switch (str){case "строка1":Result2 = "строка1";break;case "строка2":case "строка3":Result2 = "строка2 или строка3";break;default:Result2 = "другая строка";break;}Console.WriteLine("switch: " + Result2);//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// Циклы//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//Цикл forConsole.Write("\nЦикл for: ");for (int i = 0; i < 3; i++)Console.Write(i);//Цикл foreachConsole.Write("\nЦикл foreach: ");int[] array1 = { 1, 2, 3 };foreach(int i2 in array1)Console.Write(i2);//Цикл whileConsole.Write("\nЦикл while: ");int i3 = 0;while (i3 < 3){Console.Write(i3);i3++;}//Цикл do whileConsole.Write("\nЦикл do while: ");int i4 = 0;do{Console.Write(i4);i4++;} while (i4 < 3);//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// Обработка исключений//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Console.WriteLine("\n\nДеление на 0:");try{25int num1 = 1;int num2 = 1;string zero = "0";int.TryParse(zero, out num2);int num3 = num1 / num2;}catch (DivideByZeroException e){Console.WriteLine("Попытка деления на 0");Console.WriteLine(e.Message);}catch (Exception e){Console.WriteLine("Собственное исключение");Console.WriteLine(e.Message);}finally{Console.WriteLine("Это сообщение выводится в блоке finally");}Console.WriteLine("\nСобственное исключение:");try{throw new Exception("!!! Новое исключение !!!");}catch (DivideByZeroException e){Console.WriteLine("Попытка деления на 0");Console.WriteLine(e.Message);}catch (Exception e){Console.WriteLine("Собственное исключение");Console.WriteLine(e.Message);}finally{Console.WriteLine("Это сообщение выводится в блоке finally");}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// Константы//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++const int int_const = 333;//Ошибка//int_const = 1;Console.WriteLine("Константа {0}", int_const);//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// Параметры функций//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//В С# по умолчанию аргументы обычных типов передаются по значению, а объектов по ссылке//Аргументы ref всегда передаются по ссылке//Аргументы out являются только выходными параметрамиstring RefTest = "Значение до вызова функций";ParamByVal(RefTest);Console.WriteLine("\nВызов функции ParamByVal.















