АвторСообщение



Не зарегистрирован
Зарегистрирован: 30.09.13
ссылка на сообщение  Отправлено: 30.09.13 17:58. Заголовок: Вопрос по задаче 14


Объясните пжл. не понимаю.
в задаче 14 из учебника при работе оператора for (ниже скопироавал пример из учебника)
на этапе сравнения s и S и выборе большего значение.
откуда берется значение S с которым нужно сравнить s. если до этого значение S нигде не вычеслялось и не назначалось?

Возможно я что-то упустил.


//--------------------------------------------------------------------
// rectangle.mq4
// Предназначен для использования в качестве примера в учебнике MQL4.
//--------------------------------------------------------------------
int start() // Специальная функция start()
{
//--------------------------------------------------------------------
int
L=1000, // Заданная длина нити
A, // Первая сторона прямоугольн.
B, // Вторая сторона прямоугольн.
S, // Площадь прямоугольника
a,b,s; // Текущие значения
//--------------------------------------------------------------------
for(a=1; a<L/2; a++) // Заголовок оператора цикла
{ // Скобка начала тела цикла
b=(L/2) - a; // Текущее значение сторон
s=a * b; // Текущее значение площади
if (s<=S) // Выбираем большее значение
break; // Выходим за пределы цикла
A=a; // Запоминаем лучшее значение
B=b; // Запоминаем лучшее значение
S=s; // Запоминаем лучшее значение
} // Скобка конца тела цикла
//--------------------------------------------------------------------
Alert("Максимальная площадь = ",S," A=",A," B=",B);// Сообщение
return; // Оператор выхода из функции
}
//--------------------------------------------------------------------

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 6 [только новые]


Автор




Пост N: 1074
Зарегистрирован: 21.05.06
Откуда: Украина, Днепропетровск
ссылка на сообщение  Отправлено: 30.09.13 20:00. Заголовок: Homosapien$ пишет: о..


Homosapien$ пишет:
 цитата:
откуда берется значение S с которым нужно сравнить s. если до этого значение S нигде не вычеслялось и не назначалось?
Возможно я что-то упустил.



Любая переменная - это всего лишь название некоторого значения. Значение присутствует в программе более фундаментально; можно сказать, значения имеются всегда. Значения, которые никак не назвали, существуют сами по себе; в программе их называют константами. Значения, которые как-то названы, представляют из себя содержание переменных. Поэтому у любой переменной с самого первого её упоминания в программе есть значение.

Следующие записи идентичны:
int S = 0;
int S;
Формально-бюрократически эти записи читаются так: вычислить выражение справа от знака равенства и полученное значение присвоить переменной слева от знака равенства.
В первой строке справа от = явно указан 0. Вот, он и присваивается переменной S.
Во второй строке нет знака равенства (и справа от него ничего не указано). Такая запись допускается. В этом случае переменная типа int инициализируется нулём (инициализируется - это значит, впервые обретает некоторое значение; в дальнейшем это значение переменной может быть изменено).

В нашей программе указана строка:
int L=1000, A, B, S, a,b,s;
Такая запись тоже допускается. Здесь через запятую перечислены переменные, которые будут использоваться в программе как переменные целого типа (в начале строки указан int, значит эти переменные - целого типа). В данной строке переменная L инициализируется значением 1000, а все остальные переменные инициализируются нулём.

Вообще, нужно сказать, что в подобных случаях разные языки диктуют разные правила. И никак интуитивно это не узнать. Поэтому в общем случае (чтоб ни у кого не спрашивать и не ошибиться) нужно запросить вывод значения переменной в нужном месте программы. Сделать это легче всего с помощью оператора Alert().В данном случае для наглядности можно вставить в программу следующий фрагмент кода:
Alert("s = ", s, " S = ", S); // Выводим значения переменных s и S.
перед тем местом, где значения этих переменных сравниваются:

...
b=(L/2) - a; // Текущее значение сторон
s=a * b; // Текущее значение площади
Alert("s = ", s, " S = ", S); // Выводим значения переменных s и S.
if (s<=S) // Выбираем большее значение
break; // Выходим за пределы цикла
...



Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 1
Зарегистрирован: 30.09.13
ссылка на сообщение  Отправлено: 01.10.13 13:42. Заголовок: Отлично, спасибо, чт..


Отлично, спасибо, что нашли время ответить.
С начальным значением int S я разобрался.

Тогда еще вопрос.
В этом коде при итерациях происходит пересчет значения s и последующее сравнение с S.
При первом расчете полученное значение s сравнивается с 0, поскольку S по умолчанию равно 0.

Что просиходит при вотором расчете? Очевидно, что на каком то этапе значению S должно быть присвоено значение s из первого расчета.
в коде этого присвоения не видно?
Или тут какая-то другая логика?

Спасибо.

Спасибо: 0 
ПрофильЦитата Ответить
Автор




Пост N: 1075
Зарегистрирован: 21.05.06
Откуда: Украина, Днепропетровск
ссылка на сообщение  Отправлено: 02.10.13 20:44. Заголовок: Наверное, Вам имеет ..


Наверное, Вам имеет смысл перечитать этот параграф.

При втором расчёте всё так же очевидно (по ходу рассуждений смотрите на картинку 44).
Значение s сравнивается с S. И если текущее значение s (то, что правее предыдущего на кривой графика) больше, чем ранее запомненное значение переменной S, значит расчёт пока ведётся в промежутке кривой слева от перегиба (экстремума, который нас-то и интересует). И так продолжается долго (с шагом в 1 мм), а именно, до тех пор, пока всё ещё не соблюдается условие (s<=S). При этом специальный выход из цикла не происходит, а в теле цикла запоминается вновь достигнутое (большее на этом интервале) значение переменной s, - оно и присваивается переменной S.

Но как только мы пройдём экстремум (т.е. вычисления будут вестись уже справа от точки перегиба), то тут же окажется, что вновь вычисленное значение переменной s меньше, чем последнее запомненное значение в переменную S. Это-то и есть искомая ситуация, которая нам и указывает на необходимость прекратить расчёты в теле цикла и закончить исполнение программы в целом. В этом случае выход из цикла происходит с помощью оператора break. И программа заканчивает вычисления.

В общем случае исследуемая функция может иметь несколько или множество экстремумов (как в периодических функциях, - например, sin), либо не иметь экстремума. В каждом конкретном случае нужно принимать свои меры, отдавая себе отчёт с чем имеем дело.
В данном случае в рассуждениях необходимо опираться на кривую на Рис. 44. То, что кривая имеет экстремум не очевидно обычному читателю, поэтому я и дал рисунок 44 в тексте. Рассуждения здесь простые - по мере увеличения значения переменной а значение площади растёт в промежутке от 0 до экстремума, потом падает. Как только начало падать, так сразу break, которому и посвящён параграф.

(я не всегда могу ответить на вопросы пользователей сразу, но отвечаю обязательно; если будут вопросы, задавайте, это нормальный процесс)

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 2
Зарегистрирован: 30.09.13
ссылка на сообщение  Отправлено: 03.10.13 11:12. Заголовок: спасибо за терпение...


спасибо за терпение.
:) самое удивительное, что всю логику расчетов без привязки к коду я прекрасно понимаю - она не сложная:
проверять площадь с шагом 1 пока она не начнет убывать, как только начала убывать - break.

Перечитал параграф еще раз 10 :). Все равно не догоняю, с моей точки зрения не хватает одной операции присвоения.
Смотрите, где я не прав?:

1-ый расчет:
а=1, b=499, s=499
сравниваем s и S т.е. 499<=0 - "ложь", продолжаем расчет.
2-ой расчет:
а=2, b= 498, s= 996
мы должны сравнить s и S, т.е. 996 и 499.

Вот тут у меня и возникает вопрос: С какого перепугу S получила значение 499, если в предыдущем расчете S имела значчение 0?
Нигде в коде переменной S не присваивается значение s.
С моей точки зрения код должен выглядеть так:

for(a=1; a<L/2; a++) // Заголовок оператора цикла
{
b=(L/2) - a; // Текущее значение сторон
s=a * b; // Текущее значение площади
if
{
s<=S // Выбираем большее значение
break;
}else // если в предыдущем расчете ложь, то
{
S=s; // присваивем переменно S значение s и возвращаемся к циклу.
}
}

я пробовал скомпелировать свой вариант - не получается :( а ваш работает.








Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 3
Зарегистрирован: 30.09.13
ссылка на сообщение  Отправлено: 03.10.13 11:30. Заголовок: Вы знаете , видимо я..


Вы знаете , видимо я пока писал, разобрался.
в коде есть присвоение S=s,
я считал, что функция присвоения не включается пока не закончился цикл, получается, что при каждом расчете происходит присвоение.

Извините за отнятое время. Грызу дальше :)

Спасибо: 0 
ПрофильЦитата Ответить
Автор




Пост N: 1076
Зарегистрирован: 21.05.06
Откуда: Украина, Днепропетровск
ссылка на сообщение  Отправлено: 03.10.13 18:48. Заголовок: Да. Здесь такое: в о..


Да.
Здесь такое: в операторе if нет части else. Это значит, что если условие не выполняется, т.е. пока ещё не break, то исполнение оператора if заканчивается и управление просто передаётся оператору, следующему за if . А там несколько строк, где запоминаются последние вычисленные данные, - этот наборчик значений а и b характеризует лучшее их сочетание в смысле наибольшего S среди проверенных : )

А дальше просто. Рано или поздно в переборе найдётся такое s, которое меньше S и мы тут же break, т.е. правую ветку кривули проверять не будем, - незачем, здесь это важно. Вот и польза от применения break, о котором параграф.


Спасибо: 0 
ПрофильЦитата Ответить
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 11
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет