scilab учебник. Учебник Scilab. Учебник Для студентов по дисциплин Базовые средства математических пакетов
Скачать 5.73 Mb.
|
Обращение к функции quadeq X2 = -1. -0.6666667 - 0.4714045i -0.6 - 0.663325i X1 = -1. -0.6666667 + 0.4714045i -0.6 + 0.663325i Рис. 1.5.2-7 Содержимое окна SciNotes и Командного окна после загрузки сценария РИС1527 и выполнения функции quadeq В двух рассмотренных выше примерах сценарии РИС1526 и РИС1527 были созданы в редакторе SciNotes,загружены и вызваны на выполнение из Ко- мандного окна, куда и были выведены результаты. Чтобы запустить на выполнение сценарий из окна редактора SciNotes, достаточно нажать кнопку (Выполнить) или выбрать команду Выполнить в одноименном элементе меню. В результате в строке Командного окна по- явится команда exec c указанием полного пути к файлу, а курсор устанавлива- ется в начале следующей строки. Следует помнить, что переменные, созданные внутри функции, являются локальными и действуют только в пределах этой функции. Переменные, созданные в пространстве вне функций, являются глобальными и доступны во всех функциях данного файла и те- кущей рабочей сессии. В одном файле, созданном в редакторе, который является, по сути дела, всегда сценарием, может быть описано сразу несколько функций. Эти функ- ции могут общаться между собой посредством имен функций, а также вход- ных и выходных параметров. Общая структура сценария, содержащего несколько встроенных внут- ренних функций сценария, может быть следующей: // Имя Сценария и его назначение Тело сценария ... functionf1 ТелоФункцииf1 end … functionfm ТелоФункцииfm end // end сценария 167 Эта структура и некоторые другие вопросы, касающиеся области види- мости данных при использовании нескольких функций, будут рассмотрены подробно в п. 1.5.3. 1.5.3. Общая структура функций и сценариев. Области видимости переменных Общая структура кода сценария В предыдущем разделе были даны правила описания сценариев и внут- ренних встроенных в них функций, а также приведены соответствующие при- меры их описания, где в каждом sce -файле содержалось по одной функции. Однако в каждом сохраненном sce -файле могут находиться описания более чем одной независимой функции, причем в каждую из них может быть вло- жена другая функция (рис 1.5.3-1). --> // Загрузка и выполнение вложенных функцией --> exec('РИС15301.sce', 0); --> clear --> x = 2; --> r = mvf(x) r = 2. Рис. 1.5.3-1 Пример реализации вложенных функцией Как уже отмечалось, в сценарии программные коды независимых функ- ций должны располагаться одна за другой, когда как вложенные функции располагаются внутри функций. 168 На рис 1.5.3-2 показано сначала обращение из Командного окна к функции vstfun , использующей функции vfun1 и vfun2 , расположенные в сце- нарии, а затем отдельно к функции vfun2 . Этот пример показывает, что все остальные функции, при подключении сценария командой exec становятся до- ступными для использования в Командном окне. --> // Загрузка сценария РИС15302 и обращения к vstfun, vfun1 и vfun2 --> exec('РИС15302.sce', 0); --> --> clear --> y = vstfun(2) //Обращение к vstfun2(2), а из нее кvfun1(2) иvfun2(2) y = 2. --> --> f=vfun1(2), f = vfun2(2) //Независимое обращение к vfun1(2) и vfun2(2) f = 0. f = 2. Рис. 1.5.3-2 Пример обращения к функциям сценария Следует помнить, что перед обращением к любому сценарию, сохраненному в sce- файле, этот файл должен быть загружен командой exec. Имя функции как тип переменной Одно из достоинств языка Scilab является то, что функции являются ти- пом переменных. Это означает, что мы можем хранить функции в переменных и использовать переменные как функции. В компилируемых языках эта воз- можность часто называется «указатель на функцию». В следующем примере (рис 1.5.3-3) определим функцию f . Затем, уста- новим содержимое переменной fp равным функции f . Наконец, мы можем ис- пользовать функцию fp как обычную функцию. 169 --> // Загрузка сценария РИС15303 и обращения к функции f --> exec('РИС15303.sce', 0); --> --> clear --> fp = f fp = [y] = fp(t) --> --> fp(1) ans = 2. Рис. 1.5.3-3 Пример использования указателя на функцию Эта возможность позволяет использовать широко распространённый ин- струмент языков программирования, известный как функция обратного вы- зова ( callback ). Функция обратного вызова – это функция, которая передается другой функции в качестве параметра. При этом передается указатель (ссылка) на эту функцию. В свою очередь другая функция, вызывает переданную через пара- метр функцию. Поскольку функции являются переменными можно устанавливать зна- чения этих переменных несколько раз. Для того, чтобы предупредить пользо- вателей от нежелательного переопределения функций, при переопределении может появляться сообщение-предупреждение, как показано в примере на рис 1.3.5-4. --> // Загрузка сценария РИС15304 и переопределение функций --> exec('РИС15304.sce', 0); --> 170 --> clear --> f = f1 f = [y] = f(x) --> --> f = f2 Предупреждение: переопределение функции: f. Используйте funcprot(0) чтобы не выводить это сообщение --> f = --> [y] = f(x) Рис. 1.5.3-4. Получение предупреждения о переопределении функции В данном случае нет причин защищать себя от присвоения переменной f нового значения, в Scilab имеется простой способ отключить на время пре- дупреждение. Функция funcprot позволяет заблокировать режим защиты функций: pr=funcprot() – получить текущий режим защиты функций; funcprot(0) – нет сообщений, когда функция переопределена ; funcprot(1) – выдает предупреждение о переопределении функции (по умолчанию); funcprot(2) – выдает ошибку, когда функция переопределена Scilab позволяет переопределить любые функции (даже библиотечные), но это вызывает ошибку и выводится соответствующее сообщение. В следую- щем примере (рис. 1.5.3-5) функция rand определена как обычная функция, проверим, можем ли мы вызвать её как любую другую функцию, определён- ную пользователем. --> // Загрузка сценария РИС15305 и переопределение функций rand --> exec('РИС15305.sce', 0); --> clear --> rand() Предупреждение: переопределение функции: rand. Используйте funcprot(0) чтобы не выводить это сообщение --> --> funcprot(0) --> y = rand(1) y = 2. Рис. 1.5.3-5 Переопределение встроенный библиотечной функции rand , описанной в сценарии РИС15305 171 Появилось сообщение о том, что функцию rand переопределили. То есть функция rand уже существует в Scilab, что может быть легко проверено коман- дой help rand . Действительно, встроенная функция rand позволяет генериро- вать случайные числа, и мы, конечно же, не хотим ее терять и переопределить. В данном случае ошибка очевидна, но на практике ситуации могут быть го- раздо более сложными, поэтому переопределять функции надо очень осто- рожно. Видимость переменных Как известно, переменные, созданные в процессе выполнения сессии, хранятся в области Обозревателя переменных, кроме тех, которые описаны в функциях. То есть переменные, описанные внутри функций, хранятся в своих локальных областях памяти. Поэтому функция может получить доступ к пере- менным только в том случае, если данные передаются в качестве аргументов. Это позволяет защитить целостность данных. Сценарий, представленный на рис. 1.5.3-6 содержит три независимые функции со своими локальными пере- менными. Загрузив сценарий, и вызвав функцию vstfun из Командного окна, можно видеть, что переменные функций являются локальными и недоступны как из Командного окна, так и из сценария. --> // Загрузка сценария РИС15306 --> // и обращение к функции vstfun --> clear --> exec('РИС15306.sce', 0); --> --> x = 2; --> r = vstfun(x) r = 8. Рис. 1.5.3-6 Отображение данных сессии в окне Обозреватель переменных 172 В окне Обозреватель переменных отобразились только две переменные ( r и x ), используемые в Командном окне. Таким образом, локальные перемен- ные не доступны ни командной строке, ни другой sce -функции. Один из способов получить доступ к переменным локальных функций объявить переменные глобальными ( global ). Глобальные переменные хра- нятся в своей области глобальных переменных. Особенность глобальных пе- ременных состоит в том, что они видны тем объектам текущего сеанса, где они описаны как глобальные. Однако использовать глобальные переменные опасно, поскольку: 3) любая функция может получить доступ и обновить глобальную пере- менную, в этом случае другие функции, использующие эту перемен- ную, могут получить неожиданные результаты. 4) «новая» глобальная переменная может случайно получить то же са- мое имя, что и «старая» (уже существующая) глобальная переменная. Это приводит к ошибке, которая трудно диагностируется. Прежде чем обращаться к глобальным переменным функции из команд- ной строки их необходимо объявить. Для этого предназначена функция global , имеющая следующий формат: global ( СписокГлобальныхПеременных ) где в СписокеГлобальныхПеременных через запятую перечисляются имена гло- бальных переменных, заключенные в кавычки, например, global('a','b','x') Если СписокГлобальныхПеременных содержит одну переменную, то допускается создание списка без скобок и кавычек. Создадим, например, в командной строке глобальную переменную x , присвоив ей значение 2 . Теперь рассмотрим пример, приведенный на рис.1.5.3-7. --> // Загрузка сценария РИС15307 и обращение к функциям f1 и f2 --> --> clear --> exec('РИС15307.sce'); 173 --> a = 1; --> f1() // Обращение к функции f1 --> a a = 4. --> f2() // Обращение к функции f2 --> a a = 4. Рис.1.5.3-7 Пример, иллюстрирующий область видимости переменных Обратите внимание, что при обращении к функции f1, переменная а из- менила свое значение, а при обращении к функции f2 значение а осталось прежним. Дело в том, что и в командной строке, и в функции f1, переменная, а объявлена глобальной, то есть она является видимой для f1 . В функции f2 переменная а является локальной, то есть невидимой для функции f2 , таким образом, это две разные переменные, расположенные в разных областях опе- ративной памяти. В Scilab имеется еще ряд функций для работы с глобальными перемен- ными, имеющими тот же формат, что и функция global : clearglobal – уничтожает глобальные переменные списка; isglobal – проверяет, является ли переменная глобальной; gstacksize – определяет размер области глобальных переменных В любом языке программирования использование глобальных перемен- ных усложняют понимание программ, кроме того они менее защищены от из- менений. Поэтому если есть возможность, данные в функции лучше переда- вать через параметры. 1.5.4. Алгоритмические операторы Scilab и базовые программные структуры В программировании различают линейную и нелинейную структуру программного кода [ 19 ]. Программную структуру называют линейной, если операторы (инструкции, строки программного кода функции) выполняются строго в том порядке, в котором они написаны. Однако существует множество алгоритмов, структура которых нелинейная, то есть элементы алгоритма вы- полняются в зависимости от определенных условий, иногда с конечным чис- лом повторений – регулярных циклов, иногда в виде циклов, завершаемых при выполнении заданного условия. Практически любая серьезная программа имеет нелинейную структуру. Для создания таких программ необходимы спе- циальные управляющие структуры. Они имеются в любом языке программи- рования высокого уровня, в том числе и в Scilab [ 20 ]. 174 Рассмотрим эти элементы подробнее. Линейные программные структуры К линейным программным структурам можно отнести операторы при- сваивания, вычисления выражений и операторы ввода/вывода. Оператор присваивания подробно был рассмотрен в п. 2.1.2. Кратко напомним, что оператор присваивания является фундаментальным операто- ром системы программирования Scilab: ИмяПеременной = Выражение . Оператор предназначен для инициализации переменных (присвоения им конкретных значений соответствующего типа) и обозначается символом = , слева от которого находится имя переменной, а справа любое допустимое вы- ражение (правила записи арифметических, логических и строковых выраже- ний были рассмотрены в п. 1.2). Все переменные, используемые в правой части оператора присваивания, должны быть предварительно проинициализированы. Если командная строка заканчивается символом точка с запятой (;), то результат выполнения опера- тора не выводится, иначе он выводится в следующей строке командного окна. Это замечание распространяется и на выполнение операторов присваивания, расположенных в sce -файлах. Приведем несколько примеров использования операторов присваивания (рис.1.5.4-1). --> // Примеры использования операторов присваивания --> --> a = 2; // Присваивание переменной a числового значения (скаляр) --> x = a^2 - 20; // Присваивание переменной xзначения выраженияa 2 -20 --> x x = -16. --> --> A = [2 -4 7]; // Присваивание переменной Aзначений вектора [2 -4 7] --> A A = 2. -4. 7. --> --> s1 ="Система"; // Присваивание переменным s1 и s2 --> s2 = "Scilab"; // значений строковых констант --> --> s = s1 + " " + s2 // Присваивание переменной sзначения выражения s = Система Scilab Рис. 1.5.4-1 Примеры использования операторов присваивания 175 Простейшие операторы ввода/вывода данных Часто приходится создавать программы, которые способны не просто выполнять какие-либо команды и выдавать результаты, но и обмениваться ин- формацией с пользователем в процессе работы через интерфейс. На опреде- ленном этапе такая программа может прервать свою работу и выдать запрос пользователю, а ее дальнейшее поведение, например, продолжить или прекра- тить вычисления, будет зависеть от введенного пользователем ответа на этот запрос. Интерактивное взаимодействие пользователя легко реализуется путем создания интерфейса с помощью командной строки или специальных функ- ций. Для организации простейшего ввода в Scilab можно воспользоваться, в первую очередь, функцией: x = input('Подсказка'); Функция input выводит в командной строке Scilab Подсказку, и ожидает от пользователя ввода значения, которое затем присваивается переменной х На рис.1.5.4-2 представлен способ ввода исходных данных с использованием функции input --> // Пример использование функции вводаinput --> --> y = input('Введите y = ') Введите y = 5 y = 5. Рис. 1.5.4-2 Использованием функции input для ввода данных с клавиатуры Кроме функции input для ввода данных можно воспользоваться специ- альными диалоговыми окнами для интерактивного ввода Эту возможность можно реализовать с помощью функций x_dialog, x_mdialog, x_choose, x_matrix, x_message и x_message_modeless Рассмотрим подробно работу функции x_dialog , которая имеет следую- щий формат: Переменная=x_dialog('Подсказка','Значение'); Функция x_dialog выводит на экран диалоговое окно с именем Ввод значения , в котором над полем ввода отображается Подсказка . Если при использовании функции x_dialog строка 'Значение' задана пустой строкой, то поле ввода диалогового окна пусто, и пользователь может ввести в него нуж- ное значение. Если же строка 'Значение' непустая, то эта строка отображается |