#define _CRT_SECURE_NO_WARNINGS
#include <stdint.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

// 1) Функция для редактирования значения переменной через указатель
void edit_and_print_value(int* num) {
	printf("Введите новое значение переменной: ");
	scanf("%d", num); // Изменяем значение переменной через указатель
	printf("Текущее значение переменной: %d\n", *num); // Выводим новое значение
}

// 2) Функция для создания и удаления массива из 1 млн элементов
void create_and_delete_array() {
	int* array = (int*)malloc(1000000 * sizeof(int)); // Выделяем память для массива
	if (array == NULL) {
		printf("\nОшибка выделения памяти!\n");
		return;
	}

	// Заполняем массив
	for (int i = 0; i < 1000000; i++) {
		*(array + i) = i;
	}

	// Вывод первых 10 элементов
	printf("\nПервые 10 элементов массива: \n");
	for (int i = 0; i < 10; i++) {
		printf("%d ", *(array + i));
	}
	printf("\n");

	// Вывод последних 10 элементов
	printf("Последние 10 элементов массива: \n");
	for (int i = 999990; i < 1000000; i++) {
		printf("%d ", *(array + i));
	}
	printf("\n");

	free(array); // Освобождаем память
	printf("Массив удален.\n");
}

// 3) Функция для вывода массива произвольной длины
void print_array(int* array, int length) {
	printf("\nЭлементы массива:\n");
	for (int i = 0; i < length; i++) {
		printf("%d ", *(array + i));
	}
	printf("\n");
}

// 4) Функция для вывода треугольной матрицы
void create_matrix() {
	int rows = 5;
	int count = 1;

	// Выделяем память для строк
	int** matrix = (int**)malloc(rows * sizeof(int*));

	// Заполняем каждую строку
	for (int i = 0; i < rows; i++) {
		matrix[i] = (int*)malloc((i + 1) * sizeof(int));
		for (int j = 0; j <= i; j++) {
			matrix[i][j] = count++;
		}
	}

	// Вывод матрицы
	printf("\nТреугольная матрица:\n");
	for (int i = 0; i < rows; i++) {
		for (int j = 0; j <= i; j++) {
			printf("%d ", matrix[i][j]);
		}
		printf("\n");
	}

	// Освобождаем память
	for (int i = 0; i < rows; i++) {
		free(matrix[i]);
	}
	free(matrix);
}

// 5) Функция с указателем на функцию
void example_function(int x) 
{
	printf("\nЗначение: %d\n", x);
}

// Функция, принимающая указатель на функцию в качестве аргумента
void call_function(void (*func)(int), int value) {
	func(value); // Вызываем переданную функцию
}

int main() {
	// Устанавливаем кодировку для русскоязычного вывода
	system("chcp 1251>null");

	// 1) Редактирование значения переменной через указатель
	int value;
	printf("Введите начальное значение переменной: ");
	scanf("%d", &value);
	edit_and_print_value(&value);

	// 2) Создание и удаление массива из 1 млн элементов
	create_and_delete_array();

	// 3) Вывод массива произвольной длины
	int array[] = { 1, 2, 3, 4, 5 };
	int length = sizeof(array) / sizeof(array[0]);
	print_array(array, length);

	// 4) Создание и вывод треугольной матрицы
	create_matrix();

	// 5) Пример с указателем на функцию
	call_function(example_function, 10);

	return 0;
}
