Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Fortran > [General] Ошибка времени исполнения |
Автор: ghost8495 1.4.2009, 21:14 |
Задали написать програму на Фортране, но не удаётся запустить exe файл. помогите найти ошибку вот условие задачи: для каждого из значений переменно С, равных 0.8, 0.9, 1.0, 1.1, 1.2, определить площадь S, ограниченную кривой F(x)=((x-c)**2)*((x+c)**2) и осью абсцисс на отрезке [a, b ] . Известно, что в точке а функция F(x) принимает своё максимально на отрезке [0, c ] значание. Значение b положить равным 0.7*с . Обязательно использование подпрограмм EXLOC И FINT program prog1 real c, b, s, a, e, FINT integer i external F common c e=0.01 c=0.8 m=1 i=1 do while (i.le.5) b=0.7*c a=1 s=fint(f, a, b, e) write(*,77) c,a,s 77 format(1x, 'c=',F5.3, 1x, 'a=', F5.3, 1x, 's=',F5.3) c=c+0.1 i=i+1 end do pause end real function FINT(F, a, b, e) integer n, i real f, a, b, e, s, spread,h, x s=0 spred=0 n=100 do while ((abs(s-spred).ge.e.or.n.le.2*100).and.n.le.100000) spred=s h=(b-a)/n s=0 x=a do i=1,n s=s+F(x) x=x+n enddo s=s*h n=2*n enddo FINT=s end real function F(x) real x common c f=((x-c)**2)*((x+c)**2) end |
Автор: FCM 3.4.2009, 09:24 |
Что значит не запускается исполняемый файл - может не строится вообще? В определении функции F(x) по моему не хватает явного описания, ассоциированной через COMMON-блок переменной с. Добавь real c |
Автор: FatalError 3.4.2009, 14:05 |
Что бросилось в глаза - двойное определение FINT: сначала как real (т.е. как число!), потом - как функция. Какой уж там ехе-файл, до этого дело точно не дойдет: у компилятора от такого финта мозги на бекрень съедут! Да, требуемая в условии подпрограмма EXLOC не использована! (а может, и фиг с ней?) |
Автор: FatalError 3.4.2009, 14:24 |
Это, конечно, не ошибка, но кто Вас учил так циклы строить??? С самодельным увеличением фактического параметра цикла? Почему нельзя позволить фортрану самому его увеличивать, используя стандартную конструкцию цикла? И если заранее известно, что циклов будет ровно пять, ни одним меньше и ни одним больше, зачем использовать конструкцию do while, потенциально опасную сваливанием в бесконечный цикл? Оно понятно, что здесь вроде не должно так зациклиться, но вдруг где ошибочка проскочит? Да, это я говорил про цикл в основной программе, вокруг метки 77. Что там делает do while в подпрограмме, это я еще не вникал. Ну и про обсуждаемый цикл должен сказать еще и пару слов одобрения: правильно, что не был сделан цикл с переменной c в качестве параметра и с ее изменением с шагом 0.1, хотя он вроде и напрашивается! |
Автор: FatalError 3.4.2009, 15:09 |
Под описанием "финта" - функции FINT(F, a, b, e) - определяется переменная spread, а используется дальше неинициализированная переменная spred. Средство борьбы с подобными опечатками очень простое: пишем директиву implicit none в начале программы, компилятор будет ругаться на все ранее не описанные переменные. Далее. "Финт" вроде должен считать площадь на основании входных данных. Входные данные не верные: параметр а в основной программе определяется константой (a=1), хотя это точка с интервала [0, c ], в которой функция F(x) максимальна. Так как некоторые значения переменной с меньше единицы, то точка а для них благополучно улетает за пределы заданного интервала. И зачем надо численно (по методу трапеций) считать площадь под функцией, если для этой функции известно аналитическое выражение? Что делать? Составить нормальный алгоритм решения: 1. Надо как следует потрясти функцию F(x) и выбить из нее все нужные показания. Поскольку нас интересует интервал [0, c ], в точке 0 она всегда равна с**4, в точке с - нулю. Далее - берем ее производную и убеждаемся, что на участке [0, c[ она отрицательна. Стало быть, она монотонно падает, и ее высшая точка на этом интервале - при х=0. Стало быть, а=0, и нам надо интегрировать на участке от 0 до b = 0.7*с 2. А теперь, хе-хе, начинаем интегрировать. В общем виде. Поскольку это полином, найти первообразную - задачка для школьника. Ну и, соответственно, находим площадь как определенный интеграл, т.е. разность значений первообразной на концах отрезка. В общем виде, как полином, т.е.функцию от параметра с. 3. Ну и только после этого начинаем собственно программировать. Пишем цикл с перебором значений с (не важно как, сойдет и существующий, хотя он и не больно эстетичен), для каждого значения считаем площадь (вызовом функции, считающей интеграл через полином и зависящей теперь только от параметра с) и выводим данные на печать (точнее, на экран). |
Автор: awers 3.4.2009, 15:12 | ||
|
Автор: ghost8495 3.4.2009, 21:15 |
спасибо за справедливые замечания, сижу исправляю |
Автор: ghost8495 9.4.2009, 22:50 | ||
Исправил, доработал, но есть одно "но" : площадь слишком уж маленькая (
http://www.radikal.ru |
Автор: FatalError 10.4.2009, 16:06 |
Скорее всего, из-за неправильного обращения с функцией F. Зачем ее повсеместно объявлять как real? Например: real F, a, b, e, s, spred,h, x Это значит, что F - просто дробное число. И зачем вставлять F в аргументы функции FINT? |