Язык программирования C
Последнее обновление: 18.05.2017
Язык программирования С (си) является одним из самых популярных и распространенных языков. Он представляет компилируемый язык программирования
общего назначения со статической типизацией, разработанный в 1969—1973 годах в компании Bell Labs программистом Деннисом Ритчи (Dennis Ritchie).
Язык С нередко называют языком программирования «среднего уровня» или даже «низкого уровня», так как он сочетает элементы языков высокого уровня с
функциональностью и производительностью ассемблера и работает близко к аппаратной части компьютера. В итоге мы можем манипулировать данными на низком уровне и при этом использовать высокоуровневые конструкции для
управления работы программы.
Первоначально язык С предназначался для написания операционной системы Unix. Впоследствии Си стал одним из популярных языков, а его основной
сферой применения стало системное программирование, в частности, создание операционных систем, драйверов, различных утилит, антивирусов и т.д.
К слову сказать, Linux большей частью написан на Си. Однако только системным программированием применение данного языка не ограничивается. Данный язык можно использовать в программах любого уровня, где важны скорость работы и
производительность. Так, мы можем писать с помощью Си и прикладные приложения, и даже веб-сайты (используя технологию CGI — Common Gateway Interface). Но,
конечно, для создания графического интерфейса и веб-приложений, как правило, выбираются более подходящие инструменты и технологии, но тем не менее круг
использования Си довольно широк. Это в немалой степени определило популярность языка. Например, в известном рейтинге языков программирования TIOBE язык С
долгое время уверенно удерживает второе место.
Несмотря на большие возможности язык Си одновременно довольно прост. Он не содержит много конструкций, библиотек, его легко осваивать и изучать. Поэтому нередко его выбирают в качестве
языка для изучения в целом программированию.
Си является компилируемым языком, а это значит, что компилятор транслирует исходный код на Си в исполняемый файл, который содержит набор машинных инструкций.
Но разные платформы имеют свои особенности, поэтому скомпилированные программы нельзя просто перенести с одной платформы на другую и там уже запустить.
Однако на уровне исходного кода программы на Си обладают переносимостью, а наличие компиляторов, библиотек и инструментов разработки почти под
все распространенные платформы позволяет компилировать один и тот же исходный код на Си в приложения под эти платформы.
Развитие Си оказало большое влияние в целом на развитие языков программирования. В частности, его синтаксис стал основой для таких языков как
С++, С#, Java, PHP, JavaScript. Особо следует сказать про связь с C++. C++ напрямую произошёл от Си. Но впоследствии их
развитие происходило отдельно друг от друга, и даже появилась несовместимость между ними. Стандарт C99 добавил в язык Си ряд конфликтующих с C++ особенностей. В итоге в настоящее время
оба языка являются фактически самодостаточными и развиваются независимо.
Основные особенности Си
-
Универсальность — один и тот же код может быть скомпилирован на почти каждой платформе (при наличии для нее компилятора)
-
Высокая скорость выполнения
-
Компактность, небольшой размер выходных скомпилированных файлов
Основные этапы развития
В 1978 году Брайан Керниган и Деннис Ритчи опубликовали первое издание своего знаменитого труда «Язык программирования Си». Долгое время эта книга
служила неформальной спецификацией языка Си. Однако быстрое распространение Си привело к необходимости выработки общих стандартов.
И в 1983 году организация ANSI (Американский национальный институт стандартов) создала комитет для разработки спецификации Си.
А в 1989 году спецификация была утверждена. Эту версию языка принято называть ANSI C или C89.
В 1990 году спецификация ANSI C была немного дополнена Международной организацией по стандартизации (ISO). Новый стандарт стал называться ISO/IEC 9899:1990 или сокращенно С90.
В конце 1990-х годов стандарт подвергся пересмотру, что привело к выходу нового стандарта в 1999 году, который принято называть C99 (официальное название ISO 9899:1999).
И в декабре 2011 был опубликован новый и последний на данный момент стандарт для языка Си — С11 (официальное название ISO/IEC 9899:2011).
Вперед
Структуры
Последнее обновление: 16.09.2019
Наряду с классами структуры представляют еще один способ создания собственных типов данных в C#. Более того многие примитивные типы, например,
int, double и т.д., по сути являются структурами.
Например, определим структуру, которая представляет человека:
struct User { public string name; public int age; public void DisplayInfo() { Console.WriteLine($"Name: {name} Age: {age}"); } }
Как и классы, структуры могут хранить состояние в виде переменных и определять поведение в виде методов. Так, в данном случае
определены две переменные — name и age для хранения соответственно имени и возраста человека и метод DisplayInfo для вывода информации о человеке.
Используем эту структуру в программе:
using System; namespace HelloApp { struct User { public string name; public int age; public void DisplayInfo() { Console.WriteLine($"Name: {name} Age: {age}"); } } class Program { static void Main(string[] args) { User tom; tom.name = "Tom"; tom.age = 34; tom.DisplayInfo(); Console.ReadKey(); } } }
В данном случае создается объект tom. У него устанавливаются значения глобальных переменных, и затем выводится
информация о нем.
Конструкторы структуры
Как и класс, структура может определять конструкторы. Но в отличие от класса нам не обязательно вызывать конструктор для создания объекта структуры:
User tom;
Однако если мы таким образом создаем объект структуры, то обязательно надо проинициализировать все поля (глобальные переменные) структуры перед получением
их значений или перед вызовом методов структуры. То есть, например, в следующем случае мы получим ошибку, так как обращение к полям и методам происходит
до присвоения им начальных значений:
User tom; int x = tom.age; // Ошибка tom.DisplayInfo(); // Ошибка
Также мы можем использовать для создания структуры конструктор без параметров, который есть в структуре по умолчанию и при вызове которого полям структуры будет
присвоено значение по умолчанию (например, для числовых типов это число 0):
User tom = new User(); tom.DisplayInfo(); // Name: Age: 0
Обратите внимание, что при использовании конструктора по умолчанию нам не надо явным образом иницилизировать поля структуры. Также мы можем определить свои конструкторы
Например, изменим структуру User:
Также мы можем определить свои конструкторы. Например, изменим структуру User:
using System; namespace HelloApp { struct User { public string name; public int age; public User(string name, int age) { this.name = name; this.age = age; } public void DisplayInfo() { Console.WriteLine($"Name: {name} Age: {age}"); } } class Program { static void Main(string[] args) { User tom = new User("Tom", 34); tom.DisplayInfo(); User bob = new User(); bob.DisplayInfo(); Console.ReadKey(); } } }
Важно учитывать, что если мы определяем конструктор в структуре, то он должен инициализировать все поля структуры, как в данном случае устанавливаются
значения для переменных name и age. Также, как и для класса, можно использовать инициализатор для создания структуры:
Также, как и для класса, можно использовать инициализатор для создания структуры:
User person = new User { name = "Sam", age = 31 };
Но в отличие от класса нельзя инициализировать поля структуры напрямую при их объявлении, например, следующим образом:
struct User { public string name = "Sam"; // ! Ошибка public int age = 23; // ! Ошибка public void DisplayInfo() { Console.WriteLine($"Name: {name} Age: {age}"); } }
НазадВперед
Фреймворк Moq
Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core
Последнее обновление: 31.10.2015
Кроме собственно фреймворков для создания и проведения юнит-тестов при тестировании часто бывают полезны такие фреймворки, которые
позволяют имитировать или эмулировать какую-то функциональность или создавать мок-объекты. Подобных фреймворков существует множество,
и одним из самых популярных является Moq.
Итак, возьмем проект из прошлой темы и подключим Moq через NuGet в проект тестов (а не в проект веб-приложения):
После этого в узел References проекта тестов будет добавлена библиотека Moq, содержащая всю основную функциональность.
Теперь изменим класс тестов следующим образом:
using Moq; ................. public class HomeControllerTest { public void IndexViewModelNotNull() { // Arrange var mock = new Mock<IRepository>(); mock.Setup(a => a.GetComputerList()).Returns(new List<Computer>()); HomeController controller = new HomeController(mock.Object); // Act ViewResult result = controller.Index() as ViewResult; // Assert Assert.IsNotNull(result.Model); } }
Для доступа к функциональности Moq вначале подключается соответствующее пространство имен .
Moq предназначен для имитации объектов. В данном случае имитируется функциональность репозитория. Для этого объект Mock типизируется
соответствующим типом:
Затем выполняется настройка mock объекта с помощью метода . Так как нам надо имитировать возвращение методом
набора объектов, то данный метод вызывается в методе Setup, а с помощью метода определяем данный набор объектов.
Поскольку контроллер HomeController теперь в конструкторе принимает объект репозитория, то мы можем передать в конструктор мок-объект, который имитирует функциональность
репозитория:
Теперь запустим тест. Он должен завершиться неудачей, так как у нас не передается в методе Index в представление никакой модели. Поэтому изменим метод
Index:
public ActionResult Index() { var model = repo.GetComputerList(); return View(model); }
И если мы сейчас запустим тест, то он пройдет успешно.
Теперь для примера добавим в класс тестов еще один метод:
public void IndexViewBagMessage() { // Arrange var mock = new Mock<IRepository>(); mock.Setup(a => a.GetComputerList()).Returns(new List<Computer>() { new Computer()}); HomeController controller = new HomeController(mock.Object); string expected = "В базе данных 1 объект"; // Act ViewResult result = controller.Index() as ViewResult; string actual = result.ViewBag.Message as string; // Assert Assert.AreEqual(expected, actual); }
Цель данного метода — проверить сообщение, передаваемое через ViewBag. Причем я хочу, чтобы сообщение передавалось, если
в базе данных больше 0 объектов. Для этого список, возвращаемый методом , инициализируется одним объектом. А
метод проверяет оба сообщения.
Запустим тест и увидим, что он завершился неудачей. Теперь нам надо изменить метод Index в главном проекте, чтобы он соответствовал тесту:
public ActionResult Index() { var model = repo.GetComputerList(); if (model.Count > 0) ViewBag.Message = String.Format("В базе данных {0} объект", model.Count); return View(model); }
Поскольку с помощью Moq мы имитировали в методе контроллера список с одним элементом, то если мы сейчас запустим тест, то он пройдет успешно, так как
строка в тесте и значение ViewBag.Message будут совпадать.
НазадВперед
Коллекция Dictionary
Последнее обновление: 31.10.2015
Еще один распространенный тип коллекции представляют словари. Словарь хранит объекты, которые представляют пару ключ-значение.
Каждый такой объект является объектом структуры KeyValuePair<TKey, TValue>. Благодаря свойствам и
, которые есть у данной структуры, мы можем получить ключ и значение элемента в словаре.
Рассмотрим на примере использование словарей:
Dictionary<int, string> countries = new Dictionary<int, string>(5); countries.Add(1, "Russia"); countries.Add(3, "Great Britain"); countries.Add(2, "USA"); countries.Add(4, "France"); countries.Add(5, "China"); foreach (KeyValuePair<int, string> keyValue in countries) { Console.WriteLine(keyValue.Key + " - " + keyValue.Value); } // получение элемента по ключу string country = countries; // изменение объекта countries = "Spain"; // удаление по ключу countries.Remove(2);
Класс словарей также, как и другие коллекции, предоставляет методы Add и Remove для добавления и удаления элементов.
Только в случае словарей в метод Add передаются два параметра: ключ и значение. А метод Remove удаляет не по индексу, а по ключу.
Так как в нашем примере ключами является объекты типа , а значениями — объекты типа , то словарь
в нашем случае будет хранить объекты . В цикле мы их можем получить и извлечь
из них ключ и значение.
Кроме того, мы можем получить отдельно коллекции ключей и значений словаря:
Dictionary<char, Person> people = new Dictionary<char, Person>(); people.Add('b', new Person() { Name = "Bill" }); people.Add('t', new Person() { Name = "Tom" }); people.Add('j', new Person() { Name = "John" }); foreach (KeyValuePair<char, Person> keyValue in people) { // keyValue.Value представляет класс Person Console.WriteLine(keyValue.Key + " - " + keyValue.Value.Name); } // перебор ключей foreach (char c in people.Keys) { Console.WriteLine(c); } // перебор по значениям foreach (Person p in people.Values) { Console.WriteLine(p.Name); }
Здесь в качестве ключей выступают объекты типа , а значениями — объекты . Используя свойство
, мы можем получить ключи словаря, а свойство соответственно хранит все значения в словаре.
Для добавления необязательно применять метод , можно использовать сокращенный вариант:
Dictionary<char, Person> people = new Dictionary<char, Person>(); people.Add('b', new Person() { Name = "Bill" }); people = new Person() { Name = "Alice" };
Несмотря на то, что изначально в словаре нет ключа ‘a’ и соответствующего ему элемента, то он все равно будет установлен. Если же он есть, то
элемент по ключу ‘a’ будет заменен на новый объект
Инициализация словарей
В C# 5.0 мы могли инициализировать словари следующим образом:
Dictionary<string, string> countries = new Dictionary<string, string> { {"Франция", "Париж"}, {"Германия", "Берлин"}, {"Великобритания", "Лондон"} }; foreach(var pair in countries) Console.WriteLine("{0} - {1}", pair.Key, pair.Value);
То начиная с C# 6.0 доступен также еще один способ инициализации:
Dictionary<string, string> countries = new Dictionary<string, string> { = "Париж", = "Берлин", = "Лондон" };
НазадВперед
Что такое F#
Последнее обновление: 14.07.2021
F# (F Sharp или Эф шарп) — это функциональный статически типизированный язык программирования общего пользования, который создан и развивается компанией Microsoft и который предназначен для широкого круга задач.
Отличительной чертой F# является то, что он работает поверх платформы .NET и тем самым позволяет в
определенной степени использовать возможности, предоставляемые этой платформой, например, систему типов, систему сборки мусора и т.д. Это также означает, что при компиляции
код на F# компилируется в промежуточный язык IL (Intermediate Language), понятный для платформы .NET. И при запуске .NET управляет
выполнением этого приложения.
Кроме того, благодаря этому мы можем в проекте на F# использовать вспомогательные библиотеки, написанные с помощью других .NET-языков (например,
на C# или VB.NET). Подобным образом мы можем на F# написать библиотеку и затем подключить ее в проекты на других .NET-языках.
F# кроссплатформенный, не привязанный к определенной операционной системе, на нем можно разрабатывать на Windows, MacOS и Linux.
F# — достаточно зрелый язык программирования. Его первая версия вышла в мае 2005 года. Последней версией на данный момент является F# 5.0,
которая вышла в ноябре 2020 года вместе с .NET 5.0.
Для разработки на F# необходимо установить .NET SDK. Для написания кода можно выбрать любой текстовый редактор, а компилировать приложения в консоли. Однако для упрощения разработки
на Windows также можно использовать такую бесплатную среду разработки как Visual Studio от Microsoft, которая имеет полноценную поддержку работы с данным языком и
необходимые шаблоны проектов. Под MacOS есть бесплатный аналог — Visual Studio for Mac
В качестве альтернативы также можно выбрать другую — платную среду разработки — Rider от компании JetBrains, которая также имеет поддержку F# и которая работает, как на Windows, так и на MacOS и Linux.
F# позволяет создавать самые разные приложения — простые консольные приложения, серверные веб-приложения, веб-сервисы,
десктопные и мобильные приложения. Стоит отметить, что кроме тех типов проектов, которые поддерживаются .NET SDK и Visual Studio по умолчанию,
есть куча проектов, которые позволяют использовать F# для создания других типов приложений. Например, проект Fable позволяет компилировать код
F# в код JavaScript и тем самым писать на F# браузерные (клиентские) веб-приложения.
НазадВперед