КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Программирование задачи. Особенностью рассматриваемой задачи является необходимость использования в качестве формальных и фактических параметров имен и размеров массивов
Особенностью рассматриваемой задачи является необходимость использования в качестве формальных и фактических параметров имен и размеров массивов. В языке Си при передаче массива в дополнительную функцию в качестве фактических параметров выступают адрес расположения массива в оперативной памяти и фактический размер массива. Следовательно, обращение, записанное в Си для передачи массива 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. Описатели float x, y, *a, *b, int *f, arr[10]; наряду с указателями задают типы переменных x, y и целочисленного массива arr. Месторасположение указателя в списке совместного описания задается произвольно. Соответствие указателя и адреса переменной, на которую он ссылается, выражается зависимостью иу = &ип где иу – идентификатор указателя; & – операция взятия адреса; ип – идентификатор переменной. Например, оператор b = &x; определяет, что указатель b на переменную вещественного типа содержит адрес вещественной переменной x. Операторы f = &arr[0]; или f = arr; задают указателю f значение адреса массива arr (его первого элемента). Указатели позволяют не только хранить адреса переменных, но и вызывать в случае необходимости их содержимое с помощью операции разадресации. Разадресация предписывает получение содержимого переменной (ячейки оперативной памяти), на которую ссылается указатель. Разадресация выполняется указанием символа звездочка (*) перед именем указателя. Запись разадресации имеет вид *иу где иу – идентификатор указателя; * – символ операции разадресации. ü Внимание! Несмотря на совпадение форм записи описания указателей и разадресации, назначения их абсолютно различны и определяются месторасположением в программе (описателях или выполняемых участках). Операция разадресации, как правило, позволяет сформировать (получить/записать) операнд выражения или фактического параметра. Например, фрагмент программы использования операции разадресации для получения значения float g, s, *t; ... g = 15.3; t = &g; s = sqrt(*t) + *t + 0.5; ... описывает переменные g, s и указатель t как вещественные, присваивает указателю t адрес переменной g, а затем, используя операцию разадресации указателя t, формирует операнды выражения s – подкоренное выражение и второе слагаемое – как константы 15.3 (содержимое переменной g). Фрагмент float x, z, *d; ... d = &z; *d = pow(x, 2) + 5; ... поясняет использование операции разадресации для записи константы (результата вычисления выражения pow(x, 2) + 5) в ячейку переменной z с использованием указателя d. При работе с дополнительными функциями указатели используются как элементы списка формальных параметров. При этом в списке фактических параметров им должны соответствовать адреса переменных (массивов). При программировании использование массивов в вызове дополнительной функции требует указания двух фактических параметров каждого (имени и размера). При этом в заголовке вызываемой функции описываются в качестве формальных параметров пары (указатель и целая переменная) для каждого массива. Описание в дополнительной функции принимающих массивов не требуется. Элементы переданного в дополнительную функцию массива могут использоваться напрямую (указанием индексного выражения) или с помощью операции разадресации.
Так, фрагменты программы ... 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] +....; ... return f; } поясняют варианты передачи одномерных массивов в функцию, использования её элементов и способы написания прототипа. Во втором варианте прототипа тип указателя дополнен обязательным элементом – знаком «*». В дополнительной функции вызов i-го элемента массива осуществляется двумя способами: 5. индексированной переменной; 6. полным индексным выражением. В любом случае имя указателя идентифицирует массив (адрес первого элемента), а индекс i – смещение текущего элемента относительно первого. В первом случае значение текущего элемента массива вызвано через автоматически сформированный адрес, а во втором – через операцию разадресации. Для одномерных массивов в большинстве случаев используют первый способ как более привычный и компактный.
Перед составлением программы решения выполним идентификацию переменных (табл. 6.2). Таблица 6.2
Окончание табл. 6.2
Программа решения примера 6.2 #include <stdio.h> /* stdio.h - файл с прототипами функций ввода-вывода */ #include <conio.h> /* conio.h - файл с прототипом функций getch(), clrscr()*/ #include <math.h> /* math.h - файл с прототипами математических функций*/
float sum(float *t, int k); /* прототип пользовательской функции */
main() /* заголовок головной функции */ { float a, b, z1, z2, z, x[10], y[15]; /* описатели локальных */ int i, 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\n z1=%.2f z2=%.2f z=%.2f\n", z1, z2, z); getch(); }
/* определение дополнительной функции расчёта суммы элементов массива */ float sum(float *t, int k) /* заголовок дополнительной функции */ { float s; /* описание локальных */ 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); } return s; /* возвращение значения s в вызывающую функцию */ } 0.96 35. 5 4 4.5 12.3 -0.8 17 0.3 45.3 -0.3 12.7 2.5
Дата добавления: 2014-01-07; Просмотров: 303; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |