Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Следовательно, в функцию необходимо наряду с используемым фактическим размером передавать и максимальный, указанный в описателе




Если возвращаемые результаты не требуется хранить для последующего использования, достаточно описать один массив и использовать его многократно (последовательно при каждом обращении к функции). Если все возвращаемые массивы результатов требуется хранить, в вызывающей функции каждый из них должен быть описан как самостоятельный с уникальным именем и размером, определяемым логикой задачи. В этом случае в каждом обращении к дополнительной функции используется своё имя и размер. Если фактический размер выходного массива заранее известен, передача его осуществляется по значению, если рассчитывается в дополнительной функции – передаётся (возвращается) по адресу.

ü Внимание! Если размер выходного массива совпадает с одним из параметров входного, то указывать его не требуется.

В рассматриваемом примере используются два входных двумерных (a, b) и два выходных одномерных (ssa, ssb) массива. Исходя из условий задачи, предполагаем хранение выходных массивов. Следовательно, в основной функции должны быть описаны четыре массива (a, b, ssa, ssb). Элементы входных будут определены вводом значений в этой же (основной) функции, выходных – после соответствующих обращений к подпрограмме.

Работа в дополнительной функции с элементами многомерного массива производится операцией разадресации определяющего их индексного выражения.

Методика хранения многомерных массивов (разд. 9.1.1.2) позволяет рассчитывать адрес каждого элемента через начальный адрес массива, добавляя к нему сумму произведений увеличенных размеров на длину ячейки для хранения каждого элемента.

Внимание! Особенности обращения к элементам многомерных массивов – учет максимальных значений размеров по каждому измерению. Поэтому в вызове функции и её заголовке для каждого массива указывается его адрес, фактические размеры по каждому измерению и увеличенные размеры (исключая первое измерение).

Так, при передаче в дополнительную функцию двумерного массива A(mxn) с максимально требуемым размером 10x15, фрагмент обращения имеет вид

float a[10][15];

...

func(a[0], m, n, 15);

...

а заголовок дополнительной функции запишется, например, следующим образом

void func(float *z, int k, int p, int t)

при этом обращение к текущему элементу zij имеет вид

*(z + i * t + j)

С учетом изложенного, выполним программирование задачи 10.4. Идентификация переменных представлена в табл. 10.4.

Таблица 10.4

Обозначение в алгоритме   m n t s i j aij bij
Обозначение в программе   m n t s i j a[i][j] b[i][j]

Окончание табл. 10.4

  ssai ssbi mp tp k p ss d sszd zij
  ssa[i] ssb[i] mp tp k p ss d ssz[d] z[i][j]

Анализ алгоритма показывает, что основной выходной параметр оформлен в виде одномерного массива. Поэтому с учетом таблицы идентификации, рассмотренных выше правил и расчета в дополнительной функции размера возвращаемого массива, обращения примут вид:

sum_str(a, m, n, 15, ssa, &mp); и sum_str(b, t, s, 7, ssb, &tp);

где m, n, t, s – фактические используемые размеры, 15 и 7 – фактические максимальные размеры по второму измерению массивов A и B, а &mp и &tp – адреса размеров возвращаемых массивов.

Заголовок дополнительной функции преобразуется к виду:

void sum_str(float *z, int k, int p, int pmax, float *ssz, int *d)

где k и p – формальные используемые размеры, а pmax – формальный максимальный размер по второму измерению массива Z, *d – указатель размера создаваемого массива.

Универсальные размеры массивов зададим подстановочными директивами define, что позволит модифицировать увеличенные размеры всех массивов в заголовочной части программы.

Классический вариант программирования задачи

#include<stdio.h>/*файл с прототипами функций ввода-вывода*/

#include<conio.h>/*файл с прототипом функции getch(), clrscr()*/

#include <windows.h> /*файл с прототипом функции CharToOem*/

#define M 10 /* присваивание*/

#define N 15 /*максимальных*/

#define T 9 /*размеров*/

#define S 7 /*массивов А и В*/

void sum_str(float* z, int k, int p, int pmax, float *ssz, int *d);

main() /* заголовок головной функции */

{

float ap, bp, a[M][N], b[T][S], ssa[M], ssb[T]; /*описатели */

int i, j, n, m, t, s, mp, tp; /* массивов и переменных*/

char buf[30];

clrscr();

CharToOem(" Введите значения n, m, t, s: ",buf);

printf("\n %s \n",buf);

scanf("%d%d%d%d", &m, &n, &t, &s);

printf("\n m=%d n=%d \n t=%d s=%d \n", m, n, t, s);

CharToOem(" Введите построчно массив A ",buf);

printf("\n %s (%d*%d):\n", buf, m, n);

for(i = 0; i < m; i++)/*заголовок внешнего цикла ввода a[i][j]*/

for(j = 0; j < n; j++)/*заголовок внутрен. цикла ввода a[i][j]*/

scanf("%f", a[0] + i * N + j);

CharToOem("Массив A ",buf);

printf("\n %s \n", buf);

for(i = 0; i < m; i++)/* заголовок внешн. цикла вывода a[i][j]*/

{

for(j = 0; j < n; j++)/*заголовок внутр. цикла вывода a[i][j]*/

printf(" %6.2f", a[i][j]);

printf("\n");

}

CharToOem(" Введите построчно массив B ",buf);

printf("\n %s (%d*%d):\n", buf, t, s);

for(i = 0; i < t; i++) /* заголовок внешнего цикла ввода b[i][j]*/

for(j = 0; j < s; j++) /* заголовок внутр. цикла ввода b[i][j]*/

scanf("%f", b[0] + i * S + j);

CharToOem("Массив B ",buf);

printf("\n %s \n", buf);

for(i = 0; i < t; i++) /* заголовок внешн. цикла вывода b[i][j]*/

{

for(j = 0; j < s; j++) /* заголовок внутр. цикла вывода b[i][j]*/

printf(" %6.2f", b[i][j]);

printf("\n");

}

sum_str(a[0], m, n, N, ssa, &mp);

CharToOem("Массив SSA ",buf);

printf("\n %s \n", buf);

for(i = 0; i < mp; i++) /* заголовок цикла вывода ssa[ i ] */

printf(" %.2f",ssa[i]);

printf("\n"); /* перевод курсора в начало следующей строки */

sum_str(b[0], t, s, S, ssb, &tp);

CharToOem("Массив SSB ",buf);

printf("\n %s \n", buf);

for(i = 0; i < tp; i++) /* заголовок цикла вывода ssb[ i ] */

printf(" %.2f",ssb[i]);

printf("\n"); /* перевод курсора в начало следующей строки */

getch();

}

 

void sum_str(float *z, int k, int p, int pmax, float *ssz, int *d)

{

int i, j; /* описание локальных */

float ss; /* переменных */

*d = 0;

for(i = 0; i < k; i++) /*заголовок внешн. цикла расчета ss*/

{

ss = 0;

for(j = 0; j < p; j++) /* заголовок внутр. цикла расчета ss */

{

ss = ss + *(z + i * pmax + j);

}

if(ss >= 0)

{

ssz[*d] = ss;

*d=*d + 1;

}

}

}

3 4 2 3 – реальные размеры массивов А и В;

8.53 9.3 5.7 -3.5 – значения

46 -32.1 28.5 -52.6 элементов

4.7 56 65 -7.2 массива А;

1.6 7.3 15 – значения элементов

4.2 -10.18 12 массива В.

Под закрывающей скобкой приведены исходные данные для решения задачи.

Результаты решения представлены в приложении 10.7.

Программирование задачи с графическим интерфейсом

Программирование задачи при использовании графического интерфейса предварим его разработкой.

ListBoxB
ListBoxA

Для ввода значений n, m, t, s планируем однострочные поля редактирования (EditN, EditM, EditT, EditS). Для ввода элементов массивов A и B используем многострочные поля редактирования (EditA, EditB). Вывод форматированных массивов А и В и расчетных значений ssa и ssb реализуем в поля-списки (ListBoxA, ListBoxB, ListBoxSSA, ListBoxSSB).

Управление процессом решения реализуем двумя командными кнопками, расположенными в нижней части окна. Назначение каждой определяется ее названием.

С учетом планируемого интерфейса выполним программирование задачи.

#include <stdio.h>/*файл с прототипами функций ввода-вывода*/

#define M 10 /* присваивание*/

#define N 15 /*максимальных*/

#define T 9 /*размеров*/

#define S 7 /*массивов А и В*/

void sum_str(float* z, int k, int p, int pmax, float *ssz, int *d);

void TSumprDlgClient::BNClickedOk()

{

// INSERT>> Your code here.

float ap, bp, a[M][N], b[T][S], ssa[M], ssb[T]; /* описатели */

int i, j, n, m, t, s, mp, tp; /*массивов и переменных*/

char buf[15], buf1[50]="";

ListBoxA->ClearList();

ListBoxB->ClearList();

ListBoxSSA->ClearList();

ListBoxSSB->ClearList();

EditN->GetText(buf,10); /*ввод */

n=atoi(buf); /*значения n*/

EditM->GetText(buf,10); /*ввод */

m=atoi(buf); /*значения m*/

EditT->GetText(buf,10); /*ввод */

t=atoi(buf); /*значения t*/

EditS->GetText(buf,10); /*ввод */

s=atoi(buf); /*значения s*/

for(i = 0; i < m; i++)/*заголовок внешн. цикла ввода a[i][j]*/

for(j = 0; j < n; j++)/*заголовок внутрен. цикла ввода a[i][j]*/

{

EditA->GetLine(buf, sizeof(buf),i*n+j);

a[i][j] = atof(buf);

}

for(i = 0; i < m; i++)/* заголовок внешн. цикла вывода a[i][j]*/

{

strcpy(buf1, "");

for(j = 0; j < n; j++)/*заголовок внутр. цикла вывода a[i][j]*/

{

sprintf(buf,"%.2f ", a[i][j]);

strcat(buf1, buf); /*слияние строк buf и buf1*/

}

ListBoxA->AddString(buf1);

}

for(i = 0; i < t; i++)/*заголовок внешн. цикла ввода b[i][j]*/

for(j = 0; j < s; j++)/*заголовок внутр. цикла ввода b[i][j]*/

{

EditB->GetLine(buf, sizeof(buf),i*s+j);

b[i][j] =atof(buf);

}

for(i = 0; i < t; i++)/* заголовок внешн. цикла вывода b[i][j]*/

{

strcpy(buf1, ""); /*очистка содержимого строки buf1*/

for(j = 0; j < s; j++) /* заголовок внутр. цикла вывода b[i][j]*/

{

sprintf(buf,"%.2f ", b[i][j]);

strcat(buf1, buf); /*слияние строк buf и buf1*/

}

ListBoxB->AddString(buf1);

}

sum_str(a[0], m, n, N, ssa, &mp);

for(i = 0; i < mp; i++) /* заголовок цикла вывода ssa[ i ] */

{

sprintf(buf,"%.2f ", ssa[i]);

ListBoxSSA->AddString(buf);

}

sum_str(b[0], t, s, S, ssb, &tp);

for(i = 0; i < tp; i++) /* заголовок цикла вывода ssb[ i ] */

{

sprintf(buf,"%.2f ", ssb[i]);

ListBoxSSB->AddString(buf);

}

}

void sum_str(float *z, int k, int p, int pmax, float *ssz, int *d)

{

int i, j; /* описание локальных */

float ss; /* переменных */

*d = 0;

for(i = 0; i < k; i++)/* заголовок внешнего цикла расчета ss*/

{

ss = 0;

for(j = 0; j < p; j++) /* заголовок внутр. цикла расчета ss */

{

ss = ss + *(z + i * pmax + j);

}

if(ss >= 0)

{

ssz[*d] = ss;

*d=*d + 1;

}

}

}

3 4 2 3 – реальные размеры массивов А и В;

8.53 9.3 5.7 -3.5 – значения

46 -32.1 28.5 -52.6 элементов

4.7 56 65 -7.2 массива А;

1.6 7.3 15 – значения элементов

4.2 -10.18 12 массива В.

Под закрывающей скобкой приведены исходные данные для решения задачи.

Результаты решения представлены в приложении 10.8.

Заключение

Процесс – основные (главные) вычисления, реализующие общую цель задачи.

Подпроцесс – дополнительные (вспомогательные) вычисления детализации частных подзадач процесса.

Виды данных в подпроцессах – локальные, фактические, формальные параметры. Локальные – данные (параметры), используемые внутри процесса или подпроцесса без права передачи. Фактические – данные (параметры) процесса, численные значения которых требуется передать в качестве аргументов в подпроцесс. Формальные – данные (параметры) подпроцесса, получающие численные значения соответствующих фактических параметров процесса.

Взаимодействие процесса с подпроцессом – обращение. Обращение – указание перехода из процесса в подпроцесс детализации некоторого фрагмента вычислений.

Особенность алгоритмизации процессов с подпроцессами – создание нескольких отдельных алгоритмов (основного и вспомогательных). Основной – алгоритм реализации главного вычислительного процесса. Вспомогательный (дополнительный) – алгоритм реализации отдельного вычислительного подпроцесса.

Программная реализация процесса с подпроцессами – головная программа и подпрограммы. Головная (главная) программа – программный модуль, реализующий процесс (основной алгоритм). Подпрограмма – программный модуль, реализующий конкретный подпроцесс (дополнительный алгоритм).

Основная базовая конструкция языка Си/Си++ – функция. Функция – программный модуль, реализующий некоторый обособленный участок вычислений, оформленный отдельным алгоритмом. Головная функция – основной программный модуль, из которого организуется вызов дополнительных функций. Дополнительная функция – программный модуль, реализующий конкретный подпроцесс (дополнительный алгоритм).

Вызов функции – обращение к ней для передачи значений фактических параметров и получения результатов её работы. Функции Си/Си++ – вызывающие и вызываемые. Вызывающая – содержащая вызов (вызовы) любой другой. Вызываемая – к которой обращен вызов (активизируемая им).

Обязательный компонент функции – заголовок. Основные элементы заголовка: название (назначение), формальные параметры, тип возвращаемого результата. Прототип (описание) функции – структура, аналогичная заголовку, определяющая основные элементы функции (наименование, формальные параметры, тип возвращаемого результата), позволяя разместить функцию в любом месте программы. Прототипы стандартных функций находятся в стандартных заголовочных файлах.

Сложность выносимого в подпроцесс участка вычислений определяет особенности программирования вычислительных процессов с подпроцессами. Критерий сложности – количество и структура используемых формальных параметров и результатов, возвращаемых в головную функцию.

Организация процессов с подпроцесами реализует модульный принцип построения программного продукта, структурируя решаемую задачу. Эффективность использования процессов с подпроцессами наивысшая по отношению ко всем рассмотренным ранее. Глобализация принципов модульного программирования – основа объектно-ориентированного проектирования.

Вопросы для контроля

1. Какой алгоритм – основной, а какой – дополнительный?

3. Какова структура обращения к дополнительному алгоритму?

4. Какие параметры называют фактическими, формальными?

6. Какова схема взаимодействия головного алгоритма с дополнительными?

7. Чем головная программа отличается от подпрограммы?

8. На какие типы делятся подпрограммы?

9. Что такое функция, как она вызывается?

11. Для чего нужен прототип функции?

12. Какова структура программы с подпрограммами?

13. Какова структура определения функции?

16. Как осуществляется передача массивов в функцию?

17. Что такое указатель, какова структура описания указателя?

19. Для чего нужны операции взятия адреса и разадресации?

20. Чем отличаются входные параметры от выходных?

21. Каков механизм передачи в функцию выходных параметров?

22. Чем отличается передача параметров по значению от передачи по адресу?





Поделиться с друзьями:


Дата добавления: 2015-11-23; Мы поможем в написании ваших работ!; просмотров: 531 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Самообман может довести до саморазрушения. © Неизвестно
==> читать все изречения...

2538 - | 2391 -


© 2015-2025 lektsii.org - Контакты - Последнее добавление

Ген: 0.013 с.