- •1. База
- •Определения
- •Циклы
- •Целочисленные типы:
- •Вещественные типы – типы хранения дробной части
- •Квалификаторы
- •Строки
- •Реализация функций
- •Перегрузка функций (только в C++)
- •Указатели
- •Динамическое выделение памяти
- •Выделение памяти в C++
- •Адресная арифметика
- •Структуры
- •Практика
- •Задача #1
- •Задача #2
- •Задача #3
- •Задача #4
- •Задача #5
- •Задача #6
- •Задача #7
size_t – беззнаковый целочисленный тип, его размер позволяет хранить максимальное возможное количество бит, также количество бит позволяет гарантированно хранить значения указателя.
Чаще всего размер типа size_t является максимально возможным размером целочисленного типа для данной архитектуры.
sizeof – предназначен для определения размер типа или переменной. Возвращает размер типа или переменной в байтах. (stddef.h)
Возвращаемое оператором sizeof имеет тип size_t.
Строки
Строка — массив символов типа char
Нуль-терминированные строки (обычные) относятся к “char”. Обязательно есть терминальный
ноль, с помощью него задается конец строки
char a; - переменная, которая обладает двойственностью: 1) число ;2) символ.
Имя массива - адрес массива.
%s - рассматривает пробел как конец строки
‘\0’ - символ терминального нуля (невозможно ввести с клавиатуры)
a[0]=’h’ - изменение символа в строке
a[4]=’\0’ - в консоль выводятся только первые 4 элемента (0,1,2,3)
Всё, что после терминального нуля - игнорируется.
strlen - функция для определения длины строки (кол-ва символов строки, без учёта терминального нуля), заголовочные файлы <string.h> для C и <cstring> для C++;
Объявление функции: size_t strlen(const char* s);
strcpy(char* dst, const char* src); dst - строка, в которую копируются все символы из строки src (включая терминальный ноль).(НЕБЕЗОПАСНАЯ ФУНКЦИЯ!!!)
strncpy(char* dst, const char* src, size_t n); dst - строка, в которую копируются не
более, чем n символов из строки src, терминальный ноль копируется только в случае, если
длина строки src (без учёта ‘\0’) меньше n.
strcat(char* dst,const char* src); dst - строка, к которой( с конца) добавляются все символы из строки src ( включая терминальный ноль). Первый символ строки src (символ с индексом 0) записывается на место терминального нуля в строке dst и тд.(НЕБЕЗОПАСНАЯ
ФУНКЦИЯ!!!)
strncat(char* dst, const char* src, size_t n); dst - строка, к которой (с конца)
добавляются не более n символов из строки src. Терминальный ноль добавляется всегда!!!
Аргумент n должен учитывать автоматическое добавление терминального нуля.
Реализация функций
Функция - именованная область кода, которая может принимать на вход один или более аргументов и может возвращать значение какого-либо типа.
Аргументы функции - локальные переменные этой функции
Пример:
int GetMax (int a, int b) {
if (a>b) return a;
else return b
}
Пример 2 (код функции после её вызова):
int GetMin(int a; int b); int main()
{
int x,y,z;
......
}
int GetMin(int a, int b) {
if (a<b) return a;
else return b
}
Квалификатор static сохраняет в памяти значение локальных переменных (переменные автоматически обнуляются, если не инициализированы).
Пример:
static int GetMax (int a, int b) {
if (a>b) return a;
else return b
}
Квалификатор inline хуй его знает что делает, у меня нет этого в конспекте, вставлю из инета
upd: забейте он используется только в заголовочных файлах.
Квалификатор register (64 бит) - устаревший, но невозможно использовать получение адреса в переменную с квалификатором register (возможны неточности).
Квалификатор volatile указывает, что переменная может изменяться извне.
Стек - выделенная область памяти, предназначенная для передачи аргументов в функции, для хранения адресов возврата и т.д.
Структура стека: (от младших адресов к старшим, для примера возьмём функцию GetMax)
int GetMax(int a, int b)
Локальные переменные GetMax - Адрес возврата – a - b
Адрес возврата - указатель места в функции на котором прекратилось выполнение функции для выполнения другой функции.
Пример:
z = GetMax(x,y);
printf("%d\n",z) - эта строчка будет адресом возврата.
Способы передачи значения:
1)По значению;
2)По адресу;
3)По ссылке.
1)Изменение аргументов в функции не будет заметно извне (если аргумент передан по
значению), т.к функция будет работать с копиями значений, взятых из стека.
2)При необходимости изменить значение переменной, чтобы изменение затронуло переменную вне функции.
3)(Только в c++) Технически ничем не отличается от передачи по адресу.
(Тут должны быть примеры с кодом, но я не могу их вставить, если надо скину в беседу).
Оператор sizeof не применим для массивов, переданных в качестве аргумента. Размер
указателя равен битности системы.
(Ещё пример).
При передаче многомерного массива значения в первых скобках можно не писать, но остальные квадратные скобки обязательно указывать со значениями.(Пример: int a[5][3][4] - int a [][3][4]).
Вариативная функция - функция с переменным количеством аргументов. В такой функции один аргумент обязателен, остальные - нет.
int Example (int a, ...);
Команды для работы с вариативными функциями: va-start; va-end; va-copy; va-arg.
Заголовочные файлы: <stdarg.h> для C и cstdarg для C++
Перегрузка функций (только в C++)
добавлю потом, там много кода
Указатели
Указатель - это переменная, значением которой является адрес какого-либо объекта в оперативной памяти. Размер указателя совпадает с размером архитектуры.
Используя указатель, можно обратиться к значению переменной или изменить её.
Страница ОЗУ - некоторая минимальная часть оперативной памяти с которой компьютер может работать. Программы работают так, будто вся ОЗУ выделена под программу. У каждой страницы
есть физический и виртуальный адреса. Физические адреса разные, а виртуальные могут совпадать. Не каждый адрес можно прочитать или записать в него что-либо.
Гарантируется, что значения 2-х указателей, которые равны NULL, совпадают. Страница с
адресом 0 не дается программе, для избежания ошибки.
void* - указатель на объект, тип которого неизвестен.
Динамическое выделение памяти
malloc - выделение доп памяти, нужна для создания динамических массивов. В случае если ОЗУ
была успешно выделена, то функция malloc возвращает указатель на выбранную ОЗУ. В случае ошибки возвращает NULL.
Если выделить 0 байт в функции malloc, то вернется нулевой указатель или значение, которое нельзя использовать.
int* a; int n;
scanf("%d",&n);
a=(int*)malloc (n*sizeof(a[0])); if(a==NULL)
{ printf("Error\n");
