Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Resumo Este curso apresenta a linguagem de programao do Scilab da mesma forma que um curso tradicional de introduo a programao. O Scilab um ambiente de programao dedicado a resoluo de problemas cientcos e de engenharia. Ele est disponvel1 para vrios sistemas operacionais tais como Windows, Linux e Mac OS X. O material deste curso pode ser usado em qualquer um desses sistemas. Procure seu professor ou seu centro de computao local para informaes sobre como o Scilab est instalado localmente.
1 Pgina
do Scilab: http://www.scilab.org
Sumrio
1 Preliminares 1.1 Usando o Console do Scilab como uma Simples Calculadora 1.2 Variveis e o Comando de Atribuio . . . . . . . . . . . . 1.2.1 Regras para Formao de Nomes de Variveis . . . . 1.2.2 O Ponto e Vrgula . . . . . . . . . . . . . . . . . . 1.3 Expresses Aritmticas . . . . . . . . . . . . . . . . . . . . 1.3.1 Funes Matemticas Comuns . . . . . . . . . . . . 1.3.2 Funes de Arredondamento . . . . . . . . . . . . . 1.3.3 Ordem de Avaliao entre Operadores Aritmticos . 1.4 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.5 Nmeros Complexos . . . . . . . . . . . . . . . . . . . . . 1.6 O Espao de Trabalho . . . . . . . . . . . . . . . . . . . . . 1.6.1 O Comando Clear . . . . . . . . . . . . . . . . . . 1.6.2 Os Comandos Save e Load . . . . . . . . . . . . . . 1.7 Formato de Visualizao dos Nmeros . . . . . . . . . . . . 1.8 Constantes Especiais do Scilab . . . . . . . . . . . . . . . . 1.9 A Varivel ans . . . . . . . . . . . . . . . . . . . . . . . . . 1.10 Ajuda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.11 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . Arquivos de Scripts 2.1 Comando de Entrada de Dados . . 2.2 Comandos de Sada de Dados . . . 2.3 Arquivos de Scripts . . . . . . . . 2.4 Criando Arquivos de Script . . . . 2.5 Executando Arquivos de Script . . 2.6 Exemplos . . . . . . . . . . . . . 2.7 Linhas de Comentrios . . . . . . 2.8 Alterando o Diretrio de Trabalho 1 1 2 3 3 3 4 4 5 6 8 9 9 9 10 11 11 11 11 13 13 13 15 16 17 18 19 19 21 21 22 23 23 23 24 25 26
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
Estruturas de Seleo 3.1 Estruturas de Controle . . . . . . . . . . 3.2 Expresses Booleanas . . . . . . . . . . . 3.3 Variveis Booleanas . . . . . . . . . . . . 3.4 Tipos de Dados Primitivos . . . . . . . . 3.5 Ordem de Avaliao entre os Operadores . 3.6 A Seleo Simples IF-END . . . . . . . . 3.7 A Seleo Bidirecional IF-ELSE-END . . 3.8 Aninhando Seletores . . . . . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
Estruturas de Repetio 4.1 Laos . . . . . . . . . . . . . 4.2 Lao Controlado Logicamente 4.3 Lao Controlado por Contador 4.4 Exemplos com Laos . . . . . 4.5 Laos Aninhados . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
32 32 32 35 36 39 42 42 43 45 48 49 52 52 54 55 58 58 61 64 65 66 67 68 69 72 72 73 74 74 74 75 76 78 78 79 80 81 81 83 84 86
Matrizes 5.1 Vetores . . . . . . . . . . . . . . . . . 5.1.1 Acessando Elementos do Vetor . 5.2 Matrizes Bidimensionais . . . . . . . . 5.3 Vetores de String . . . . . . . . . . . . 5.4 Estudo de Caso . . . . . . . . . . . . . 5.5 Exemplos com Matrizes . . . . . . . . 5.5.1 Ordenao de Vetores . . . . . 5.5.2 Gerando Nmeros Aleatrios . 5.5.3 Uma Aplicao de Matrizes . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
Manipulao Matricial 6.1 Construo de Matrizes . . . . . . . . . . . 6.2 Secionamento de Matrizes . . . . . . . . . 6.2.1 Indexao Linear . . . . . . . . . . 6.3 O Operador $ . . . . . . . . . . . . . . . . 6.4 Atribuio . . . . . . . . . . . . . . . . . . 6.5 Dimenso de Matrizes . . . . . . . . . . . 6.6 Operaes Escalar-Matriz . . . . . . . . . . 6.7 Operaes Matriz-Matriz . . . . . . . . . . 6.8 Soluo de Sistemas de Equaes Lineares . 6.9 Transposta de Matrizes Complexas . . . . . 6.10 Zeros e Ones . . . . . . . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
Funes 7.1 Introduo . . . . . . . . . . . . . . . . . . . . . . . . . 7.2 Parmetros de Entrada e Sada . . . . . . . . . . . . . . 7.3 Funes Denidas pelo Usurio . . . . . . . . . . . . . 7.4 A Idia Bsica das Funes . . . . . . . . . . . . . . . . 7.5 Escopo de Variveis . . . . . . . . . . . . . . . . . . . . 7.5.1 Variveis Locais . . . . . . . . . . . . . . . . . 7.5.2 Variveis Globais . . . . . . . . . . . . . . . . . 7.6 Os Programas do Scilab . . . . . . . . . . . . . . . . . . 7.7 Passagem de Parmetros . . . . . . . . . . . . . . . . . 7.8 Exemplos . . . . . . . . . . . . . . . . . . . . . . . . . 7.9 O Comando return . . . . . . . . . . . . . . . . . . . . 7.10 Estudo de Caso: Um Programa de Estatstica . . . . . . 7.10.1 O Comando de Mltipla Escolha SELECT-CASE
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
Captulo
PRELIMINARES
N
1.1
ESTE captulo sero apresentados o ambiente de trabalho do Scilab e conceitos bsicos de programao como variveis, tipos de dados e expresses aritmticas.
O Scilab pode fazer operaes aritmticas com nmeros reais e complexos. Os operadores aritmticos so: Adio Subtrao Multiplicao Diviso Potenciao
+ * /
Quando o Scilab executado surge uma janela chamada de console do Scilab como mostrado na Figura a seguir. O console do Scilab o mecanismo usado pelo usurio para interagir com o Scilab por meio de comandos1 .
1 Em computao, esta forma de interagir com o computador chamada de Interface de Linha de Comandos. Consiste em digitar uma linha de texto representando um comando ou tarefa a ser executada pelo computador. parte fundamental de muitos softwares cientcos (e.g., Matlab, Maple) e est presente em vrias linguagens de programao (e.g., Python e Perl) e sistemas operacionais como Linux (Shell) e Windows (DOS e Powershell).
-->
Ele chamado de prompt e indica que o console do Scilab est esperando um comando a ser digitado pelo usurio. Portanto, as operaes aritmticas so digitados aps o smbolo > e em seguida tecla-se [ENTER]. Exemplo:
-->2+3 [ENTER] ans = 5.
Outros exemplos:
-->5+6/2 ans = 8. -->4^2 ans = 16. // 4 elevado a potncia de 2
1.2
Uma varivel uma abstrao de uma clula ou um conjunto de clulas na memria do computador. Informaes so armazenas em variveis para posterior uso. Muitos programadores costumam a interpretar variveis como sendo um nome para uma posio na memria do computador. Fundamental na programao, o comando de atribuio usado para atribuir ou modicar a informao contida na varivel. No Scilab, usa-se o smbolo = para atribuio. O smbolo de atribuio = no Exemplo: digite estes comandos no console:
-->a = 2 a = 2. -->b = 4 a = 4. -->area = a*b area = 8. -->b = b+1 b = 5. // // Incrementa uma unidade na varivel b // // Atribui o produto de a e b para varivel area // Atribui 4 para varivel b // Atribui 2 para varivel a
signica igualdade matemtica, uma vez que o comando de atribuio i = i+1 vlido, mas no representa igualdade matemtica.
1.2.1
Os nomes de variveis (tambm conhecidos por identicadores) devem seguir as seguintes regras: 1. Nomes de variveis comeam com uma letra seguido de letras, algarismos ou sublinhados. Por exemplo: Alpha, notas, A1, B23 e cor_do_objeto; 2. Caracteres especiais no so permitidos. Isto , no permitido usar #, $, &, %, ?, !, @, <, ~, etc; 3. Caracteres acentuados no so permitidos; 4. Nomes de variveis so sensveis a maisculas e minsculas. Por exemplo, varivel Alpha diferente das variveis ALPHA, alpha e AlPhA. De acordo com as regras acima, os seguintes nomes de variveis so vlidos:
A ausncia ou presena do ponto e vrgula no nal de um comando do Scilab visualiza ou suprime, respectivamente, o resultado do clculo. Por exemplo, o resultado do seguinte comando, digitado com ponto e vrgula, suprimido:
-->A = 4+4^2; -->
Mais exemplos:
-->a=2; -->b=4; -->area=a*b area = 8. // aqui o ponto e vrgula foi // suprimido porque precisamos // visualizar o resultado.
1.3
EXPRESSES ARITMTICAS
Os operadores aritmticos combinam nmeros e variveis para formar expresses aritmticas. Exemplos:
A+B*C (NOTA1+NOTA2)/2 1/(a^2+b^2)
1.3.1
As principais funes matemticas do Scilab so mostradas na Tabela 1.1. O nmero e a base do logaritmo natural e D 2; 718281828::: so representadas pelas variveis especiais %pi e %e, respectivamente. Exemplos:
-->cos(2*%pi) ans = 1. -->%e^2 ans = 7.389056098931 -->abs(-5) ans = 5. -->modulo(8,3) ans = 2. -->modulo(6,3) ans = 0. -->sign(-4) ans = - 1. -->sign(5) ans = 1. // Resto da diviso entre 8 e 3 // valor absoluto // 2,718281828 ao quadrado // coseno de 2 vezes PI
1.3.2
Funes de Arredondamento
34. -->round(a) ans = 35. -->ceil(3.1) ans = 4. // arredonda para mais. // arredonda para o inteiro mais prximo
1.3.3
Para uma boa avaliao de uma expresso aritmtica necessrio se familiarizar com a ordem de avaliao dos operadores. Aqui, as regras importantes so: prioridade, associatividade e parnteses.
ceil(x) 2 2 2 -1 -1 -1
floor(x) 1 1 1 -2 -2 -2
fix(x) 1 1 1 -1 -1 -1
round(x) 2 2 1 -1 -2 -2
Operaes de alta prioridade so realizadas primeiro do que as operaes de baixa prioridade. A ordem de prioridade entre os operadores a seguinte: Prioridade 1a 2a 3a Exemplos:
2+10/5 A+B/C+D R*3+B3/2+1 10/5 avaliada primeiro. B/C avaliada primeiro. B3 avaliada primeiro.
Associatividade da direita para a esquerda da esquerda para a direita da esquerda para a direita
Associatividade a regra usada quando os operadores tm a mesma prioridade. Por exemplo, para as operaes de adio e subtrao (que possuem mesma prioridade) a regra de associatividade diz que a operao mais a esquerda avaliada primeiro:
A-B+C+D
O mesmo vale para multiplicao e diviso:
A*B/C*D
No entanto, para potenciao, a regra da associatividade diz que a operao mais a direita deve ser avaliada primeiro:
A^B^C^D
A+4 avaliada primeiro devido aos parnteses. A-B avaliada primeiro. Depois a adio. Por ltimo, a diviso. 3/2 avaliada primeiro.
1.4
STRINGS
Strings so usados para toda e qualquer informao composta de caracteres alfanumricos e/ou caracteres especiais (exemplo, #, $, &, %, ?, !, @, <, ~, etc). Os strings so envolvidos
Um das atividades mais comuns em programao a concatenao de strings. Concatenao a juno de dois ou mais strings. Isto pode ser feito com o operador +.
-->a + b ans = abcdefgh -->n = "Pedro" n = Pedro -->m = "Paulo" m = Paulo -->m + n ans = PauloPedro -->m + " e " + n ans = Paulo e Pedro // Concatena Paulo com Pedro // inserindo espaos entre eles. // Concatena Paulo com Pedro sem // espao entre eles. // Concatena abcd com efgh
Muitas vezes precisamos armazenar informaes que contm as aspas. Isto pode ser feito repetindo as aspas. Exemplos:
-->n = "O orculo disse ""conhea-te a ti mesmo"" para Socrtes." n = O orculo disse "conhea-te a ti mesmo" para Socrtes.
1.5
NMEROS COMPLEXOS
No necessrio manuseio especial em Scilab para nmeros complexos. As operaes com nmeros complexos so to fceis como nos reais. A unidade imaginria representado por %i, ou seja, %i igual a sqrt(-1). Exemplos:
x = 3 + 4*%i y = 1 - %i z1 = x - y z2 = x * y z3 = x / y real(z1) imag(z1) abs(x) atan(imag(x),real(x)) conj(z2) sin(x)
Parte real de z1 Parte imaginria de z1 Valor absoluto do nmero complexo Argumento do nmero complexo Conjugado Seno de um nmero complexo
1.6
O ESPAO DE TRABALHO
digitado no Scilab, a varivel x armazenada em uma rea da memria do Scilab denominada de Espao de Trabalho (do ingls, workplace). O Espao de Trabalho uma parte da memria do computador que armazena as variveis criadas pelo console do Scilab e pelos arquivos de Script (mostrados adiante).
1.6.1
O Comando Clear
O comando clear apaga todas a variveis do Espao de Trabalho criadas pelo usurio. Exemplo:
-->clear // Apaga todas a variveis
1.6.2
As variveis so apagadas quando o usurio termina a execuo do Scilab. Para us-las da prxima vez que executar o Scilab, voc deve salva-las com o comando save(arquivo). Por exemplo,
-->a = 2; -->b = 3; -->c = 4; -->save("dados.dat");
As variveis foram salvas no arquivo dados.dat. O comando load(arquivo) usado para recuperar variveis que foram salvas no arquivo. Por exemplo,
-->clear -->a+b !--error 4 undefined variable : a -->load("dados.dat"); // apaga todas as variveis // variveis a e b no existem // porque foram apagadas
// recupera as variveis a, b e c
10
-->a+b ans = 5.
// Ok!
1.7
O comando format modica a quantidade de dgitos com que os nmeros so mostrados no Scilab. Por exemplo, o comando
--> format(5)
far com que todas os nmeros sejam visualizados em 5 posies (incluindo o ponto decimal e um espao para o sinal). Por exemplo,
-->sqrt(3) ans = 1.73
A raiz de 3 foi mostrada ocupando 16 posies (sendo uma posio para o ponto, um espao reservado para o sinal, uma posio para a parte inteira e 13 posies para a parte fracionria). O comando format('e') mostra os nmeros em notao cientca. Por exemplo,
-->format('e') -->2*%pi/10 ans = 6.283185307E-01
1.
que chamado de formato de varivel. Vejamos outras formas de usar o comando format:
-->format('v',10)
11
1.8
O Scilab possue vrias constantes pr-denidas. Algumas constantes pr-denidas no podem ser alteradas.
%pi %eps %inf %nan %i %e %t ou %T %f ou %F %s %z
O nmero . Constante que representa a preciso numrica da mquina. o menor nmero que, somado a 1, resulta em um nmero maior que 1 no computador. Representa innito 1. No p numrico (do ingls, Not A Number). 1. A base do logaritmo natural. Representa o valor booleano verdadeiro. Representa o valor booleano falso. Um polinmio com uma nica raiz em zero e s como o nome da varivel. A constante %s denida como poly(0,'s'). Um polinmio com uma nica raiz em zero e s como o nome da varivel. A constante %z denida como poly(0,'z').
1.9
A VARIVEL ANS
A varivel ans (abreviao da palavra inglesa answer) armazena o valor corrente de sada do Scilab. Pode-se usar ans para efetuar clculos porque ela armazena o valor do ltimo clculo realizado. Exemplo:
-->4+5 ans = 9. -->cos(ans)+3 ans = 2.0888697
1.10
AJUDA
O comando apropos procura comandos e funes utilizando uma palavra-chave. Por exemplo, se no sabemos o nome da funo que calcula o seno hiperblico, podemos digitar algo como
--> apropos hyperbolic
1.11
EXERCCIOS
1. O que so variveis?
12
2. Quais os tipos primitivos de informao manipuladas pelo Scilab? 3. Assinale os identicadores (nomes de variveis) vlidos: a) (X) e) 5NOTA i) A+B b) XMU2 f) NOTA1 j) I00001 c) AH! g) A[4] l) NOTA/2 d) NOTA1 h) A&B m) PEDROEPAULO
4. Escreva as declaraes aritmticas para o clculo das seguintes frmulas: 2h a) c D .h C 0:5d / ln p b) z D 2e x sin x p c) m D 2 y 2 C p 1 C p2 s sinaCb x aCb e) g D L 0:5 r 2 r 2 arcsin.h=r/ d) s D
1=2
h.r 2
h2 /
5. Considere as variveis A=11, B=5, C=-4 e D=2. Calcule as expresses abaixo. a) 3*modulo(A,3)-C b) 2^(2*abs(C))/8 c) (A/B-fix(A/B)+sign(C)+2.8)^(15/B) d) sqrt(cos(A)^2+sin(A)^2) + sin(D*%pi/4) e) (A+C)/A * round(sign(C)+D/4)-fix(D/1.5) 6. Qual a primeira operao a ser executada em cada um dos comandos abaixo. a) R + S - W b) W1 + W2 / C ^ 2 c) NOTA + MEDIA/N d) X + Y + C * D e) A + D + B ^ 2 + E * 3 f) A * B / C * D
Captulo
ARQUIVOS DE SCRIPTS
Este captulo trata de programas sequenciais em Scilab. Sero apresentados comandos de entrada e sada alm de mostrar como editar e executar programas no Scilab.
2.1
Programas de computador podem solicitar dados do usurio via teclado usando o comando input que tem duas formas bsicas (uma para nmeros e outra para strings). A primeira delas, usada para solicitar dados numricos, tem a seguinte forma:
<variavel> = input(<string> );
Esta funo mostra o texto <string> e em seguida solicita que o usurio digite um nmero. Por m, o nmero digitado atribudo a <variavel> . Exemplo:
-->x = input("Digite um nmero") Digite um nmero-->10 x = 10.
A segunda forma do comando input usada para solicitar dados do tipo string ao usurio. Sua forma :
<variavel> = input(<string>,"s");
Exemplo:
-->a = input("Digite alguma coisa","s") Digite alguma coisa-->Ol a Ol =
2.2
Comandos de sada de dados fornece ao usurio um meio de visualizar dados e o resultado de algum processamento. A forma mais simples de visualizar dados no Scilab suprimir o ponto e vrgula no nal do comando como mostrado na Seo 1.2.2. 13
14
-->x = 3; -->y = 4; -->r = sqrt(x*x+y*y) r = 5. // Com a omisso do ponto e virgula // o resultado exibido
A FUNO DISP
A funo disp() outra maneira de exibir dados. Por exemplo,
-->v0 = 2; -->a = 4; -->t = 3; -->v = v0+a*t; -->disp(v) 14. // disp no mostra o nome // da varivel
A funo disp freqentemente usada em conjunto com a funo string que converte um nmero em string. Por exemplo,
-->disp("A velocidade final " + string(v)) A velocidade final 14
A FUNO PRINTF
A funo printf a forma mais exvel de exibir dados porque produz uma sada for- printf um clone do comando de matada. Por exemplo,
-->printf("Al mundo\n"); Al mundo
mesmo nome da linguagem de programao C.
O caracter \n (chamado de new line) avisa ao comando printf para gerar uma nova linha. Mais precisamente, \n move o cursor para o comeo da linha seguinte. Por exemplo, colocando \n aps o string Al faz com que printf gere uma nova linha aps Al:
-->printf("Al\nmundo"); Al mundo
2.3 Arquivos de Scripts / UFRN-DCA - 13 de Junho de 2011 A forma geral do comando printf :
15
printf(<formato>,<lista de dados> ); <formato> uma string descrevendo a forma com que a lista de dados ser exibida. Exemplo:
-->A = 2; -->printf("A varivel A contm o valor %g\n",A); A varivel A contm o valor 2
A smbolo %g (chamado de caractere de formatao) indica como cada varivel da lista de dados ser exibido dentro da string de formatao <formato> . Neste ltimo exemplo, %g substituido pelo valor da varivel A no momento da impresso. No seguinte exemplo, as variveis A e B substituiro os caracteres de formatao %g nas posies correspondentes:
-->A = 8/4; -->B = A + 3; -->printf("Os valores calculados foram %g e %g\n",A,B); Os valores calculados foram 2 e 5
Mais exemplos:
-->printf("A = %g B = %g",A,B); A = 2 B = 5 -->printf("A = %g\nB = %g\n",A,B); A = 2 B = 5 -->F = "Os valores calculados foram %g e %g"; -->printf(F,A,B); Os valores calculados foram 2 e 5
Se a variavel for do tipo string, usa-se o caractere de formatao %s em vez de %g. Por exemplo:
-->nome = "Joao"; -->altura = 1.65; -->printf("A altura de %s %g",nome, altura); A altura de Joao 1.65
2.3
ARQUIVOS DE SCRIPTS
Digitamos comandos no console do Scilab para resolver problemas simples. Mas, se o nmero de comandos para digitar grande, ento melhor salvar os comandos em um arquivo de script. Um arquivo de script um arquivo que contm um script, isto , uma sequncia de comandos para ser executada pelo computador. Os comandos do arquivo de script so executados automaticamente pelo Scilab da mesma forma que voc faria se os tivesse digitado no console.
16
Arquivos de script so arquivos de texto puro ou plano, isto , arquivos sem formataes como negrito, itlico e sublinhado e, por causa disso, eles podem ser criados em qualquer editor de texto. O Scilab j contm um editor de textos (chamado SciNotes) que facilita a criao de arquivos de script. Por isso recomendvel utilizar o SciNotes em vez de algum outro editor de texto. Mas se voc quiser usar um editor diferente, como o Microsoft Word, tenha o cuidado de salvar os arquivos como um arquivo texto. Caso contrrio, se o arquivo for salvo no formato nativo (e.g., o formato doc do Word) podero conter caracteres especiais que causaro erros no Scilab.
2.4
Para criar arquivos de scripts, selecione a opo Aplicativos SciNotes1 ou clique no cone correspondente na barra de ferramentas.
Note que o arquivo de script acima contm comandos para converter graus Farenheit em graus Celsius.
1 As guras mostradas nesta seo podem no corresponder exatamente a verso do scilab que voc utilizando.
17
O prximo passo salvar o arquivo de script. Selecione a opo ARQUIVO SALVAR. Digite o nome farenheit.sce (os nomes de arquivos de script possuem extenso .sce) e selecione a pasta de sua preferncia para salvar o arquivo.
O usurio pode criar novos arquivos de script selecionando a opo ARQUIVO NOVO. Os passos para executar um script so mostrados na seo seguinte.
2.5
Alternativamente, pode-se executar um script teclando Ctrl+Shift+E, ou seja, teclando nas teclas Ctrl, Shift e E simultaneamente ou selecionando a opo Executar do editor. Uma terceira forma de executar um script a mostrado na Seo 2.8. A Figura 2.1 mostra a execuo do script farenheit.sce criado na Seo 2.4. O Scilab solicitou um nmero para fazer a converso de graus Farenheit em graus Celsius. Digitou-se 50 e depois ENTER:
18
Se houver erros de digitao no script ento poder ocorrer erros na sua execuo. Neste caso, retorne ao editor e corrija o erro. Em seguida, siga os mesmos passos descritos anteriormente: salve o script (selecione ARQUIVO SALVAR) e ento execute o script (tecle Ctrl+Shift+E ou selecione EXECUTAR).
2.6
EXEMPLOS
Exerccio resolvido 2.6.1. Escreva um programa Scilab para calcular a distncia entre dois pontos .x1 ; y1 / e .x2 ; y2 / no plano cartesiano. Os pontos so digitados pelo usurio. A distncia entre dois pontos dada por: q d D .x1 x2 /2 C .y1 y2 /2 Soluo:
1 2 3 4 5 6 7 8 x1 = input("Digite X1 da primeira coordenada"); y1 = input("Digite Y1 da primeira coordenada"); x2 = input("Digite X2 da segunda coordenada"); y2 = input("Digite Y2 da segunda coordenada"); dx = x1 - x2; dy = y1 - y2; d = sqrt(dx*dx + dy*dy); printf("A distncia %g\n",d);
Execute este script no Scilab. O resultado de uma possvel execuo seria: Resultado Digite X1 da primeira coordenada-->2 Digite Y1 da primeira coordenada-->3 Digite X2 da segunda coordenada-->5 Digite Y2 da segunda coordenada-->7 A distncia 5 Exerccio resolvido 2.6.2. Elabore um programa Scilab para calcular a resistncia equivalente entre dois registores R1 e R2 em paralelo. Lembre-se que a resistncia equivalente entre dois registores em paralelo dado por: 1 1 1 D C Req R1 R2 Esta frmula, tambm pode ser reescrita como: Req D Soluo:
1 2 3 4 r1 = input("Digite o valor da primeira resistncia (em ohms)"); r2 = input("Digite o valor da segunda resistncia (em ohms)"); req = (r1*r2)/(r1+r2); printf("A resistncia equivalente igual a %g\n",req);
R1 R2 R1 C R2
19
2.7
LINHAS DE COMENTRIOS
Boa programao: insira comentrios para explicar o funcionamento do programa
Comentrios podem ser inseridos em um programa para dar clareza e assim fazer as pessoas compreenderem o que nele est escrito. Comentrios so inseridos aps smbolo //. O smbolo // indica que o resto da linha (i.e., o comentrio) deve ser ignorado pelo Scilab. Um exemplo mostrado a seguir:
1 2 3 4 5 6 // Programa para calcular a resistncia equivalente de dois // registores em paralelo. r1 = input("Digite o valor da primeira resistncia (em ohms)"); r2 = input("Digite o valor da segunda resistncia (em ohms)"); req = (r1*r2)/(r1+r2); printf("A resistncia equivalente igual a %g\n",req);
2.8
Uma forma alternativa de executar scripts atravs do comando exec. O comando exec tem a forma:
exec(<script> )
Como exemplo, considere o script farenheit.sce descrito na seo 2.4.
-->exec("farenheit.sce"); Digite os graus Farenheit-->50 Equivale a 10 graus Celsius.
AVISO: este comando funciona somente se o arquivo de script estiver no diretrio atual do scilab caso contrrio ocorrer um erro como este:
-->exec("farenheit.sce"); !--error 241 O arquivo "farenheit" no existe.
Resolva este problema alterando o diretrio atual: selecione ARQUIVO ALTERAR O DIRETRIO ATUAL e depois escolha a pasta de farenheit.sce (i.e., c:nexemplos) na caixa de dilogo a seguir:
20
Agora o script deveria rodar sem problemas. Alternativamente, o diretrio atual pode ser alterado com o comando chdir (ou abreviadamente cd)2 :
-->cd c:\exemplos; // altera o diretrio corrente
Mesmo pertencendo a uma pasta diferente do diretrio atual, um script ainda pode ser executado, desde que fornecido o caminho (do ingls, path) da pasta do script. Por exemplo:
-->cd c:\outrodir -->exec('c:\exemplos\farenheit.sce'); Digite os graus Farenheit-->50 Equivale a 10 graus Celsius. // alterao do diretrio atual
O comando unix_w permite a execuo de qualquer comando comum do DOS (no windows) ou do shell (no Linux/Unix). Por exemplo, o comando DIR do DOS (utilizado para visualizar o diretrio de trabalho) pode ser executado do seguinte modo:
-->unix_w('dir')
2 Para executar um comando chdir (ou qualquer outro comando) automaticamente no inicio de uma sesso do Scilab, inclua ele no arquivo de script de congurao scilab.star.
Captulo
ESTRUTURAS DE SELEO
Este captulo introduz as expresses booleanas e as estruturas de seleo que permitem os programas tomarem decises.
3.1
ESTRUTURAS DE CONTROLE
Os programas desenvolvidos no captulo anterior basicamente liam (e/ou escreviam) variveis e avaliavam expresses aritmticas atribuindo o resultado a uma varivel. Os comandos de tais programas eram executados sequencialmente na ordem em que foram escritas, isto , de cima para baixo e da esquerda para a direita. Vale dizer, porm, que bem poucos programas teis podem ser construdos desta forma. De fato, necessrio adicionar dois mecanismos para tornar os programas exveis e poderosos: 1. As estruturas de seleo; 2. As estruturas de repetio. A estruturas de seleo so teis para implementar situaes que requerem a execuo de aes alternativas que dependem de certas condies. Exemplos: Se a nota do aluno for maior que 7 ento avise que ele foi "aprovado"; caso contrrio informe que ele est em recuperao. Se a lmpada est queimada compre uma nova lmpada; caso contrrio acenda a lmpada para ler o livro. Compre ou venda aes da bolsa de valores de acordo se ndices econmicos sobem ou descem, respectivamente. Portanto, a estrutura de seleo um mecanismo para selecionar entre caminhos alternativos de execuo comandos. A estrutura de repetio um mecanismo para repetir a execuo de uma sequncia de comandos. Os comandos que implementam estes mecanismos so chamados de comandos de controle. So exemplos de comandos de controle: IF, FOR e WHILE mostrados adiante. Uma estrutura de controle formado por um comando de controle juntamente com o conjunto de comandos cuja execuo ele controla. Com estas trs estruturas: 1. Sequncia, 2. Seleo,
21
22
3. Repetio, possvel construir qualquer programa de computador (esta a tese principal da chamada programao estrutura). A estrutura de seleo ser estudada neste captulo e a estrutura de repetio no captulo 4. O uso das estruturas de seleo requer o domnio das expresses booleanas estudadas na seo seguinte.
3.2
EXPRESSES BOOLEANAS
O termo booleano, largamente usado na computao, uma homenagem ao matemtico e lgico George Boole.
Da mesma forma que avaliar uma expresso aritmtica produz um valor numrico, avaliar expresses booleanas produz um valor lgico (verdadeiro ou falso). Expresses booleanas so tambm chamadas de expresses lgicas. Uma expresso booleana simples usa os operadores relacionais para comparar expresses aritmticas: Operadores Relacionais Operador Descrio < Menor que <= Menor ou igual a > Maior que >= Maior ou igual a == Igual a <> ou = Diferente de Por exemplo, suponha que a varivel A contm o valor 5. Ento temos:
As expresses booleanas podem ser combinadas usando os operadores booleanos: Operadores Booleanos Operador Descrio & E (conjuno) | Ou (disjuno no exclusiva) No (negao) Os operadores so denidos pelas seguintes tabelas (tambm chamadas de tabelas verdade):
Por exemplo, considere as seguintes atribuies A = 5, B = 1, C = 2, D = 8 e E = 3. Erro comum de programao: Ento temos:
programadores principiantes costumam confundir o operador Igual a (==) com o operador de atribuio (=).
23
3.3
VARIVEIS BOOLEANAS
Da mesma forma que contedo de uma varivel pode ser um valor numrico ou um string, ela pode conter um valor booleano (verdadeiro ou falso). Assim,
C = 1 > 2 A = C | 2 > 10
C um varivel booleana com valor falso. A um varivel booleana com valor falso.
No Scilab, duas variveis especiais %t (do ingls, true) e %f (do ingls, false) representam o valor verdadeiro e falso, respectivamente. Exemplos:
B = %f A = %t C = A | B
3.4
O Scilab manipula trs tipos primitivos de informao que consta na maioria das linguagens de programao tradicional: 1. O nmero real; 2. O tipo string; 3. O tipo booleano. O Scilab no possue o tipo nmero inteiro (usado em muitas linguagens). O tipo da varivel pode mudar toda vez que um valor lhe atribudo. O novo tipo ser o mesmo do ltimo valor atribudo. Exemplo:
A = 2.5; A = "livro"; // A varivel A um nmero real // Agora ela uma string
3.5
A ordem de avaliao entre todos operadores que j foram descritos dado na Tabela 3.1. Exemplos:
K | P &
Primeiro realizada a operao &. Seguindo com a operao |. Primeiro realizada a operao >, depois a operao <, por m a operao |. Primeiro realizada a operao >. Seguindo com a operao ~. Depois com a operao <. Por m com a operao &.
24
6a 7a 8a
no potenciao multiplicao diviso Adio Subtrao Menor que Menor ou igual a Maior que Maior ou igual a Igual a Diferente de e ou
da direita para a esquerda da direita para a esquerda da esquerda para a direita da esquerda para a direita da esquerda para a direita
~ ( 2 < 5 ) | 40 / 5 == 10 & 6 + ~ %t | 40 / 5 == 10 & 6 + %f | 40 / 5 == 10 & 6 + %f | 8 == 10 & 6 + %f | 8 == 10 & 8 > %f | 8 == 10 & %t %f | %f & %t %f | %f &f
2 2 2 2 5
5 5 5 5
3.6
Caracteriza-se por permitir a execuo de uma sequncia de comandos quando certas condies, representadas por expresses booleanas, forem satisfeitas. A seleo simples tem a seguinte forma:
if <expresso booleana> <sequncia de comandos> end
A sequncia de comandos s ser executada se a expresso booleana retornar um valor verdadeiro. Exerccio resolvido 3.6.1. Elaborar um programa para escrever a mdia de duas notas. Se a mdia for maior que sete, o programa dever tambm escrever Parabns. Soluo:
1 2 3 4 5 6 7 nota1 = input("digite a primeira nota"); nota2 = input("digite a segunda nota"); media = (nota1+nota2)/2; printf("Sua mdia %g\n",%g) if media > 7 printf("Parabns!"); end
25
digite a primeira nota-->7.5 digite a segunda nota-->8.1 Sua mdia 7.8 Parabns!
Resultado
Comentrio. Este programa escreve a mdia do aluno, mas s executa a linha 6 se sua nota for maior que 7.
3.7
Caracteriza-se por selecionar entre duas sequncias de comandos quando certas condi- Boa es, representadas por expresses booleanas, forem satisfeitas. A seleo bidirecional programao: Sempre use tem a seguinte forma:
if <expresso booleana> <primeira sequncia de comandos> else <segunda sequncia de comandos> end
endentao, ou seja, acrescente dois espaos antes dos comandos que esto aninhados no comando IF para melhorar a A primeira sequncia de comandos ser executada se a expresso booleana devolver legibilidade do um valor verdadeiro, caso contrrio a segunda sequncia de comandos ser executada. Os programa.
seguintes exemplos ilustram o comando de seleo bidirecional. Exerccio resolvido 3.7.1. Elaborar um programa para ler quatro notas, calcular a mdia e informar se o aluno passou de ano (aprovado) ou no (reprovado). A mdia para passar de ano 6. Soluo:
1 2 3 4 5 6 7 8 9 10 11 12 // Leitura das notas nota1 = input("Digite a 1a. nota bimestral"); nota2 = input("Digite a 2a. nota bimestral"); nota3 = input("Digite a 3a. nota bimestral"); nota4 = input("Digite a 4a. nota bimestral"); media = (nota1 + nota2 + nota3 + nota4)/4; printf("Media = %g\n",media); // Calculo da media anual if media > 6 printf("Aluno aprovado\n"); else printf("Aluno reprovado\n"); end Digite a 1a. nota Digite a 2a. nota Digite a 3a. nota Digite a 4a. nota Media = 8.325 Aluno aprovado bimestral-->8.4 bimestral-->7.3 bimestral-->9.1 bimestral-->8.5 Resultado
Comentrio. O comando IF testa se a mdia maior que 6,0. Se sim, o programa executa o comando da linha 9 que escreve Aluno aprovado. Caso contrrio, o programa executa a linha 11 que escreve Aluno reprovado.
26
Exerccio resolvido 3.7.2. Elaborar um programa para calcular o valor da funo f .x/ D dado um valor x fornecido via teclado. Soluo:
1 2 3 4 5 6 7 x = input("Entre com o valor de x"); if x >= 0 f = x^2+16; else f = 0; end; printf("O valor da funo %g\n",f); Entre com o valor de x-->2 O valor da funo 20 Resultado
x 2 C 16 se x 0 0 se x < 0
3.8
ANINHANDO SELETORES
Comandos de seleo podem ser aninhados de diversas formas criando ampla variedade de construes como mostra os exemplos a seguir. Exerccio resolvido 3.8.1. Elaborar um programa para escrever a situao do aluno. O aluno com mdia maior ou igual a 7,0 ser aprovado. O aluno com mdia entre 5,0 e 7,0 car em recuperao. Com mdia abaixo de 5,0, o aluno ser reprovado. Soluo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 // Leitura das notas nota1 = input("Digite a 1a. nota nota2 = input("Digite a 2a. nota nota3 = input("Digite a 3a. nota nota4 = input("Digite a 4a. nota media = (nota1 + nota2 + nota3 + printf("Media = %g\n",media); if media >= 7 printf("Aprovado\n"); else if media >= 5 printf("Recuperao\n"); else printf("Reprovado\n"); end end Digite a 1a. Digite a 2a. Digite a 3a. Digite a 4a. Media = 6.7 Recuperao nota nota nota nota bimestral-->7.3 bimestral-->6.5 bimestral-->5.5 bimestral-->7.5 Resultado bimestral"); bimestral"); bimestral"); bimestral"); nota4)/4;
27
Comentrio. Se a mdia for maior ou igual que 7 o programa escreve Aprovado (linha 11). Caso contrrio o programa executa o segundo IF (aps o else). Aqui, temos um novo teste IF (aninhado dentro de primeiro IF) que far o programa escrever Recuperao se mdia for maior ou igual a 5 (linha 14) ou, caso contrrio, Reprovado (linha 16). Exerccio resolvido 3.8.2. menor deles. Soluo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // Leitura dos nmeros a = input("Digite um numero"); b = input("Digite um numero"); c = input("Digite um numero"); // Determina o menor nmero if a < b & a < c menor = a; else if b < c menor = b; else menor = c; end end printf("O menor nmero %g\n",menor); Digite um numero-->2 Digite um numero-->3 Digite um numero-->1 O menor nmero 1 Resultado
Vejamos dois casos um pouco mais complicados. Exerccio resolvido 3.8.3. Elaborar um programa Scilab para ler trs medidas a, b e c. Depois vericar se elas podem ser as medidas dos lados de um tringulo. Se forem, vericar ser se o tringulo equiltero, issceles ou escaleno. Soluo: Para saber se trs medidas podem ser as medidas dos lados de um tringulo usamos o seguinte propriedade da Geometria (conhecido como desigualdade triangular): Em todo tringulo, cada lado menor que a soma dos outros dois. Portanto, se as medidas satisfazem a desigualdade triangular acima ento elas formam um tringulo, caso contrrio no formam um tringulo. Relembrando, tambm, que os tringulos se classicam em: 1. Equiltero se tem trs lados de medidas iguais. 2. Issceles se tem dois lados de medidas iguais. 3. Escaleno se dois quaisquer lados no possuem medidas iguais. Com as informaes acima, elaboramos o seguinte programa:
28
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
// Leitura das medidas a = input("Digite a primeira medida"); b = input("Digite a segunda medida"); c = input("Digite a terceira medida"); if a < b + c & b < a + c & c < a + b // // if a == b & b == c printf("Tringulo equiltero"); // else if a == b | a == c | b == c printf("Tringulo issceles"); // else printf("Tringulo escaleno"); // end end else printf("No um tringulo\n"); end Digite a primeira medida-->5 Digite a segunda medida-->5 Digite a terceira medida-->3 Tringulo issceles Digite a Digite a Digite a No um primeira medida-->5 segunda medida-->3 terceira medida-->1 tringulo Verifica se as medidas formam um tringulo. Trs lados iguais. Dois lados iguais. Todos os lados so diferentes.
Resultado
Comentrio. Aps a leitura das medidas a, b e c (linhas 2-4), o programa verica, na linha 6, se estas medidas satisfazem a desigualdade triangular. Se sim, o programa classica o tringulo formado por a, b, e c (linhas 8-16) do seguinte modo. Na linha 8, se a expresso booleana a == b & b == c retornar verdadeiro ento todos os lados so iguais e portanto o tringulo equiltero. Caso contrrio, o programa segue adiante para classicar o tringulo em issceles ou escaleno. Se, porm, as medidas no satisfazem a desigualdade triangular da linha 6, ento o programa no executa as linhas 8-16, e simplesmente escreve que a medidas no formam um tringulo (linha 19). Exerccio resolvido 3.8.4. (Equao do segundo grau). Dados os trs coecientes a, b , c de uma equao do segundo grau ax 2 C bx C c D 0, elaborar um algoritmo para calcular suas razes. O discriminante da equao dado por D b 2 4ac . Para cada situao da seguinte tabela, o algoritmo tomar a respectiva ao:
29
Ao Escrever que a equao degenerada. Calcular e escrever a nica raiz x D c=b . Calcular e escrever as duas razes: x1 D 0 x2 D b=a
a0ec 0e
Calcular e escrever as duas razes: p bC x1 D 2a p b x2 D 2a As razes so complexas. Escrever as partes real e imaginria das duas razes.
a0ec 0e<0
Soluo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 // // Programa para calcular as razes de uma equao do 2o grau // a=input("Digite o coeficiente a :"); b=input("Digite o coeficiente b :"); c=input("Digite o coeficiente c :"); if (a==0) & (b==0) // Equacao degenerada. printf("Equacao degenerada\n"); end if (a==0) & (b<>0) // Equao do 1o grau printf("Raiz nica em %g.\n",-c/b); end if (a<>0) & (c==0) // Equacao do 2o grau com raizes reais em 0 e -b/a x = -b\a; printf("Raiz1 = 0\n"); printf("Raiz2 = %g\n",x); end if (a<>0) & (c<>0) disc = b*b - 4*a*c; // Equacao do 2o grau // Clculo do discriminante
if disc >= 0 // Teste do discriminante // Raizes reais. x1 = -b/(2*a) + sqrt(disc)/(2*a); x2 = -b/(2*a) - sqrt(disc)/(2*a); printf("Raiz1 = %g\n",x1); printf("Raiz2 = %g\n",x2);
30
33 34 35 36 37 38 39 40
else // Raizes complexas pr = -b/(2*a); pi = sqrt(abs(disc))/(2*a); printf("Parte Real = %g\n",pr); printf("Parte Imaginria = %g\n",pi); end end Digite o coeficiente a :-->1 Digite o coeficiente b :-->-5 Digite o coeficiente c :-->6 Raiz1 = 3 Raiz2 = 2 Digite o coeficiente a :-->0 Digite o coeficiente b :-->5 Digite o coeficiente c :-->10 Raiz nica em -2. Digite o coeficiente a :-->2 Digite o coeficiente b :-->3 Digite o coeficiente c :-->6 Parte Real = -0.75 Parte Imaginria = 1.56125 Resultado
Resultado
Resultado
O Scilab manipula nmeros complexos automaticamente e por isso no era necessrio se preocupar em manipular os nmeros complexos como foi feito no exemplo anterior. O mesmo no acontece com algumas linguagens tradicionais. Por exemplo, em linguagem C, devemos tomar cuidado com nmeros complexos pois se o discriminante da equao for um nmero negativo ento a raiz quadrada gera um erro. Por exemplo, em C uma declarao equivalente a esta
x1 = -b/(2*a) + sqrt(disc)/(2*a); x2 = -b/(2*a) - sqrt(disc)/(2*a);
produzia um erro se o valor da varivel disc fosse negativo. O Scilab no gera erro ao calcular a raiz quadrada de um nmero negativo. Ao invs disso, o Scilab produz um nmero complexo automaticamente. A seguir mostrado uma outra verso do programa do exemplo anterior (desta vez sem se preocupar se o discriminante negativo ou no):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // // Programa para calcular as razes de uma equao do 2o grau // Esta verso manipula os nmeros complexos diretamento. a=input("Digite o coeficiente a :"); b=input("Digite o coeficiente b :"); c=input("Digite o coeficiente c :"); if (a==0) & (b==0) // Equacao degenerada. printf("Equacao degenerada\n"); end if (a==0) & (b<>0) // Equao do 1o grau printf("Raiz nica em %g.\n",-c/b); end
31
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
if (a<>0) & (c==0) // Equacao do 2o grau com raizes reais em 0 e -b/a x = -b\a; printf("Raiz1 = 0\n"); printf("Raiz2 = %g\n",x); end if (a<>0) & (c<>0) // Equacao do 2o grau disc = b*b - 4*a*c; // Clculo do discriminante x1 = -b/(2*a) + sqrt(disc)/(2*a); x2 = -b/(2*a) - sqrt(disc)/(2*a); printf("Raiz1 ="); disp(x1); printf("Raiz2 ="); disp(x2); if isreal(x1) printf("As razes so reais"); else printf("As razes so complexas"); end end
Comentrio. O comando de sada de dados disp (linhas 28 e 30) foi usado porque o comando printf no imprime nmeros complexos. Para saber se as razes so reais ou complexas, foi utilizado uma funo especial isreal() do Scilab que devolve verdadeiro (%t) se seu argumento for um nmero real, ou falso (%f) se seu argumento for um nmero complexo. Exemplos:
-->isreal(1+3*%i) ans = F -->isreal(3) ans = T
escreveram As razes so reais se x1 for um nmero real, caso contrrio, escreveram As razes so complexas.
Captulo
ESTRUTURAS DE REPETIO
4.1 LAOS
Computadores so frequentemente usados para repetir uma mesma operao muitas vezes. Para fazer isso, utiliza-se uma estrutura de repetio. Ela faz com que um conjunto de comandos seja executado zero, uma ou mais vezes. A estrutura de repetio , tambm, chamado de lao (do ingls, loop). O conjunto de comandos que se repete em um lao denominado de corpo do lao. H dois tipos de lao no Scilab: 1. Lao controlado logicamente; 2. Lao controlado por contador. No lao controlado logicamente, os comandos (i.e., o seu corpo) so repetidos indenidamente enquanto uma certa expresso booleana for satisfeita. No lao controlado por contador, os comandos so repetidos um nmero predeterminado de vezes. Denomina-se iterao a repetio de um conjunto de comandos. Portanto, cada execuo do corpo do lao, juntamente com a condio de terminao do lao, uma iterao. Nas sees seguintes sero estudados as estruturas de repetio do Scilab.
4.2
O lao while um lao controlado logicamente. Ele repete a execuo de um conjunto de comandos (o seu corpo), mas vericando antes de executar os comandos se permitido repeti-los ou no. O lao while tem a seguinte forma:
while <expresso booleana> <conjunto de comandos> end
Enquanto a <expresso booleana> for verdadeira o <conjunto de comandos> repetido indenidamente. No momento em que <expresso booleana> for falsa o <conjunto de comandos> no ser mais repetido. Vale salientar que se <expresso booleana> for falsa da primeira vez, o <conjunto de comandos> jamais ser executado. A elaborao de programas com laos envolve, frequentemente, o uso de duas variveis com funes especiais: os contadores e os acumuladores na qual sero mostradas a seguir. Considere os seguintes clculos no console do Scilab:
-->i = 1 i =
32
33
Note que cada vez que a expresso i = i + 1 executada o valor da varivel i incrementado de um. A varivel i da expresso i = i + 1 chamada de contador. Os exemplos a seguir ilustram o uso do contador em laos while. Exerccio resolvido 4.2.1. Calcular a mdia das notas de cinco alunos. Soluo: este programa realiza a tarefa de ler as notas de um aluno e calcular a sua mdia. O programa dever repetir esta tarefa cinco vezes (usando while). O contador usado para contar o nmero de repeties.
1 2 3 4 5 6 7 8 9 10 11 i = 1; while i <= 5 nota1 = input("Digite a 1a. nota nota2 = input("Digite a 2a. nota nota3 = input("Digite a 3a. nota nota4 = input("Digite a 4a. nota media = (nota1 + nota2 + nota3 + printf("Media = %g\n",media); i = i + 1; end printf("Fim do programa"); Digite a 1a. nota Digite a 2a. nota Digite a 3a. nota Digite a 4a. nota Media = 7.8 Digite a 1a. nota Digite a 2a. nota Digite a 3a. nota Digite a 4a. nota Media = 6.975 Digite a 1a. nota Digite a 2a. nota Digite a 3a. nota Digite a 4a. nota Media = 7.275 Digite a 1a. nota Digite a 2a. nota Digite a 3a. nota bimestral-->7.5 bimestral-->8.2 bimestral-->8.3 bimestral-->7.2 bimestral-->6.5 bimestral-->6.2 bimestral-->8.2 bimestral-->7.0 bimestral-->8.2 bimestral-->7.8 bimestral-->4.8 bimestral-->8.3 bimestral-->6.5 bimestral-->7.1 bimestral-->8.3
Resultado
34
Digite a 4a. nota Media = 7.175 Digite a 1a. nota Digite a 2a. nota Digite a 3a. nota Digite a 4a. nota Media = 9.1 Fim do programa
Comentrio. O programa comea inicializando a varivel i com o valor um (linha 1). Por causa disso, a expresso i <= 5 do lao while verdadeira. Ento o corpo do lao executado pela primeira vez (primeira iterao). O lao while incrementa o valor da varivel i com o valor de um toda vez que o corpo do lao (linhas 3-9) executado. Depois que o corpo do lao tem sido executado cinco vezes (ou seja, aps cinco iteraes) a varivel i possui valor seis e a expresso i <= 5 falsa. Por causa disso o lao termina e o programa passa a executar a linha seguinte imediatamente aps o m do lao (que a linha 11). Agora, considere os seguintes clculos executados no console do Scilab:
-->soma = 20 soma = 20. -->x = 2.5 x = 2.5 -->soma = 0 soma = 0. -->soma = soma + x soma = 2.5 -->soma = soma + x soma = 5.
Qual o valor da varivel soma aps repetir a execuo do ltimo comando mais duas vezes? A varivel soma da expresso soma = soma + x chamada de acumulador. Vejamos um exemplo. Exerccio resolvido 4.2.2. inteiros entre 1 e 100. Soluo: Elaborar um programa para calcular a soma de todos os
35
1 2 3 4 5 6 7
cont= 1; soma = 0; while cont <= 100 soma = soma + cont; cont = cont + 1; end printf("Soma total = %g\n",soma); Soma total = 5050 Resultado
Comentrio. O programa inicializa as variveis cont e soma com 1 e 0, respectivamente (porque?). Cada vez que o corpo do lao executado, o valor de soma incrementado com o valor corrente da varivel cont. Deste modo, a varivel soma assume os seguintes valores a cada repetio do lao. Valor da varivel soma 1 3 6 : : : 5050
4.3
O comando FOR o lao controlado por contador do Scilab. Ele repete a execuo de um conjunto de comandos (i.e., o seu corpo) um nmero pr-determinado de vezes. Na forma bsica, o lao FOR possui o nome de uma varivel (chamada de varivel de controle) e especica seu valor inicial e nal e, opcionalmente, o tamanho do passo (ou incremento) da varivel de controle. Ver a Figura 4.1. O seguinte programa escreve a palavra disciplina 10 vezes:
for i=1:10 printf("disciplina\n"); end
Aqui a varivel de controle i assume, inicialmente, o valor um e o printf("disciplina\n") executado. Note que o tamanho do passo foi omitido neste exemplo. Quando isto ocorre o passo igual a um. Um passo igual a um indica que a varivel de controle incrementada de um em cada iterao. O lao for, repete a execuo de printf("disciplina\n") e a varivel de controle i incrementada para o valor 2. Da terceira vez que printf("disciplina\n")
36
executado, a varivel de controle i incrementada para o valor 3 e assim por diante at alcanar o valor 10 que o valor nal. Outros exemplos seguem. Exerccio resolvido 4.3.1. Elabore um programa para escrever todos os nmeros pares inteiros entre 1 e 50. Soluo:
1 2 3 for i=2:2:50 printf("%g ",i); end Resultado 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50
Comentrio. O primeiro nmero par 2, logo o varivel de controle deve iniciar com 2. Porque os nmeros devem ser escritos de dois em dois, o passo deve ser igual a 2. O valor nal na varivel de controle , obviamente, 50. Exerccio resolvido 4.3.2. Elabore um programa para calcular 5 (fatorial de 5)
1 2 3 4 5 6 fat = 1; for cont=2:5 fat = fat * cont; end printf("O fatorial de 5 igual a %g\n",fat); Resultado
Comentrio. Note que a cada interao do lao, a varivel fat assume os seguintes valores Valor da varivel fat 1 2 6 24 120
4.4
Exerccio resolvido 4.4.1. Algoritmo para calcular o fatorial. Elabore um programa para calcular o fatorial para qualquer valor n fornecido pelo usurio. Sabendo que: N D 1 2 3 ::: .N 1/ N;
37
1 2 3 4 5 6
n = input("Entre com um nmero"); fat = 1; for cont=2:n fat = fat * cont; end printf("O fatorial de %g igual a %g\n",n,fat); Entre com um nmero-->8 O fatorial de 8 igual a 40320 Resultado
Exerccio resolvido 4.4.2. Exemplo de Somatrio. Elabore um programa que calcule e escreve o valor de S. 1 3 5 7 99 C C C C ::: C 1 2 3 4 50 Soluo: note que h uma relao entre numerador e denominador da seguinte forma: SD 2 denominador 1 D numerador
Usaremos esta relao para calcular cada termo da srie no seguinte programa:
1 2 3 4 5 s = 0; for d=1:50 s = s + (2*d-1)/d; end printf("Valor de S = %g\n",s); Valor de S = 95.5008 Resultado
Exerccio resolvido 4.4.3. O Algoritmo de Euclides. O Algoritmo de Euclides est presente no quinto livro de Euclides escrito por volta de 300 anos antes de Cristo. Sua nalidade calcular o Mximo Divisor Comum (M.D.C.). Conhecido por muitos estudantes, o Algoritmo de Euclides desempenha importante papel na matemtica, e por isso interessante estud-lo. Para calcular o M.D.C. entre dois nmeros segue-se o algoritmo: Passo 1. Leia duas variveis a e b Passo 2. r = o resto da diviso entre a e b Passo 3. a = b Passo 4. b = r Passo 5. Se o valor de r zero ento a o M.D.C. procurado e o programa termina; caso contrrio volte ao passo 2. Seguindo este algoritmo manualmente, com um lpis e papel, possvel calcular o M.D.C. entre 544 e 119, escrevendo a seguinte tabela:
38
a 544 119 68 51 17
b 119 68 51 17 0
r.rest o/ 68 51 17 0
Exerccio resolvido 4.4.4. Usando um valor sentinela para interromper um lao Elabore um programa que leia via teclado um conjunto de valores inteiros e positivos. O nal do conjunto conhecido pelo valor -1. Determine o maior valor deste conjunto.
1 2 3 4 5 6 7 8 9 n = input("Digite um nmero inteiro positivo"); valormax = n; while n <> -1 if n > valormax valormax = n; end n = input("Digite um nmero inteiro positivo"); end printf("Valor mximo = %g\n",valormax);
Comentrio. A cada iterao a varivel valormax armazena o maior valor dos nmeros digitados at ento. Portanto, no nal, valormax armazenar o maior valor do conjunto. Resultado Digite um nmero inteiro positivo-->28 Digite um nmero inteiro positivo-->15 Digite um nmero inteiro positivo-->81 Digite um nmero inteiro positivo-->34 Digite um nmero inteiro positivo-->3 Digite um nmero inteiro positivo-->-1 Valor mximo = 81 Exerccio resolvido 4.4.5. A srie de Fibonacci. A srie de Fibonacci se dene como tendo os dois primeiros elementos iguais a um e cada elemento seguinte igual a soma dois elementos imediatamente anteriores. Exemplo, 1; 1; 2; 3; 5; 8 : : : Pede-se que escreva todos os elementos da srie de Fibonacci menor ou igual a N. O valor de N fornecido pelo teclado. Soluo:
39
1 2 3 4 5 6 7 8 9 10 11 12
n = input("Digite um numero inteiro positivo"); printf("Numeros de fibonacci menor ou igual a %g\n",n); a = 1; b = 1; printf("%g %g ",a,b); // imprime os dois primeiros elementos c = a + b; // calcula o proximo elemento while (c <= n) printf("%g ",c); a = b; b = c; c = a + b; // calcula o proximo elemento end Resultado Digite um numero inteiro positivo-->1000 Numeros de fibonacci menor ou igual a 1000 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
4.5
LAOS ANINHADOS
Este programa escreve quatro vezes o caracter x em uma linha como segue:
xxxx
Pode-se usar laos aninhados para produzir diversas linhas de xxxx, conforme ilustra do no seguinte exemplo: Exerccio resolvido 4.5.1. O seguinte programa gera uma sequencia de quatro xs por linha. O nmero de linhas digitado pelo usurio.
1 2 3 4 5 6 7 lin = input("Quantas linhas"); for i = 1:lin for j = 1:4 printf("x"); end printf("\n"); // mudana da linha end Quantas linhas-->5 xxxx xxxx xxxx xxxx xxxx Resultado
Comentrio. Este programa solicita ao usurio o nmero de linhas. Neste exemplo, o usurio digitou 5 linhas. O programa, ento, escreve 5 linhas e em cada linha ele repete 4 vezes o caractere x do seguinte modo. Inicialmente, o varivel i assume o valor 1 na linha 2. Em seguida, a varivel j assume o valor 1. O lao interno das linhas 3-5 repetido 4 vezes escrevendo 4 xs, ou seja, xxxx. Quando o lao interno termina (aps
4.5 Laos Aninhados / UFRN-DCA - 13 de Junho de 2011 4 repeties), o comando printf("\n") da linha 6 cria uma nova linha. Em seguida, o end da linha 7 encontrada e o programa retorna para a linha 2. Na linha 2, o valor da varivel i atualizado para 2. Em seguida, o programa executa novamente o lao interno e o programa escreve novamente xxxx. Novamente, o programa executa o comando printf("\n") gerando uma nova linha e o programa retorna a linha 2, onde a varivel i atualizado para 3. Este lao continua at a varivel i ser igual a 5. O prximo programa escreve a tabuada de 1 at 10. Este programa usa o string de formatao %f em vez de %g para que os dados permaneam alinhados na tabela da tabuada. O string de formatao %f permite especicar o nmero de caracteres que ser ocupado pelo dado escrito com printf e tambm o nmero de dgitos depois do ponto decimal. Por exemplo, o string %5.2f escreva um nmero ocupando cinco caracteres com dois dgitos depois do ponto decimal. Exemplo:
-->a = 223.345547867783; -->printf("%5.2f",a); 23.35
40
O seguinte exemplo, escreve a varivel a ocupando 10 caracteres com dois dgitos aps o ponto decimal:
-->printf("%10.2f",a); 23.35
1 2 3 4 5 6 7 8 9 10
Comentrio. Inicialmente, a varivel i assume o valor um na linha 3. Na linha 4, o programa escreve o nmero um para indicar que a tabuada de um ser escrita nesta
4.5 Laos Aninhados / UFRN-DCA - 13 de Junho de 2011 mesma linha. Em seguida, a varivel j assume o valor um. O lao interno das linhas 5-7 repetido 10 vezes escrevendo a tabuada de um. Quando o lao interno termina (aps 10 repeties), o comando printf("\n") da linha 8 gera uma nova linha. O programa retorna para a linha 3. Na linha 3, o valor da varivel i atualizado para dois. Em seguida, o programa executa novamente o lao interno e o programa escreve a tabuada de dois. Novamente, o programa executa o comando printf("\n") gerando uma nova linha e o programa retorna a linha 3, onde a varivel i atualizado para trs. A tabuada de trs ento escrita. Lao externo continua at a varivel i ser igual a dez.
41
Captulo
MATRIZES
Matrizes so agregados de dados dentro de uma mesma varivel. Matrizes so agregados de dados homogneos no sentido de que os dados tm sempre mesmo tipo de contedo, ou seja, uma matriz pode conter somente dados numricos ou somente strings, mas no os dois simultaneamente 1 . No jargo da informtica, agregados de dados homogneos so frequentemente chamados de arrays ou arranjos. Preferimos o termo matriz (ao invs de array) porque mais usual no jargo da matemtica.
5.1
VETORES
Matrizes unidimensionais so chamados de vetores. Em um vetor possvel armazenar vrios itens em uma nica varivel. Na Figura 5.1 mostrada uma varivel nota contendo as notas de alunos. Os itens contidos em um vetor so chamados de elementos do vetor. Portanto, o vetor nota possui dez elementos. Seus elementos podem ser acessados individualmente. Por exemplo, nota(4) refere-se ao quarto elemento do vetor nota. O valor entre os parnteses de nota(4) chamado de ndice ou subscrito e usado para individualizar um elemento do vetor. Vetores podem ser construdos usando os colchetes [ e ]. Os elementos so envolvidos por colchetes e separados por espaos (ou vrgula). Exemplo,
-->nota = [8.1 5.2 9.2 7.2 6.5 5.2 8.5 9.5 6.5 10.0];
42
43
Uma aplicao de vetores armazenar variveis indexadas da matemtica. Por exemplo, as variveis indexadas x1 D 2, x2 D 4, x3 D 2 e x4 D 3 so armazenadas como:
-->x(1) = 2; -->x(2) = 4; -->x(3) = 2; -->x(4) = 3;
ou equivalentemente como
-->x = [2 4 2 3];
Se o vetor for grande, pode-se usar o smbolo .. para continuar escrevendo da linha seguinte. Exemplo:
-->b = [2 3 7 .. -->9 8 4] b = ! 2. 3. 7. 9. 8. 4. !
5.1.1
Os elementos de um vetor podem ser acessados de vrias maneiras. Por exemplo, considere as variveis:
44
a = [2 4 5 1 3]; i = 2;
Ento tem-se:
a(i+2) a(a(4))
Devolve 1 porque acessa o quarto elemento (i+2 igual a 4) do vetor a. Devolve 2. Como valor de a(4) 1, avaliar a(a(4)) o mesmo avaliar a(1). Logo, a(a(4)) igual a a(1) que, por sua vez, igual a 2. Devolve 4, porque a(a(3)) igual a(5) que, por sua vez, igual a 3. E a(2*i) igual a(4), que igual a 1. Logo, a(a(3))+a(2*i) igual a 3 + 1 = 4.
a(a(3))+a(2*i)
nota = [8.1 5.2 9.2 7.2 6.5 5.2 8.5 9.5 6.5 10.0]; soma = 0; for i=1:10 soma = soma + nota(i); end printf("Mdia das notas = %g\n",soma/10);
Comentrio. Para somar os elementos do vetor, cada elemento foi acessado individualmente e adicionado, um por vez, em um acumulador soma, atravs do lao for...end (linhas 3 a 5). Exerccio resolvido 5.1.2. Ler dois vetores A e B de 10 elementos. Construir um vetor C tal que cada elemento de C seja o dobro da soma entre os elementos correspondentes de A com B. Escrever o vetor C.
1 2 3 4 5 6 7 8 9 10 11 12 for i=1:10 // Leitura de A e B a(i) = input("Digite um valor"); end for i=1:10 b(i) = input("Digite um valor"); end for i=1:10 c(i) = 2*(a(i)+b(i)); // Calculo de C end for i=1:10 // Escreve de C printf("%g ",c(i)); end
Comentrio. O lao for...end, das linhas 1 a 3, faz a leitura de um elemento do vetor a de cada vez. A leitura controlado pelo ndice que faz com que cada leitura seja armazenado em um elemento diferente do vetor a. No lao for...end das linhas 7 a 9, o clculo de cada elemento do vetor c controlado pelo ndice que faz com que seja somando os elementos correspondentes de a e b. Exerccio resolvido 5.1.3. Ler dois vetores A e B de 10 elementos. Construir um vetor C tal que o elemento de ndice mpar de C seja igual ao elemento correspondente de A, caso contrrio, seja igual ao elemento correspondente de B. Por exemplo, c[1]==a[1], c[3]==a[3], : : : . Mas, c[2]==b[2], b[4]==a[4], : : : . Escrever o vetor C.
45
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
for i=1:10 // Leitura de A e B a(i) = input("Digite um valor"); end for i=1:10 b(i) = input("Digite um valor"); end for i=1:10 if modulo(i,2)<>0 // Testa se o ndice i mpar. c(i) = a(i); // Se for mpar c(i) recebe o valor de a(i) else c(i) = b(i); // Se for par c(i) recebe o valor de b(i) end end for i=1:10 // Escreve o vetor C printf("%g ",c(i)); end
Comentrio. A funo modulo (resto de uma diviso) verica se o ndice do vetor C mpar ou par porque se resto da diviso entre um nmero qualquer e dois diferente de zero ento ele mpar (no divisvel por dois).
5.2
MATRIZES BIDIMENSIONAIS
Matrizes bidimensionais usam dois ndices para individualizar elementos. Na Figura 5.2 mostrada uma matriz. Matrizes so construdas usando colchetes. Cada linha da matriz separada por um ponto e vrgula e cada elemento de uma linha separado por espao (ou vrgula). Por exemplo, a seguinte matriz da matemtica, AD poderia ser construda pelo comando:
-->a = [2 3 4; 4 5 2] a = ! ! 2. 4. 3. 5. 4. ! 2. !
2 3 4 4 5 2
Alternativamente, mudando-se a linha (teclando enter) tambm separa as linhas da matriz. Exemplo:
-->a = [2 3 4 --> 4 5 2] a = ! ! 2. 4. 3. 5. 4. ! 2. ! // tecle enter aqui
46
Exerccio resolvido 5.2.1. Dado a matriz A: 2 3 1 2 4 6 5 5 8 6 6 AD6 6 8 10 11 5 4 9 1 5 7 2 3 8 8 Pede-se: a) Colocar a matriz A na memria do computador.
3 7 7 7 7 5
a = [3 1 2 4; 5 5 8 6; 8 10 11 5; 9 1 5 7; 2 3 8 8];
d) Calcular a soma dos quadrados dos elementos da segunda linha de A e escrever o resultado.
47
a = [3 1 2 4; 5 5 8 6; 8 10 11 5; 9 1 5 7; 2 3 8 8]; soma = 0; for i=1:4 soma = soma + a(2,i)^2; end printf("soma = %g\n",soma);
h) Escrever a matriz A.
a = [3 1 2 4; 5 5 8 6; 8 10 11 5; 9 1 5 7; 2 3 8 8]; for i=1:5 for j=1:4 printf("%3.0f ",a(i,j)); end printf("\n"); end
i) Ler uma matriz B de mesma dimenso que A. Efetuar a soma matricial A C B e armazenar o resultado na matriz C .
a = [3 1 2 4; 5 5 8 6; 8 10 11 5; 9 1 5 7; 2 3 8 8]; for i=1:5 for j=1:4 b(i,j) = input("Digite um nmero"); end end for i=1:5 for j=1:4
48
j) Ler uma matriz B de mesma dimenso que A. Escrever IGUAIS se A for uma matriz igual B . Caso contrrio, escrever DIFERENTES.
a = [3 1 2 4; 5 5 8 6; 8 10 11 5; 9 1 5 7; 2 3 8 8]; for i=1:5 for j=1:4 b(i,j) = input("Digite um nmero"); end end iguais = %t; for i=1:5 for j=1:4 if a(i,j) <> b(i,j) iguais = %f; end end end if iguais printf("Iguais\n"); else printf("Diferentes\n"); end
Exerccio 5.2.2. Elabore um programa para ler a matriz A, trocar a segunda linha com terceira linha e escrever a matriz A.
5.3
VETORES DE STRING
O vetor mes foi construdo de tal modo que h uma correspondncia entre o nmero do ms e o ndice do elemento. Por exemplo, o ms de nmero 11 (novembro) acessado pelo elemento mes(11). Este fato usado para resolver o exerccio a seguir. Exerccio resolvido 5.3.1. Elaborar um programa que leia o dia, o nmero de ms e o ano e escreva a dada no formato D de MMM de AAAA(ou D de MMM de AA). Por exemplo, se o dia 31, o ms 12 e o ano 2003, ento o programa dever escrever 1 de dez de 2003.
49
Soluo:
1 2 3 4 5 mes = ["jan" "fev" "mar" "abr" "jun" "jul" "ago" "set" "nov" "dez"]; dia = input("Digite o dia"); nunmes = input("Digite o numero do mes"); ano = input("Digite o ano"); printf("%g de %s de %g\n",dia,mes(nunmes),ano); Digite o Digite o Digite o 2 de abr dia-->2 numero do mes-->4 ano-->2003 de 2003 Resultado
Comentrio. Porque a varivel nunmes contm o nmero do ms, o comando printf capaz de escrever o nome do ms atravs do elemento mes(nunmes).
Exerccios
O que este programa escreve?
1 2 3 4 5 6 7 8 poema(1) = 'uma rosa'; poema(2) = ''; for a=1:3 for b=1:2 printf("%s ",poema(b)); end end printf('%s',poema(1));
5.4
ESTUDO DE CASO
Esta seo ilustra a facilidade que as matrizes oferecem a programao de computadores. Primeiramente, ser mostrado a soluo de um problema sem o uso de vetores visando apontar as diculdades deste procedimento. Em seguida, o mesmo problema ser resolvido com o uso de vetores. Considere o problema: Suponha uma turma com quatro alunos. Elaborar um programa que leia as quatro notas dos alunos e seus respectivos nomes e escreva apenas os nomes com a nota acima da mdia. Neste sentido, uma possvel soluo (sem vetores) seria a seguinte:2
2
Comumente o clculo da mdia das notas pode ser efetuado pelo seguinte trecho de programa:
soma = 0; for i = 1:4 nota = input("Digite a nota"); soma = soma + nota; end media = soma/4;
Esta abordagem no resolve o problema proposto porque precisamos comparar se cada nota digitada maior que a mdia. Mas vale notar que as notas j foram perdidas no momento que calculado a mdia na ltima linha (exceto a ltima nota que no foi perdida porque est armazenada na varivel nota). Deste modo, no podemos comparar as mdia com as notas (que foram perdidas). Portanto, a m de evitar a perda das notas, necessrio armazenar cada nota digitada em uma varivel diferente.
50
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
aluno1 = input("Nome do aluno","s"); nota1 = input("Nota"); aluno2 = input("Nome do aluno","s"); nota2 = input("Nota"); aluno3 = input("Nome do aluno","s"); nota3 = input("Nota"); aluno4 = input("Nome do aluno","s"); nota4 = input("Nota"); media = (nota1+nota2+nota3+nota4)/4; if nota1 >= media printf("%s\n",aluno1); end if nota2 >= media printf("%s\n",aluno2); end if nota3 >= media printf("%s\n",aluno3); end if nota4 >= media printf("%s\n",aluno4); end
Suponha que, ao invs de uma turma com quatro alunos, houvessem uma turma com cinco alunos, ento teramos: Suponha uma turma com cinco alunos. Elaborar um programa que leia as cinco notas dos alunos e seus respectivos nomes e escreva apenas os nomes com a nota acima da mdia. A soluo deste problema seria similar ao programa anterior, apenas acrescentando algumas linhas (e.g., para ler a quinta nota). A soluo seria:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 aluno1 = input("Nome do aluno","s"); nota1 = input("Nota"); aluno2 = input("Nome do aluno","s"); nota2 = input("Nota"); aluno3 = input("Nome do aluno","s"); nota3 = input("Nota"); aluno4 = input("Nome do aluno","s"); nota4 = input("Nota"); aluno5 = input("Nome do aluno","s"); nota5 = input("Nota"); media = (nota1+nota2+nota3+nota4+nota5)/5; printf("Relao de alunos acima da mdia\n"); if nota1 >= media printf("%s\n",aluno1); end if nota2 >= media printf("%s\n",aluno2); end if nota3 >= media printf("%s\n",aluno3); end if nota4 >= media printf("%s\n",aluno4); end if nota5 >= media
51
26 27
printf("%s\n",aluno5); end
Novamente, suponha que, ao invs de uma turma com cinco alunos, houvessem uma turma com dez alunos. Neste caso, um programa, para ler 10 notas, iria crescer bastante em tamanho (em relao programa anterior) porque seria preciso ler 10 variveis para as notas (i.e., nota1, nota2, : : :, nota10) e 10 para os nomes de alunos, totalizando 20 variveis. Do mesmo modo, para uma turma com 20 alunos, seria preciso ler 40 variveis, sendo as 20 notas e os 20 nomes dos alunos. Considere a situao que fosse preciso ler as notas de todas as turmas de um colgio com 10000 alunos. Ou seja, Suponha uma colgio com 10000 alunos. Elaborar um programa que leia as 10000 notas dos alunos e seus respectivos nomes e escreva apenas os nomes com a nota acima da mdia. Este programa assume proporo gigantesca porque preciso ler 20000 variveis (10000 para as notas e 10000 para os nomes de aluno) tornando-o impraticvel de ser programado (do modo como foi feito antes). Note que as variveis,
Comentrio. No lao for...end das linhas 3 a 6, as notas e os nomes de aluno so lido um de cada vez. O acumulador soma, dentro do lao, soma todas as notas (uma por vez). Os nomes dos alunos com nota acima da mdia so escritos no segundo lao for...end nas linha 8 a 12. Cada nota comparada, uma de cada vez, com a mdia e caso a nota de ndice i passe no teste, o correspondente nome do aluno de ndice i escrito. A concluso que o uso de vetores permite ler e armazenar grande quantidade de notas (e nomes) em um simples lao for...end reduzindo, deste modo, o tamanho de um programa cuja elaborao sem o uso de vetores se torna impraticvel.
52
5.5
5.5.1
A ordenao de elementos de um conjunto fundamental no dia a dia. Um exemplo bem comum so as listas telefnicas cuja ordenao em ordem alfabtica possibilita rapidamente encontrar um nmero de telefone. Um outro exemplo a ordenao de livros por autor ou por assunto em uma grande biblioteca. Por isso a ordenao uma atividade constantemente solicitada em programao. Provavelmente, o algoritmo de ordenao mais conhecido da computao chama-se o algoritmo da bolha. A idia do algoritmo da bolha passar por todo o vetor comparando cada elemento com o elemento seguinte (i.e., a(i) com a(i+1)) e troca-los caso estes dois elementos no estejam na ordem apropriada. Por diversas vezes, o algoritmo repete a passada at o vetor car completamente ordenado. Vejamos como funciona este algoritmo para ordenar o a = [5 4 3 2 6]. A) Vetor inicial desordenado: a = [5 4 3 2 6] Passo A.1 Comparar a(1) e a(2). Se a(1) > a(2), troque os dois elementos. a = [4 5 3 2 6] Houve troca do nmero 4 com o nmero 5. Passo A.2 Comparar a(2) e a(3). Se a(2) > a(3), troque os dois elementos. a = [4 3 5 2 6] Houve troca do nmero 5 com o nmero 3. Passo A.3 Comparar a(3) e a(4). Se a(3) > a(4), troque os dois elementos. a = [4 3 2 5 6] Houve troca. Passo A.4 Comparar a(4) e a(5). Se a(4) > a(5), troque os dois elementos. a = [4 3 2 5 6] No houve troca porque a(4) no maior que a(5). B) Repetio a iterao (porque o vetor ainda no est ordenado): Passo B.1 Comparar a[1] e a[2]. Se a[1] > a[2], troque os dois elementos. a = [3 4 2 5 6] Houve troca do nmero 4 com o nmero 3. Passo B.2 Comparar a[2] e a[3]. Se a[2] > a[3], troque os dois elementos. a = [3 2 4 5 6] Houve troca do nmero 4 com o nmero 2. Passo B.3 Comparar a[3] e a[4]. Se a[3] > a[4], troque os dois elementos. a = [3 2 4 5 6] No houve troca. Passo B.4 Comparar a[4] e a[5]. Se a[4] > a[5], troque os dois elementos. a = [3 2 4 5 6] Novamente no houve troca. C) Repetio a iterao (porque o vetor no est ordenado) Passo C.1 Comparar a[1] e a[2]. Se a[1] > a[2], troque os dois elementos. a = [2 3 4 5 6] Houve troca do nmero 3 com o nmero 2.
53
Passo C.2 Comparar a[2] e a[3]. Se a[2] > a[3], troque os dois elementos. a = [2 3 4 5 6] No houve troca. Passo C.3 Comparar a[3] e a[4]. Se a[3] > a[4], troque os dois elementos. a = [2 3 4 5 6] No houve troca. Passo C.4 Comparar a[4] e a[5]. Se a[4] > a[5], troque os dois elementos. a = [2 3 4 5 6] No houve troca. D) Repetio a iterao. (a) Passo D.1 Comparar a[1] e a[2]. Se a[1] > a[2], troque os dois elementos. a = [2 3 4 5 6] No houve troca. (b) Passo D.2 Comparar a[2] e a[3]. Se a[2] > a[3], troque os dois elementos. a = [2 3 4 5 6] No houve troca. (c) Passo D.3 Comparar a[3] e a[4]. Se a[3] > a[4], troque os dois elementos. a = [2 3 4 5 6] No houve troca. (d) Passo D.4 Comparar a[4] e a[5]. Se a[4] > a[5], troque os elementos. a = [2 3 4 5 6] No houve troca. E) Se no houve troca na ltima iterao ento pare porque o vetor j est ordenado. O seguinte trecho de programa implementa o algoritmo da bolha para ordenar a vetor a (supondo que o vetor a j foi lido e est na memria).
1 2 3 4 5 6 7 8 9 10 11 12 13 n = length(a); HouveTroca = %t; while HouveTroca HouveTroca = %f; for i = 1:(n-1) if a(i) > a(i+1) temp = a(i); a(i) = a(i+1); a(i+1) = temp; HouveTroca = %t; end end end // Obtem o tamanho do vetor
Comentrio. A varivel booleana HouveTroca indica se houve troca ou no aps a ltima passada pelo vetor. A varivel HouveTroca assume o valor falso na linha 4, e se dentro do lao interno for...end no houver troca ento a varivel HouveTroca continuar com valor falso (isto far com que o lao while...end encerre a execuo do programa). Caso contrrio, a varivel HouveTroca assume o valor verdadeiro na linha 10) (isto far com que o lao while...end execute nova iterao). A troca de um elemento com o elemento seguinte (i.e., a(i) com a(i+1)) realizado pelo trecho:
54
A varivel temp uma varivel temporria usada apenas para guardar o valor de a(i) antes que o mesmo seja perdido na atribuio a(i) = a(i+1). Exerccio 5.5.1. Modique trecho de programa que contm algoritmo da bolha para colocar o vetor em ordem decrescente (troque o operador > por < na linha 6). Use esta modicao para elaborar um programa para ler um vetor com 5 elementos, coloca-lo em ordem decrescente e escreve-lo.
5.5.2
Exerccio resolvido 5.5.2. Elabore um programa que, simulando lanamentos de dados, calcule a freqncia de cada resultado aps 100 lanamentos. Para resolver este problema utiliza-se a funo rand (tambm chamada de gerador de nmeros aleatrios). Esta funo retorna um nmero diferente (aleatrio) cada vez que chamada, por exemplo:
-->rand() ans = .4410204 -->rand() ans = .8859080 -->rand() ans = .6868068
Os nmeros aleatrios gerados por rand so nmeros fracionrios no intervalo 0; 1. No entanto, o problema pede para gerar nmeros inteiros aleatoriamente entre 1 e 6 de modo a simular o lanamento de um dado. Isto pode ser obtido com o seguinte procedimento. Primeiro, multiplica-se rand por 6 para gerar nmeros no intervalo 0; 6. Por exemplo:
-->6*rand()
Em seguida, usa-se a funo fix() para gerar apenas nmeros inteiros entre 0 e 5 (inclusive). Por exemplo,
-->fix(6*rand())
Por m, adiciona-se o valor 1 na expresso anterior para gerar nmeros inteiros entre 1 e 6.
-->fix(6*rand())+1)
e obtm-se, deste modo, nmeros inteiros aleatrios entre 1 e 6 na qual simula o lanamento de um dado como requerido. Ser utilizado, tambm, um vetor f que armazena a freqncia de cada dado. Por exemplo, o elemento f(1) armazena a freqncia do dado 1, o elemento f(2) armazena a freqncia do dado 2, e assim por diante. Soluo:
55
1 2 3 4 5 6 7 8 9 10 11
for i = 1:6 f(i) = 0; // inicializa o vetor de frequencias end for i=1:100 r = fix(6*rand())+1; // lanamento do dado f(r) = f(r)+1; // adiciona 1 ao dado r end for i=1:6 f(i) = f(i)/100; // divide o vetor f por 100 para obter a frequencia. printf("freqncia do dado %1.0f = %5.2f\%\n",i,f(i)); end
5.5.3
Exerccio resolvido 5.5.3. Alguns candidatos prestaram concurso para cinco vagas em uma empresa. Os resultados das provas do concurso esto armazenadas nas seguintes matrizes: Nome Ana Carlos Francisco Jos Magali Marcos Maria Marta Paulo Pedro Escreva um programa que: a) Armazene o nomes dos candidados em um vetor nome e as notas das provas em uma matriz nota 10 3. O smbolo ... ser usado para continuar os comandos na linha seguinte.
nome = ["Ana" "Carlos" "Francisco" ... "Jos" "Magali" "Marcos" ... "Maria" "Marta" "Paulo" "Pedro"]; nota = [6.5 8.0 7.5 6.1 7.1 8.3 8.1 5.2 7.5; 7.2; 8.3; 6.0; ... ... ... ...
Matemtica 6,5 8,0 7,5 6,1 5,1 4,1 9,1 8,8 9,5 8,2
Portugus 7,1 8,3 8,1 5,2 6,1 5,5 8,9 8,5 9,3 8,5
Digitao 7,5 7,2 8,3 6,0 6,5 5,4 9,4 9,0 9,1 7,8
56
6.5; ... 5.4; ... 9.4; ... 9.0; ... 9.1; ... 7.8];
b) Calcule a mdia de cada candidato, armazene em um vetor media e escreva-o. Neste programa e nos seguintes assumido que o cdigo acima j est includo no programa.
1 2 3 4 5 6 7 8 9 10 11 12 [m,n]=size(nota); for i=1:m soma = 0; for j=1:n soma = soma+nota(i,j); end media(i)=soma/3; end printf("Nome Media\n"); // linha de cabeario for i=1:m printf("%-10s %3.1f\n",nome(i),media(i)); end Nome Ana Carlos Francisco Jos Magali Marcos Maria Marta Paulo Pedro Media 7.0 7.8 8.0 5.8 5.9 5.0 9.1 8.8 9.3 8.2 Resultado
d) Elabore um programa para escrever um relatrio dos candidatos em ordem de classicao dos candidados. O soluo desta questo mostrado no programa listado abaixo. Na primeira parte do programa (linhas 1-8), calcula-se a mdia da mesma maneira que no item(b) deste exerccio. Na segunda parte do programa (linhas 10-25) feita a ordenao dos vetores com o algoritmo da bolha. O vetor ordenado o vetor media, mas
5.5 Exemplos com Matrizes / UFRN-DCA - 13 de Junho de 2011 note que para cada dois elementos trocados do vetor do media tambm trocado os respectivos elementos do vetor nome para acompanhar a mesma ordem do vetor media. Na ltima parte do programa (linha 27-30) impresso o relatrio dos candidatos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 [m,n]=size(nota); for i=1:m // Computa as medias dos alunos soma = 0; for j=1:n soma = soma+nota(i,j); end media(i)=soma/3; end // ordenao e troca dos elementos HouveTroca = %t; while HouveTroca HouveTroca = %f; for i = 1:(m-1) if media(i) < media(i+1) temp = media(i); // troca o elemento media i com i+1 media(i) = media(i+1); media(i+1) = temp; temp = nome(i); // troca o elemento nome2 i com i+1 nome(i) = nome(i+1); nome(i+1) = temp; HouveTroca = %t; // Houve troca end end end printf(" Nome Media\n"); // linha de cabeario for i=1:m printf("%2.0f- %-10s %3.1f\n",i,nome2(i),media(i)); end Nome Paulo Maria Marta Pedro Francisco Carlos Ana Magali Jos Marcos Media 9.3 9.1 8.8 8.2 8.0 7.8 7.0 5.9 5.8 5.0 Resultado
57
12345678910-
Captulo
MANIPULAO MATRICIAL
A manipulao matricial uma das mais interessantes caractersticas do Scilab porque reduzem susbtancialmente a quantidade de linhas de cdigo e, frequentemente, torna o programa mais eciente.
6.1
CONSTRUO DE MATRIZES
Exemplo,
-->1:2:15 ans = ! 1. 3. 5. 7. 9. 11. 13. 15. !
-->log(a)
58
59
ans !
0.7071068
1.225E-16 !
-->a' ans = ! 1.
Concatenao de Matrizes
Uma operao muito comum a concatenao de matrizes. Por exemplo:
-->a = [1 2 3]; -->b = [4 5 6]; -->[a b] ans = ! 1. 2. 3. 4. 5. 6. !
-->[a; b] ans = ! ! 1. 4. 2. 5. 3. ! 6. !
->[a; 5 4 3] ans = ! ! 1. 5. 2. 4. 3. ! 3. !
Mais exemplos:
-->c = [1 2 3 4]; -->d = [2 3 1 2; 3 4 5 4; 5 6 7 4] d =
60
2. 3. 5.
3. 4. 6.
1. 5. 7.
2. 4. 4.
-->[d; c; c] ans = 2. 3. 5. 1. 1. 3. 4. 6. 2. 2. 1. 5. 7. 3. 3. 2. 4. 4. 4. 4.
Vale resaltar que a concatenao s possvel se houver consistncia dimensional entre as matrizes. Por exemplo, o seguinte exemplo gera um erro por que o vetor c tem dimenses inconsistentes com os vetores a e b:
-->a = [1 2 3]; -->b = [4 5 6]; -->c = [1 2 3 4]; -->[a; b; c] !--error 6 inconsistent row/column dimensions
linspace e logspace
Construmos um vetor de 5 elementos igualmente espaos entre 0 e 10 com o operador dois pontos da seguinte forma:
-->1:0.125:1.5 ans = ! 1. 1.125 1.25 1.375 1.5 !
Note que precisamos conhecer o incremento de 0,125 para gerar o vetor acima. Se o incremento no conhecido, pode ser mais simples usar a funo linspace para gerar o vetor acima. Sua sintaxe
linspace(inicio,fim,n)
61
Cria um vetor linha que comea em inicio, incrementa em um e um at atingir fim. Cria um vetor linha que comea em inicio, incrementando de incremento at atingir fim. Cria um vetor linha com n valores igualmente espaados comeando em inicio e terminando em fim. Cria um vetor linha com n valores logaritmicamente espaados comeando em inicio e terminando em fim. Cria vetor linha com os elementos de a e b. Cria matriz com os elementos de a na primeira linha e os elementos de b na segunda linha.
A funo linspace gera um vetor com n valores igualmente espaados comeando em inicio e terminando em fim. Exemplo:
-->linspace(1,1.5,5) ans = ! 1. 1.125 1.25 1.375 1.5 !
A funo logspace(inicio,fim,n) gera n elementos logaritmicamente espaados. O primeiro elemento 10 elevado ao inicio e o ltimo elemento 10 elevado ao fim. Por exemplo:
-->logspace(1,2,4) ans = ! 10. 21.544347 46.415888 100. !
O seguinte exemplo plota o grco da funo seno. A funo plot2d(x,y) cria um grco onde x e y so vetores de mesmo tamanho representando os pontos do eixo x e y de uma funo qualquer. Usamos 50 pontos no intervalo de 0 at 2 :
-->x = linspace(0,2*%pi,50); -->y = sin(x); -->plot2d(x,y);
Na verdade, a funo plot2d(x,y) apenas conecta os pontos dados por meio de linhas retas. Portanto, para obter uma aparncia suave da curva do grco preciso uma quantidade suciente de pontos (no caso usamos 50 pontos). Um resumo das operaes construo de matrizes mostrado na Tabela 6.1.
6.2
SECIONAMENTO DE MATRIZES
O Scilab permite manipulao de parte da matriz (uma submatriz). Esta operao denominada de secionamento (do ingls, slicing). Considere o vetor:
62
(a) v(2:4)
(b) a(1:3,2)
(c) a(2:3,1:3)
Obtemos uma parte do vetor (subvetor) usando o comando v(2:4) que refere-se aos elementos 2, 3, e 4 do vetor v (ver Figura 6.1(a)):
-->v(2:4) ans = ! 5. 6. 3. !
Considere a matriz:
-->a = [2 3 1; 7 8 4; 2 8 8] a = ! ! ! 2. 7. 2. 3. 8. 8. 1. ! 4. ! 8. !
-->a(2,:) ans = ! 7.
63
Apesar de no ser a maneira mais simples, a transposta da matriz a pode ser calculada da seguinte forma:
-->[a(:,1)';a(:,2)';a(:,3)'] ans = ! ! ! 2. 3. 1. 7. 8. 4. 2. ! 8. ! 8. !
64
6.2.1
Indexao Linear
A operao de indexar, com apenas um ndice, uma matriz bidimensional chamada de indexao linear. A matriz tratada como se fosse um longo vetor coluna formado pelas colunas da matriz (uma coluna abaixo da outra). Por exemplo, a Figura 6.2.1 mostra ndices lineares da seguinte matriz:
-->A = [2 3 1; 7 8 4; 2 8 8; 6 4 5] A = ! ! ! ! 2. 7. 2. 6. 3. 8. 8. 4. 1. 4. 8. 5. ! ! ! !
65
Extrai as linhas v(1), v(2), ..., v(n) de A. Extrai as colunas v(1), v(2), ..., v(n) de A. Retorna um vetor coluna construdo percorrendo as colunas da matriz A pela ordem crescente dos ndices da coluna. Extrai os elementos de A cujos ndices correspondem a v(1), v(2), ..., v(n), como se A fosse o vetor-coluna A(:)
Outros exemplos,
-->A(2:5) ans = ! ! ! ! 7. 2. 6. 3. ! ! ! !
6.3
O OPERADOR $
-->x(3:$) ans = ! 6. 4.
66
6.4
ATRIBUIO
Outro exemplo:
-->A(:,1) = 4 A = ! ! ! 4. 4. 4. 3. 7. 1. 1. ! 2. ! 8. ! // O nmero 4 expandido para preencher toda a coluna 1.
Considere o vetor:
-->v = [2 4 7 1 3]; -->v([2 4]) = 8 v = ! 2. 8. 7. // atribui 8 para o segundo e o quarto elemento de v 8. 3. !
Quando voc atribui uma matriz vazia [] a uma linha (ou coluna), ela eliminada. Por exemplo,
67
-->A(2,:) = [] A = ! ! 2. 1. 3. 2.
Considere a matriz B:
-->B = [2 3; 5 8] B = ! ! 2. 5. 3. ! 8. !
Como a matriz B no possui a terceira linha e nem a quarta coluna, ela foi ampliada com os novos elementos assumindo valor zero.
6.5
DIMENSO DE MATRIZES
A funo size() retorna um vetor de dois elementos com o nmero de linhas e colunas de uma matriz. Por exemplo:
-->a = [1 2 3 4 5; 3 4 5 6 5] a = ! ! 1. 3. 2. 4. 3. 5. 4. 6. 5. ! 5. !
-->size(a) ans = ! 2. 5. !
6.6 Operaes Escalar-Matriz / UFRN-DCA - 13 de Junho de 2011 As funes size(x,1) e size(x,2) retornam somente o nmero de linhas e colunas, respectivamente:
-->size(a,1) ans = 2. -->size(a,2) ans = 5.
68
Considere o vetor:
-->b = [3 1 2 4];
Apesar de ser um vetor, b interpretado, a seguir, como uma matriz 1x4. Por exemplo:
-->size(b,"c") ans = 4. // devolve o numero de colunas de b
6.6
OPERAES ESCALAR-MATRIZ
Operaes entre escalar e matriz seguem a regras comuns da matemtica. Considere a matriz:
-->A = [1 2 3 4; 5 6 7 8] A = ! ! 1. 5. 2. 6. 3. 7. 4. ! 8. !
Exemplo de multiplicao:
-->2*A ans = ! ! 2. 10. 4. 12. 6. 14. 8. ! 16. !
Exemplos de diviso:
69
-->A(:,2)/2 ans = ! ! 1. ! 3. !
Exemplos de expresses:
-->A-2 ans = ! - 1. ! 3. -->3*A-2 ans = ! ! 1. 13. 4. 16. 7. 19. 10. ! 22. ! 0. 4. 1. 5. 2. ! 6. !
6.7
OPERAES MATRIZ-MATRIZ
-->B = [3 1 3 8; 3 9 6 5] B = ! ! 3. 3. 1. 9. 3. 6. 8. ! 5. !
70
-->v = [2; 3; 4; 5] v = ! ! ! ! 2. 3. 4. 5. ! ! ! !
O operador de multiplicao pontuada (.*) realiza uma multiplicao elemento por elemento entre matrizes. Considere as matriz:
-->A = [1 2 3 4; 5 6 7 8] A = ! ! 1. 5. 2. 6. 3. 7. 4. ! 8. !
-->B = [3 1 3 8; 3 9 6 5] B = ! ! 3. 3. 1. 9. 3. 6. 8. ! 5. !
Multiplicao pontuada:
-->A.*B ans = ! ! 3. 15. 2. 54. 9. 42. 32. ! 40. !
71
Do mesmo modo, a diviso elemento por elemento, requer o uso do ponto (diviso pontuada):
-->A./B ans = ! ! 0.3333333 1.6666667 2. 0.6666667 1. 1.1666667 0.5 ! 1.6 !
Existe tambm a potenciao elemento por elemento que tambm requer o uso do ponto (potenciao pontuada): Em geral, o Scilab
-->[2 3 2 4].^[1 2 3 4] ans = 2. 9. 8. 256.
utiliza menos laos que as linguagens de programao tradicionais devido sua habilidade de substituir laos por alguma operao matricial.
Exemplo de expresso:
-->A.^(2+1)+B/2 ans = ! ! 2.5 126.5 8.5 220.5 28.5 346. 68. ! 514.5 !
A seguinte expresso:
-->2.^A ans = ! ! 2. 32. 4. 64. 8. 128. 16. ! 256. !
eleva 2 a cada um dos elementos de A. Exerccio resolvido 6.7.1. Calcular o valor da funo f .x/ D sin.x/ cos.x/ para xD 2 3 8 ; ;:::; 8 8 8 8 ;
Em muitas linguagens de programao este problema seria utilizar um lao FOR, como por exemplo:
1 2 3 4 5 6 x = %pi/8 : %pi/8 : %pi; a = sin(x); b = cos(x); for i=1:8 y(i) = a(i)*b(i); end
72
6.8
O Scilab foi especialmente projetado para simplicar clculos de Algebra Linear. Um dos problemas mais comuns de Algebra Linear a soluo de sistemas de equaes lineares: 8 x2 C 2x3 D 5 < x1 x1 x2 6x3 D 0 : 4x1 C x3 D 5 Este sistema tambm pode ser escrito na forma matricial Ax D b: 3 2 3 32 2 5 x1 1 1 2 4 1 1 6 5 4 x2 5 D 4 0 5 5 x3 4 0 1 Iniciamos a soluo do sistema preparando as matrizes A e b:
-->A = [1 -1 2; A = ! ! ! 1. - 1. 1. - 1. 4. 0. 1 -1 -6; 4 0 1]
2. ! - 6. ! 1. ! // A transposta importante!
-->b = [5 0 5]' b = ! ! ! 5. ! 0. ! 5. !
O operador de diviso esquerda \ resolve o sistema, isto , o resultado de A\b a soluo do sistema:1
-->A\b ans = ! 1.09375 ! ! - 2.65625 ! ! 0.625 !
6.9
Se a matriz possue nmeros complexos, o operador de transposio () produz a transposta conjugada, ou seja, aplica a transposio e a conjugao complexa na matriz. Por exemplo:
-->a = [%i 2+%i 5; -1+2*%i 3*%i %i] a = ! i ! - 1. + 2.i -->a' ans =
1 O operador de diviso a direita = denido em termos do operador de diviso esquerda: A=b = (A'nb')'.
2. + i 3.i
5. ! i !
73
Tabela 6.3: Transposta de Matrizes Complexas Seja A e B matrizes reais. Considere a matriz complexa: Z = A + %i*B Ento:
Z' = A' - %i*B' Z.' = A' + %i*B'
! - i ! 2. - i ! 5.
- 1. - 2.i ! - 3.i ! - i !
Use o operador de transposio pontuada (.) para produzir a transposta sem operao de conjugao:
-->a.' ans = ! ! ! i 2. + i 5. - 1. + 2.i ! 3.i ! i !
6.10
ZEROS E ONES
Captulo
FUNES
7.1 INTRODUO
Quando o tamanho de um programa estende-se a centenas de linhas, o programa torna-se difcil de compreender e administrar. Por isso, dividir um grande programa computacional em partes menores para facilitar a compreenso (ou legibilidade) do problema uma tarefa comum em programao de computadores. No Scilab, este trecho menor do programa chamado de funo. Funes so tambm chamadas de sub-rotinas, mdulos, subprogramas ou subalgoritmos. Funes so usados tambm para evitar repetio do mesmo cdigo no programa. Por exemplo, suponha que seu programa tenha a tarefa de por em ordem crescente vrias listas de nmeros. Em vez de repetir o cdigo toda vez que for realizar esta tarefa, voc escreve uma funo para ordenar listas numricas e depois chama a mesma funo sempre que for ordenar uma lista. Neste sentido, as funes apresentam as seguintes vantagens: a) Voc escreve o cdigo somente uma vez. b) Voc pode reutilizar a funo em outros programas. c) Uma vez que voc tem corrigido todos os erros do programas (i.e., depurado o programa), ele funcionara corretamente no importa quantas vezes voc use a funo. Em resumo, funes so usadas para: 1. Dividir um grande programa em programas menores; 2. Repetir uma tarefa que realizada frequentemente sem ter que repetir o mesmo cdigo em vrios lugares; 3. Aumentar a legibilidade do programa. No Scilab j existem muitas funes prontas (pr-denidas), algumas delas elementares (cos(x) e sin(x)) e outras especcas para aplicaes em engenharia, matemtica, fsica, e na estatstica. O objeto de estudo deste captulo so as funes denidas pelo usurio. Isto , funes que so elaboradas pelos prprios usurios do Scilab.
7.2
As funes recebem dados por meio de uma lista de parmetros de entrada, e retorna resultados por uma lista de parmetros de sada. Por exemplo, a funo cos(x) recebe um valor e retorna um valor, logo tem um parmetro de entrada e um de sada. A funo, modulo(x,y) recebe dois valores (o numerador e o denominador) e retorna um valor (o resto). Logo, modulo(x,y) tm dois parmetros de entrada e um de sada. A funo size(x), tem um parmetro de entrada e dois de sada. Por exemplo, 74
75
-->a = [1 2 3; 4 5 6] a = ! ! 1. 4. 2. 5. 3. ! 6. !
-->[l c] = size(a) c = l 3. = 2.
porque recebe uma matriz e devolve dois valores (o nmero de linhas e colunas).
7.3
Palavra reservada que indica o inicio de uma funo. o nome da funo denido pelo usurio. parmetros de entrada. parmetros de sada. Comandos do Scilab a serem executados pela funo.
o cabealho da funo e serve, entre outras coisas, para dar o nome da funo e denir a lista de parmetros de entrada e sada (tambm chamados de parmetros formais). Quando h apenas um parmetro de sada, os colchetes podem ser omitidos. Por exemplo, a seguinte funo tem apenas um parmetro de sada e um parmetro de entrada. Esta funo calcula o fatorial de um nmero:
1 2 3 4 5 6 7 function y = fat(n) p = 1; for i = n:-1:2 p = p*i; end y = p; endfunction
Na linha de comando y = p da funo fat(x) atribudo o valor a ser retornado pelo parmetro de sada y. IMPORTANTE: Cada parmetro da lista de parmetros de sada de uma funo necessrio aparecer a esquerda de pelo menos um comando de atribuio da funo.
76
Quando a funo termina, o valor contido nos parmetros de sada so retornados ao programa que chamou a funo. Uma chamada (ou ativao) de funo a solicitao explcita para executar uma funo. A seguinte chamada de funo no console do Scilab executa a funo fat:
-->fat(4) ans = 120.
Quando ocorre a chamada fat(5), o valor 5 passado para a varivel n (o parmetro de entrada de fat). Deste modo, a funo fat calcula o fatorial de n (igual a 5) e retorna o valor contido no parmetro de sada y, ou seja, 120. comum criarmos functions em um arquivo de script separado para ser utilizado em vrios programas. Para isto digitamos a funo em um arquivo com extenso .SCI. Por exemplo, fatorial.sci. Em seguida, usamos a funo exec() do Scilab para carregar o arquivo fatorial.sci para dentro do Scilab. Por exemplo:
--> exec("fatorial.sci");
Neste comando, foi assumido que o arquivo fatorial.sci foi salvo no diretrio atual do Scilab. Use a opo ARQUIVO ALTERAR O DIRETRIO ATUAL ou o comando chdir() para mudar o diretrio atual do Scilab. Uma funo denida pelo usurio tem o mesmo status de uma funo pr-denida do Scilab e, portanto, pode ser usada do mesmo modo. Vejamos um exemplo. Exerccio resolvido 7.3.1. Calcular o seguinte somatrio usando a funo fat denida acima. 10 X SD i D 1 C 2 C : : : C 10
i D1
Soluo:
1 2 3 4 soma = 0; for j=1:10 soma = soma + fat(j); end
Comentrio. Para executar este programa, o usurio deve, antes, carregar a funo fat(). Isto pode ser feito atravs, por exemplo, da funo exec().
7.4
Com as funes possvel escrever um programa e chama-lo quantas vezes quiser em diferentes pontos de um outro programa, geralmente, usando diferentes parmetros de entrada. Se uma funo chamada, o controle de execuo dos comandos transferido para a funo. Quando a funo termina, o controle devolvido ao programa chamador no mesmo local em que a funo foi originalmente chamada (ver Figura 7.1). E o programa chamador continua executando os seus comandos a partir da linha imediatamente depois da chamada da funo. Considere as seguintes funes
77
Figura 7.1: O programa principal chama as funes func1(), func2() e func3(). O controle transferido para as funes, mas sempre retorna ao programa principal. A funo func3() chama func4() transferindo o controle para func4(). A funo func4(), quando termina, retorna o controle ao programa chamador (que func3()).
1 2 3 4 5 6 7 8 1 2 3 4
function y = soma(x) n = length(x); // calcula o tamanho do vetor s = 0; for i=1:n s = s + x(i); end y = s; endfunction function y = media(x) n = length(x); y = soma(x)/n; // chama a funo soma endfunction
No programa principal, a chamada da funo soma() (na linha 5) transfere o uxo de controle para a funo que, ao terminar, devolve o controle para o programa chamador.
78
O programa principal executa o comando da linha seguinte (linha 6) e chama a funo media(). A funo media() chama a funo soma() (linha 3 da funo media()) que devolve o controle para a funo media() que ento devolve o controle para o programa chamador.
7.5
ESCOPO DE VARIVEIS
Relembremos que as variveis denidas no console do Scilab e pelos scripts so armazenadas em uma rea da memria chamada de espao de trabalho. Por exemplo,
--> clear; --> x = 2; --> y = 3; // apaga todas as variveis do espao de trabalho
por que a varivel w no est no espao de trabalho (uma vez no foi denida no console). As variveis denidas pelas funes tambm no so armazenadas no espao de trabalho. Deste modo, estas variveis no so visveis no console. Por exemplo, a varivel p da funo fat() no pode ser usada no console:
--> fat(3) --> p + 1 // gera erro
porque p no esta denida no espao de trabalho. Neste caso, dizemos que p uma varivel local da funo fat(). A seguir introduziremos os conceitos de variveis locais e o globais.
7.5.1
Variveis Locais
Uma varivel dita ser local quando denida dentro de uma funo. Toda varivel local deixa de existir (torna-se invlida) quando a funo nalizada. Por isso, a varivel local dita ser visvel localmente na funo. As variveis locais tambm no podem alterar as variveis do espao de trabalho. Vejamos um exemplo. Considere a seguinte funo:
1 2 3 4 5 6 7 function y = beta(x) a = 3; b = 2; c = 5; printf("a = %g b = %g y = a + b + c + x; endfunction
c = %g\n",a,b,c);
79
1 2 3 4 5
b = %g
c = %g\n",a,b,c);
a = 3 b = 2 c = 5 a = 23 b = 50 c = 200
Note que dentro da funo beta as variveis a, b e c possuem os valores 3, 2, e 5 respectivamente. Ao passo que, fora da funo beta, as variveis a, b e c possuem os valores 23, 50, e 200 respectivamente. A explicao desta discordncia a seguinte: as variveis a, b, e c dentro da funo beta so locais e por isso deixam de existir to logo a funo termine. Scilab armazena as variveis locais da funo em uma local diferente das do espao de trabalho. Portanto, as variveis do espao de trabalho (a = 23, b = 50, c = 200) no so alteradas pela funo. O fato de que as variveis locais s poderem ser usadas internamente pela funo elimina qualquer conito que possa surgir, caso um programa (ou outras funes) resolva utilizar os mesmos nomes de variveis da funo. Uma forma de evitar este comportamento usar as variveis globais.
7.5.2
Variveis Globais
Para alterar as variveis do programa principal, temos que transforma-las em variveis globais usando a declarao global. Por exemplo, considere a seguinte funo:
1 2 3 4 5 6 7 8 9 function y = gama(x) global R; global S; R = 1; S = 2; t = 3; printf("R = %g S = %g y = R + S + t + x; endfunction
t = %g\n",R,S,t);
S = %g
t = %g\n",R,S,t);
R = 1 R = 1
S = 2 S = 2
t = 3 t = 15
7.6 Os Programas do Scilab / UFRN-DCA - 13 de Junho de 2011 Note que as variveis R e S do programa principal foram alteradas dentro da funo gama(). Isto aconteceu porque usamos a comando global. Porm a varivel t no foi alterada pela funo gama() porque no uma varivel global, ou seja, a varivel t no foi declarada como global, permanecendo como uma varivel local. Conclumos que variveis locais so visveis somente dentro na funo, mas variveis globais podem ser visveis tanto dentro como fora de uma funo. Variveis globais so, portanto, uma forma de compartilhar uma varivel entre a funo e o programa chamador. A declarao global deve ser usado tanto no programa chamador como na funo (e em qualquer funo que venha a compartilhar a mesma varivel). A declarao global opcional quando uma varivel, apesar de ser global, no modicada pela funo. Por exemplo, considere a funo:
1 2 3 4 5 function y = eta(x) global S S = x+3; y = R + S; endfunction
80
Boa programao: use caixa alta para nomes de variveis globais para tornar claro ao leitor que so globais e para no confundir com variveis locais.
Claramente, as variveis R e S so globais, mas somente a varivel S foi declarada global por que ela modicada pela funo eta(). A varivel global R no precisa ser declarada global porque no modicada pela funo eta().
7.6
OS PROGRAMAS DO SCILAB
Existem no Scilab dois tipos de programas: 1. Arquivo de comandos. (a) uma sequncia de comandos do Scilab; (b) Possuem extenso de arquivo .SCE (mas no obrigatrio); (c) executado pelo comando exec(); (d) Armazena suas variveis em uma rea chamada Espao de Trabalho (Workplace). 2. Arquivo de funes. (a) uma sequncia de functions (sub-rotinas); (b) Possuem extenso de arquivo .SCI; (c) carregado pelo comando exec(); (d) Armazena suas variveis em uma rea prpria. Essas variveis so chamadas de locais.
81
7.7
PASSAGEM DE PARMETROS
Funes podem ter zero, um ou mais de um parmetros de entrada. Por exemplo, uma funo com o seguinte cabealho possui um parmetro de entrada:
function x = fatorial(n)
Um parmetro de sada pode ser um nmero, um vetor ou uma matriz. A seguinte Funo possui trs parmetros de sada (e trs de entrada):
1 2 3 4 5 6 7 8 9 function [x, y, z] = beta(a, b, c) a = a/2; b = b/2; c = c/2; printf("a=%g b=%g c=%g\n",a,b,c); x = a; y = b; z = c; endfunction
Este programa chama beta() e passa os parmetros r1, r2 e r3 do seguinte modo: o valor de r1 colocado em a, o valor de r2 colocado em b e o valor de r3 colocado em c. Do mesmo modo, a funo retorna os parmetros x, y e z para as variveis d1, d2 e d3, respectivamente. O resultado do programa Resultado a=1 b=2 c=3 a=10 b=20 c=30 d1=1 d2=2 d3=3
7.8
EXEMPLOS
Exerccio resolvido 7.8.1. Ler trs pontos .x1 ; y1 /, .x2 ; y2 / e .x3 ; y3 / do plano cartesiano representando os vrtices de um tringulo. Calcular a rea do tringulo. Da geometria, tem-se o seguinte fato: se a, b e c so as medidas dos lados de um tringulo, ento a rea deste tringulo dada por: p area D s.s a/.s b/.s c/
82
onde s o semi-permetro dado por: aCbCc 2 Para calcular os lados do triangulo ser usado a funo dist para calcular a distncia entre dois pontos .x1 ; y1 / e .x2 ; y2 / no plano cartesiano: sD
1 2 3 function d = dist(x1,y1,x2,y2) d = sqrt((x2-x1)^2+(y2-y1)^2); endfunction
// Clculo dos lados do tringulo a = dist(x1,y1,x2,y2); b = dist(x1,y1,x3,y3); c = dist(x2,y2,x3,y3); s = (a+b+c)/2; // medida do lado A // medida do lado B // medida do lado C // semiperimetro
Exerccio resolvido 7.8.2. Elaborar uma funo inverte() que receba um vetor X. A funo retorna um vetor x invertido. Por exemplo, se a funo recebe |[2 1 8 5]|, ela retorna [5 8 1 2]. Soluo:
1 2 3 4 5 6 function y = inverte(x) n = length(x); for i=1:n y(i) = x(n+1-i); end endfunction
Exerccio resolvido 7.8.3. Muitas funes matemticas podem ser calculadas por meio de um somatrio innito de termos. Em cada caso, a preciso aumenta medida que mais termos na srie so considerados. Um exemplo, a funo cos x : cos x D 1 x2 x4 C 2 4 x6 C 6
Para clculos prticos, este somatrio innito devem terminar aps um nmero nito de termos (penalizando a preciso do resultado). Preparar uma funo para calcular o coseno (funo COSENO.x; n/), com duas variveis de entrada, onde a primeira varivel de entrada x e a segunda varivel de entrada o nmero de termos a serem utilizados nos clculos. Soluo
83
1 2 3 4 5 6 7 8 9 10
function y = coseno(x,n) s = 1; for i=1:n num = x^(2*i); den = fat(2*i); sinal = (-1)^i; s = s + sinal*num/den; end y = s; endfunction
Exerccio resolvido 7.8.4. Elaborar uma funo membro que receba um nmero e um vetor. Uma funo retorna o valor %t se o nmero existe no vetor. Caso contrrio, a funo retorna %f.
7.9
O COMANDO RETURN
Normalmente uma funo termina aps executar a ltima linha. O comando return, porm, pode interromper a execuo de uma function em qualquer ponto do programa. Por exemplo,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 function [maxdc, indic] = mdc(a, b) // Esta funo calcula o mximo divisor de dois // nmeros a e b positivos. // indic retorna 1 se o clculo do m.d.c. teve xito // retorna 0 se os dados de entrada foram // inadequados. indic = 0; maxdc = 0; if round(a) <> a | round(b) <> b return; // Aqui o comando return interrompe // o programa. end if a < 1 | b < 1 return; // Aqui tambm o comando return // interrompe o programa. end if a < b t = a; a = b; b = t; end indic = 1; r = 1;
84
25 26 27 28 29 30 31
7.10
Ser elaborado nesta seo um programa para calcular as seguintes estatsticas de conjuntos de valores digitados pelos usurio e armazenado no vetor x D .x1 ; x2 ; : : : ; xn /. soma.x/ D mdia.x/ D varincia.x/ D
n X i D1
xi
n
1X xi n
i D1
n X .xi
mdia.x//2
O primeiro programa de estatstica mostrado abaixo no emprega a tcnica da subrotina. Tornando-se grande e mais complexo.
85
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
end if opcao == 3 soma = 0; for i=1:n soma = soma + x(i); end media = soma/n; d = 0; for i = 1:n d = d + (x(i)-media)^2; end dpad = sqrt(d/(n-1)); printf("O desvio padro igual a %g",dpad); end if opcao == 4 soma = 0; for i=1:n soma = soma + x(i); end media = soma/n; d = 0; for i = 1:n d = d + (x(i)-media)^2; end var = d/(n-1); printf("A varincia igual a %g",var); end
O programa 2, mostrado a seguir, emprega a tcnica de modularizao, que divide o programa em partes menores tornando-o mais fcil de compreender.
86
22 23 24 25 26 27 28
if opcao == 3 printf("O desvio padro igual a %g",dpad(x)); end if opcao == 4 printf("A varincia igual a %g",var(x)); end
As sub-rotinas:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 // Funo soma function y = soma(x) n = length(x); s = 0; for i=1:n s = s + x(i); end y = s; endfunction // Funo mdia function y = media(x) n = length(x); y = soma(x)/n; endfunction // Funo varincia function y = var(x) n = length(x); m = media(x); d = 0; for i = 1:n d = d + (x(i)-m)^2; end y = d/(n-1); endfunction // Funo Desvio Padro function y = dpad(x) y = sqrt(var(x)); endfunction
Note que para calcular a varincia foi usado a funo mdia, evitando assim a repetio de cdigo. Alis, como j foi dito, evitar a repetio de cdigo uma das vantagens de usar sub-rotinas. A funo length(x) usada no cdigo acima explicada na prxima seo.
7.10.1
O comando SELECT-CASE conveniente para testar se uma expresso igual a uma lista de valores diferentes. A sintaxe do SELECT-CASE :
select <expresso> case <valor1> then <comandos> ... case <valor2> then <comandos> ...
87
case <valor i> then <comandos> ... else <comandos> ... end end
Se <expresso> for igual a <valor1> ento o primeiro case executado. Se <expresso> for igual a <valor2> ento o segundo case executado. E assim por diante. O comando else executado se todas as comparaes do comando case forem falsas.
soma igual a %g\n",soma(x)); mdia igual a %g\n",media(x)); desvio padro igual a %g\n",dpad(x)); varincia igual a %g\n",var(x));
A seguir o programa 3 incrementado em dois aspectos: 1. Usa um loop que repete o menu at o usurio digitar a opo 0; 2. Verica se o usurio digitou uma opo invlida usando o comando ELSE.
1 2 3 4
88
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
printf("Opo 0 - Fim\n"); opcao = input("Digite sua opo"); select opcao case 1 printf("A soma igual a %g\n",soma(x)); case 2 printf("A mdia igual a %g\n",media(x)); case 3 printf("O desvio padro igual a %g\n",dpad(x)); case 4 printf("A varincia igual a %g\n",var(x)); case 0 printf("At a logo\n"); else end end printf("Voc digitou uma opo invlida\n");