![](/user_photo/2706_HbeT2.jpg)
- •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
- •Приложение коды клавиш
- •Краткий справочник по Си
- •Оператор вывода на принтер
- •Структура оператора
- •Структура оператора
- •Структура оператора
- •Библиографический список
Подпрограмма с аргументом – одномерным массивом
В примере 6.1 в качестве операндов использовались константы, переменные, вызовы функций и составляющие их арифметические выражения. В реальных задачах возможно также использование массивов (индексированных переменных). Рассмотрим программирование подобного класса задач на конкретном примере 6.2.
Постановка задачи примера
Вычислить значение функции:
если a=0.96; b=1445, n<=10; m<=15.
Формирование математической модели
Основная часть математической формулировки выполнена в постановке задачи. Дополним её описанием массивов.
X(n) – одномерный массив;
xi– значениеi-го элемента;
– диапазон изменения индекса i;
i=i+ 1 – шаг изменения индекса i.
Примем n = 5, зададимся x1=0,5; x2=1,3; x3=-0,8; x4=17; x5=0,3
Примем m = 4, зададимся y1=5,3; y2=-0,3; y3=1,7; y4=2,5
Выбор метода решения
Анализ задачи рекомендует использование дополнительного алгоритма, в который необходимо вынести несколько формул для получения одного результата – суммы элементов одномерного массива. Особенность задачи заключается в необходимости передачи в дополнительный алгоритм, в качестве фактических параметров, одномерных массивов, X(n), а затемY(m). Математическое обозначение каждого массива фактически содержит два элемента: имя и размер, поэтому в программировании принято передавать каждый из них отдельно. Для их получения в дополнительном алгоритме в качестве формальных параметров зададимся именем массива Т и размером k.
Назвав подпрограмму sum, запишем два обращения к ней:
sum( X(n) ), sum(Y(m) ).
В первом фактическими параметрами являются имя массива X и его размер n, во втором – Y и m.
Составление алгоритма решения
С учётом выбранных обозначений составим схемы основного и дополнительного алгоритмов (рис. 6.4). Используемые в дополнительном алгоритме переменные sи i являются локальными. Печать промежуточных значений i, ti,sпредусмотрена для облегчения отладки программы.
Рис. 6.4. Схемы основного и дополнительного алгоритмов примера 6.2
Программирование задачи
Особенностью рассматриваемой задачи является необходимость использования в качестве формальных и фактических параметров имен и размеров массивов.
В языке Си при передаче массива в дополнительную функцию в качестве фактических параметров выступают адрес расположения массива в оперативной памяти и фактический размер массива.
Следовательно, обращение, записанное в Си для передачи массива X(n), имеет видsum(x,n), а для массиваY(m) –sum(y,m).
Внимание! В списке фактических параметров идентификатор одномерного массива однозначно подразумевает адрес его первого элемента.
Поэтому имя может быть заменено адресом первого элемента массива, т. е. рассмотренные обращения можно записать как sum( &x[0] ,n) иsum( &y[0] ,m).
Для приема значений фактических параметров, передаваемых в виде адреса, в списке формальных параметров используются указатели.
Указатель– переменная для хранения адреса.
Физически указатель является поименованной ячейкой оперативной памяти, предназначенной для хранения адреса других переменных и массивов. Следовательно, указатель отличается от простой переменной только типом хранимой константы – адресом. Правильное название – указатель на переменную.
Указатели, как и простые переменные, обозначаются именами (идентификаторами). Имена задаются самим пользователям по обычным для переменных правилам.
Указатели описываются аналогично переменным и массивам. Тип указателя определяется типом переменной (массива), на которую он ссылается.
Структура описания указателя:
описатель * иу1 [, * иу2, . . . , * иуN ];
где описатель – ключевое слово, определяющее тип указателя;
* – признак указателя при описании;
иу1... иуN – идентификаторы указателей;
, – разделитель списка идентификаторов;
[ ] – признак необязательности содержимого;
; – символ окончания оператора описания.
Описание указателей производится в начале программы (функции) аналогично простым переменным и массивам. При этом используются отдельные операторы описания или в списках уже существующих (наряду с переменными и массивами) указываются имена указателей с предшествующими им звездочками.
Например, описатели
float*a, *b;
int*f;
описывают два указателя на вещественные переменные, адреса которых будут указаны в ячейках с именами aиb, и один – на целую переменную, адрес которой можно хранить в ячейкеf.
Описатели
floatx,y, *a, *b,
int*f,arr[10];
наряду с указателями задают типы переменных x,yи целочисленного массиваarr. Месторасположение указателя в списке совместного описания задается произвольно.
Соответствие указателя и адреса переменной, на которую он ссылается, выражается зависимостью
иу = &ип
где иу – идентификатор указателя;
& – операция взятия адреса;
ип – идентификатор переменной.
Например, оператор
b= &x;
определяет, что указатель bна переменную вещественного типа содержит адрес вещественной переменнойx.
Операторы
f= &arr[0]; илиf=arr;
задают указателю fзначение адреса массиваarr(его первого элемента).
Указатели позволяют не только хранить адреса переменных, но и вызывать в случае необходимости их содержимое с помощью операции разадресации.
Разадресация предписывает получение содержимого переменной (ячейки оперативной памяти), на которую ссылается указатель. Разадресация выполняется указанием символа звездочка (*) перед именем указателя.
Запись разадресации имеет вид
*иу
где иу – идентификатор указателя;
* – символ операции разадресации.
Внимание! Несмотря на совпадение форм записи описания указателей и разадресации, назначения их абсолютно различны и определяются месторасположением в программе (описателях или выполняемых участках). Операция разадресации, как правило, позволяет сформировать (получить/записать) операнд выражения или фактического параметра.
Например, фрагмент программы использования операции разадресации для получения значения
floatg,s, *t;
. . .
g= 15.3;
t= &g;
s=sqrt( *t) + *t+ 0.5;
. . .
описывает переменные g,sи указательtкак вещественные, присваивает указателюtадрес переменнойg, а затем, используя операцию разадресации указателяt, формирует операнды выраженияs– подкоренное выражение и второе слагаемое – как константы 15.3 (содержимое переменнойg).
Фрагмент
floatx,z, *d;
. . .
d= &z;
*d=pow(x, 2 ) + 5;
. . .
поясняет использование операции разадресации для записи константы (результата вычисления выражения pow(x, 2 ) + 5) в ячейку переменнойzс использованием указателяd.
При работе с дополнительными функциями указатели используются как элементы списка формальных параметров. При этом в списке фактических параметров им должны соответствовать адреса переменных (массивов).
При программировании использование массивов в вызове дополнительной функции требует указания двух фактических параметров каждого (имени и размера). При этом в заголовке вызываемой функции описываются в качестве формальных параметров пары (указатель и целая переменная) для каждого массива. Описание в дополнительной функции принимающих массивов не требуется.
Элементы переданного в дополнительную функцию массива могут использоваться напрямую (указанием индексного выражения) или с помощью операции разадресации.
. . . floatfunk(float* ,int); main( ) { float
t, x[10];
. . .
n = 10;
t = funk( x , n );
. . . } float
funk( float *px, int n1 ) { . . . for(
i=0 ; i <= n1 ; i++ ) f
= . . . + *(px+i) + . . . .;
. . .
returnf; }
.. .
float funk( float *px , int n1 );
main( )
{ float t, x[10];
. . .
n = 10;
t = funk( x , n );
. . .
}
float funk( float *px, int n1 )
{ . . .
for( i=0 ; i <= n1 ; i++ )
f = . . . + px[i] + . . . .;
. . .
returnf;
}
поясняют варианты передачи одномерных массивов в функцию, использования её элементов и способы написания прототипа. Во втором варианте прототипа тип указателя дополнен обязательным элементом – знаком «*».
В дополнительной функции вызов i-го элемента массива осуществляется двумя способами:
индексированной переменной;
полным индексным выражением.
В любом случае имя указателя идентифицирует массив (адрес первого элемента), а индекс i– смещение текущего элемента относительно первого. В первом случае значение текущего элемента массива вызвано через автоматически сформированный адрес, а во втором – через операцию разадресации.
Для одномерных массивов в большинстве случаев используют первый способ как более привычный и компактный.
Перед составлением программы решения выполним идентификацию переменных (табл. 6.2).
Таблица 6.2
Обозначение в алгоритме |
1 |
a |
b |
n |
m |
i |
j |
xi |
Обозначение в программе |
2 |
a |
b |
n |
m |
i |
j |
x[i] |
Окончание табл. 6.2
1 |
yj |
z1 |
z2 |
z |
k |
ti |
s |
2 |
y[j] |
z1 |
z2 |
z |
k |
t[i] |
s |
Программа решения примера 6.2
#include<stdio.h> /*stdio.h- файл с прототипами функций ввода-вывода */
#include<conio.h> /*conio.h- файл с прототипом функцийgetch( ),clrscr( )*/
#include<math.h> /*math.h- файл с прототипами математических функций*/
floatsum(float*t,intk); /* прототип пользовательской функции */
main( ) /* заголовок головной функции */
{
floata,b,z1,z2,z,x[10],y[15]; /* описатели локальных */
inti,j,n,m; /* переменных и массивов */
clrscr( );
printf("\nВведите значенияa,b,n,m: ");
scanf("%f%f%d%d", &a, &b, &n, &m);
fprintf(stdout,"\n a=%.2f b=%.2f n=%d m=%d\n", a, b, n, m);
for( i = 0 ; i < n ; i++ ) /* заголовок цикла ввода x[ i ] */
{
printf(" Введите значениеx(%d): ",i+1);
scanf("%f", &x[i]);
}
for( i = 0 ; i < n ; i++ ) /* заголовок цикла вывода x[ i ] */
fprintf(stdout," %.2f",x[i]);
printf("\n"); /* перевод курсора в начало следующей строки */
for(j= 0 ;j<m;j++ ) /* заголовок цикла вводаy[j] */
{
printf(" Введите значение y(%d): ",j+1);
scanf("%f", &y[j]);
}
for(j= 0 ;j<m;j++ ) /* заголовок цикла выводаy[j] */
fprintf(stdout," %f",y[j]);
z1 =cos(a) +sum(x,n); /* вычисление с обращением к */
z2 =sum(y,m) -b; /* дополнительным функциям */
z=z1 /z2;
fprintf(stdout,"\n\nz1=%.2fz2=%.2fz=%.2f\n",z1,z2,z);
getch( );
}
/* определение дополнительной функции расчёта суммы элементов массива */
floatsum(float*t,intk) /* заголовок дополнительной функции */
{
floats; /* описание локальных */
int i; /* переменных sиi*/
s = 0;
for( i = 0 ; i < k ; i++ ) /* заголовок цикла расчета суммы */
{
s = s + t[ i ];
fprintf(stdout,"\n %2d %6.2f %8.2f ", i+1 , t[ i ], s);
}
returns; /* возвращение значенияsв вызывающую функцию */
}
0.96 35. 5 4
4.5 12.3 -0.8 17 0.3
45.3 -0.3 12.7 2.5