Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Программирование на языке Си. Учебно-методическое пособие

.pdf
Скачиваний:
1
Добавлен:
07.09.2026
Размер:
1 Мб
Скачать
☆
31
4. Массивы
Массив – это участок памяти, содержащий элементы одного типа, объединенные одним именем. Чтобы использовать массив, надо его объявить – выделить место в памяти. Типом массива называется тип входящих в него элементов. Массивы могут быть разных типов – int, float, char, и т. д. Массив
объявляют так же, как и обычные переменные, но после имени массива в
квадратных скобках записывается количество элементов в нем.
int m[10], float a[20], char c[30];
При объявлении массива можно сразу заполнить его начальными
значениями, перечисляя их внутри фигурных скобок. В этом случае размер массива в квадратных скобках можно не указывать, он будет определен автоматически:
Пример:
int a[4] = { 1, 4, 9, 16 }; int a[] = {1, 4, 9, 16 }; int a[3] = { 1, 4, 9, 16 }; - ошибка int a[4] = { 1, 4}; - добавится 2 нуля int a[4]={0} все 0
Для повышения универсальности программы размер массива лучше определять через константу, которой дано имя. В этом случае при изменении количества элементов в массиве достаточно только поменять значение этой константы.
Чтобы обратиться к элементу массива, надо написать имя массива и затем
в квадратных скобках номер нужного элемента a[0]; a[1]; a[2];
Пример
const int N = 10 // или #define N 10 int a[N]; for(int i=0; i<N; i++) a[i]=i*i;
Размер массива не может быть переменной в стандарте. (Можно с версии С99.)
Следует соблюдать осторожность, выход за границы массива не
контролируется. Нумеруются элементы массива всегда от 0 до N-1. Это надо учитывать, если описан массив:
32
int a[10]; a[10]=0; - ошибка, выход за границы массива, последний элемент
массива в этом примере имеет индекс 9.
Пример: ввод элементов с клавиатуры и вывод максимального на экран
#include <stdio.h> int const N=6; int main() { int m[N], i; printf("input mas"); for(int i=0; i<N; i++) scanf("%d",&m[i]); max=m[0]; for(int i=1; i<N; i++) if(max<m[i]) max=m; printf("\n%d",max); }
Заполнение массива случайными числами
Функция rand() позволяет генерировать псевдослучайные числа в диапазоне от 0 до RAND_MAX , константа RAND_MAX=32767.
#include <stdio.h> #include <stdlib.h> int const N=6; int main() { float m[N], i; for(int i=0; i<N; i++) { m[i]=rand()%100; printf("%10.3f",m[i]); } printf("\n"); for(int i=0; i<N; i++) { m[i]=rand()/float(RAND_MAX); printf("%10.3f",m[i]); } }
Если необходимо при каждом запуске программы получать разные
последовательности, генератор надо инициализировать изменяющимся числом, например, текущим временем.
33
Пример инициализации генератора случайных чисел с помощью функции srand():
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
int main(void){
long i,t;
t = time(NULL); printf("%d %s\n", t,ctime(&t));
srand(time(NULL));
for(i=0; i<10; i++)
printf("%d\n", rand() % 100);
}
Пример формирования неповторяющихся случайных чисел:
#include <stdio.h> #include <stdlib.h> #include <time.h> #define N 5 // количество чискл #define M (N+1) // диапазон чисел
int main(void){ int i, j, flag; int a[N]; // массив чисел int k[M]={0}; //массив подсчета повтров чисел srand(time(NULL)); printf("Variant 1\n"); for(i=0; i<N;i++) { do{ a[i]=rand()%M; flag=0; for(j=0;j<i;j++)//поиск повторов if(a[i]==a[j]) {flag=1; break;} }while(flag); printf("%4d", a[i]); } printf("\nVariant 2\n"); for(i=0;i<N;i++) { do{ a[i]=rand()%M;
34
}while (k[a[i]]++); //проверка, встречалось ли число ранее printf("%4d", a[i]); } printf("\nk[i]\n"); for(i=0;i<M;i++) printf("%4d", k[i]); }
Пример реализации генератора псевдослучайных чисел (ГПСЧ) в языке С. Использует линейный конгруэнтный метод.
#define RAND_MAX 32767
static unsigned long int next = 1;
int rand(void) { next = next * 1103515245 + 12345; return (unsigned int)(next/65536) % RAND_MAX; }
void srand(unsigned int seed) { next = seed; }
В С11 есть более совершенные ГПСЧ, например, вихрь Мерсенна.
#include <iostream> #include <time.h> #include <random> using namespace std; int main(){ //2
19937
– период ГПСЧ
mt19937 mersenne(time(0)); // инициализация
for (int count = 0; count < 48; ++count) { cout << mersenne() << "\t"; } }
Примеры программ обработки массивов
1. Подсчитать мат ожидание значение и среднее отклонение от него для
массива из N случ чисел.
35
M=(Σa[i])/N, D=(Σabs(M-a[i]))/N
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int const N=10000;
int main() {
float m[N], i, s=0, d=0;
for(int i=0; i<N; i++) {
m[i]=rand()%101;
s+=m[i];
}
s/=N;
printf("%f\n",s);
for(int i=0; i<N; i++) {
d+=fabs(s-m[i]);
}
d/=N;
printf("%f\n",d);
}
2. Циклическая перестановка элементов массива. 1,2,3,4,5 -> 2,3,4,5,1 (на к
элементов сдвиг)
for(i=0; i<k; i++) t[i]=m[i]; for(int i=0; i<N-k; i++) { m[i]=m[i+k]; } for(i=0; i<k; i++) m[N-k+i]=t[i]; for(int i=0; i<N; i++) { printf("%4d",m[i]); }
3. Сортировка – рассмотрим простые методы сортировки. Метод выбора (поиск минимального элемента)
for(int i=0;i<N-1;i++){ int min=i; for(int j=i+1;j<N;j++){ if( a[j]< a[min]) min=j; } t=a[i],a[i]=a[min],a[min]=t; }
36
Метод пузырька (сравниваются соседние элементы)
k=0; do { flag=0; for(i=N-1; i>k; i--) if (m[i]<m[i-1]) t=m[i],m[i]=m[i-1],m[i-1]=t,flag=1; k++; }while(flag);
Метод вставок (на каждом шаге алгоритма мы выбираем один из
элементов массива и вставляем его на нужную позицию в уже
отсортированной части массива).
for(i=1; i<N; i++) { int j=i; while(j>0 && m[j]<m[j-1]) t=m[j],m[j]=m[j-1],m[j-1]=t,j--;
}
4. Поиск в отсортированном массиве.
Пусть элементы массива m уже расставлены по возрастанию и требуется
найти элемент, равный x, среди элементов с номерами от L до R. Для этого используем следующий алгоритм: выбираем средний элемент между L и R, он
имеет номер с=(L+R)/2, где деление выполняется нацело. Сравним его с
искомым x. Если он равен x, мы нашли то, что искали. Если x меньше m[c], надо искать дальше между m[L] и m[c], если x больше x[c], дальше ищем между m[c] и m[R].
Пример.
int l, r, c, k; l=0; r=N-1; k=0; while ( l <= r ) { c = (l + r) / 2; if ( m[c] == x ) { k = 1; break; } if ( x < m[c] ) r = c - 1; else l = c + 1; } if ( k ) printf ( "нашли: m[%d]=%d", c, m[c] ); else printf ( "нет элемента" );
37
Многомерные массивы
Часто обычный массив неудобен для хранения данных из-за своей линейной структуры. Например, таблица умножения, таблица координат. Из многомерных массивов чаще всего используют 2-х мерные (матрицы).
В языке Си каждый индекс записывается отдельно в квадратных скобках.
int a[3][4];
Каждую строку матрицы можно рассматривать как обычный одномерный
массив. Поэтому можно сказать, что матрица – это массив из массивов.
Существует только два ограничения:
1. Все элементы матрицы должны быть одного типа.
2. Все строки матрицы должны быть одинаковой длины.
Первый индекс элемента матрицы – это номер строки, второй – номер столбца.
В памяти элементы массива располагаются в следующем порядке:
a[0][0], a[0][1],a[0][2],a[0][3],a[1][0],…. a[2][3]
Инициализация многомерных массивов, пример:
int a[2][3] = {{1, 2, 3},{4, 5, 6}};
Для работы с матрицами обычно требуется вложенный цикл, то есть цикл в цикле.
Примеры алгоритмов
1. Сформировать таблицу Пифагора. Дополнить каждую строку
матрицы суммой элементов стоки, каждый столбец – суммой элементов столбца, вычислить сумму элементов диагонали.
int main(){ int i, j, m[N+1][N+1]={0};
for(i=0;i<N;i++) for(j=0;j<N;j++) m[i][j]=i*j; for(i=0; i<N;i++) { m[N][N]+=m[i][i]; for(j=0;j<N;j++) { m[i][N]+=m[i][j]; m[N][j]+=m[i][j]; } } for(i=0;i<=N;i++) { for(j=0;j<=N;j++) printf("%4d",m[i][j]);
38
printf("\n"); } }
2. Заполнить матрицу случайными числами. Найти строку с
максимальной суммой элементов и заменить в ней положительные значения нулями.
int main(){
int i,j,m[N][N]={0},s,n,sm=0;
for(i=0;i<N;i++) {
for(s=j=0;j<N;j++) {
m[i][j]=rand()%100-50;
s+=m[i][j];
printf("%4d",m[i][j]);
}
if(s>sm) sm=s, n=i;
printf("\n");
}
printf("\nn=%d sm=%d\n\n",n,sm);
for(i=0; i<N; i++)
if(m[n][i]>0) m[n][i]=0;
for(i=0;i<N;i++) {
for(j=0;j<N;j++) printf("%4d",m[i][j]);
printf("\n");
}
}
3. Удалить заданные строку и столбец матрицы.
int i,j, ii, jj, m[N][N], a[N-1][N-1];
for(ii=i=0; i<N; i++){
if(i==n) continue;
for(jj=j=0;j<N;j++)
if (j!=n) a[ii][jj++]=m[i][j];
ii++;
}
4. Отсортировать каждую строку матрицы.
for(i=0;i<N;i++) for(j=0;j<N-1;j++) for(k=0;k<N-1;k++) if(m[i][k]>m[i][k+1]) t=m[i][k],m[i][k]=m[i][k+1],m[i][k+1]=t;
39
Контрольные вопросы
Каковы индексы первого и последнего элементов массива, объявленного
как float y[n];?
Как вычислить сумму элементов массива, исключая крайние элементы? Как вычислить сумму нечётных и чётных элементов массива? Как объявить двумерный массив? Как инициализировать?
40
5. Строки
Строка – это массив символов. Последний символ строки должен иметь 0 код, он обозначает конец строки. Пример описания строки:
char st[80]; 80 – количество байт, выделяемое под строку в памяти. При выделении памяти глобальные переменные заполняются нулями, а
локальные содержат «мусор». Начальное значение строки можно задать при объявлении в двойных кавычках после знака равенства, в этом случае если размер строки не указан, он определяется автоматически по количеству
символов в начальном значении строки:
char st[80]=”Hello”; char st[]=”Hello”;
const char hello[] = "Hello";
Ввод стоки с клавиатуры, пример:
printf("Как тебя зовут? "); scanf("%s", st); printf("Привет, %s!", st);
scanf – считывает до первого пробела, если надо считать всю строку –
используем gets(st);
Основные функции для работы со строками <string.h>
int n; char st1[80], st2[80];
1. int strcmp(st1,st2) возвращает ноль если равны, больше нуля если st1>st2 и
меньше нуля если st1<st2 Символы сравниваются попарно (по их кодам)
до первого различия.
strncmp(st1,st2,n); //сравнивается только первые n символов
2. char *strcat(st1,st2) – сцепление строк (к st1 добавляется st2)
char *strncat(st1,st2,n) //добавляются только первые n символов
возвращает указатель на st1
char st1[]=”Hello”;
printf(“%s”,strcat(st1,” Word”);
3. char *strcpy(st1,st2) – st2 копируется в st1 char *strncpy(st1,st2,n); // копируются только первые n символов
возвращает указатель на st1
4. char *strstr(st1,st2) – поиск подстроки st2 в строке st1, возвращает
указатель на первый символ найденной подстроки или NULL
char str1[] = "Hello Word", str2[] = "Wo", *ptr; ptr = strstr(str1, str2); printf("The substring is: %s\n", ptr); //(Word)
5. int strlen(st1) – возращает длину строки.
6. char *strtok(char *string, const char *delit);
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]