Базовый курс. Занятие №2
Второе занятие по 0-му блоку базового курса.
Необходимо изучить следующие главы.
Глава 12. Примитивные типы данных
Глава 13. Контекст исполнения кода
Глава 14. Объектная техника
Глава 15. Сервисные средства по написанию кода
Также нужно выполнить домашнее задание, текст которого доступен на странице.
В этой же теме необходимо написать отчет о выполнении задания.
ps. Участники курса без доступа в мастер-группу отчитываться по домашним заданиям не могут.
— залогиньтесь.
Если не активировали токен — посмотрите видео-инструкцию (видео N5)
Если вы залогинены, у Вас активирован токен доступа, но вы все равно видите эту запись —напишите нам на e-mail поддержки.
1. всё получилось (зацикливание)
2. в п.г) ошибся
3. Через промежуточную переменную всё понятно, без её использование сделал через сложение и вычитание (от участников мастер-группы открыл для себя новые варианты решения)
Д.з.№ 2
1. Зацикливание = локальная переменная
2. А= “010010”; Б =”01010″; В= 1; Г= “010-101”
3.
//с
//д.з 2.3 вариант 1
Выплачено = 1000 ;
Начислено = 2000;
ПромежуточнаяПеремен = Выплачено;
Выплачено = Начислено;
Начислено = ПромежуточнаяПеремен;
//д.з 2.3 вариант 2
Выплачено = 1000 ;
Начислено = 2000;
Выплачено=Начислено+Выплачено;
Начислено=Выплачено-Начислено;
Выплачено=Выплачено-Начислено;
//-с
все получилось проблем не возникло
п.3
//через переменную
тмп = Начислено;
Начислено = Выплачено;
Выплачено = тмп;
// через операции +-
Начислено = Начислено+Выплачено;
Выплачено = Начислено-Выплачено;
Начислено = Начислено-Выплачено;
1. Бесконечный цикл, пришлось принудительно завершать программу. Сначала предполагал, что будет работать присваивание , а не сравнение.
2. Возникли трудности с Г. Какой приоритет при выборе операции (Конкатенация или преобразование переменной)?
3. Первый вариант с промеж переменной аналогичен представленному в видеокурсе. Второй В=А+В ; А=В-А ; А=В-А . Но это сработает только для числовых переменных. Более читабелен вариант с промежуточной переменной
1.Зацикливание. Массив М заполняется значениями “Ложь”
2.Без отладчика правильно ответил только на А и В.
А “010010”
Б “01010”
В 1
Г “010-101”
3.Первый способ:
Временно = Начислено;
Начислено = Выплачено;
Выплачено = Временно;
Второй способ:
Начислено = Начислено + Выплачено;
Выплачено = Начислено – Выплачено;
Начислено = Начислено – Выплачено;
1. Проблем не возникло.
Бесконечный цикл. Масив наполняется элементами со значением “Ложь”.
2. Правильно определил только А.
Поигрался в отладчике, все осознал.
Единственно, возник вопрос, где это может быть полезно на практике? Читаемость кода, ИМХО, гораздо лучше при использавании функций преобразования значений “Число”, Строка”.
3. Проблем не возникло.
//С использованием промежуточной переменной
Начислено = 1000;
Выплачено = 2000;
ВременнаяПеременная = Начислено;
Начислено = Выплачено;
Выплачено = ВременнаяПеременная;
//Без использования промежуточной переменной
//1-й вариант
Начислено = 1000;
Выплачено = 2000;
Выплачено = Начислено + Выплачено;
Начислено = Выплачено – Начислено;
Выплачено = Выплачено – Начислено;
//2-й вариант
Начислено = 1000;
Выплачено = 2000;
Выплачено = Начислено*Выплачено;
Начислено = Выплачено/Начислено;
Выплачено = Выплачено/Начислено;
>Единственно, возник вопрос, где это может быть полезно на практике?
Большого практического смысла нет, но иногда приходится встречаться с подобным кодом, поэтому нужно его понимать.
1. Зацикливание. Массив беконечно заполняется значением ЛОЖЬ
2. Пункты А,В без проблем. Пункт Б – были сомнения: не будет ли синтакс.ошибки. Если нет, то и Г решается без проблем.
3. Второй вариант почему-то понял очень сложно: одной строкой сформировать функцию вида а = f(a,b), которая меняет местами значения a и b без дополнительных переменных (например, “игрой” параметров по ссылке и значению). Не получилось …. Получилось лишь так (что, наверное, равносильно вводу 3 переменной):
Создаю функцию
Функция f(a,b, Знач c) //3 -параметр – по значению!
a=b;
Возврат с
КонецФункции
Тогда одной строкой замену можно записать так
Выплачено = f(Начислено,Выплачено,Начислено)
Перем ТекДата;
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ТекДата=Дата(‘2012.01.01’);
ГодСообщения=Строка(Сред(ТекДата,7,4));
КолРабДней=0;
Пока ТекДата<Дата(‘2022.01.01’) цикл
Пока Строка(Сред(ТекДата,7,4))=ГодСообщения Цикл
Если Не (Выходной()или Праздничный())тогда
КолРабДней=КолРабДней+1;
КонецЕсли;
ТекДата=ТекДата+86400;
КонецЦикла;
Сообщить(Строка(ГодСообщения)+”год – “+КолРабДней+” рабочих дней” );
ГодСообщения=Строка(Сред(ТекДата,7,4));
КолРабДней=0;
КонецЦикла;
КонецПроцедуры
&НаСервере
Функция Выходной()
Возврат (ДеньНедели(ТекДата)=6) или (ДеньНедели(ТекДата)=7);
КонецФункции
&НаСервере
Функция Праздничный()
Возврат (Строка(Сред(ТекДата,1,5))=”01.01″ или Строка(Сред(ТекДата,1,5))=”23.02″ или Строка(Сред(ТекДата,1,5))=”08.03″);
КонецФункции
1. Бесконечный цикл.
2. Правильно определил только А и В.
3. Промеж = Начислено;
Начислено = Выплачено;
Выплачено = Промеж;
и без переменной:
Начислено = Выплачено + Начислено;
Выплачено = Начислено – Выплачено;
Начислено = Начислено – Выплачено;
1. В ловушку зацикливания попалась, выводы сделала :) Так как тестировала без отладчика-пришлось принудительно останавливать бесконечную работу (через диспетчер задач- и поэтому вопрос – есть ли более правильный способ остановить бесконечный цикл?)
2.А и В – решились без проблем, Б и Г – ошиблась, причины осознала
3.Первый вариант – с промежуточной переменной вопросов не вызвал, вспомнился пример из видеоурока. второй вариант пришлось подсмотреть у более опытных товарищей. Спасибо, урок интересный.
>есть ли более правильный способ остановить бесконечный цикл?
Есть, но только если возможно к сеансу подключиться отладчиком.
Тогда ловите этот вечный цикл точкой останова и прекращаете отладку, например Shift+F5.
1. Получился бесконечный цикл, добавляющий в массив Ложь
2. Угадал только В. Вообще, интересно как ведет себя платформа в тиких ситуациях.
3. Вариант с дополнительной переменной
<code>ВремЗначение = Начислено;
Начислено = Выплачено;
Выплачено = ВремЗначение;</code>
Без использования дополнительной переменной
<code>Начислено = Начислено + Выплачено;
Выплачено = Начислено-Выплачено;
Начислено = Начислено-Выплачено;</code>
Интересно, что при перестановке трех переменных использование дополнительной переменной дает уже больше экономии по операциям (4 против 6)
<code>ВремЗначение = Начислено;
Начислено = Выплачено;
Выплачено = Удержано;
Удержано = ВремЗначение;</code>
без временной переменной
<code>//меняем первую с третьей
Начислено = Начислено + Удержано;
Удержано = Начислено-Удержано;
Начислено = Начислено-Удержано;
//вторую с третьей
Выплачено = Выплачено + Удержано;
Выплачено = Выплачено-Удержано;
Удержано = Выплачено-Удержано;
</code>
плюс первый способ универсальный
Решение ДЗ2:
1. Знак равно в выражении М.Добавить(Счетчик=Счетчик+1); действует не как присваивание, а как сравнение. Поэтому цикл бесконечный.
2. Так как первый аргумент везде – Строка, то результирующий тип данных будет тоже строка
А. обычная конкатенация “010”+”010″=”010010″
Б. унарная операция +”010″ преобразует строку в число и конкатенация “010”++”010″=”01010″
В. Не понятно почему система преобразует выражение в Число и не выдает ошибку на “-“, хотя первый аргумент – строка. В 1С выдало “010”-“010″+1=1 тип Число
Г. Второй аргумент имеет унарный минус и преобразовался к числу. Общее выражение – строка (как и положено) “010”+-“010″+1=”010-101”
3. Вариант с третьей переменной:
ВременнаяПеременная=Выплачено;
Выплачено=Начислено;
Начислено=ВременнаяПеременная;
Вариант без использования третьей переменной:
Выплачено=Выплачено+Начислено;
Начислено=Выплачено-Начислено;
Выплачено=Выплачено-Начислено;
1. Бесконечный цикл
2. А. 010010
Б. 010010
В. 1
Г. 010-101
Не понял в Г. как так? Прошу разъяснения.
3. По условию задачи промежуточная переменная не требуется, переменная была-бы необходима ели требовалось значения переменных поменять местами, а так простое присвоение числа переменным:
Начислено = 2000;
Выплачено = 1000;
>Не понял в Г. как так? Прошу разъяснения.
Пояснение будет в решении задания.
1. Бесконечный цикл так как значение переменной Счетчик не изменяется.
Логическое выражение Счетчик= Счетчик +1 передает в функцию М.Добавить значение ИСТИНА
2. А.«010»+ «010» = «010010»
В. «010»+ «010»= «010»+10=«010»+ «10»= «01010»
С. «010»-«010»+1=10-10-1=1
Г. «010»+ -«010»+1= =«010»+ (-10)+1=«010»+ «-10»+ «1»= «010-101» (совершенно неочевидно!!!)
3.С исп.промежуточной переменной
Н=1000; В=2000;
А=Н;
Н=В;
В=А;
Без использования
Н=1000; В=2000;
Н=Н+В; //Н=3000;
В=Н-В; //В=1000;
Н= Н-В;//Н=2000;
Процедура зацикливается, т.к. не выполняется условие выхода из цикла – нет прироста Счетчика. Второе задание оказалось не столь очевидным. Предполагал, что система приведет переменные в кавычках к числам. Пришлось пересмотреть приоритеты выполнения операций. Замена переменных через дополнительную переменную уже была рассмотрена в одном из видеоуроков. Вариант без использования сторонних переменных думаю лучше использовать через сложение-вычитание, т.к. в общем случае при перемножении отрицательных величин теряется знак переменной.
1 задание в добавлении сравнивается значения счетчика Сч и Сч+1 присваивается ложь, цикл бесконечный.
2 задание
строка+строка=строка
строка+число=строка
число-число+число=число
строка+число+число=строка
3 задание хотелось чтобы можно было в функцию передать (начислено, выплачено), а вернуть в процедуру (выплачено,начислено)
в общем сделала используя вычитание и сложение
1) Зацикливание, М= Массив
2) Угадала, но не все
3) С использованием – легко:
<code>
А =Выплачено;
Начислено =А;
А =Начислено; </code>
Бес использования – сложение и вычитание
1) В теле цикла счетчик не меняет своего значения, значит в цикле будет добавляться элемент массива М со значением Ложь. Элемент массива будет добавляться до тех пор, пока не будет добавлен максимально возможный элемент массива. После чего выполнение программного кода будет прервано и будет сгенерировано ошибочное сообщение.
Дождался сообщения — Недостаточно памяти! Запуск и отладка все подтвердили.
2) «010» + «010» результат «010010»
«010» ++ «010» результат «010010»
«010» – «010» +1 результат 1
«010» +- «010» +1 результат сообщение об ошибке
итого два правильных ответа и два не правильных.
3)
&НаКлиенте
Перем Начислено, Выплачено;
&НаКлиенте
Процедура Сформировать(Команда)
Начислено=1000;
Выплачено=2000;
ВрЗнач=Начислено;
Начислено=Выплачено;
Выплачено=ВрЗнач;
//вариант 1
Начислено=1000;
Выплачено=2000;
ОбменЧислами(Начислено, Выплачено);
//вариант 2
Начислено=1000;
Выплачено=2000;
Начислено=Начислено*Pow(10,СтрДлина(СтрЗаменить(Строка(Выплачено),Символ(160),””)))+Выплачено;
Выплачено=Цел(Начислено/Pow(10,СтрДлина(СтрЗаменить(Строка(Выплачено),Символ(160),””))));
Начислено=Начислено % Pow(10,СтрДлина(СтрЗаменить(Строка(Выплачено),Символ(160),””)));
КонецПроцедуры
&НаКлиенте
Процедура ОбменЧислами(Знач ПервоеЧисло, Знач ВтороеЧисло)
Начислено=ВтороеЧисло;
Выплачено=ПервоеЧисло;
КонецПроцедуры // ОбменЧислами()
1. Цикл зациклился :)
2.
А. «010» + «010»
Б. «010» ++ «010»
В. «010» – «010» + 1
Г. «010» +- «010» + 1
А. “010” + “010” = “010010”
Б. “010” ++ “010” = “01010”
В. “010” – “010” + 1 = 1
Г. “010” +- “010” + 1 = “010-101”
3. С переменной:
ПромежПерем = Выплачено;
Выплачено = Начислено;
Начислено = ПромежПерем;
Без переменной (вот тут я голову поломал блин):
Выплачено = Начислено + Выплачено;
Начислено = Выплачено – Начислено;
Выплачено = Выплачено – Начислено;
Почему у меня некоторые строки повторяются?
Это особенность работы сайта: когда вы вставляете текст из буфера и его правите возможно задвоение.
Теперь буду писать всё ручками.
1. Пока не запустила отладчик, думала, что в массиве будут числа от 1 до 1000:-( Потому что считала, что там операция присваивания,а не сравнения.
Но отладчик ясно показал,что получается массив бесконечной лжи)))
2. В уме неправильно решила примеры с унарными операциями. КАк показал отладчик, унарная операция “+” со строкой эквивалентна 0 +”строка”. А поскольку если тип первого операнда число, то платформа автоматически пытается строку в число преобразовать. Вот так, сделала два открытия Америки – унарные операции в целом и унарные операции над строками:-)
3. <code>
//с использованием промежуточной переменной
Начислено = 1000;
Выплачено = 2000;
ПП = Начислено;
Начислено = Выплачено%
Выплачено = ПП;
//Без использования промежуточной переменной – этот способ взорвал мой мозг
а = 1000;
б = 2000;
б=а+б;
а=б-а;
б=б-а;
</code>
1. Получаем массив до бесконечности заполняемый ложью – результатом булевской операции сравнения.
2. Изначально правильно вычислил результаты вариантов А и В. Сделал вывод система при невозможности корректно произвести операцию над операндом данного типа преобразует его в тип по отношению к которому данная операция допустима.
3. С использованием промежуточной переменной:
<code>
Промежуточная = Начислено;
Начислено = Выплачено;
Выплачено = Промежуточная;
</code>
Без ее использования:
– вариант 1
<code>
Начислено = Начислено + Выплачено;
Выплачено = Начислено – Выплачено;
Начислено = Начислено – Выплачено;
</code>
– вариант 2
<code>
Начислено = Начислено * Выплачено;
Выплачено = Начислено / Выплачено;
Начислено = Начислено / Выплачено;
</code>
Задания выполнила.
В пункте 1. верно предположила что будет зацикливание, так как счетчик не увеличивается, и массив заполнится значениями “ложь”
В пункте 2. ошиблась в б и г, пришлось пересмотреть соответствующие уроки + прочитав комментарии пришла к выводу, что при сложении строк анализируется наличие унарных операций и они выполняются раньше.
Пункт 3:
Перем = Начислено;
Начислено = Выплачено;
Выплачено = Перем;
и без переменной:
Выплачено = Начислено+Выплачено;
Начислено = Выплачено – Начислено;
Выплачено = Выплачено – Начислено;
Задание 2 выполнено
в первом пункте интуитивно понял, что либо ошибку выдаст на Синтаксис, либо будет бескончный цикл,вдумавшись понял, что идет момент сравнения, а не увеличение значения переменной
все остальное получилось
3 задание неправильно сделала, ввела доп переменную.
Переделала:
Начислено = Строка(Начислено)+Строка(Выплачено);
Выплачено = Лев(Начислено,СтрДлина(Начислено)-СтрДлина(Выплачено));
Начислено = Прав(Начислено,СтрДлина(Начислено)-СтрДлина(Выплачено));
1 задание. Результат был понятен.
2 задание. Кроме варианта А ничего не угадала.
3 задание.
а)ПромежЗнач = Начислено;
Начислено = Выплачено;
Выплачено = ПромежЗнач;
б)строкаСум = Строка(Начислено)+Строка(Выплачено);
Начислено = Прав(строкаСум,СтрДлина(Выплачено));
Выплачено = Лев(строкаСум,СтрДлина(Начислено));
1. Бесконечный цикл. Там нет наращивания переменной Счетчик. Массив заполняется булевом “Ложь”.
2. А, Б, В – угадал. Г – про “-” забыл. Строка(-10) = “-10”.
3. Сначала был взорван мозг, так как нужно хранить где-то третье значение. Допускал что переменные могут иметь любые значения. Думал, что задача на контекст и нужно с ним играть. Глобальную переменную создать нельзя как в 7.7) Есть ПараметрыСеанса, но это уже третья переменная…
Объявил переменные на клиенте и одну на сервере.
“Запоминал” третье значение в этой серверной переменной, но она “жила” только до выхода из процедуры. При следующем обращении к ней из другой серверной процедуры она была уже “Неопределено”.
Потом перечитал задание и пришла мысль с преобразованием в строки, так как в условии задано, что значения числовые. В итоге наваял:
//второй способ – только при числ. значениях
Начислено = “” + Начислено + Выплачено;
Выплачено = Число(СтрЗаменить(Начислено,Строка(Выплачено),””));
Начислено = Число(Сред(Начислено, СтрДлина(Строка(Выплачено))+1));
Кстати, родился вопрос:
Почему объявленная ы модуле формы переменная с директивой “&НаСервере” теряет значение при повторном обращении к серверной процедуре?
Хороший вопрос.
Серверная переменная модуля формы живет только в контексте серверного вызова.
То есть ее значение не храниться вместе с формой.
Такой подход необходим для оптимизации работы формы.
Если требуется сохранить значение в форме, чтобы оно было доступно на сервере, то можно создать реквизит формы с соответствующим типом данных.
1. Все правильно угадал.
2. В пункте Г немного задумался.
3. Сделал. Вот вариант без промежуточной переменной (хотя сам так никогда не делаю из-за нечитабельности):
Начислено=Начислено+Выплачено;
Выплачено=Начислено-Выплачено;
Начислено=Начислено-Выплачено;
1. Получается “Вечный двигатель” :)
2.”010010″,”01010″,1,”010-101″ (вариант г. решила при помощи отладчика)
3.//1 вариант (промежуточная переменная)
Начислено=1000;
Выплачено=2000;
ПромежуточнаяПеременная=Выплачено;
Выплачено=Начислено;
Начислено=ПромежуточнаяПеременная;
//2 вариант (без промежуточной переменной)
Начислено=Начислено+Начислено;
Выплачено=Выплачено/2;
1,2) разобралась;
3.1) Временная = Начислено;
Временная = Начислено;
Выплачено = Временная;
3.2) Всего = Строка(Начислено) + Строка(Выплачено);
КолЗнВсего = (СтрДлина(Всего));
КолЗнВыплачено = (СтрДлина(Выплачено));
КолЗнНачислено = КолЗнВсего – КолЗнВыплачено;
Выплачено = Число(Лев(Всего,КолЗнНачислено));
Начислено = Число(Прав(Всего,КолЗнВыплачено));
Всего = Строка(Начислено) + Строка(Выплачено);
КолЗнВсего = (СтрДлина(Всего));
КолЗнВыплачено = (СтрДлина(Выплачено));
КолЗнНачислено = КолЗнВсего – КолЗнВыплачено;
Выплачено = Число(Лев(Всего,КолЗнНачислено));
Начислено = Число(Прав(Всего,КолЗнВыплачено));Всего = Строка(Начислено) + Строка(Выплачено); КолЗнВсего = (СтрДлина(Всего)); КолЗнВыплачено = (СтрДлина(Выплачено)); КолЗнНачислено = КолЗнВсего – КолЗнВыплачено; Выплачено = Число(Лев(Всего,КолЗнНачислено)); Начислено = Число(Прав(Всего,КолЗнВыплачено));
Извините, докорректировалась))
Это особенность нашего блога.
Задание №1 – выполнено;
Задание №2 – выполнено;
Задание №3 –
Выплачено = Выплачено + Начислено; Начислено = Выплачено – Начислено; Выплачено = Выплачено – Начислено;
В первом задании сразу было понятно, что цикл будет с бесконечным добавлением элементов массива со значением “Ложь”.
Во втором задании угадал ответы в пунктах А, В. С пунктами Б, Г разобрался только после проверки результата: если перед строкой стоит + или -, система выполняет преобразование в число, теряется ноль перед значащими цифрами, а затем, так как слева в выражении стоит строка, идёт обратное преобразование к строке вне зависимости от количества последующих операторов.
С третьим заданием проблем не возникло:
С использованием промежуточной переменной:
<code>Процедура Тест(Команда)
Начислено = 1000;
Выплачено = 2000;
Промежуточная = Начислено;
Начислено = Выплачено;
Выплачено = Промежуточная;
КонецПроцедуры</code>
Без ее использования:
<code>Процедура Тест(Команда)
Начислено = 1000;
Выплачено = 2000;
Начислено = Начислено + Выплачено;
Выплачено = Начислено – Выплачено;
Начислено = Начислено – Выплачено;
КонецПроцедуры</code>
1) Из-за того, что в строке
М.Добавить(Счетчик = Счетчик + 1)
происходит не присваивание значения, а сравнение, массив заполняется значением Ложь до бесконечности.
2) Верно определил только первое значение. Для себя решил, что использование таких конструкций не добавляет читабельности коду.
3) Если допустить, что переменные можно приводить к типу “Строка”, то можно использовать такой вариант:
——-
Уплачено= “” + Начислено + Уплачено;
Начислено = Число(СтрЗаменить(Уплачено,Начислено,””));
Уплачено = Число(СтрЗаменить(Уплачено,Начислено,””));
——-
Если к типу “Строка” приводить нельзя – можно использовать такой вариант:
——-
Начислено = Начислено +(*) Уплачено;
Уплачено = Начислено – (/)Уплачено;
Начислено = Начислено – (/)Уплачено;
——-
Можно использовать пары операций сложения/вычитания и умножения/деления;
Еще один вариант с приведением к строке:
——-
Уплачено = “” + Начислено + Символы.ПС + Уплачено;
Начислено = Число(СтрПолучитьСтроку(Уплачено,2));
Уплачено = Число(СтрПолучитьСтроку(Уплачено,1));
——-
Но вообще говоря, самым адекватно воспринимаемым вариантом при реализации на языке 1С мне кажется вариант через вспомогательную переменную.
1.
Зацикливание, Счетчик внутри цикла Пока не изменится;
2.
А – «010010», Б – «010010»; В – 1; Г -“010-101”;
3.
Промежуточная = Начислено;
Начислено = Выплачено;
Выплачено = Промежуточная;
или так
Начислено = Начислено*Выплачено;
Выплачено = Начислено/Выплачено;
Начислено = Начислено/Выплачено;
а можно и так
Начислено = Начислено – Выплачено;
Выплачено = Выплачено + Начислено;
Начислено = Выплачено – Начислено;
Ответы по пунктам задания:
1) Сначала подумал что массив заполнится числами от 0 до 1000, но потом разобрался что присваивания не происходит в скобках и происходит зацикливание.
2) Тут запутался, решил правильно только 3 пример пересмотрел соответсвующие уроки и уложил в голове как все это работает.
3)
3.1 (с доп. переменной)
А = 1000;
Б = 2000;
В = Б;
Б = А;
А = В;
3.2 (без доп. переменной)
А = 1000;
Б = 2000;
А=А+Б;
Б=А-Б;
А=А-Б;
Задание выполнено.
1) В выражении “Счетчик = Счетчик + 1” знак “=” выступает не как знак присваивания, а в качестве знака сравнения, следовательно в массив добавляются значения “Ложь”, а увеличение счетчика на 1 не происходит. Результат => Зацикливание
2) Результаты:
а) “010010” (Строка)
б) “01010” (строка)
в) 1 (Число)
г) “010-101” (Строка)
3)
А = 1000;
Б = 2000;
а) с использование промежуточной переменной:
В = А;
А = Б;
Б = В;
б) Без нее:
А = А + Б; //1000+2000=3000
Б = А-Б; // 3000-2000 = 1000
А = А-Б; // 3000 – 1000 = 2000
Вариант а) на мой взгляд более информативен
Задание 1 промахнулся со счетчиком.
Задание 2 промахнулся в операциях с двойным знаками, потом пришлось “вдумываться”.
Задание 3 это я уже проходил в своей жизни.
3. Без дополнительной переменной
а=б-а;
б=б-а;
а=а+б;
Решила дополнить свой отчет:
1. зацикливается. Вопросов не возникло.
2.А,Б,Г- угадала .Г- нет. Пересмотрела уроки: «+-»= «-» , но у нас первый тип данных строка, значит, система будет преобразовывать к строке, и мы имеем операцию присоединения строки, а не сложение, т.е. «010»+(-«010»)+1.
3. С дополнительной переменной
с=а;
а=б;
б=с;
1) Скорее интуитивно не понравилось, что элемент в массив добавляется через оператор присвоения… Думал, что вернёт ошибку при исполнении.
На практике – получил бесконечный цикл. Исправил, как на мой взгляд должно выглядеть:
(в теле цикла)
<code>
М.Добавить(Счетчик);
Счетчик = Счетчик + 1;
</code>
В итоге – массив с 1000 элементов (я так понимаю – от 0 до 999)
2) Врать не буду, в уме – только в третьем выражении увидел результат – “1”, остальные вызвали затруднение.
Посмотрел на реакцию системы:
<code>
Сообщить(“010″+”010”);
Сообщить(“010″++”010”);
Сообщить(“010”-“010″+1);
Сообщить(“010″+-“010″+1);
</code>
Вернулось соответственно: 010010; 01010; 1; 010-101.
В табло первое-второе-четвёртое значение – “строка”, третье – “число”
3) Первая часть, в принципе, была рассмотрена в уроке:
<code>
ВременнаяПеременная = Начислено;
Начислено = Выплачено;
Выплачено = ВременнаяПеременная;
</code>
Вторую часть попробовал сделать с помощью операций над строками:
<code>
Начислено = Строка(Начислено) + Строка(Выплачено);
Выплачено = Число(Лев(Начислено,(СтрДлина(Начислено)-СтрДлина(Выплачено))));
Начислено = Число(Прав(Начислено,(СтрДлина(Начислено)-СтрДлина(Выплачено))));
</code>
Проверку провёл с примером из ДЗ, числами от 1 до 40 знаков (в т.ч. с отрицательными), вроде работает без сбоев. Значение Неопределено или булево возвращают ошибки.
Ок.
Задание выполнил. Задание понравилось.
1) В первом задании сразу определил, что цикл будет бесконечным, так как переменная “Счетчик” не будет меняться. При этом в каждом цикле массив будет увеличиваться на один элемент равным булевскому значению “Ложь”, так как “Счетчик” не равен “Счетчику+1”.
2) Второе задание понравилось больше всего, потому что из четырех выражений, я правильно рассчитал только одно(“В”). :)
А. Здесь я почему-то решил, что строки будут преобразованы к числам. На самом деле операция конкатенации для двух строк будет доминирующей, несмотря на то, что в строках содержится число. Правильный ответ – будет совершена операция конкатенации, результат выражения строка “010010”.
Б. Здесь я поторопился и решил, что результат тоже будет равен числу. На самом деле сначала вторая строка преобразовывается к числу +10, потом производиться операция конкатенации и в результате мы получаем строку “01010”.
В. Вот здесь я получил правильный результат. Строки преобразуются к числам, в результате получаем число ноль и к числу ноль прибавляем единицу, результат число “1”.
Г. Здесь я решил, что результат будет таким же как в пункте “В”. На самом деле, сначала вторая строка будет преобразована к числу “-10”, затем операцией конкатенации прикреплена к первой строке, затем к полученной строке операцией конкатенации будет прикреплено число “1”, предварительно преобразованное к типу строка. В результате получим строку “010-101”.
3) На втором этапе решения задания пришлось хорошенько включить голову, плюс появился интерес найти самое оптимальное решение.
А. С использованием промежуточной переменной(всё просто!):
<code>
Переменная=Начислено;
Начислено=Выплачено;
Выплачено=Переменная;
</code>
Б. Без её использования. Здесь у меня есть три варианта решения задачи:
1. Используя арифметических операций умножения и деления:
<code>
Начислено=Начислено*Выплачено;
Выплачено=Начислено/Выплачено;
Начислено=Начислено/Выплачено;
</code>
Вариант будет медленным для больших чисел.
2. Используя арифметических операций сложения и вычитания:
<code>
Выплачено=Начислено+Выплачено;
Начислено=Выплачено-Начислено;
Выплачено=Выплачено-Начислено;
</code>
Более быстрый, чем предыдущий вариант.
3. Используя дополнительную функцию Присвоить(А,Б), код функции:
<code>
А=Б;
Возврат А;
</code>
В результате выполнения, функция вернет значение “А” равное значению “Б”. Тогда код примет вид:
<code>
Начислено=Начислено+Выплачено-Присвоить(Выплачено,Начислено);
</code>
В результате переменные поменяются местами.
На мой взгляд самый рациональный вариант, это вариант с использованием промежуточной переменной.
Отличное решение!
Спасибо.
Так сильно увлекся, что не удержался и выполнил тестирование:)
Выполнял тестирование на своём ноутбуке, использовал версию платформы 8.2.13.219, сделал обработку куда можно было вводить любые значения “Начислено” и “Выплачено”. И четыре функции, реализующие различные способы меняющий значения переменных местами:
[1] С использованием дополнительной переменной;
[2] Используя арифметических операций сложения и вычитания;
[3] Используя арифметических операций умножения и деления;
[4] Используя дополнительную функцию Присвоить(А,Б);
Для замера производительности, использовал стандартные функции отладчика. Далее будут идти результаты в формате [способ вычисления] – (время выполнения, с).
Первый тест(Начислено=2000, Выплачено=1000):[1] – (0,000049)
[2] – (0,000064)
[3] – (0,000064)
[4] – (0,000112)
Второй тест(Начислено=45 977,12, Выплачено=22 399,37):
[1] – (0,000067)
[2] – (0,000067)
[3] – (0,000067)
[4] – (0,000114)
Третий тест(Начислено=1 234 567,89, Выплачено=9 876 543,21):
[1] – (0,000094)
[2] – (0,000064)
[3] – (0,000069)
[4] – (0,000111)
Вывод: при работе с небольшими числами(до 5 цифр), лучше использовать вариант[1]. При работе с более большими числами(более 5 цифр), варианты [1], [2] и [3] будут одинаково производительны. Но а при работе с большими числами(более 9 цифр) выигрывают [2] и [3] . Я конечно ожидал других результатов, так как думал, что самым затратным будет вариант [3], по крайней мере для других языков так оно и есть. Вариант [4] самый затратный по времени, так как используется вызов другой функции и он всегда будет проигрывать способу [2]. По данным тестирования можно предположить, что [2] способ самый оптимальный. Конечно, на основании данных тестов нельзя сделать объективную оценку какой способ лучше при работе с платформой 1С 8.2.13.219. Сам я пользуюсь и всем рекомендую использовать способ [1], так как в таком случаи код более “читабильный”.
Спасибо авторам за столь чудесное домашнее задание, которое на пару часов погрузило меня в изучение платформы :)
Спасибо за тестирование.
Сделаю ремарку.
Перечислим виды операции, которые встречаются в платформе:
– Запись в БД (самая медленная);
– Чтение из БД (вторая по “трудоемкости” операция”;
– Исполнение алгоритмов встроенного языка.
Исходя из этого если говорить об оптимизации, то упор нужно делать на самые затратные операции.
К сожалению, запись никак нельзя оптимизировать (ее платформа делает сама, интерфейсы закрыты).
А вот чтение можно. Для этого нужно корректно составлять запрос к БД.
Что касается алгоритмов, то их оптимизация обычно (но не всегда) не приводит к существенным результатам – конфигурация может “ускориться” на 5%, при этом будет потрачено большое количество сил.
Вывод – прежде всего нужно бороться за “быстрое” чтение.
Спасибо за информацию. Наверно именно поэтому очень много дискуссий про оптимизацию запросов и очень мало по поводу оптимизации алгоритмов встроенного языка. Выигрыш от оптимизации запроса может в несколько раз превысить выигрыш от оптимизации алгоритма на встроенном языке. Поэтому наверно имеет смысл стремиться к оптимизированным запросам и к “читабельному” коду. :)
Совершенно верный вывод.
1)Зацикливание. В данном контексте “Счетчик = Счетчик +1” это не присвоение значения переменой “Счетчик”, а логическое выражение проверки на равенство.
2)А. Результат Строка, ибо строка+строка не требует преобразования.
Б. Результат Строка. Первоначально выполняется унарная операция “+”, и как следствие преобразование строки к числу, а затем строка+число=строка.
Б. Результат Число. Операция “Строка – строка” не возможна, необходимо преобразование в число, т.е. получаем “число – число + число” = число.
Г. Результат Строка. Первой операцией выполнятся унарная “-” в результате чего второй операнд принимает значение типа число “-10”. Последующие два действия сводятся к операции строка+число=строка
3.
А = 1000;
Б = 2000;
//первый вариант
Г=А;
А=Б;
Б=Г;
//второй вариант
Б = А+Б;
А = Б-А;
Б = Б-А;
Явилось сюрпризом, что счетчик не увеличивался, а выходом операции было булево значение, думала, что будет массив с числовыми значениями. Вспомнила видео из ответов на вопросы пользователей, поняла ошибку.
Обнаружилась проблема с кавычками – при копировании из файла вставляются не форматные)). Из полученных выражений не поняла 4-е.
Варианты:
<code>
//1 вариант
А = Выплачено;
Выплачено = Начислено;
Начислено = А;
//2 вариант
Начислено = Начислено + Выплачено; //Н = 3000
Выплачено = Начислено – Выплачено;//В = 1000
Начислено = Выплачено – Начислено;//Н = 2000
</code>
Все впринципе понятно только с 4-ым примером во втором задании ошибся.
Начислено = 1000;
Выплачено = 2000;
ВремПер = Начислено;
Начислено = Выплачено;
Выплачено = ВремПер;
Начислено = 2000;
Выплачено = 4000;
Начислено = Выплачено + Начислено;
Выплачено = Начислено – Выплачено;
Начислено = Начислено – Выплачено;
Начислено = 1000; Выплачено = 2000; ВремПер = Начислено; Начислено = Выплачено; Выплачено = ВремПер; Начислено = 1000; Выплачено = 2000; Начислено = Выплачено + Начислено; Выплачено = Начислено – Выплачено; Начислено = Начислено – Выплачено;
а нельзя свои коменты править а то второй раз с копированием ошибся=(
К сожалению, такой возможности нет.
вот 2-й вариант 3-его задание без создания еще одной переменной:
<code>
Начислено = 1000;
Выплачено = 2000;
Выплачено = Выплачено – Начислено;
Начислено = Начислено + Выплачено;
Начислено = 1000; Выплачено = 2000;
Выплачено = Выплачено – Начислено; Начислено = Начислено + Выплачено;</code>
только вот срабатывать он будет при условии что Выплачено>Начислено, можно конечно поправить это проверкой на условие, но тогда лучше использовать все таки первый вариант который выложил