Рейтинг - 0.0 (0)

Всем огромный привет! Мы продолжаем изучать C# и сегодня мы рассмотрим интересные темы, такие как "переполнение переменных" и некоторые возможности переменных. Начнём с непонятным на первый взгляд переполнением. Каждый тип данных имеет свой диапазон значений. Основные перечислены в этом уроке(см. Диапазон значений). Если значение переменной будет вне диапазона, то это приведёт либо к ошибке приложения, либо к выводу некорректных данных. Для примера возьмём всеми любимый int:

Диапазон этого типа от -2147483648 до 2147483647. Если представить переменную в виде бутылки, то это будет выглядеть так:


Когда мы указываем некое значение переменной, то её ёмкость увеличивается в зависимости от самого значения.
Например выражение:
Код
int A = 0;
заполнит этот "бочонок" ровно до середины, так как он является центром диапазона:


При выполнении всяких операций над переменной, этот объём постоянно меняется. И существует вероятность, что переменная выйдет за пределы. Если значение слишком большое, то происходит "выливание" части значения. В шарпе обычно значение указывается на минимум, и прибавляется к нему остаток. Чтобы это продемонстрировать наглядно, напишем такой код:
Код
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1 {
    class Program {
        static void Main( string[] args ) {
            int A = 2147483647;
            A *= 2;
            Console.WriteLine( A );
            Console.ReadKey();
        }
    }
}
В результате мы получаем результат -2. Каким образом получилось такое явно неправильное значение? Давайте считать! Максимальный диапазон чисел составляет 2147483647. Дальше уже считается переполнением. Делается само умножение на значение, получаем 4294967294. Так как это значение вне диапазона, то система забирает остаток от максимального значения: 4294967294 - 2147483647 = 2147483647. Далее минимальный диапазон переменной прибавляет к результату вычитания, при этом отнимает единицу от мин. значения, чтобы значение "влезало" в диапазон: ( -2147483648 - 1) + 2147483647 = -2147483649 + 2147483647 = -2. Все эти операции нужны для того, чтобы значение переменной соответствовало указанному ей типу. В противных случаях переменная будет занимать больший размер(в байтах, и даже в битах), чем требуется, что делает работу приложения нестабильным. Вот и вся арифметика.

Возникает вопрос: как избежать переполнения? Самый простой вариант - указывать другой тип данных, с большим диапазоном, к примеру: long. Если такой вариант не устраивает, то можно воспользоваться конструкцией checked. Она позволяет проверить результат операции над переменной. К примеру так:
Код
A = checked( A *= 2 );
Если результат операции умножения выходит за диапазон, то возникает исключение. Этим можно восспользоваться! Заточим этот блок в try:
Код
try {
     A = checked( A *= 2 );
     Console.WriteLine( A );
} catch {
     Console.WriteLine( (long) A * 2);
}
Результат:


Далее по плану изучим out. Он используется в функциях как выходной параметр. Сам параметр должен быть создан в коде, где вызывается функция, а описания параметра функции должно встречаться в её теле. Простой пример такой функции:
Код
static void Plus( int Value, out int Result ) {
     Result = Value += 50;
}
А в теле мейна пишем:
Код
static void Main( string[] args ) {
     int k;
     Plus( 10, out k );
     Console.WriteLine( k );
     Console.ReadKey();
}
Результат:


С примера видно, что в теле основной программы мы создали переменную k. Мы не задавали ей никакого значения - за нас это сделала функция, которая реализовала это в теле. Результат записался в переменную k, как выходной параметр.

На очереди у нас ещё одна интересная фича - передача ссылок на переменные. Когда мы передаём в функцию какое-то значение, то в функцию кидается её копия. К примеру возьмём такую функцию:
Код
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1 {
    class Program {
        static void Main( string[] args ) {
            int A = 10;
            Plus( A );
            Console.ReadKey();
        }

        static void Plus( int A ) {
            A += 50;
            Console.WriteLine( "Функция: значение А = {0}", A);
        }
    }
}
Результат такой операции:

Давайте проверим, чему равно значение A:
Код
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1 {
    class Program {
        static void Main( string[] args ) {
            int A = 10;
            Plus( A );
            Console.WriteLine( "Мейн: значение А = {0}", A );
            Console.ReadKey();
        }

        static void Plus( int A ) {
            A += 50;
            Console.WriteLine( "Функция: значение А = {0}", A);
        }
    }
}
Проверяем нашу программу:


Как видим, в функцию передалась копия переменной, но есть одна фича, которая позволяет передавать переменную напрямую, используя ссылки, в c# известны как ref. Добавим эту сточку в параметр функции, а также объявим при вызове функции:
Код
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1 {
    class Program {
        static void Main( string[] args ) {
            int A = 10;
            Plus( ref A );
            Console.WriteLine( "Мейн: значение А = {0}", A );
            Console.ReadKey();
        }

        static void Plus( ref int A ) {
            A += 50;
            Console.WriteLine( "Функция: значение А = {0}", A);
        }
    }
}
Результат:


Таким образом мы можем динамически изменять значение переменных. Это также увеличивает скорость работы программы, так как она не создаёт копию параметров.

Надеюсь, этот урок был полезен для Вас. Это был мистерио, пока.

Теги: Детальнее о ref, out и checked
Вход на сайт

Поиск
Категории раздела
Мини-чат
Пожалуйста, все вопросы по скриптингу задавать на форуме!
Наш опрос
Чего не хватает сайту?
Всего ответов: 5
Активность на сайте
Пожертвования
Кошельки WebMoney:
U859420971000
R407741810602
Z331072372430
E314272616890
Друзья сайта
Полезные ресурсы
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Сегодня нас посетили:
Рекомендую
Реклама