- •1. Основные этапы разработки программных продуктов
- •1.1 Постановка задачи
- •Словесная формулировка
- •Формульная постановка задачи
- •1.2 Создание программного продукта
- •1.2.1.Формирование математической модели
- •Формирование исходных данных
- •Составление расчётных зависимостей
- •Правила формирования математической модели.
- •1.2.2.Алгоритмизация задачи
- •Выбор метода решения
- •Составление алгоритма решения
- •Программирование задачи
- •1.2.3. Реализация программного продукта
- •1.2.4. Работа с результатами
- •1.2.5.Анализ результатов решения
- •1.2.6.Принятие решения
- •1.2.7.Составление технической документации
- •1.3.Полная обработки задачи пользователя
- •1.4.Обеспечение эффективности разработки программных продуктов
- •2.5 Идентификаторы
- •2.6 Описание операций
- •2.6.1 Унарные операции
- •2.6.2 Бинарные операции
- •2.6.3 Пунктуаторы
- •Программирование простых ветвлений
- •4.1.5. Программирование задачи
- •Правила составления и использования
- •4.1.5.2. Операторы условной передачи управления
- •Укороченный оператор условного перехода
- •Правила записи и выполнения
- •Условная операция
- •Технология программирования арифметических циклов
- •Циклы с аналитическим заданием аргумента
- •Постановка задачи
- •Формирование математической модели
- •Выбор метода решения
- •Составление алгоритма
- •Оператор цикла с предусловием
- •Правила записи и выполнения
- •Оператор цикла с постусловием
- •Правила записи и выполнения
- •Оператор пошагового цикла for
- •Правила записи и выполнения
- •Программа по алгоритму цикла с предусловием
- •Программа по алгоритму цикла с постусловием
- •Программа по алгоритму цикла с параметром
- •Циклы с табличным заданием аргумента
- •Описание массивов
- •Описатель имя[размер];
- •Обозначение элементов массива
- •Имя[индекс]
- •Описатель имя[разм_1] …[разм_i]… [разм_n];
- •Постановка задачи
- •Математическая формулировка
- •Выбор метода решения
- •Составление алгоритма решения
- •Алгоритмизация структурой цикла с предусловием
- •Алгоритмизация структурой цикла с постусловием
- •Алгоритмизация структурой цикла с параметром
- •Программирование задачи
- •Описание массивов
- •Обозначение элементов массива
- •Составление программ решения задачи
- •Улучшение качества программных продуктов
- •Организация ввода-вывода Использование укороченных спецификаторов
- •Ввод переменных
- •Вывод переменных
- •Организация ввода в диалоге
- •Варианты ввода массивов
- •Оформление выводимых величин
- •Управление выполнением программ Использование составных присваиваний
- •Выбор устройства вывода
- •Повторение расчётов
- •Приостановка вывода
- •Очистка экрана
- •Позиционирование курсора
- •Пример улучшения качества
- •Программирование с использованием подпрограмм
- •Имя (фактические параметры)
- •Подпрограмма с одним результатом
- •Формирование математической модели
- •Выбор метода решения
- •Составление алгоритма решения
- •Программирование задачи
- •Составление алгоритма решения
- •Программирование задачи
- •Составление алгоритма решения
- •Программирование задачи
- •Подпрограмма с результатом – массивом
- •Постановка задачи
- •Математическая формулировка
- •Выбор метода решения
- •Составление алгоритма решения
- •Программирование задачи
- •Обработка текстовой информации в Си Символьные строки
- •Определение значения символьной строки
- •Массивы строк
- •Ввод строки
- •Выделение памяти
- •Функции ввода символьной строки
- •Функция ввода символьной строки gets( )
- •Функция ввода символьной строки scanf( )
- •Преобразование символьных строк
- •Функция atoi( )
- •Функция atol( )
- •Функции atof( ) и atold( )
- •Методика ввода числовых данных с использованием функции gets( )
- •Вывод строки
- •Вывод строки функциями printf( ) и fprintf( )
- •Вывод строки функциями puts( ) и fputs( )
- •Перевод чисел в формат символьной строки
- •Обработка символьных строк
- •Определение длины строки
- •Объединение строк
- •Копирование строк
- •Сравнение строк
- •Функции по работе с датой и временем.
- •Структуры.
- •Работа с дисками.
- •Ввод-вывод потока.
- •Открытие потока.
- •Объектно−ориентированное программирование
- •Классы ObjectWindows
- •Приложение коды клавиш
- •Краткий справочник по Си
- •Оператор вывода на принтер
- •Структура оператора
- •Структура оператора
- •Структура оператора
- •Библиографический список
Описатель имя[разм_1] …[разм_i]… [разм_n];
где описатель – ключевое слово, определяющее тип элементов массива;
имя – идентификатор массива (формируется аналогично имени переменной);
размер – целая константа, определяющая количество элементов массива;
i - номер измерения (i=1 – первое измерение, i=2 – второе имзерение и т.д.);
n - измерение массива;
разм_i - целая константа, определяющая количество элементов массива по i-му измерению;
[ ] – ограничители размера массива по каждому измерению.
Константное выражение разм_i может быть опущено в случаях:
-
при обявлении массив инициализируется;
-
массив объявлен как формальный параметр;
-
массив обявлен как ссылка на массив, явно определённый в другом файле.
Инициализация одномерного массива
float[3]={1.,3.5,4.1}; или float[]={1.,3.5,4.1};
Инициализация многомерного массива
float[2][3]={{1.,3.5,4.1},{1.,3.5,4.1}}; или float[][]={{1.,3.5,4.1},{1.,3.5,4.1}};
Обозначение элементов многомерного массива.
Индексированная переменная (индексное выражение) – обозначение ячейки для хранения каждого элемента массива.
Структура обозначения индексированной переменной многомерного массива:
имя[индекс _1]…[ индекс _i]…[индекс_n];
имя – индетификатор массива;
индекс_i - целая константа, определяющая номер элемента по i-му измерению;
[ ] – ограничители размера массива по каждому измерению.
Методика хранения многомерных массивов позволяет рассчитывать адрес каждого элемента через начальный адрес массива путём прибавления к нему значения смещения текущего элемента относительно первого
а = а1+ смещение
При этом а1-адрес первого элемента.
Для двухмерного массива смещение определяется по формуле
смещение = индекс_1*разм_2+индекс_2
Для трёхмерного массива смещение определяется по формуле
смещение = индекс_1*(разм_2*разм_3+индекс_2*разм_3+индекс_3
Указатели и адресная арифметика
Указатель – это переменная, содержащая адрес другого объекта Си-программы. Ели переменная содержит адрес некоторого другого объекта, то говорят, что переменная указывает на этот объект. Указатель может указывать на обычную переменную, массив, строку, структуру, другой указатель, функцию.
Применение указателей необходимо или полезно в следующих ситуациях:
-
при динамическом распределении памяти;
-
при работе с файлами;
-
передача указателей в качестве параметров функции позволяет вызываемой функции изменять данные вызывающей функции;
-
указатель является альтернативным (по отношению к индексам) способом работы с массивом и позволяет обеспечить передачу массива для обработки вызываемой функции;
-
можно определить указатель на функцию и использовать этот указатель для вызова функции. Это даёт возможность передавать функции в функции.
Структура описания указателя
описатель иу1[,*иу2,…,*иуN];
описатель – ключевое слово, определяющая тип указателя ( тип объекта, на который он ссылается);
иу1, …,иуN – идентификаторы указателей;
* - признак указателя при описании.
Соответствие указателя и адреса переменной, на которую он ссылается , выражается зависимостью
иу=&ип;
иу – идентификатор указателя
& - операция взятия адреса
ип – идентификатор переменной
Указатель позволяет не только хранить адреса переменных, но и вызывать в случае необходиомсти их содержимое с помошью операции разадресации (*).
Разадресация указателя предписывает получение содержимого переменной (ячейки оперативной памяти), на которую он ссылается.
Запись разадресации имеет вид
*иу
Присваивание указателей
Можно присваивать один указатель другому. Однако эта операция имеет смысл только в том случае, если обоа указателя адресуют один и тот же тип.
int i=12535,*p1,*p2;
pi1=&i;
p2=p1;
print(“%d\n”,i);
print(“%d\n”,*p1);
print(“%d\n”,*p2);
Использование указателей в арифметических операциях.
С указателями могут быть использованы только операции (++), (--), сложение и вычитания.
Если к указателям применяются операции (++), (--) то их содержимое увеличивается или уменьшается на размер объекта, который они адресуют.
Указатель может быть элементом в операциях сложения и вычитания вторым операндом операции должна быть целочисленная константа. Содержимое указателя увеличивается или уменьшается на значение, равное произведению константы на размер объекта, который они адресуют.
Связь массивов и указателей
Между массивами и указателями существует прямая связь. Когда объявляется массив, например
int arr[25];
то этим объявляется несколько больше, чем только выделения памяти для двадцати пяти элементов типа int.А именно, идентификатор массива arr определяется как константный указатель на первый элемент массива (адрес первого элемента массива &arr[0]).
Так как идентификатор массива определяется как адрес. то следующее присваивание является допустимым
int arr[25];
int *ptr;
ptr=arr;
последний оператор можно записать в эквивалентной форме
ptr=&arr[0];
Для доступа к элементам массива тоже существуют два способа
Первый способ доступа к элементам массива связан с использованием обычных индексных выражений вида arr[i].
Второй способ связан с использованием адресного выражения (или выражения с указателем на массив)
*(ptr+i)
В общем случае индексное выражение в языке Си имеет вид:
выражение_1[выражение_2]
где выражение_1 – это любой указатель, например, идентификатор массив, а выражение_2 – это целая величина. Однако требуется только, чтобы одно из выражений было указателем, а второе целой величиной. Поэтому выражение_1 может быть целой величиной, а выражение_2 – указателем.
Рассмотрим, как вычисляется индексное выражение arr[5]. Идентификатор arr является указателем начала массива. В соответствии с правилами выполнения операции сложения указателя с целой величиной целая величина преобразуется к адресному представлению путём умножения её на размер типа, адресуемого указателем. Целая константа 5 умножается на размер типа int преобразованное значение числа 5 представляет 5 позиций типа int. Это преобразованное значение числа 5 складывается со значением указателя arr , то даёт адрес, относящийся к шестой ( т.к. нумерация идёт с нулевого индекса) позиции типа int после arr. К полученному результату применяется операция “разадресация”. Результатом является значение шестого элемента массива. В терминах языка Си это выглядит так:
arr[5]=*(arr+5)=*(arr+5*syzeof(int))
Следовательно следующие выражения ссылаются на шестой элемент массива arr.
arr[5]
5[arr]
*(arr+5)
*(5+arr)
Как следует из определения индексного выражения, любой указатель может быть задан с индексом. Указатель на массив также может быть проиндексирован. выражения
ptr[5]
5[pt]
ссылаются на тот же шестой элемент массива arr. Если расписать индексное выражение ptr[5], то получится адресное выражение
*(ptr+5)
Операции с указателями на массивы.
Если два указателя ptr1 и ptr2 ссылаются на один и тот же массив
int arr[SIZE]
int *ptr1, *ptr2;
int i;
ptr1=ptr2=arr;
то к ним можно применить операции, перечисленные ниже
Операция |
Результат операции |
ptr1++ ptr1-- |
Устанавливает ptr1 на следующий (предыдущий) элемент массива аrr |
ptr1+i ptr1-i |
Устанавливает ptr1 на i-й элемент после (перед) ptr1 |
ptr2- ptr1 |
Даёт число элементов между ptr1 и ptr2 (отрицательное, если ptr2 указывает на элемент с меньшим индексом) |
ptr1 == ptr2 |
Результат «истина» (1), если ptr1 и ptr2 указывают на один и тот же элемент массива. В противном случае – “ложь” (0) |
ptr1 != ptr2 |
Результат «истина» (1), если ptr1 и ptr2 указывают на разные элементы массива. В противном случае – “ложь” (0) |
ptr1 < ptr2 ptr1 <= ptr2 |
Результат «истина» (1), если ptr1 указывает на элемент массива с меньшим (или равным) индексом, чем ptr2. В противном случае – “ложь” (-0) |
ptr1> ptr2 ptr1 >= ptr2 |
Результат «истина» (1), если ptr1 указывает на элемент массива с большим (или равным) индексом, чем ptr2. В противном случае – “ложь” (-0) |
Указатели на многомерные массивы.
Многомерный массив в языке Си – это массив массиов, т.е. массив, элементами котрого являются массивы. Например трехмерный массив есть масив, элементы которого двухмерные массивы
arr[L][M][N];
Массив arr состоит из L элементов. Каждый элемент – это двухмерный массив размерностью M на N.
Рассмотрим, как осуществлять доступ к элементм многомерного массива через указатель. Сделаем это на примере массива arr.
Объявим указатель и свяжем его с массивом arr
int *ptr;
ptr=arr[0][0][0];
arr[i][j][k], или к k-му элементу j-й строки i-го массива M на N массива arr. Последовательно это выполняется так
адрес первого массива M на N ptr
в массиве arr
адрес i-го массива M на N ptr + i*(M*N)
в массиве arr
адрес j-й строки i-го массива M на N ptr + i*(M*N) +j*N
в массиве arr
адрес k-го элемента j-й строки i-го массива ptr + i*(M*N) +j*N+k
M на N ptr + i*(M*N) +j*N в массиве arr
k-й элемент j-й строки i-го массива *(ptr + i*(M*N) +j*N+k)
M на N ptr + i*(M*N) +j*N в массиве arr
Рассмотрим программирование арифметических циклов с табличным изменением аргумента на конкретном примере задачи о вознаграждениях.