Чаще всего программы обрабатывают не одиночные данные, а с наборы данных. Для хранения таких наборов в языке Си используются массивы. Массив представляет собой набор однотипных значений. Объявление массива выглядит следующим образом:
тип_переменной название_массива [длина_массива]
После типа переменной идет название массива, а затем в квадратных скобках размер массива - максимальное количество значений, которое можно поместить в массив.
Важно !!! Все элементы массива располагаются в памяти подряд !!!
Каждый элемент массива имеет свой номер, который называется индексом. По этому индексу можно обращаться к отдельным элементам. Например:
#include <stdio.h>
int
main(
void
)
{
int
numbers[4];
numbers[0] = 1;
numbers[1] = 2;
numbers[2] = 3;
numbers[3] = 4;
printf
(
"numbers[0] = %d \n"
, numbers[0]);
// 1 - первый элемент
printf
(
"numbers[2] = %d \n"
, numbers[2]);
// 3 - третий элемент
return
0;
}
Важно !!! Нумерация элементов начинается с нуля, поэтому первый элемент массива имеет индекс 0, а не 1 - numbers[0] !!!
Язык Си позволяет сразу объявить и инициализировать массив значениями. Для этого применяется инициализатор - набор значений в фигурных скобках. При этом размер массива можно явно не указывать, так как он будет вычисляться исходя из количества элементов в инициализаторе:
int numbers[] = { 1, 2, 3, 5 };
Также, можно инициализировать не все элементы, но в этом случае следует указывать размер массива:
int numbers[5] = { 10, 12}; // 10, 12, 0, 0, 0
Можно инициализировать значения не по порядку:
int numbers[5] = { [1]=11, [3] = 13 };
Важно !!! Если начальные значения не заданы, то в памяти лежит мусор !!!
Размер массива можно установить динамически с помощью переменной/константы:
#include <stdio.h>
int main( void )
{
int maxSize;
printf ("Input num = ");
scanf("%d", &maxSize);
int array[maxSize];
array[0] = 1;
array[1] = 2;
array[2] = 3;
for (int i = 0; i < maxSize; i++)
{
printf ("%d = %d\n", i, array[i]);
}
return 0;
}
После инициализации элементов массива их значения можно многократно изменять, но иногда не требуется или даже нежелательно изменять элементы массива. В этом случае можно определить массив как константный, и компилятор выдаст ошибку при попытке изменения массива
const int numbers[3] = {11, 12, 13};
Многомерные массивы
Часто в программах удобнее работать с многомерным массивом - массив, элементами которого являются другие массивы. Для примера определим двухмерный массив чисел:
int
numbers[3][2] = { {1, 2}, {4, 5}, {7, 8} };
Здесь массив numbers имеет три элемента (3 строки), а каждый из этих элементов сам представляет массив из двух элементов (2 столбцов).
Стоит отметить, что двухмерные и прочие многомерные массивы фактически являются абстракциями. В реальности все массивы являются одномерными и представляют сплошной блок памяти:
int
numbers[3][2] = { 1, 2, 4, 5, 7, 8 };
Для перебора многомерного массива используются вложенные циклы. Общее количество циклов равно мерности массива. Пример перебора двумерного массива:
#include <stdio.h>
int
main(
void
)
{
int
numbers[3][2] = { {1, 2}, {4, 5}, {7, 8} };
// проходим по 3 строкам таблицы
for
(
int
i = 0; i < 3; i++)
{
// проходим по 2 столбцам каждой строки
for
(
int
j = 0; j < 2; j++)
{
printf
(
"numbers[%d][%d] = %d \n"
, i, j, numbers[i][j]);
}
}
return
0;
}
Размер и количество элементов массива
Для того, чтобы узнать размер массива, можно использовать оператор sizeof, который возвращает размер всего массива в байтах в виде значения типа size_t:
#include <stdio.h>
int main( void )
{
int numbers[] = { 5, 6, 7};
size_t size = sizeof(numbers);
size_t count = sizeof(numbers) / sizeof(numbers[0]);
printf("numbers size: %zu \n", size); // numbers size: 12
printf("count: %zu \n", size); // count: 12
return 0;
}
Так как size_t фактически является псевдонимом для типа unsigned long long, то есть 64-разрядное положительное число, то для его вывода на консоль применяется спецификатор %zu.
Количество элементов в массиве можно вычислить разделив размер всего массива на размер одного элемента:
size_t
count =
sizeof
(numbers) /
sizeof
(numbers[0]);
Сортировка пузырьком
При работе с данными часто возникает потребность в их сортировке. Для этого существуют алгоритмы различной сложности и быстродействия. Самый простой из них – это сортировка пузырьком.
Напишем программу, получающую данные массива от пользователя и сортирующую этот массив по возрастанию, используя сортировку пузырьком:
#include <stdio.h>
#define MAX_SIZE 5
int Input(int* arr, int n)
{
int i;
for(i=0; i < n; i++)
scanf("%d",&arr[i]);
return i;
}
void Print(int *arr,int len)
{
int i;
for (i = 0; i < len; i++)
printf("%d ",arr[i]);
printf("\n");
}
void SwapArr(int *arr,int i,int j)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
void BubbleSort(int* arr,int n)
{
int noSwap;
for (int i = 0; i < n; i++)
{
printf("%d\n",i);
noSwap = 1;
for (int j = n-1; j > i; j--)
{
if( arr[j - 1] > arr[j] )
{
SwapArr(arr,j-1,j);
noSwap = 0;
}
}
if(noSwap)
break;
}
}
int main( void )
{
int arr[MAX_SIZE];
Input(arr, MAX_SIZE);
BubbleSort(arr, MAX_SIZE);
Print(arr, MAX_SIZE);
return 0;
}
В константе MAX_SIZE устанавливается размер массива, функция Input получает значения элементов массива, функция BubbleSort осуществляет сортировку, функция Print выводит значения элементов на консоль. Функция SwapArr является вспомогательной и просто меняет элементы местами.
Комментарии ()