2016 пересдача ответы вариант 2 (1161202)
Текст из файла
Ответы на вопросы экзамена по курсу«Языки программирования» 09.01.2017В ответах курсивом выделены необязательные пояснения, которые можно опустить(особенно на экзамене)Вариант 2Задача 2-1Есть ли ошибка в тексте приведенной ниже функции r_vowels(s) на языке C#(функция подсчитывает число гласных букв русского алфавита в строке-аргументе s)?Если есть, то объясните, в чем она состоит и как изменить текст функции, чтобы онаработала правильно?public static int r_vowels(string s) {int i,cnt = 0; const string vowels = ”АЕЁИОУЫЭЮЯаеёиоуыэюя”;for (i=0; i<s.Length; ++i) if (vowels.IndexOf(s[i])>=0) ++cnt;return cnt;}ОтветТекст этой задачи с небольшими изменениями, вызванными синтаксическими различиямиC# и JavaScript, скопирован из задачи 1 первого варианта (для JavaScript), однако ответыв задачах различны в силу различий в представлении символов в двух языках.В языке C# представление символов в оттранслированной программе (и, следовательно,строк) зафиксировано — это кодировка Юникода UTF16 (в .NET – UTF16 Little-Endian).Поэтому операция индексирования строк вполне корректна для выделения символа изстрок на русском языке, и функция будет работать правильно.Задача 2-2Что будет выдано в стандартный канал вывода после выполнения следующей программы на С++? Считать,что все нужные директивы include и using добавлены в текст.class TT {int _p;public:TT(const TT& t) : _p(t._p){ cout << "TT& " << _p<< endl;}explicit TT(int p = 0) : _p(p){cout << "Hello, "<< _p << endl; }~TT() {cout << "goodbye, " << _p << endl;}};int main() { list<TT> v; v.push_back(TT(1)); v.push_back(TT(2)); return 0; }Добавьте в класс TT РОВНО ОДИН метод так, чтобы результатом стали следующие строки (<CR> означаетпереход на новую строку):Hello, 1<CR> TT&& 1<CR> goodbye, -1<CR> Hello, 2<CR> TT&& 2<CR> goodbye, -2<CR> goodbye, 1<CR>goodbye, 2<CR>ОтветБудет выдано:Hello, 1TT& 1goodbye, 1Hello, 2TT& 2goodbye, 2goodbye, 1goodbye, 2Надо вставить конструктор перемещения (move-конструктор):TT(TT&& t): _p(t._p) { t._p = -t._p; cout << "TT&& " << _p << endl;}Задача 2-3Дайте определение функции-генератора языка Python.
Напишите пример функции-генератора, включая ееиспользование. Как связаны понятия функции-генератора и сопрограммы в Python?ОтветФункция-генератор отличается от обычной тем, что содержит конструкцию yield. ВызовФГ возвращает объект-итератор it. Последовательный вызов фунции next(it) передаетуправление ФГ до очередного yield. Данные, которые указаны в yield, возвращаются какрезультат вызова next(it). При выходе из ФГ генерируется исключение StopIterationПример;def NN(n):for in range(1,n+1):yield i*iИспользование:for x in NN(100):print(x)Печатает первые 100 квадратов целых чисел (1,4,9,16,..…)Связь сопрограмм и ФГ — см ответ на задачу 1-3 первого вариантаЗадача 2-4На языке Java написан класс CSV (не компилируется из-за отсутствия объявления имени Printer и знаковвопроса в вызовах метода print):public class CSV {public static void main(String[] args) {for (int i = 0; i < 10; ++i) print(???, i); // подставить правильное значениеprint(???, 10); // подставить правильное значение}static void print(Printer p, Object x) {p.print(x);}static void printInner(Object x) {System.out.print('\"');System.out.print(x); System.out.print("\", ");}static void printLast(Object x) {System.out.print('\"');System.out.print(x); System.out.println("\"");}}Объявить тип данных Printer и заменить вопросы в вызовах метода print на правильные значения (НЕИСПОЛЬЗУЯ лямбда-выражения) так, чтобы в канал вывода было выдано:"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"ОтветСм.
ответ и замечания по поводу задачи 1-4 из первого вариантаВо-первых, надо определить функциональный интерфейсметодом print(Object x):Printerc единственнымpublic interface Printer {void print(Object x);}Во-вторых, вставить вместо вопросов ссылки на методы классаCSV:for (int i = 0; i < 10; ++i) print(CSV::printInner, i);print(CSV::printLast, 10);Замечание: если бы не ограничение в условии, то можно было бы вместо вопросовподставить лямбда-выражения вида: x→{ тело соответствующего метода}Задача 2-5Переписать программу из задачи №4 на языке С# так, чтобы она выдавала в стандартный канал вывода те жесамые значения (набор и сигнатуры методов класса CSV должны остаться без изменения). Для выводаиспользовать System.Console.Write(…) и WriteLine(…)ОтветСм. ответ и замечания по поводу задачи 1-5 из первого вариантаpublic class CSV{delegate void Printer(Object x);static void Main(String[] args) {for (int i = 0; i < 10; ++i) print(CSV.printInner, i);print(CSV.printLast, 10);}static void print(Printer p, Object x){p(x);}static void printInner(Object x) {System.Console.Write('\"');System.Console.Write(x);System.Console.Write("\", ");}static void printLast(Object x) {System.Console.Write('\"');System.Console.Write(x);System.Console.WriteLine("\"");}}Задача 2-6Объявление шаблонного класса CalcSort на языке С++ предполагает, что над параметром шаблона Tвыполняются 4 арифметические операции (+,-,*,/), операции сравнения:template <typename T> class CalcSort { … };Напишите эквивалентное объявление обобщенного класса CalcSort на языке C# (опустив, как и выше,все объявления членов класса), добавив при необходимости нужные объявления типов вне этого класса.ОтветВ силу того, что реальное инстанцирование обобщений и генерация кода в C# происходятв момент выполнения (runtime), то вся информация о свойствах типа ( то есть обоперациях над типом) должна быть доступна компилятору в точке определенияобобщения (а не в точке конкретизации, как в С++), когда ничего не известно оконкретных фактических аргументах.
Ее задают посредством where-клаузы вопределении обобщения. При этом удобнее всего «запаковать» эти свойства в интерфейс(а не конкретный класс, хотя и так можно) — и указать, что тип-фактическийпараметр должен реализовывать этот интерфейс. Тут возникает две проблемы: вопервых, только классы или структуры могут быть фактическими параметрами этогообобщения, во-вторых, интерфейсы не могут содержать перегрузки стандартныхопераций (в С# стандартные операции перегружаются статическими методами,которых у интерфейсов быть не может). Поэтому надо указать для сравнений —стандартный интерфейс IСomparable, а арифметические операции выразить с помощьюсвоего интерфейса, который по условию и требуется определить.interface Arithmetic<T> {T Add(T x);T Mult(T x);T Sub(T x);T Div(T x);}class CalcSort<T> where T : IComparable<T>, Arithmetic<T> { … }Ошибкойявляетсяуказаниенесколькихпараметровметодоварифметическогоинтерфейса,неупотреблениеобобщенныхинтерфейсов, другие ограничения (зачем лишние?) типа class,struct и т.
д., перегрузки стандартных операций в интерфейсах.Грубейшей ошибкой является зыбыть про ограничения вообщеЗадача 2-7Дайте определение и пример внутреннего класса в языке Java. Есть ли аналогичное понятие в языках С++или С#?ОтветКоротко: детали ответа можно найти в книге Гослинга, Арнольда и Холмса «Языкпрограммирования Java» 3-е издание, п.5.2. Внутренние классы, стр.142-144.В С# и C++ такого понятия нет.Замечание. Постоянная (и грубая) ошибка: путать внутренние и вложенные классы.Это - «две большие разницы».
Подробно и обстоятельно написано там же в 5 главе«Вложенные классы и интерфейсы».Задача 2-8Пусть программа на языке Java содержит следующий ошибочный фрагмент:class D { }interface IFace <T, R>{R Generate();void Process(T x);}IFace<Object, D> i1;i1 = new ObjectFace(); //error!i1 = new DFace(); //error!class ObjectFace implements IFace<Object,Object> {public Object Generate() { return newObject();}public void Process(Object x) {}}class DFace implements IFace<D, D> {public D Generate() { return new D(); }public void Process(D x) { }}Объясните, в чем состоит ошибка, и исправьте РОВНО ОДНУ строчку во фрагменте так, чтобы ошибкаисчезла.ОтветСм.
ответ и замечания по поводу задачи 1-8 из первого вариантаВ языке Java указание вариантности делается не при определении, а приИСПОЛЬЗОВАНИИ обобщенного интерфейса. Это делается с помощью понятияметасимвольной маски типа-параметра обобщения. Без метасимвольной маскиконкретизация обобщенного интерфейса инвариантна. Но мы можем объявитьпеременную с типом — конкретизацией обобщенного интерфейса, где в качествепараметра типа стоит символьная маска.
Тогда к этой переменной может бытьковариантно (? super T) или контравариантно (? extends T) преобразовано значениеконкретизаций обобщенного интерфейса без масок.ВместоIFace<Object, D> i1;поставить IFace<? extends Object, ? super D> i1;.
Характеристики
Тип файла PDF
PDF-формат наиболее широко используется для просмотра любого типа файлов на любом устройстве. В него можно сохранить документ, таблицы, презентацию, текст, чертежи, вычисления, графики и всё остальное, что можно показать на экране любого устройства. Именно его лучше всего использовать для печати.
Например, если Вам нужно распечатать чертёж из автокада, Вы сохраните чертёж на флешку, но будет ли автокад в пункте печати? А если будет, то нужная версия с нужными библиотеками? Именно для этого и нужен формат PDF - в нём точно будет показано верно вне зависимости от того, в какой программе создали PDF-файл и есть ли нужная программа для его просмотра.














