Слайд 2
Массив
Массив – это группа однотипных элементов, имеющих общее
имя и расположенных в памяти рядом.
Особенности:
все элементы имеют один
тип
весь массив имеет одно имя
все элементы расположены в памяти рядом
На рисунке показана структура целочисленного одномерного массива a. Размер этого массива — 16 ячеек:
Int a[16];
а[0] а[1] а[2] а[3] а[4] а[5] а[6] а[7] а[8] а[9] а[10] а[11] а[12] а[13] а[14] а[15]
Заметьте, что максимальный индекс одномерного массива a равен 15, но размер массива 16 ячеек. Нумерация элементов массива в Си начинается с НУЛЯ !
Примеры:
string ListStudent [30]; //список студентов в группе
int flat [180]; //квартиры в доме
float x[10], y[10]; //координаты точек на плоскости
char Name [10] = {‘v’, ‘a’, ‘l’, ‘e’, ‘n’, ‘t’, ‘i’, ‘n’}; //имя
Слайд 3
Инициализация массивов
Явное задание размеров массива:
int
flat [180];
Инициализация массива с присвоением начальных значений:
string days[7]={“Sunday”, “Monday”, “Tuesday”,
“Wednesday”, “Thursday”, “Friday”, “Saturday”};
Если начальные значения не заданы, в ячейках
находится «мусор»!
Следующая инициализация выделит память под 5 целых чисел,
а начальных значений задано только 3. В этом случае четвёртый
и пятый элемент будут инициализированы (по умолчанию) значением 0.
int testScore[5]= {74, 87, 91};
Инициализация следующего вида не будет компилироваться:
float milles[4]= {74.4, 87.2, , 91.7};
Неявное задание размеров массива (размер массива определяется числом элементов справа от оператора присваивания):
char name[ ]={ ‘v’, ‘a’, ‘l’, ‘e’, ‘n’, ‘t’, ‘i’, ‘n’ };
Размер определяется константой:
const int N=15;
string ListStudent [N];
Слайд 4
Что неправильно?
int N =
10;
float A[N];
const int
int X[4.5];
int A[10];
A[10] = 0;
float X[5];
int n = 1;
X[n-2] = 4.5;
X[n+8] = 12.;
выход за границы массива
(стираются данные в памяти)
int X[4];
X[2] = 4.5;
дробная часть отбрасывается
(ошибки нет)
float B[2] = { 1., 3.8, 5.5 };
int A[2] = { 1, 3.8 };
float
Слайд 5
Массивы
Объявление:
Ввод значений элементов массива с клавиатуры:
Поэлементные операции:
Вывод значений
элементов массива на экран:
const int N = 5;
int
A[N], i;
printf("Введите 5 элементов массива:\n");
for( i=0; i < N; i++ ) {
printf ("A[%d] = ", i );
scanf ("%d", & A[i] );
}
A[0] =
A[1] =
A[2] =
A[3] =
A[4] =
5
12
34
56
13
for( i=0; i < N; i++ ) A[i] = A[i]*2;
printf("Результат:\n");
for( i=0; i < N; i++ )
printf("%4d", A[i]);
Результат:
10 24 68 112 26
Слайд 6
Случайные числа
Случайное целое число X в интервале от
1 до 20
#include
#include
#include
int main()
{
srand((unsigned)time(NULL));
int x=rand()%20+1; // генерируем числа в диапазоне от 1 до 20
printf("%i",x);
return 0;
}
void srand(unsigned int) - функция установки начального значения генератора псевдослучайных чисел.
unsigned - приведение аргумента к типу беззнакового целого
time - функция выдачи текущего времени
NULL - нулевой указатель, передаваемый функции time для выдачи текущего времени только как результата.
Слайд 7
Заполнение массива случайными числами
#include
#include
#include
main()
{
srand((unsigned)time(NULL));
const int
N = 10;
int A[N], i;
printf("Исходный массив:\n");
for (i = 0;
i < N; i++ ) {
A[i] = random(100) + 50;
printf("%4d", A[i]);
}
...
}
int random(int N)-функция выдает случайное число от 0 до N-1
{ return rand() % N; }
Слайд 8
ПРИМЕР : Реверс массива
Задача: переставить элементы массива в
обратном порядке (выполнить инверсию).
Алгоритм:
поменять местами A[0] и A[N-1], A[1]
и A[N-2], …
Псевдокод:
for ( i = 0; i < N/2; i++ )
// поменять местами A[i] и A[N-1-i]
сумма индексов N-1
Слайд 9
ПРИМЕР : Циклический сдвиг элементов массива
Задача: сдвинуть элементы
массива влево на 1 ячейку, первый элемент становится на
место последнего.
Алгоритм:
A[0]=A[1]; A[1]=A[2];… A[N-2]=A[N-1];
Цикл:
for ( i = 0; i < N-1; i ++)
A[i] = A[i+1];
почему не N?
main()
{
const int N = 10;
int A[N], i, c;
// заполнить массив
// вывести исходный массив
c = A[0];
for ( i = 0; i < N-1; i ++)
A[i] = A[i+1];
A[N-1] = c;
// вывести полученный массив
}
Слайд 10
Двумерный массив
В двумерном массиве, кроме количества элементов массива,
есть такие характеристики как, количество строк и количество столбцов двумерного
массива.
В объявлении двумерного массива нужно указать:
тип данных;
имя массива.
В первых квадратных скобках указывается количество строк двумерного массива, во вторых квадратных скобках — количество столбцов двумерного массива. Двумерный массив визуально отличается от одномерного второй парой квадратных скобочек.
// пример объявление двумерного массива:
int a[5][3];
// инициализация двумерного массива:
int a[5][3] = { {4, 7, 8}, {9, 66, -1}, {5, -5, 0}, {3, -3, 30}, {1, 1, 1} };
Слайд 11
Матрицы
Задача: запомнить положение фигур на шахматной доске.
1
2
3
4
5
6
c6
A[5][2]
Слайд 12
Двумерный массив (Матрица)
Объявление:
const int N = 3, M
= 4;
int A[N][M];
float a[2][2] = {{3.2, 4.3}, {1.1, 2.2}};
char
sym[2][2] = { 'a', 'b', 'c', 'd' };
Ввод с клавиатуры:
for ( i = 0; i < N; i ++ )
for ( j = 0; j < M; j ++ ) {
printf ( "A[%d][%d]=", i, j);
scanf ( "%d", &A[i][j] );
}
A[0][0]=
25
A[0][1]=
14
A[0][2]=
14
...
A[2][3]=
54
i
j
for ( j = 0; j < M; j ++ )
for ( i = 0; i < N; i ++ ) {
Слайд 13
Двумерный массив (Матрица)
Заполнение случайными числами
for ( i =
0; i < N; i ++ )
for (
j = 0; j < M; j ++ )
A[i][j] = random(25)- 10;
цикл по строкам
цикл по столбцам
Вывод на экран
for ( i = 0; i < N; i ++ ) {
for ( j = 0; j < M; j ++ )
printf("%5d", A[i,j]);
printf("\n");
}
перейти на новую строку
for ( j = 0; j < M; j ++ )
printf("%5d", A[i][j]);
вывод строки
в той же строке
Слайд 14
Пример: Нахождение суммы элементов матрицы
main()
{
const int N
= 3, M = 4;
int A[N][M], i, j,
S = 0;
... // заполнение матрицы и вывод на экран
for ( i = 0; i < N; i ++ )
for ( j = 0; j < M; j ++ )
S += A[i][j];
printf("Сумма элементов матрицы S=%d", S);
}
Слайд 15
Пример: Вычисление коэффициентов
Бинома Ньютона
называются биномиальными коэффициентами.
Задание
Используя два
описанных ниже метода, найти значения коэффициентов разложения многочлена (a
+ b)n .
Входные данные
С клавиатуры вводится число n — значение максимальной степени, для которой нужно посчитать коэффициенты бинома Ньютона.
Выходные данные
На экран выводятся n + 1 строк. Каждая i – я строка (0 i n ) содержит целые числа, записанные через пробел, — посчитанные биномиальные коэффициенты Cik (0 k i).
называется биномом Ньютона, а коэффициенты
(0 m n)
Определение
Многочлен вида
Слайд 16
Выпишем коэффициенты разложения в строчку, начиная с n
= 0, 1 и так далее следующим образом:
n | Коэффициенты
0 | 1
1 | 1 1
2 | 1 2 1
3 | 1 3 3 1
4 | 1 4 6 4 1
5 | 1 5 10 10 5 1
6 | 1 6 15 20 15 6 1
7 |1 7 21 35 35 21 7
... |...........................................
Для каждого коэффициента можно записать следующие рекуррентные соотношения:
Треугольник Паскаля
Слайд 17
где выражение n! (n-факториал) обозначает произведение всех натуральных
чисел от 1 до n.
Исходя из соотношений:
0! = 1,
n!= n*(n − 1)! (n > 0)
можно написать рекурсивную функцию вычисления факториала, а затем использовать ее для вычисления биномиальных коэффициентов по приведенной выше формуле.
Биномиальные коэффициенты также можно вычислить по следующей формуле (число сочетаний из n по k):
int faсt(int n)
{
if (!n) return 1;
return (n * faсt(n-1));
}
Определение числа сочетаний с помощью рекурсии
Слайд 18
Чем плох массив символов?
char A[4] = { 'A',
'3', '[', 'Ж'};
char B[10];
Это массивы символов:
Для массива:
каждый символ
– отдельный объект;
массив имеет длину N, которая задана при объявлении
Что нужно:
обрабатывать последовательность символов как единое целое
строка должна иметь переменную длину
Слайд 19
Символьные строки
рабочая часть
s[0]
s[1]
s[2]
s[3]
char s[80];
признак окончания строки: символ с
кодом 0
Символьная строка – это последовательность символов, заключенная в
двойные кавычки, которая заканчивается символом '\0'. Строка символов хранится в памяти ЭВМ как массив символов.
Значение символьной строки - это адрес ее первого символа. При трансляции программы компилятор разместит все символьные строки в памяти, а в программу вместо них подставит соответствующие адреса (т.е. значения символьных строк!).
Слайд 20
Объявление символьных строк
Объявить строку = выделить ей место
в памяти и присвоить имя.
char s[80];
char s1[80] =
"abc";
char qqq[] = "Вася";
выделяется 80 байт, в строке – «мусор» (если она глобальная, то нули '\0‘)
выделяется 80 байт, занято 4 байта
(с учетом '\0')
выделяется 5 байт
(с учетом '\0')
Слайд 21
Ввод и вывод символьных строк
Задача: ввести слово с
клавиатуры и заменить все буквы «а» на буквы «б».
main()
{
char q[80];
int i;
printf("Введите строку\n");
scanf( "%s", q);
i = 0;
while ( q[i] != '\0' ) {
if ( q[i] == 'а' ) q[i] = 'б';
i ++;
}
printf ( "Результат: %s ", q );
}
%s
не надо ставить &:
q &q[0]
%s – формат для ввода и вывода символьных строк (выводится только часть до '\0'
"%s"
пока не дошли до конца строки
переход к следующему символу
начали с q[0]
Слайд 22
Ввод одного слова:
Ввод строки с пробелами:
char q[80];
printf ("Введите
текст:\n");
scanf ( "%s", q );
printf ("Введено:\n%s", q );
Ввод символьных
строк
Введите текст:
Вася пошел гулять
Введено:
Вася
char q[80];
printf("Введите текст:\n");
gets ( q );
printf("Введено:\n%s", q );
Введите текст:
Вася пошел гулять
Введено:
Вася пошел гулять
Слайд 23
Универсальный способ:
Только для одной строки:
printf ( "Результат: %s",
q );
Вывод символьных строк
puts ( q );
можно выводить сразу
и другую информацию: надписи, значения переменных, …
вывод только одной строки
после вывода – переход на новую строку
printf ( "%s\n", q );
Слайд 24
Функции для работы со строками
Длина строки: strlen
(string length)
Подключение библиотеки:
#include
char q[80] = "qwerty";
int n;
n =
strlen ( q );
n = 6
Слайд 25
Сравнение строк
char q1[80], q2[80];
int n;
gets ( q1 );
gets
( q2 );
n = strcmp ( q1, q2 );
strcmp
(string comparison):
Слайд 26
Пример решения задачи
Задача: ввести строку и определить, сколько
в ней слов. Программа должна работать только при вводе
правильного пароля.
Идея решения:
проверка пароля – через strcmp
количество слов = количеству первых букв слова
первая буква: пробел и за ним «не пробел»
исключение: предложение начинается со слова (а не с пробела)
Слайд 27
Проверка пароля
#include
main()
{
char secret[] = "123", pass[20];
printf ( "Введите пароль\n" );
gets ( pass );
if ( strcmp ( pass, secret ) != 0 )
{
printf ( "Пароль неверный" );
getch ();
return 1;
}
...
}
если пароль неверный...
сообщить об ошибке и выйти из программы
аварийное завершение, код ошибки 1
Слайд 28
Основная часть программы
#include
#include
main()
{
char q[80];
int i, len, count = 0;
... // проверка
пароля
printf ("Введите предложение\n");
gets ( q );
len = strlen( q );
if ( q[0] != ' ') count++;
for ( i = 0; i < len - 1; i ++ )
if ( q[i] == ' ' && q[i+1] != ' ' )
count ++;
printf ( "Найдено %d слов", count );
}
особый случай
если нашли пробел, а за ним не пробел…
предыдущий слайд
Слайд 29
Копирование строк
strcpy (string copy)
char q1[10] = "qwerty", q2[10]
= "01234";
strcpy ( q1, q2 );
куда
откуда
копирование «хвоста» строки
char q1[10]
= "qwerty", q2[10] = "01234";
strcpy ( q1, q2+2 );
q2
q1
q2 = &q2[0]
q2+2 = &q2[2]
Слайд 30
Копирование строк
копирование в середину строки
char q1[10] = "qwerty",
q2[10] = "01234";
strcpy ( q1+2, q2 );
q2
q1
q1+2 = &q1[2]
char
q1[10] = "qwerty", q2[10] = "01234";
strcpy ( q1+2, q2+3 );
q2
q1
q2+3 = &q2[3]
q1+2 = &q1[2]
Слайд 31
Копирование строк
strncpy – копирование нескольких символов
char q1[10] =
"qwerty", q2[10] = "01234";
strncpy ( q1+2, q2, 2 );
q2
q1
q1+2
= &q1[2]
Слайд 32
Копирование строк
копирование строки-константы
char q1[10] = "qwerty";
strcpy ( q1+1,
"ABCD");
q1
char q1[10] = "qwerty";
strcpy ( "ABCD", q1+2 );
НЕ
Слайд 33
Копирование строк
копирование внутри одной строки
char q[10] = "012345";
strcpy
( q, q+2 );
q
char q[10] = "012345";
strcpy ( q+2,
q );
q
Зацикливание!
Слайд 34
Объединение строк
strcat (string concatenation) = копирование второй строки
в конец первой
char q1[10] = "qwe", q2[10] = "0123";
strcat
( q1, q2 );
q2
q1
char q1[10] = "qwe", q2[10] = "0123";
strcat ( q1, q2+2 );
q2
q1