При решении задач с большим количеством данных одинакового типа использование переменных с различными именами, не упорядоченных по адресам памяти, затрудняет программирование. В подобных случаях в языке Си используют объекты, называемые массивами.
Массив — это непрерывный участок памяти, содержащий последовательность объектов одинакового типа, обозначаемый одним именем.
Массив характеризуется следующими основными понятиями:
Элемент массива (значение элемента массива) – значение, хранящееся в определенной ячейке памяти, расположенной в пределах массива, а также адрес этой ячейки памяти. Каждый элемент массива характеризуется тремя величинами:
- адресом элемента — адресом начальной ячейки памяти, в которой расположен этот элемент;
- индексом элемента (порядковым номером элемента в массиве);
- значением элемента.
Имя массива – идентификатор, используемый для обращения к элементам массива.
Размер массива – количество элементов массива
Размер элемента – количество байт, занимаемых одним элементом массива.
Графически расположение массива в памяти компьютера можно представить в виде непрерывной ленты адресов.
Представленный на рисунке массив содержит q элементов с индексами от 0 до q-1. Каждый элемент занимает в памяти компьютера k байт, причем расположение элементов в памяти последовательное.
Адреса i-го элемента массива имеет значение
n+k·i
Адрес массива представляет собой адрес начального (нулевого) элемента массива. Для обращения к элементам массива используется порядковый номер (индекс) элемента, начальное значение которого равно 0. Так, если массив содержит q элементов, то индексы элементов массива меняются в пределах от 0 до q-1.
Длина массива – количество байт, отводимое в памяти для хранения всех элементов массива.
ДлинаМассива = РазмерЭлемента * КоличествоЭлементов
Для определения размера элемента массива может использоваться функция
Например,
sizeof(int) = 4;
sizeof(float) = 4;
sizeof(double) = 8;
Объявление и инициализация массивов
Для объявления массива в языке Си используется следующий синтаксис:
тип имя[размерность]={инициализация};
Инициализация представляет собой набор начальных значений элементов массива, указанных в фигурных скобках, и разделенных запятыми.
Если количество инициализирующих значений, указанных в фигурных скобках, меньше, чем количество элементов массива, указанное в квадратных скобках, то все оставшиеся элементы в массиве (для которых не хватило инициализирующих значений) будут равны нулю. Это свойство удобно использовать для задания нулевых значений всем элементам массива.
Если массив проинициализирован при объявлении, то константные начальные значения его элементов указываются через запятую в фигурных скобках. В этом случае количество элементов в квадратных скобках может быть опущено.
При обращении к элементам массива индекс требуемого элемента указывается в квадратных скобках [].
Пример на Си
2
3
4
5
6
7
8
#include <stdio.h>
int main()
{
int a[] = { 5, 4, 3, 2, 1 }; // массив a содержит 5 элементов
printf("%d %d %d %d %d\n", a[0], a[1], a[2], a[3], a[4]);
getchar();
return 0;
}Результат выполнения программы:
Однако часто требуется задавать значения элементов массива в процессе выполнения программы. При этом используется объявление массива без инициализации. В таком случае указание количества элементов в квадратных скобках обязательно.
Для задания начальных значений элементов массива очень часто используется параметрический цикл:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int a[5]; // объявлен массив a из 5 элементов
int i;
// Ввод элементов массива
for (i = 0; i<5; i++)
{
printf("a[%d] = ", i);
scanf("%d", &a[i]); // &a[i] - адрес i-го элемента массива
}
// Вывод элементов массива
for (i = 0; i<5; i++)
printf("%d ", a[i]); // пробел в формате печати обязателен
getchar(); getchar();
return 0;
}
Многомерные массивы
В языке Си могут быть также объявлены многомерные массивы. Отличие многомерного массива от одномерного состоит в том, что в одномерном массиве положение элемента определяется одним индексом, а в многомерном — несколькими. Примером многомерного массива является матрица.
Общая форма объявления многомерного массива
Элементы многомерного массива располагаются в последовательных ячейках оперативной памяти по возрастанию адресов. В памяти компьютера элементы многомерного массива располагаются подряд, например массив, имеющий 2 строки и 3 столбца,
будет расположен в памяти следующим образом
Общее количество элементов в приведенном двумерном массиве определится как
КоличествоСтрок * КоличествоСтолбцов = 2 * 3 = 6.
Количество байт памяти, требуемых для размещения массива, определится как
КоличествоЭлементов * РазмерЭлемента = 6 * 4 = 24 байта.
Инициализация многомерных массивов
Значения элементов многомерного массива, как и в одномерном случае, могут быть заданы константными значениями при объявлении, заключенными в фигурные скобки {}. Однако в этом случае указание количества элементов в строках и столбцах должно быть обязательно указано в квадратных скобках [].
Пример на Си
2
3
4
5
6
7
8
9
#include <stdio.h>
int main()
{
int a[2][3] = { 1, 2, 3, 4, 5, 6 };
printf("%d %d %d\n", a[0][0], a[0][1], a[0][2]);
printf("%d %d %d\n", a[1][0], a[1][1], a[1][2]);
getchar();
return 0;
}Однако чаще требуется вводить значения элементов многомерного массива в процессе выполнения программы. С этой целью удобно использовать вложенный параметрический цикл.
Пример на Си
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int a[2][3]; // массив из 2 строк и 3 столбцов
int i, j;
// Ввод элементов массива
for (i = 0; i<2; i++) // цикл по строкам
{
for (j = 0; j<3; j++) // цикл по столбцам
{
printf("a[%d][%d] = ", i, j);
scanf("%d", &a[j]);
}
}
// Вывод элементов массива
for (i = 0; i<2; i++) // цикл по строкам
{
for (j = 0; j<3; j++) // цикл по столбцам
{
printf("%d ", a[j]);
}
printf("\n"); // перевод на новую строку
}
getchar(); getchar();
return 0;
}Результат выполнения
Передача массива в функцию
Обработку массивов удобно организовывать с помощью специальных функций. Для обработки массива в качестве аргументов функции необходимо передать
- адрес массива,
- размер массива.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
// Функция обмена
void change(int *x, int n)
{
// x - указатель на массив (адрес массива)
// n - размер массива
int i;
int max, index;
max = x[0];
index = 0;
// Поиск максимального элемента
for (i = 1; i<n; i++)
{
if (x[i]>max)
{
max = x;
index = i;
}
}
// Обмен
x[index] = x[0];
x[0] = max;
}
// Главная функция
int main()
{
int a[10];
int i;
for (i = 0; i<10; i++)
{
printf("a[%d] = ", i);
scanf("%d", &a[i]);
}
change(a, 10); // вызов функции обмена
// Вывод элементов массива
for (i = 0; i<10; i++)
printf("%d ", a[i]);
getchar();
getchar();
return 0;
}Результат выполнения
Пример на Си Дан массив размерности n. Вычислить произведение четных элементов
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
// Функция вычисления произведения чётных элементов
int func(int *x, int n) // произведение четных элементов
{
int p = 1; // начальное значение произведения
int i;
for (i = 0; i<n; i++)
{
if (x[i] % 2 == 0) // остаток от деления на 2 равен 0?
p = p * x[i];
}
return p;
}
// Главная функция
int main()
{
int a[5]; // объявлен массив a из 5 элементов
int i;
int pr;
// Ввод элементов массива
for (i = 0; i<5; i++)
{
printf("a[%d] = ", i);
scanf("%d", &a[i]); // &a[i] - адрес i-го элемента массива
}
pr = func(a, 5); // вычисление произведения
printf("\n pr = %d", pr); // вывод произведения четных элементов
getchar(); getchar();
return 0;
}Результат выполнения

В группе числится 10 студентов. Каждый студент сдает 3 экзамена: программирование, английский, философию. Полученные оценки заносятся в двумерный массив, где каждая новаястрока содержит оценки нового студента. Размер массива 3*10.
Определить:
– средний балл за все экзамены каждого студента;
– у какого студента наибольший и наименьший средний балл;
– количество несдач (оценка меньше 4)
В чём сложность?
Если с одномерными массивами, чутка разобрался, то тут сложность
Здесь получается массив arr[10][3]. Чтобы с таким массивом работать, нужен вложенный цикл. На сайте есть пример работы с многомерными массивами: https://prog-cpp.ru/c-massiv/
Вопрос по поводу работы с массивом из функции:
Что произойдёт с данными исходного массива, если я:
— передам указатель на массив и его размер в функцию
— внутри функции создам копию исходного массива и изменю её
— изменю указатель так, чтобы он ссылался на изменённую копию исходного массива
Эти данные просто станут "мусорными" значениями или удалятся (как в Python)?
Так лучше не делать!
Выделенная память не будет корректно освобождена до завершения работы программы.
Здравствуйте! Помогите, пожалуйста разобраться!
Есть массив
Если я в программе пишу :
то на экран дисплея выводится количество элементов массива (7).
Попытался функцию создать,чтобы количество элементов выводить так:
2
3
4
{
display = N_ELEMENTS (strRU)
};
Выводит на дисплей число 2 для любого массива.
Когда мы передаем указатель в функцию, функция не знает ничего о размере массива. Соответственно, sizeof(x) — это размер указателя, а sizeof(*(x)) — это размер элемента.
помогите пожалуйста как сделать так что бы программа выводила все максимальные серии а не только первую :
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <stdio.h>
void kisa2(double * * , int, int);
int main() {
int i, j, R, C , y;
printf("Введите количество строк в матрице:\n");
scanf("%d", & R);
printf("Введите количество столбцов в матрице:\n");
scanf("%d", & C);
double * * matr = (double * * ) malloc(R * sizeof(double * ));
for (i = 0; i < R; i++) {
matr[i] = (double * ) malloc(C * sizeof(double));
}
for (i = 0; i < R; ++i) {
for (j = 0; j < C; ++j) {
printf("matr[%d][%d]:", i, j);
scanf("%lf", & ( * ( * (matr + i) + j)));
printf("\n");
}
}
for (i = 0; i < R; ++i) {
for (j = 0; j < C; ++j) {
printf("%.2lf ", matr[i][j]);
}
printf("\n");
}
printf("\n\n\n");
printf("введите номер функции :");
scanf("%d", & y);
switch (y) {
case (2):
kisa2(matr, R, C);
break;
default:
printf("видимо вы ошиблись ");
}
return 0;
}
void kisa2(double * * matr, int R, int C) {
int n = R, m = C, i, j, cnt = 0, ipos = -1, maxcnt = 0, icnt = -1;
for (i = 0; i < n; i++) //поиск
{
cnt = 0; //номера
for (j = 1; j < m; j++) { //строки
if (matr[i][j] == matr[i][j — 1]) //в которой
cnt++; //находится
else { //самая
if (cnt > maxcnt) { //длинная
maxcnt = cnt;
ipos = i; //серия
icnt++; //счетчик
} //одинаковых
cnt = 0;
} //элементов
}
if (cnt > maxcnt) {
maxcnt = cnt;
ipos = i;
icnt++; //счетчик
}
}
if (-1 == icnt)
printf("\nСтрок с одинаковыми элементами нет!");
else
printf("\nНомер строки, в котором находится самая длинная серия одинаковых элементо в:%d ", ipos);
}
}
В первом цикле найти длину максимальной серии элементов.
Во втором цикле вывести все номера строк с такой длиной серии.
Елена, здравствуйте, какое условие применить чтобы решить данное условие: В матрице mхn найти минимальный элемент k-ого столбца и сумму положительных элементов ниже p-ой строки. у меня первая половина задачи работает, но как сделать, чтобы находило сумму ниже введенной строки?
2
3
4
5
6
7
8
9
for(int i=p+1; i<m; i++)
{
for(int j=0; j<n; j++)
{
if(a[i][j]>0)
sum+=a[i][j];
}
}
спасибо огромное! правда начинает считать через одну строчку, но суть я понял!
надо
2
3
4
5
6
7
8
9
for(int i=p; i<m; i++)
{
for(int j=0; j<n; j++)
{
if(a[i][j]>0)
sum+=a[i][j];
}
}
и сразу все как нужно становится
Здравствуйте, подскажите пожалуйста как это сделать, используя массив составьте программу для добавления элемента в начало массива.
Создать массив, длиной на 1 элемент больше исходного массива (рекомендую через динамическое выделение памяти, если не известна длина исходного массива).
Ввести элемент, разместить его в нулевом элементе созданного массива. Остальные элементы (начиная с первого) скопировать из исходного массива.
Здраствуйте, подскажите пожалуйста как сделать указатель на двумерный массив,точнее как он корректно выглядит, чтобы потом его можно было использовать как аргумент функции. Касательно функции тоже есть вопросы, к примеру :
2
3
4
5
6
7
8
9
10
for ..
for …
m[i][j] = rand () % 10;
}
int main (){
int mas [3][3], **m_1 = mas;
data (**m_1, 3);
}
Вопрос: Как правильно в подпрограмме обращаться к элементам массива через этот указатель, и как в главной программе правильно вызвать эту функцию?
Спасибо.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdlib.h>
void data(int** m, int n) {
for (int i=0; i<n; i++)
for (int j=0; j<n; j++)
m[i][j] = rand() % 10;
}
int main() {
int mas[3][3];
int** m = (int**)malloc(3 * sizeof(int*)); // или int* m[3];
for (int i = 0; i < 3; i++)
m[i] = (int*)mas[i];
data(m, 3);
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d ", m[i][j]);
}
printf("\n");
}
getchar();
return 0;
}
Спасибо большое!
А для массива типа char это также будет работать?
Да
Добрый день, Елена! Спасибо за статью!
При выводе массива на экран с помощью printf() или вводе элементов массива с помощью scanf() всегда необходимо использовать специальный код? Что будет если в качестве спецификатора преобразования в printf()/scanf() использовать %s — для символов/ Правильно ли это?
%s используется для ввода строк, а строка — это массив символов, а не один символ.
Здравствуйте, подскажите как можно найти 5 максимальных значений в матрице заданной динамически
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <stdlib.h>
#include <locale.h>
#include <string.h>
#include <limits.H>
#include <malloc.h>
int main()
{
int *a;
int i, j, n, m;
system("chcp 1251");
system("cls");
oo:
printf("Введите количество строк: ");
scanf("%d", &n);
if(n>0 && n<=15);
else
goto oo;
pp:
printf("Введите количество столбцов: ");
scanf("%d", &m);
if(m>0 && m<=15);
else
goto pp;
// Выделение памяти
a = (int*)malloc(n*m * sizeof(int));
// Ввод элементов массива
for (i = 0; i<n; i++)
{
for (j = 0; j<m; j++)
{
printf("Элемент[%d][%d] = ", i+1, j+1);
scanf("%d", (a + i*m + j));
}
}
// Вывод элементов массива
for (i = 0; i<n; i++)
{
for (j = 0; j<m; j++)
{
printf("%d ", *(a + i*m + j));
}
printf("\n");
}
//Максимальное положительное
return 0;
}
Посмотрите сортировку прямым выбором и выполните 5 итераций.
Хоть матрица и двумерная, никаких ограничений на строки и столбцы не возлагается, и с ней можно работать как с одномерной, содержащей n*m элементов.
Здравствуйте Елена! Помогите пож. Имеем массив int a [1] [8]; Мне нужно передать [8] в переменную для дальнейшего просмотра каждого элемента этой строки. Просматриваю в дебаге, поэтому printf пока не применял. Я не знаю правильно выражаюсь или нет? Я только учусь.
Для работы с массивами внутри функции передаются указатель на массив и размер массива
Я три дня не могу с места сдвинутся. Ничего не выходит.
2
3
4
{
{0x0E,0x11,0x11,0x11,0x1F,0x11,0x11,0x00},
};
Как мне обратится к 0, 1, 2 и т.д. Дайте пож. пример.
2
3
4
5
{
uint16_t a = simvol[0][i]; // все символы по порядку
// Что-то с ними делаем
}
Спасибо Елена!
Задача заполнить массив случайными числами с последующей сортировкой
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdlib.h>
#include <time.h>
#define CONST 50
int main()
{
int r,a,inner,outer,temp;
int rnd[CONST]={};
srand((unsigned)time(NULL));
puts("Массив случайных чисел:");
for (a=0;a<CONST;a++)
{ r=rand();
rnd[CONST]=(r%100)+1;
printf("%d\t",rnd[CONST]);
}
putchar('\n');
for(outer=0;outer<CONST-1;outer++)
{
for (inner=outer+1;inner<CONST;inner++)
{
if(rnd[outer]>rnd[inner])
{
temp=rnd[outer];
rnd[outer]=rnd[inner];
rnd[inner]=temp;
}
}
}
puts("Отсортированный массив:");
for(a=0;a<CONST;a++)
printf("%d\t",rnd[a]);
putchar('\n');
return 0;
}
Что не так?После сортировки 0.
2
3
4
5
6
{
r = rand();
rnd[a] = (r % 100) + 1;
printf("%d\t", rnd[a]);
}
Задано массив действительных чисел A(2n), n=<200. Сделать программу которая вычисляет сумму тех чисел из A(n+1)….,A(2n), которые превышают среднее ариф значение чисел A(1),…….,A(n)
Сначала для первой половины массива вычислить среднее арифметическое.
Потом сравнить с ним все элементы из второй половины массива и найти требуемую сумму.
Есть ли способ задать размер массива через scanf?
Есть, если использовать динамическое выделение памяти
Превратить массив таким образом, чтобы сначала располагались все элементы, целая часть которых лежит в интервале [a, b], а затем — остальные.
Как сделать это задание ?!
Помогите пожалуйста
Рассмотрите пожалуйста вопрос побыстрее если можно конечно
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int back = n-1;
for(int i=0; i<n; i++)
{
if(x[i]<=a || x[i]>=b)
{
y[back] = x[i];
back—;
}
else
{
y[front]=x[i];
front++;
}
}
Получили массив y, элементы в котором расположены согласно заданию
Здравствуйте, как можно сделать массив который заполняется до определенного условия например: вводятся положительные числа и заканчивается ввод, когда были введены как минимум три нечетных числа и четыре четных числа
Память для такого массива можно выделить только статически под максимальный размер.
Или использовать перевыделение realloc, или список.
А вообще — в цикле после ввода очередного элемента должна стоять проверка требуемого условия, и если условие выполняется, то выходим из цикла через break;
2
3
4
5
6
7
8
9
10
11
12
13
14
int count = 0;
int odd = 0;
int even = 0;
for(int i=0; i<20; i++)
{
printf("a[%d]=", i);
scanf("%d", &a[i]);
count++; // количество введенных элементов
if(a[i] %2 == 0) even++;
else odd++;
if((odd >=3) && (even >=4))
break;
}
Здравствуйте! Подскажите,пожалуйста,как в си задавать константы. Например,я хочу,чтобы у меня массив состоял из N элементов,а для этого надо,чтобы где-то N было задано,тобишь в const.
я пробовала так:
но ничего не получалось
#define N 5
Спасибо за статью! Она была очень полезна) Вы привели такие примеры которые мне наглядно показали что к чему и я наконец закончил своё задание!)
Здравствуйте Елена могли бы пожалуйста разъяснить следующую программу. Tут 6 семей дали свою оценку для анкеты,программа посчитала частоту оценок.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#define SEMYA 6
#define OCENKI 6
int main()
{
int j, i;
int otvet[SEMYA] ={2,2,1,3,3,3};
int freq[OCENKI]={};
for(i=0; i<=SEMYA-1; i++)
{
freq[otvet[i]] = freq[otvet[i]]+1;
}
printf(" ocenka: ferq:\t\n");
for (j=0;j<=OCENKI-1; j++)
{
printf(" \t%d \t%d\n", j, freq[j]);
}
return (0);
}
В массиве freq сохраняются значения на 1 больше соответствующих значений массива otvet. Затем значения из массива freq выводятся.
Здравствуйте! Можете, пожалуйста, привести пример функции, в которой числа в массиве генерируются случайным образом генератором случайных чисел. Имеется ввиду, чтобы пользователь ввел количество чисел в массиве, а они уже сгенерировались сами. Буду очень признателен!
ответ прошу прислать на мой e-mail: mnuriyev101@gmail.com
https://prog-cpp.ru/c-rand/
Посмотрите здесь
Здравствуйте, а что хранится в массиве в случае объявления массива без инициализации?
В случае объявления массива без инициализации в массиве хранится мусор. До инициализации значения элементов массива использовать нельзя.
Имеется ввиду нельзя брать значения из массива мусорные? А, записывать в ячейки массива ведь можно неициализированного? Ну записал, я к примеру, сроку, надо же просто быть уверенным, что длины массива хватит, это раз, а во вторых что нуль-терминатор в конце стоит (если массив символов). Так же? А что там дальше после нуль-терминатора нам же на важно по идее для чтения потом уже этой строки, я правильно понимаю или все таки это важно иницилизировать нулями весь массив в любом случае надо при первом использовании? И еще. Если ли замена стандартной функции копирования строки в массив, чтобы она проверяла все таки что в массиве хватает места для записи? Или это все самому надо в программе проверять прописывать всегда перед записью в массив?
Если мы введем часть массива символов, но не все значения, то при выводе может обнаружиться мусор, потому что вывод осуществляется до символа, равного нулю. То, что стоит после нуль-символа, нас действительно не интересует.
Стандартная функция strcpy() не следит за выделенной областью памяти, поэтому желательно это проверять самостоятельно или использовать защищённую функцию strcpy_s()
Здравствуйте, для чего пишется getchar 2-жды в конце каждой программы?
Владимир, getchar() дважды пишется в программах, которые используют ввод с помощью scanf() или cin. Дело в том, что когда пользователь при вводе нажимает Enter, генерируются сразу два символа — перевод строки и возврат каретки. Если в конце программы написать один getchar(), то программа прекратит свое выполнение (закроет консоль), поскольку оставшийся в буфере символ возврата каретки будет воспринят функцией getchar() как введенный.
Поэтому есть простое правило: если в программе использовался ввод с помощью scanf() или cin, в конце нужно дважды вызвать функцию getchar().
В тех программах, где нет ввода, можно использовать один getchar(), например здесь.
Альтернативой функции getchar() также может служить вызов system("pause"); из библиотеки stdlib.h. При этом пользователю будет выведено сообщение «Для продолжения нажмите любую клавишу…».
Подскажите,как СИ знает длину массива?
Где хранится длина создаваемого массива? Ведь её тоже НАДО ГДЕ ТО ХРАНИТЬ! Например, я знаю, что языке Forth правилом хорошего тона является прописывание в начальной ячейке массива длины данного массива, чтобы ты, зайдя в первую ячейку смог считать (узнать) длину всего массива. А в языке СИ где хранится длина массива? В какой то другой области памяти или в какой то переменной типа int?
В другой области памяти для динамического массива, для статического задаётся константой.