В переменные длины массивы в C: руководство для начинающих

Здравствуйте, будущие программисты! Сегодня мы отправимся в увлекательное путешествие в мир переменных массивов длины (VLA) в C. Не волнуйтесь, если вы новички в программировании - я буду вашим доброжелательным гидом, объясняя все шаг за шагом. Так что погружаемся!

C - Variable Length Arrays

Что такое переменные массивы длины?

Прежде чем мы начнем, давайте поймем, что такое переменные массивы длины. Представьте, что вы планируете вечеринку, но не знаете, сколько гостей придет. Не было бы замечательно, если бы вы моглиsetup стол, который магически adjusts了自己的 размер в зависимости от количества гостей? Именно так VLAs работают в программировании!

Переменный массив длины - это массив, размер которого определяется во время выполнения (когда запускается программа), а не во время компиляции (когда программа готовится к запуску). Эта функция была введена в стандарте C99 и предоставляет большую гибкость при создании массивов.

Создание переменного массива длины

Давайте начнем с простого примера создания VLA:

#include <stdio.h>

int main() {
int n;
printf("Сколько чисел вы хотите сохранить? ");
scanf("%d", &n);

int numbers[n];  // Это наш переменный массив длины

printf("Введите %d чисел:\n", n);
for (int i = 0; i < n; i++) {
scanf("%d", &numbers[i]);
}

printf("Вы ввели: ");
for (int i = 0; i < n; i++) {
printf("%d ", numbers[i]);
}

return 0;
}

Разберем это:

  1. Мы спрашиваем пользователя, сколько чисел он хочет сохранить.
  2. Мы создаем массив numbers с размером n, который ввел пользователь.
  3. Затем мы используем цикл для ввода n чисел от пользователя.
  4. Наконец, мы выводим все числа, которые ввел пользователь.

Вот красота VLA - нам не нужно было знать размер массива при написании кода. Размер определяется во время выполнения программы!

Двумерные переменные массивы длины

Теперь давайте поднимем уровень и рассмотрим двумерные VLAs. Представьте, что вы создаете схему рассадки на свадь, но не знаете, сколько столов будет или сколько мест будет на каждом столе. Двумерные VLAs могут помочь!

Вот пример:

#include <stdio.h>

int main() {
int tables, seats;

printf("Сколько столов? ");
scanf("%d", &tables);

printf("Сколько мест за столом? ");
scanf("%d", &seats);

int seating[tables][seats];  // Наш 2D переменный массив длины

// Присваиваем номера мест
for (int i = 0; i < tables; i++) {
for (int j = 0; j < seats; j++) {
seating[i][j] = i * seats + j + 1;
}
}

// Выводим схему рассадки
printf("\nСхема рассадки:\n");
for (int i = 0; i < tables; i++) {
printf("Стол %d: ", i + 1);
for (int j = 0; j < seats; j++) {
printf("%3d ", seating[i][j]);
}
printf("\n");
}

return 0;
}

В этом примере:

  1. Мы спрашиваем пользователя о количестве столов и мест за столом.
  2. Мы создаем двумерный массив seating с размерами [tables][seats].
  3. Мы присваиваем номера мест каждому месту.
  4. Наконец, мы выводим схему рассадки.

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

Рваные массивы

Теперь, где事情 становятся действительно интересными. Что, если каждый стол на нашей свадь имеет разное количество мест? Введите рваный массив - массив массивов, где каждый подмассив может иметь разную длину.

Хотя C не поддерживает рваные массивы напрямую, как некоторые другие языки, мы можем имитировать их с помощью VLA и указателей. Вот как:

#include <stdio.h>
#include <stdlib.h>

int main() {
int tables;
printf("Сколько столов? ");
scanf("%d", &tables);

int *seats = malloc(tables * sizeof(int));
int **seating = malloc(tables * sizeof(int*));

// Вводим количество мест для каждого стола
for (int i = 0; i < tables; i++) {
printf("Сколько мест за столом %d? ", i + 1);
scanf("%d", &seats[i]);
seating[i] = malloc(seats[i] * sizeof(int));
}

// Присваиваем номера мест
for (int i = 0; i < tables; i++) {
for (int j = 0; j < seats[i]; j++) {
seating[i][j] = j + 1;
}
}

// Выводим схему рассадки
printf("\nСхема рассадки:\n");
for (int i = 0; i < tables; i++) {
printf("Стол %d: ", i + 1);
for (int j = 0; j < seats[i]; j++) {
printf("%3d ", seating[i][j]);
}
printf("\n");
}

// Освобождаем выделенную память
for (int i = 0; i < tables; i++) {
free(seating[i]);
}
free(seating);
free(seats);

return 0;
}

Этот пример более сложен, так что давайте разберем его:

  1. Мы создаем массив seats для хранения количества мест для каждого стола.
  2. Мы создаем указатель на указатель seating для имитации нашего рваного массива.
  3. Мы динамически выделяем память для каждого стола на основе его количества мест.
  4. Мы присваиваем номера мест и выводим схему рассадки, как и раньше.
  5. Наконец, мы освобождаем выделенную память, чтобы избежать утечек памяти.

Этот подход позволяет нам иметь разное количество мест для каждого стола -真正做到 гибкость!

Методы таблицы

Вот quick reference таблица методов, которые мы использовали в наших примерах:

Метод Описание Пример
scanf() Читает форматированный ввод от пользователя scanf("%d", &n);
printf() Выводит форматированный вывод в консоль printf("Привет, %s!", name);
malloc() Динамически выделяет память int *arr = malloc(n * sizeof(int));
free() Освобождает динамически выделенную память free(arr);

Помните, с великой властью приходит великая ответственность. VLAs и динамическое распределение памяти - это мощные инструменты, но их нужно использовать осторожно, чтобы избежать проблем, таких как переполнение стека или утечки памяти.

И вот и все! Вы только что сделали свои первые шаги в мир переменных массивов длины в C. Помните, практика делает мастера, так что не бойтесь экспериментировать с этими концепциями. Счастливого кодирования!

Credits: Image by storyset