Файл: Понятие переменной в программировании. Виды и типы переменных (Язык программирования C++).pdf
Добавлен: 31.03.2023
Просмотров: 159
Скачиваний: 1
СОДЕРЖАНИЕ
8.1 Переменные в C#
Си-шарп – язык жесткой типизации. Каждая переменная должна быть определенного типа данных. Ниже, в таблице наведены встроенные типы данных языка Си-шарп:
Оперативная память - массив байтов, где каждый байт имеет уникальный адрес. Для bool достаточно одного бита: 0 - false, 1 - true, но минимальная адресуемая сущность - байт, поэтому ненулевой байт считается за истину, нулевой - ложью.
Таблица 1 – Типы данных C#
Тип |
Область значений |
Размер |
sbyte |
-128 до 127 |
Знаковое 8-бит целое |
byte |
0 до 255 |
Беззнаковое 8-бит целое |
char |
U+0000 до U+ffff |
16-битовый символ Unicode |
bool |
true или false |
1 байт* |
short |
-32768 до 32767 |
Знаковое 16-бит целое |
ushort |
0 до 65535 |
Беззнаковое 16-бит целое |
int |
-2147483648 до 2147483647 |
Знаковое 32-бит целое |
uint |
0 до 4294967295 |
Беззнаковое 32-бит целое |
long |
-9223372036854775808 до 9223372036854775807 |
Знаковое 64-бит целое |
ulong |
0 до 18446744073709551615 |
Беззнаковое 64-бит целое |
float |
±1,5*10-45 до ±3,4*1033 |
4 байта, точность — 7 разрядов |
double |
±5*10-324 до ±1,7*10306 |
8 байтов, точность — 16 разрядов |
decimal |
(-7,9 * 1028 до 7,9 * 1028) / (100–28) |
16 байт, точность — 28 разрядов |
Для того, чтобы использовать переменную, ее сначала нужно объявить:
static void Main(string[] args)
{
int a; // объявляем переменную a типа int
a = 5; // записываем в переменную a число 5
int b, c; // объявить можно сразу несколько переменных через запятую
bool d; // объявляем переменную d типа bool
d = true; // записываем в переменную d значение true (истина)
long e = 10; // при объявлении переменной можно сразу же задавать ей значение, это называется инициализацией
float f = 5.5f; // чтобы записать число с плавающей точкой типа float, нужно после значения добавлять суффикс f.
char g = 'g'; // объявление символьной переменой g с ее инициализацией значением символа 'g'
}
При использовании переменной, в которую не было записано значение, компилятор выдаст ошибку "Use of unassigned local variable [variableName]".
static void Main(string[] args)
{
int a;
Console.WriteLine(a); //ошибка
}
Язык Си-шарп чувствительный к регистру символов. Переменные max и Max это не одно и то же. Не забывайте этого, чтобы не иметь лишних проблем.
Имя переменной должно отображать суть данных, которые она отображает. Не стоит называть переменные ни о чем не говорящими именами типа a, b, c. Используйте английские слова. Высота – height, возраст – age и т. д.
Нельзя использовать кириллические символы в именах переменных.
Преобразование встроенных типов данных
Переменные одного типа можно преобразовывать в переменные другого типа. Преобразование бывает явным и неявным. Неявное преобразование выполняет компилятор.
Пример неявного преобразования:
static void Main(string[] args)
{
int a = 35;
short b = 10;
a = b; // неявное преобразование. Так как int большего размера, чем short – утери данных не будет
b = a; // ошибка компиляции, нельзя тип большего размера неявно преобразовать в тип меньшего размера
}
При явном преобразовании необходимо непосредственно перед переменной, которую вы хотите преобразовать, указать в скобках тип, к которому приводится переменная.
Пример явного преобразования:
static void Main(string[] args)
{
int a = 35000;
short b = 10;
b = (short) a; // в этом случае уже ошибки не будет. Так как максимальное значение типа short 32767, здесь будет утеря данных.
}
9. Kotlin
Kotlin стремительно развивается и обладает рядом преимуществ. Среди них:
- лаконичность языка программирования;
- совместимость с Java;
- поддерживается Google;
- рост сообщества.
Вполне возможно, что скоро приложения для Android-девайсов будут писаться исключительно на Kotlin, поэтому желающим развиваться в направлении мобильной разработки настоятельно рекомендуется присмотреться к данному ЯП.
9.1 Переменные в Kotlin
Для хранения данных в программе в Kotlin, как и в других языках программирования, применяются переменные. Переменная представляет именованный участок памяти, который хранит некоторое значение.
Каждая переменная характеризуется определенным именем, типом данных и значением. Имя переменной представляет поизвольный идентификатор, который может содержать алфавитно-цифровые символы или символ подчеркивания и должен начинаться либо с алфавитного символа, либо со знака подчеркивания. Для определения переменной можно использовать либо ключевое слово val, либо ключевое слово var.
Например, определим переменную age:
val age: Int |
Вначале идет слово val или var, затем имя переменной и через двоеточие тип переменной. То есть в данном случае объявлена переменная age, которая имеет тип Int. Тип Int говорит о том, что переменная будет содержать целочисленные значения.
После определения переменной ей можно присвоить значение:
fun main(args: Array<String>) { val age: Int age = 23 println(age) } |
Для присвоения значения переменной используется знак равно. Затем мы можем производить с переменной различные операции. Например, в данном случае с помощью функции println значение переменной выводится на консоль. И при запуске этой программы на консоль будет выведено число 23. Присвоение значение переменной должно производиться только после ее объявления. И также можно сразу присвоить переменной начальное значение при ее объявлении. Такой прием называется инициализацией:
fun main(args: Array<String>) { val age: Int = 23 println(age) } |
Изменяемые и неизменяемые переменные
Выше было сказано, что переменные могут объявляться как с помощью слова val, так и с помощью слова var. В чем же разница между двумя этими способами?
С помощью ключевого слова val определяется неизменяемая переменная (immutable variable). То есть можно присвоить значение такой переменной только один раз, но изменить его после первого присвоения уже не сможем.
Например, в следующем случае мы получим ошибку:
fun main(args: Array<String>) { val age: Int age = 23 // здесь норм - первое присвоение age = 56 // здесь ошибка - переопределить значение переменной нельзя println(age) } |
В этом плане подобные переменные похожи на константы в других языках программирования. А у переменной, которая определена с помощью ключевого слова var мы можем многократно менять значения (mutable variable):
fun main(args: Array<String>) { var age: Int age = 23 println(age) age = 56 println(age) } |
Поэтому если не планируется изменять значение переменной в программе, то лучше определять ее с ключевым словом val.
10. Rust
В 2016 году Rust занял первое место в опросе «что разработчики любят больше всего» на Stack Overflow. Rust оказался языком программирования, который разработчики действительно ценят (79.1% голосов). Язык разработки с открытым исходным кодом, разработанный Mozilla Foundation, работает как низкоуровневый.
Самое интересное здесь то, что Rust делает акцент на безопасном коде (т. е. объекты управляются языком программирования от начала до конца). В нем хоть и нет наследования, зато имеются способности (traits) и структуры. Данный язык программирования универсален и опирается на трех основах: эргономика, скорость и безопасность.
10.1 Переменные в Rust
Переменные в Rust объявляются ключевым словом let. Если тип переменной не указан, он определяется автоматически из контекста. По умолчанию все переменные неизменяемы (immutable), т.е. по сути константы. Ключевое слово mut позволяет создать изменяемое значение.
let hi = "hi";
let mut count = 0;
При желании можно определить тип явно «в стиле Pascal»:
let mut count: int = 0;
Указатели и их типы
По умолчанию все переменные и литералы в Rust размещаются статически в стеке. Для динамического выделения памяти используются указатели, но они отличаются от привычных в С/С++. Имеется три типа указателей: заимствованные (borrowed, задаются добавлением к переменной префикса «&»), принадлежащие (owned, префикс «~») и управляемые (managed, префикс «@»). Заимствованный указатель - это то же, что ссылка (reference) в С++; он является адресом уже соответствующей переменной:
let mut s = "Text"; // Текстовая переменная в стеке
let p = &s; // Ссылка на нее (адрес в памяти)
io::println(*p); // Разыменование ссылки и вывод на экран
Принадлежащий указатель, грубо говоря, эквивалентен классу unique_ptr<> в С++: при инициализации он выделяет память в куче и помещает туда переменную. Этот указатель уникален - никто другой не может ссылаться на ту же переменную:
let mut s1 = ~"Text"; // Переменная в куче
let mut s2 = s1; // Семантика перемещения - теперь s2 ссылается на выделенную
// память, а s1 не определен(произошло «перемещение»)
let p = &s1; // ОШИБКА! Ссылка s1 уже не определен!
Управляемый указатель похож на shared_ptr<> в С++, но он автоматически попадает в поле зрения сборщика мусора того потока, где он определен:
let mut s1 = @"Text"; // Переменная в куче потока
let mut s2 = s1; // s1 и s2 ссылаются на одну и ту же память
Массивы
В Rust имеются встроенные массивы (векторы) - как статические, так и динамические:
let a: [int,..3] = [1,5,10]; // Статический массив из 3 элементов
let mut b: @[int] = @[1,2,3]; // Динамический массив из 3 элементов
b += [4,5,6]; // добавляем еще три элемента
Функции объявляются следующим образом:
fn f1(val: int) -> int { // Функция возвращает тип int return 42+val;
}
io::println(fmt!("%i",f1(1))) // Выводим форматированное значение 43
Функции не видят окружающего их контекста и могут общаться с «внешним миром» только через переменные в стиле функциональных языков программирования. В том же стиле в Rust определены замыкания (анонимные функции с захватом контекста):
// Функция принимает как аргумент другую функцию с сигнатурой fn(int)
// и вызывает ее с параметром 10
fn call_closure_with_ten(b: &fn(int)) { b(10); }
// Переменная в локальном контексте
let captured_var = 20;
// Объявляем замыкание; между || перечисляются аргументы // все переменные локального контекста видны!
let closure = |arg| println(fmt!("captured_var=%d, arg=%d", captured_var, arg));
// Передаем замыкание в функцию
call_closure_with_ten(closure);
Как и переменные замыкания бывают трех типов: стековые, управляемые и принадлежащие с разными накладными расходами и областями применения. Например, так можно определить максимальное число в массиве с помощью обычного (стекового) замыкания:
let mut max = 0;
[1, 2, 3].map(|x| if *x > max { max = *x });
Заключение
Дух функционального программирования в Rust проник даже в управляющие конструкции. Например, нормального цикла for в Rust нет, но зато есть специальный синтаксис замыканий:
// Функция принимает массив чисел и другую функцию fn для их обработки
fn each(v: &[int], op: &fn(v: &int) -> bool) {
let mut n = 0; while n < v.len() {
if !op(&v[n]) { break;
}
n += 1;
}
}
// Вызываем нашу функцию а-ля управляющую конструкцию // Все, что находится в фигурных скобках, становится телом замыкания, // которое передается как второй аргумент в функцию each for each([2, 4, 8, 5, 16]) |n| { if *n % 2 != 0 {
println("found odd number!");
break;
}
}
СПИСОК ЛИТЕРАТУРЫ
1) Блэнди Д., Орендорф Д. Программирование на языке Rust / Д. Блэнди, Д. Орендорф, Д. А. Мовчан. – М., 2018. – 550с.
2) Усов В. А. Swift. Основы разработки приложений под iOS и macOS / Усов В. Санкт-Петербург – Изд-во: Питер, 2017 – 368 с.
3) Язык программирования C++. Базовый курс / Б. Л. Стенли , Ж. Лажойе, Б. Э. Му. – М., 2017. – 1120 с.
4) Язык программирования C# / А. Хейлмберг, М. Торгерсен, С. Вилтамут, П. Голд. – М. – 2012. – 784 с.
5) Саммерфильд М. Программирование на языке Go / М. Саммерфильд,
А. Кисилев. – Москва: Изд-во ДМК Пресс, 2013. – 580 с.
6) Зандстра М. PHP. Объекты, шаблоны и методики программирования / М. Зандстра, С. Тригуб. – Москва: Изд-во Вильямс, 2016. – 1000с.
7) Минник К., Холланд Е. JavaScript для чайников / К. Минник, Е. Холланд, А. Гузикевич. – М., 2016. – 500 с.
8) Шилдт Г. Java: Руководство для начинающих / Г. Шилдт, А. Гузикевич. – Москва: Изд-во Вильямс., 2017 – 500 с.