1_Типы данных и переменные
Урок 1 : Типы данных и переменные
Переменные - это именованные ячейки памяти для хранения данных. В этом уроке вы узнаете, какие типы данных существуют в C# и как с ними работать.
1. Что такое переменная
Переменная - это именованная область памяти, в которой хранится значение определённого типа.
Можно представить переменную в виде контейнера с некоторым определённым содержимым.
Например бочка с водой или ящик с ноутбуками, в данном случае поменять содержимое контейнеров не получится, как и с переменными определённых типов.
Переменная состоит из трёх частей:
тип имя значение
↓ ↓ ↓
int counter = 0 ;
| Часть | Описание | Пример |
|---|---|---|
| Тип | Определяет, какие данные хранятся и сколько памяти занимают | int, string, bool |
| Имя | Идентификатор для обращения к переменной | counter, playerName |
| Значение | Данные, хранящиеся в переменной | 0, "Hero", true |
// Объявление и присвоение значения
int health = 100;
// Объявление без значения (значение по умолчанию)
int score; // score = 0 по умолчанию
string name; // name = null по умолчанию
// Изменение значения
health = 80;
- Переменные пишутся в camelCase:
playerHealth,maxSpeed - Имена должны быть говорящими:
hpхуже, чемcurrentHealth - Нельзя начинать имя с цифры:
2player- ошибка,player2- норма
2. Основные типы данных C#
Целочисленные типы
| Тип | Размер | Диапазон | Пример |
|---|---|---|---|
byte |
1 байт | 0 … 255 | Цвет канала RGB |
short |
2 байта | −32 768 … 32 767 | Небольшие счётчики |
int |
4 байта | ≈ −2 млрд … 2 млрд | Стандартный целый тип |
long |
8 байт | Очень большой диапазон | Метки времени (timestamp) |
int lives = 3;
long population = 8_000_000_000L; // L - суффикс для long, _ - разделитель для читаемости
Числа с плавающей точкой
| Тип | Размер | Точность | Пример использования |
|---|---|---|---|
float |
4 байта | ~7 цифр | Позиции, физика в Unity |
double |
8 байт | ~15 цифр | Научные расчёты |
decimal |
16 байт | ~28 цифр | Финансовые расчёты |
float speed = 5.5f; // f - суффикс обязателен для float!
double pi = 3.14159265; // double по умолчанию
decimal price = 9.99m; // m - суффикс для decimal
Без суффикса f значение 5.5 считается double. Написать float x = 5.5; - ошибка компиляции. Всегда пишите 5.5f.
Символы и строки
char letter = 'A'; // Один символ, в одинарных кавычках
string greeting = "Hello!"; // Строка символов, в двойных кавычках
string empty = ""; // Пустая строка
string nullStr = null; // Отсутствие строки (ссылка на ничто)
Основные методы строк
string - не просто набор символов: у строки есть встроенные методы для работы с текстом.
| Метод | Что делает | Пример | Результат |
|---|---|---|---|
Contains(s) |
Содержит ли строка подстроку s |
"Привет мир".Contains("мир") |
true |
Trim() |
Убирает пробелы с обоих концов | " текст ".Trim() |
"текст" |
Replace(a, b) |
Заменяет все вхождения a на b |
"а б в".Replace(" ", "") |
"абв" |
Split(c) |
Разбивает по разделителю c, возвращает string[] |
"a,b,c".Split(',') |
{"a","b","c"} |
Строка в C# неизменяема: методы возвращают новую строку, а не изменяют существующую. text.Trim() не меняет text - нужно сохранить результат в переменную:
text = text.Trim(); // теперь text обновлён
Логический тип
bool isAlive = true; // isAlive имеет занчение истина
bool hasKey = false; // hasKey имеет значение ложь
bool isGameOver = lives <= 0; // Результат сравнения - тоже bool. Если lives <= 0, isGameOver истина.
Итоговая таблица
| Тип | Категория | Значение по умолчанию |
|---|---|---|
int |
Целое | 0 |
float |
Вещественное | 0f |
double |
Вещественное | 0.0 |
bool |
Логический | false |
char |
Символ | '\0' |
string |
Строка | null |
3. Операторы присваивания и сравнения
Арифметические операторы
int a = 10;
int b = 3;
int sum = a + b; // 13 - сложение
int diff = a - b; // 7 - вычитание
int prod = a * b; // 30 - умножение
int quot = a / b; // 3 - целочисленное деление (дробная часть отбрасывается)
int rem = a % b; // 1 - остаток от деления
float x = 10f;
float y = 3f;
float div = x / y; // 3.333... - деление float даёт дробный результат
10 / 3 равно 3, а не 3.33. Чтобы получить дробный результат, хотя бы один операнд должен быть float/double: 10f / 3 или (float)10 / 3.
Присваивание
int x = 10; // = присваивает значение
x = 20; // x теперь равен 20
// Составные операторы присваивания
x += 5; // x = x + 5 → 25
x -= 3; // x = x - 3 → 22
x *= 2; // x = x * 2 → 44
x /= 4; // x = x / 4 → 11
x %= 3; // x = x % 3 (остаток от деления) → 2
// Инкремент и декремент
x++; // x = x + 1
x--; // x = x - 1
Сравнение
= - присваивает значение переменной.
== - сравнивает два значения и возвращает bool.
int a = 5;
int b = 10;
bool isEqual = (a == b); // false - равны ли?
bool notEqual = (a != b); // true - не равны?
bool less = (a < b); // true - меньше?
bool greater = (a > b); // false - больше?
bool lessOrEq = (a <= b); // true - меньше или равно?
bool greatOrEq = (a >= b); // false - больше или равно?
Логические операторы
bool hasHealth = true;
bool hasAmmo = false;
bool canFight = hasHealth && hasAmmo; // && (И): только оба true → true
bool canAct = hasHealth || hasAmmo; // || (ИЛИ): хотя бы одно true → true
bool isDead = !hasHealth; // ! (НЕ): инвертирует → false
4. Преобразование типов
Часто нужно перевести данные из одного типа в другой - например, текст от пользователя превратить в число для вычислений или число отобразить как строку.
Строка → число
int.Parse() - преобразует строку в int. Если строка не является числом - программа выдаст ошибку.
string input = "42";
int number = int.Parse(input); // 42
// Аналогично для других типов
float speed = float.Parse("3.14");
bool isReady = bool.Parse("true"); // "True" или "False" без учёта регистра
Безопасное преобразование: TryParse
int.TryParse() - пробует преобразовать строку. Если не получилось - возвращает false и не выдаёт ошибку.
Console.Write("Введите число: ");
string userInput = Console.ReadLine();
if (int.TryParse(userInput, out int result))
{
Console.WriteLine($"Вы ввели: {result}");
}
else
{
Console.WriteLine("Это не число!");
}
Parse- используйте, когда уверены в корректности данных (например, значение задали сами в коде).TryParse- используйте, когда данные приходят от пользователя: не падает при неверном вводе.
Число → строка
Метод ToString() есть у любого типа - он возвращает строковое представление значения:
int score = 100;
float speed = 3.14f;
bool isAlive = true;
string s1 = score.ToString(); // "100"
string s2 = speed.ToString(); // "3,14" (зависит от региональных настроек)
string s3 = isAlive.ToString(); // "True"
// На практике чаще используют интерполяцию - она вызывает ToString() автоматически:
Console.WriteLine($"Счёт: {score}, Жив: {isAlive}");
Явное приведение числовых типов
Для преобразования между числовыми типами используется (тип) перед значением:
double d = 9.99;
int i = (int)d; // 9 - дробная часть отбрасывается, не округляется!
int a = 42;
float f = (float)a; // 42.0f - расширение без потерь
float x = 3.7f;
int n = (int)x; // 3 - не 4!
(int)3.9 даёт 3, а не 4. Для округления используйте Math.Round().
5. Ключевое слово var
var позволяет не писать тип явно - компилятор выводит его из правой части выражения автоматически. Тип всё равно фиксируется при компиляции (это не динамическая типизация).
var age = 25; // компилятор видит 25 → int
var name = "Алексей"; // видит строку → string
var speed = 3.5f;// видит float-литерал → float
var player = new Player();// видит класс → Player
// Переменная с var по-прежнему строго типизирована:
age = "текст"; // ОШИБКА: нельзя присвоить строку переменной типа int
- Когда тип очевиден из правой части:
var list = new List<int>() - Когда имя типа очень длинное:
var dict = new Dictionary<string, List<int>>() - Избегайте
varтам, где тип неочевиден:var result = Calculate();- непонятно, что возвращаетCalculate
Для углублённого изучения
Значимые и ссылочные типы
В C# все типы делятся на две категории по тому, где хранятся данные:
Значимые типы (Value Types)
Хранят данные непосредственно в переменной. При присваивании создаётся копия.
int a = 10;
int b = a; // b - независимая копия
b = 99;
Console.WriteLine(a); // 10 - a не изменился!
Console.WriteLine(b); // 99
К значимым типам относятся: int, float, double, bool, char, struct, enum.
Ссылочные типы (Reference Types)
Хранят адрес (ссылку) на объект в куче памяти (heap). При присваивании копируется ссылка, а не сами данные.
int[] arr1 = { 1, 2, 3 };
int[] arr2 = arr1; // arr2 указывает на тот же массив!
arr2[0] = 99;
Console.WriteLine(arr1[0]); // 99 - arr1 тоже изменился!
К ссылочным типам относятся: string, class, array, interface.
Значимые типы хранятся в стеке, ссылочные - в куче. Это разные способы организации памяти: стек быстрый и автоматически очищается, куча позволяет хранить данные произвольного размера.
string - ссылочный тип, но ведёт себя похоже на значимый, потому что является неизменяемым (immutable). Каждое «изменение» строки создаёт новый объект в памяти.
Nullable-типы
По умолчанию значимые типы (int, float, bool и др.) не могут содержать null - у них всегда есть конкретное значение. Чтобы разрешить «отсутствие значения», используется знак вопроса после типа: int?.
int a = null; // ОШИБКА: int не может быть null
int? b = null; // OK: nullable int
int? score = null; // значение не задано
int? level = 5; // значение есть
// Проверка на null
if (score == null)
Console.WriteLine("Счёт не известен");
// Свойство HasValue и Value
if (level.HasValue)
Console.WriteLine($"Уровень: {level.Value}"); // "Уровень: 5"
| Тип | Может быть null | Значение по умолчанию |
|---|---|---|
int |
Нет | 0 |
int? |
Да | null |
bool |
Нет | false |
bool? |
Да | null |
Оператор ?? - null-coalescing (подстановка при null)
Возвращает левый операнд, если он не null, иначе - правый. Удобно задавать «значение по умолчанию» для nullable-переменных.
int? savedScore = null;
int displayScore = savedScore ?? 0; // savedScore == null → берём 0
Console.WriteLine(displayScore); // 0
string playerName = null;
string name = playerName ?? "Гость"; // "Гость"
// Цепочка ??
string result = a ?? b ?? c ?? "по умолчанию";
Оператор ?. - null-conditional (безопасный вызов)
Вызывает метод или обращается к свойству только если объект не null. Если объект null - возвращает null вместо выброса исключения.
string text = null;
// Без ?. - NullReferenceException!
// int len = text.Length;
// С ?. - безопасно
int? len = text?.Length; // null, а не исключение
// Комбинируем ?. и ??
int safeLen = text?.Length ?? 0; // 0, если text == null
// Пример с объектом
Player player = null;
player?.Attack(); // ничего не произойдёт, исключения не будет
?. и ?? вместе
Связка obj?.Property ?? defaultValue - один из самых частых паттернов в C#. Сначала безопасно читаем значение, потом подставляем запасное, если получили null.
Перечисления (enum)
Когда переменная должна принимать одно из нескольких заранее известных именованных значений, вместо «магических» чисел или строк используют enum. Это делает код читаемым и защищает от опечаток.
// Объявление enum (обычно - на уровне пространства имён или класса)
enum Direction
{
North, // = 0 по умолчанию
East, // = 1
South, // = 2
West // = 3
}
// Использование
Direction move = Direction.North;
Console.WriteLine(move); // "North"
Console.WriteLine((int)move); // 0
Явные числовые значения
Значения элементов можно задать вручную. Незаданные элементы продолжают нумерацию от предыдущего.
enum ItemRarity
{
Common = 0,
Uncommon = 1,
Rare = 10,
Epic = 20,
Legendary = 100
}
ItemRarity drop = ItemRarity.Rare;
Console.WriteLine((int)drop); // 10
Константы: const и readonly
const
Значение задаётся при компиляции и никогда не меняется. Должно быть известно на этапе написания кода.
const int MaxHealth = 100;
const float Gravity = 9.81f;
const string GameName = "MyGame";
MaxHealth = 200; // ОШИБКА: нельзя изменить константу
readonly
Значение задаётся при инициализации или в конструкторе, после чего не меняется. Подходит для значений, которые неизвестны до запуска программы.
class Config
{
readonly int startTime;
Config()
{
startTime = (int)DateTime.Now.Ticks; // можно задать в конструкторе
}
}
| Характеристика | const |
readonly |
|---|---|---|
| Когда задаётся | При компиляции | При инициализации или в конструкторе |
| Может быть полем класса | Да | Да |
| Может быть локальной переменной | Да | Нет |
| Допустимые типы | Только примитивы и string | Любые типы |
Итог урока
- Переменная это контейнер информации имеющий имя, тип и значение
- Основные типы:
int,float,bool,char,string - Методы строк:
Contains()- поиск подстроки;Trim()- убрать пробелы по краям;Replace()- замена;Split()- разбить на массив; методы не меняют оригинал, а возвращают новую строку - Арифметические операторы:
+,-,*,/,%; целочисленное деление отбрасывает дробную часть =- присвоение,==- сравнение;+=,-=- составные операторы- Преобразование типов:
int.Parse()- строка в число;TryParse()- безопасный вариант без ошибки при неверном вводе;ToString()- в строку;(тип)- явное числовое приведение (отбрасывает дробь, не округляет) var- компилятор выводит тип автоматически, тип всё равно фиксированный- Значимые типы копируют данные, ссылочные копируют адрес
- Nullable-типы (
int?): разрешаютnull;??подставляет значение по умолчанию,?.безопасно вызывает метод - enum - перечисление именованных констант; делает код читаемым и защищённым от ошибок
const- константа,readonly- неизменяемое поле
📋 Перейти к практическим заданиям урока 1
Материалы для дополнительного ознакомления :
Переменные и константы
Литералы
Типы данных
Арифметические операции
Условные выражения
Значимые и ссылочные типы
Строки