Главная > C# > Задачи по C#. Ответы.

Задачи по C#. Ответы.

Как обещал, привожу ответы на задачи по C#. Сами задачи находятся здесь http://blog.webferia.ru/lang/csharp/zadachi1/. Статья — копипаст с http://blogs.msdn.com/b/gaidar/archive/2008/11/10/9058797.aspx . Привожу ее как есть без каких либо изменений.

1. Каков результат компиляции и выполнения приведенного ниже кода?

static void Main(string[] args) 
{ 
    Console.WriteLine(GetSomeResult(10000)); 
}

static long GetSomeResult(long someValue) 
{ 
    long value1 = 10 * 1000 * 10000 * someValue; 
    long value2 = 10 * 1000 * 10000 * 100000; 
    return value2 / value1; 
}

Ответ: из-за строчки long value2 = 10 * 1000 * 10000 * 100000 возникает ошибка компиляции (переполнение int), поскольку вычисления производятся в int арифметике до присвоения значения переменной value2. Чтобы ошибки не возникало, нужно использовать один из параметров типа long, для этого можно явно указать литеру L у одного из чисел long value2 = 10 * 1000 * 10000 * 100000L;

2. Какое значение присвоено x, если приведенный ниже код выводит False?

float x; 
Console.Write(x == x)

Ответ: по спецификации это особенность NaN. Т.е. float x = float.NaN;

3. А почему следующий код выводит False?

public static void Main() 
{ 
    Test t = new Test(); 
    Console.WriteLine(t.Equals(t)); 
}

Ответ: этот вопрос — ловушка для людей ожидающих подвоха. Описанное поведение можно воспроизвести опледелив класс Test следующим образом:

public class Test
{
    public bool Equals(Test t)
    {
        return false;
    }
}

. Общее правило, которое подчеркивает эта задача — не стоит переопределять поведение методов с одинаковыми названиями — это обязательно запутает пользователей кода.

4. Что будет выведено на экран при выполнении приведенного ниже кода?

static void Main(string[] args) 
{ 
    char a = 'a'; 
    int b = 0; 
    Console.WriteLine(true ? a : b); 
}

Ответ: 97. Типы операндов не совпадают и компилятор приводит переменные к общему совместимому типу Int32.

5. А в этом случае, что будет на экране?

NameValueCollection col = new NameValueCollection(); 
Console.WriteLine("Элемент test " + col["test"] != null ? "Существует!" : "Не существует!");

Ответ: Существует. Сначала работает оператор +, после этого сравнивается с null строка «Это test».

6. Что следует ожидать на экране?

Console.WriteLine("A" + "B" + "C"); 
Console.WriteLine('A' + 'B' + 'C');

Ответ: ABC 198. Конкатенация для символов не определена, поэтому будут получены числовые значения, затем просуммированы.

7. Циклическая инициализация полей? Интересненько, а в результате что будет на консоли выведено?

public class A { public static int x = B.y + 1; } 
public class B { public static int y = A.x + 1; }

static void Main(string[] args) 
{ 
    Console.WriteLine("A.x = " + A.x); 
    Console.WriteLine("B.y = " + B.y); 
}

Ответ: A.x = 2 B.y = 1. Тут все просто: вызывается конструктор A, затем конструктор B, но т.к. не определено значение A.x, то для используется 0 в конструкторе B.

8. Инкремент, инкремент, а что же будет?

int j = 0;

for (int i = 0; i < 10; i++) 
    j = j++;

Console.WriteLine(j);

Ответ: 0. Подлый вопрос, поскольку тут внимание отвлекает ++. Но, на деле, оператор ++ возвращает значение переменной до инкрементации, поэтому j сохраняет исходное значение. (код, по сути, аналогичен z = j; j = j + 1; j = z ).

9. А что будет выведено в результате такого цикла?

int end = int.MaxValue; 
int begin = end - 100; 
int counter = 0;

for (int i = begin; i <= end; i++) 
    counter++;

Console.WriteLine(counter);

Ответ: цикл бесконечный по определению — все значения int меньше или равны int.MaxValue.

10. А такого?

float begin = 1000000000; 
int counter = 0;

for (float i = begin; i < (begin + 10); i++) 
    counter++;

Console.WriteLine(counter);

Ответ: бесконечный цикл. Для таких больших значений float нет разницы между begin + 1 и begin + 10. Вообще, использовать не целые счетчики циклов — моветон и дорога в ад.

11. Какой же метод выберет компилятор?

class A { public void Test(int n) { Console.WriteLine("A"); } } 
class B : A { public void Test(double n) { Console.WriteLine("B"); } }

static void Main(string[] args) 
{ 
    B b = new B(); 
    b.Test(5); 
}

Ответ: В. Приоритет отдается методу класса, по типу ссылки, если в нем определен метод с типами аргументов позволяющих выполнить преобразование без потерь.

12. А в этом случае?

public class Test 
{ 
    public Test(object obj) { Console.WriteLine("object"); } 
    public Test(int[] obj) { Console.WriteLine("int[]"); } 
}

public static void Main() { Test t = new Test(null); }

Ответ: Int[]. Компилятор при определении вызова не использует текущее значение, а выбирает наиболее «специфический» конструктор. Нужно явно указать указать тип, если есть желание вызвать конструктор object: new Test((object)null);

13. Что будут выведено на экран в результате выполнения кода приведенного ниже?

List<int> list = new List<int>() { 1, 2, 3, 4, 5 };

List<int> all = list.FindAll( 
i => { Console.Write(i); return i < 3; } 
);

Ответ: 12345. Делегат, переданный методу FindAll вызывается для каждого элемента. Вопрос на внимательность, поскольку делегат используется как фильтрующая функция, применяемая к каждому элементу.

14. А такого кода?

List<int> list = new List<int>() { 1, 2, 3 }; 
var x = list.GroupBy(i => { Console.Write(i); return i; }); 
var y = list.ToLookup(i => { Console.Write(i); return i; });

Ответ: 123. Выполнение GroupBy отложено до обращения к результату. Вывод 123123 будет если дописать, например, строку var z = x.ToArray();

15. И наконец, сложный вопрос из трех частей. Что будет выведено на экран в каждом из трех случаев, приведенных ниже:

А)

try { 
    Console.WriteLine("Hello "); 
    return; 
} 
finally { Console.WriteLine("Goodbye "); } 
Console.WriteLine("world!");

Ответ: Hello Goodbye. Finally выполняется даже если выполнение прервано по return.

Б)

try { 
    Console.WriteLine("Hello "); 
    Thread.CurrentThread.Abort(); 
} 
finally { Console.WriteLine("Goodbye "); } 
Console.WriteLine("world!");

Ответ: Hello Goodbye. Abort выбрасывает исключение ThreadAbortException, которое обрабатывается finally, затем выполнение прерывается.

В)

try { 
    Console.WriteLine("Hello "); 
    System.Environment.Exit(0); 
} 
finally { Console.WriteLine("Goodbye "); } 
Console.WriteLine("world!");

Ответ: Hello. Выполнение программы прерывается в точке вызова System.Environment.Exit(0) и управление передается ОС. Слишком жестко наступаем песне на горло.

На последок, небольшой бонус — задача, которую мне прислал Владимир Биллиг. Как вы думаете, что будет выведено в консоли в результате выполнения следующего кода (и почему):

byte b1 = 1, b2 = 2, b3 = b1 + b2;

if (b3 > b1) 
    Console.WriteLine("OK!"); 
else 
    Console.WriteLine("wow!");
Categories: C# Tags: ,
  1. агагаг
    4 февраля 2011 в 19:21 | #1

    вообще ошибку выдаст. так как b3 будет невозможно неявно преобразовать из byte в int.

  2. b_victor
    17 октября 2011 в 07:25 | #2

    Если поправить, то выдаст ОК!

    byte b1 = 1;
    byte b2 = 2;
    var b3 = (byte) (b1 + b2);

    Console.WriteLine(b3 > b1 ? «OK!» : «wow!»);

    Console.ReadKey();

  3. deiop
    16 июля 2012 в 12:45 | #3

    byte b1 = 1, b2 = 2, b3 = Convert.ToByte(b1 + b2);

  4. Юлия
    3 февраля 2014 в 08:08 | #4

    Помоги написать описание для этой программы. Что она делает и какие функции выполняет.
    using System;
    namespace ConsoleApplication1
    {
    class Demo
    {
    public int a = 13; // поле данных
    public const double c = 1.66; // константа
    public static string s = «Demo»; // статическое поле класса
    double y; // закрытое поле данных
    }

    class Class1
    { static void Main()
    {
    Demo x = new Demo(); // создание экземпляра класса Demo
    Console.WriteLine( x.a ); // x.a — обращение к полю класса
    Console.WriteLine( Demo.c ); // Demo.c — обращение к константе
    Console.WriteLine( Demo.s ); // обращение к статическому полю
    Console.ReadKey(true);
    }
    }

  5. Арман
    25 января 2017 в 17:02 | #5

    Интересные задачки

  1. Пока что нет уведомлений.