Curso de Basic
Começando a Programar


  O objetivo deste capítulo é apresentar o funcionamento de um programa em Basic, bem como as principais estruturas utilizadas para o controle do programa.


  Fluxo de execução do programa

  Um programa em Basic é uma listagem numerada, disposta de forma crescente.
  O programa começa a executar seqüencialmente as linhas, a partir da linha de menor valor. Ex:
 10 F=100
 20 G=25
V 30 H=G+F
  A primeira linha a ser executada nesse exemplo é a linha 10, que possui uma instrução que faz com que a variável "F" receba o valor igual a 100.
  A segunda linha executada é a linha 20, onde a variável "G" recebe o valor igual a 25.
  A última linha a ser executada é a linha 30, que realiza a operação de soma entre as variáveis "F" e "G" e armazena o resultado na variável "H".

  Após a execução da última linha, o programa termina.
  Pode-se colocar a instrução "END" para indicar o término de um programa, mas não é obrigatório. Entretanto, há situações em que o uso do END é obrigatório. Mais adiante veremos quando ele é necessário.


  Desvios - GOTO, GOSUB-RETURN

  Os comandos de desvio servem para interromper a execução seqüêncial do programa em Basic, de modo a desviá-lo para uma determinada linha. Ex:
10 PRINT"LINHA 10"
20 GOTO 40
30 PRINT"LINHA 30"
40 PRINT"LINHA 40"
  Saída:
  LINHA 10
  LINHA 40

  O programa desvia na linha 20 para a linha 40, saltando a execução da linha 30. Veja como funciona o salto:
10 PRINT"LINHA 10"
20 GOTO 40         ───┐
30 PRINT"LINHA 30"    
40 PRINT"LINHA 40" <──┘

  O comando GOTO desvia a execução do programa sem criar um ponto de retorno. Já a instrução GOSUB cria um ponto de retorno na instrução imediatamente após ela.
  A instrução GOSUB deve ser acompanhada do RETURN, que tem como objetivo retornar ao ponto estabelecido. Ex:
10 PRINT"LINHA 10"
20 GOSUB 40    x  ← ponto de retorno
30 PRINT"LINHA 30" 
40 PRINT"LINHA 40"
50 RETURN
  Saída:
  LINHA 10
  LINHA 40
  LINHA 30
  LINHA 40
  RETURN without GOSUB in 50

  O respectivo fluxo desse salto com retorno é:
 10 PRINT"LINHA 10"
┌───┘ 20 GOSUB 40           x ─┐
 30 PRINT"LINHA 30"    │  │
└──>  40 PRINT"LINHA 40" │  │  │
      50 RETURN          └──┘  V

  Primeiramente, a mensagem "LINHA 10" é impressa na linha 10.
  Na linha 20, o programa é desviado para a linha 40. O ponto de retorno é a instrução seguinte ao GOSUB.
  Na linha 40, a mensagem "LINHA 40" é impressa.
  Na linha 50, o retorno relativo ao GOSUB da linha 20 é chamado, retornando a essa linha.
  Ao retornar para a linha 20, ele executa a instrução imediatamente seguinte ao GOSUB. Como não há instrução alguma, o programa passa para a linha 30.
  Na linha 30, a mensagem "LINHA 30" é impressa.
  Na linha 40, a mensagem "LINHA 40" é impressa.
  Na linha 50, a instrução RETURN é chamada novamente, mas sem que um GOSUB tenha sido utilizado (pois o primeiro já foi descartado). Nesse caso, um erro de "RETURN without GOSUB" acontece.

  Para que esse erro não aconteça, devemos indicar o término do programa após executar a linha 30, utilizando a instrução "END". Assim, ela dever ser colocada entre as linhas 30 e 40 do programa.
10 PRINT"LINHA 10"
20 GOSUB 40
30 PRINT"LINHA 30"
35 END
40 PRINT"LINHA 40"
50 RETURN
  Saída:
  LINHA 10
  LINHA 40
  LINHA 30

  No exemplo a seguir, vamos inserir uma instrução após o GOSUB e observar o resultado.
10 PRINT"LINHA 10"
20 GOSUB 40 : PRINT"LINHA 20"
30 PRINT"LINHA 30"
35 END
40 PRINT"LINHA 40"
50 RETURN
  Saída:
  LINHA 10
  LINHA 40
  LINHA 20
  LINHA 30

  Após retornar na linha 50, o programa procura pela próxima instrução após o GOSUB que é PRINT"LINHA 20".


  Entendendo o mecanismo do GOSUB-RETURN

  A cada chamada da instrução GOSUB, o número da linha e a próxima instrução são colocados em uma pilha, que está inicialmente vazia.
  A instrução RETURN quando é executada, procura essas informações topo da pilha e desvia o programa para lá.
  Quando a pilha está vazia, a instrução RETURN gera um erro chamado "RETURN without GOSUB", seguido do número da linha onde o RETURN foi executado. Ex:
10 GOSUB 40
20 RETURN
30 END
40 GOSUB 60
50 RETURN
60 PRINT"Olá"
70 RETURN
  Saída:
  Olá
  RETURN without GOSUB in 20

  O fluxo de execução desse programa, bem como o funcionamento da pilha do GOSUB-RETURN, pode ser visto a seguir:
Linha | Próx  |
Atual | Linha | Pilha
------+-------+------
  -   |  10   |  -
  10  |  40   |  10:end
  40  |  60   |  10:end, 40:end
  60  |  70   |  10:end, 40:end
  70  |  40   |  10:end
  40  |  50   |  10:end
  50  |  10   |  -
  10  |  20   |  -
  20  |  -    |  -        * Erro no RETURN (pilha vazia)


  Sub-rotinas com o GOSUB-RETURN

  O mecanismo de GOSUB-RETURN permite utilizar o recurso de sub-rotinas, que são trechos de códigos que realizam determinadas tarefas. Elas são chamadas, desviando-se o programa do ponto atual para ela, depois retornando à proxima linha em relação ao ponto de chamada. Ex:
10 A=10
20 B=54
30 GOSUB 100
40 PRINT "Resultado:";C
50 END
100 '
110 ' Sub-rotina para somar dois números
120 '
130 C=A+B
140 return
  Saída:
  Resultado: 64

  A sub-rotina pode ser chamada quantas vezes o necessário com o GOSUB, pois sempre haverá um par GOSUB-RETURN para ela.
  No capítulo de funções, veremos como criar funções utilizando esse recurso.


  Estruturas de repetição - FOR, GOTO

  Essas estruturas têm como por objetivo repetir um conjunto de instruções, quantas vezes o necessário.

  Sintaxe para o FOR:
FOR variável_de_controle = valor_inicial TO valor final [STEP valor_do_passo]
' Trecho de código a ser repetido
NEXT variável_de_controle
  Exemplo:
10 FOR I=1 TO 3
20 PRINT I
30 NEXT I
  Saída:
  1
  2
  3

  A cada repetição desse laço, o valor da variável "I" aumenta em uma unidade, pois é o valor de incremento padrão. Entretanto, o valor do incremento pode ser modificado pela opção STEP. Ex:
10 FOR I=1 TO 3 STEP 2
20 PRINT I
30 NEXT I
  Saída:
  1
  3

  O valor do incremento pode ser negativo e/ou real. Ex:
10 FOR I=3 TO 1 STEP -1
20 PRINT I
30 NEXT I
40 PRINT
50 FOR J=1 TO 2 STEP .5
60 PRINT J
70 NEXT J
  Saída:
  3
  2
  1

  1
  1.5
  2


  Condição de parada do laço FOR

  A condição de parada do laço FOR é quando a variável de controle "VC" ultrapassar o valor final "VF" estabelecido. Nesse caso, temos:
VC > VF : ' Caso laço progressivo
VC < VF : ' Caso laço regressivo

  Importante: caso o valor final seja ultrapassado, ele não será utilizado. Ex:
10 FOR I=1 TO 6 STEP 4
20 PRINT I
30 NEXT
  Saída:
  1
  5

  Outra observação é que não é necessário indicar a variável de controle para laços FOR simples, como visto na linha 30.


  Cuidados

  A variável de controle utilizada não deverá ser modificada dentro do laço de repetição. Caso contrário, o programa poderá perder o controle. Ex:
10 FOR I=1 TO 10
20 PRINT I
30 I=1
40 NEXT I
  Saída:
  1
  2
  2
  2
  ...

  A instrução NEXT incrementa o valor da variável "I", mas como à ela está sempre sendo atribuído o valor 1 na linha 30, o programa roda infinitamente.


  Laços FOR aninhados

  Podemos criar laços FOR aninhados, ou seja, um dentro do outro, de forma que as instruções FOR mais internas rodam primeiro que as mais externas. Ex:
10 FOR A=1 TO 2
20 FOR B=1 TO 3
30 PRINT "A=";A;"B=";B
40 NEXT B
50 NEXT A
  Saída:
  A= 1 B= 1
  A= 1 B= 2
  A= 1 B= 3
  A= 2 B= 1
  A= 2 B= 2
  A= 2 B= 3

  Observe que a variável "B" é incrementada primeiro que a variável "A", uma vez que ela está no laço mais interno.
  Assim que o laço FOR relativo à variável "B" termina, "A" incrementa uma unidade e o laço do "B" começa mais uma vez.

  A linha 40 poderia ser substituída pela instrução "NEXT B,A" e a linha 50 poderia ser apagada. É uma forma alternativa. Nesse caso, as instruções NEXT devem conter as variáveis de controle sempre na ordem da mais interna para a mais externa.

  Importante: não confundir laços aninhados com laços seqüenciais, como o mostra exemplo a seguir.
10 FOR A=1 TO 2
20 PRINT "A=";A
30 NEXT A
40 FOR B=1 TO 3
50 PRINT "B=";B
60 NEXT B
  Saída:
  A= 1
  A= 2
  B= 1
  B= 2
  B= 3

  Nesse caso, o laço de "A" executa completamente antes do laço do "B" começar. Assim, "A" e "B" estão em laços seqüenciais.


  Utilizando mais de uma variável de controle para o FOR

  Se desejarmos controlar mais de uma variável dentro do mesmo laço FOR, devemos sempre associar essas variáveis à variável de controle do FOR.
  Por exemplo, sejam as variáveis "I" e "J", onde cada uma possui valor inicial e final próprios. Assim, "I" varia de 1 a 10 e "J" de 4 a 8. Como fazê-los variar de forma independente?
  A solução é utilizar "I" como variável de controle e "J" associado a "I" através de uma regra de três. Dessa forma, temos:
10 ┬   ┬ 8
   │   │
i  ┤   ├ j
   │   │
1  ┴   ┴ 4
 i-1     j-4
----- = -----
10-1     8-4
(i-1).4 = (j-4).9
4i - 4 = 9j - 36
j = (4i + 32)/9

  Dessa forma, a equação que relaciona "J" com "I" é:
J = (4*I + 32)/9

  O programa em Basic que fará o incremento das duas variáveis de forma independente é:
10 FOR I=1 TO 10
20 J = (4*I + 32) / 9
30 PRINT "I=";I;"J=";INT(J)
40 NEXT I
  Saída:
  A= 1 B= 4
  A= 2 B= 4
  A= 3 B= 4
  A= 4 B= 5
  A= 5 B= 5
  A= 6 B= 6
  A= 7 B= 6
  A= 8 B= 7
  A= 9 B= 7
  A= 10 B= 8


  Uma alternativa para o FOR

  O comando de desvio GOTO pode ser utilizado para criar laços de repetição, se for direcionado à linhas anteriores. Entretanto, essa repetição se torna infinita.
  Para resolver esse problema, é necessário criar uma condição de saída dessa estrutura de repetição.
10 PRINT"Isto é repetitivo"
20 GOTO 10
  Saída:
  Isto é repetitivo
  Isto é repetitivo
  ...

  A execução só pára quando o usuário pressiona as teclas CONTROL + STOP.

  Devemos então, utilizar uma condição de parada, conforme visto anteriormente. Assim, temos:
10 A=1
20 IF A>2 THEN END
30 PRINT"Isto é repetitivo"
40 A=A+1
50 GOTO 20
  Saída:
  Isto é repetitivo
  Isto é repetitivo

  A linha 20 testa se a condição de parada foi atingida. Já a linha 40 é responsável por incrementar a variável de controle "A". Caso a variável "A" não fosse alterada, a condição de parada não seria atingida e o programa rodaria infinitamente.
  Dessa forma, o programa genérico que é equivalente ao laço FOR é:
10 VC=1 : VF=2 : ST=1
20 IF VC>VF THEN END
30 ' Rotina
40 VC=VC+ST
50 GOTO 20

  Onde:
  Entretanto, foi visto que o FOR possui incrementos e decrementos na variável de controle.
  De forma a corrigir esse problema, temos:
10 VC=1 : VF=2 : ST=1
20 IF (VC>VF AND ST>=0) OR (VC<VF AND ST<0) THEN END
30 ' Rotina
40 VC=VC+ST
50 GOTO 20

  Exemplos:
10 A=1 : VF=3 : ST=1
20 IF (A>VF AND ST>=0) OR (VC<A AND ST<0) THEN END
30 PRINT A
40 A=A+ST
50 GOTO 20
  Saída:
  1
  2
  3

10 A=2 : VF=1 : ST=-1
20 IF (A>VF AND ST>=0) OR (VC<A AND ST<0) THEN END
30 PRINT A
40 A=A+ST
50 GOTO 20
  Saída:
  2
  1

  Obs: é possível utilizar o STEP igual a 0. Nesse caso, o programa roda infinitamente.


  Decisões - IF

  Na execução do programa, às vezes é necessário tomar algumas decisões, baseadas em algum tipo de informação.
  Conforme foi visto na seção anterior, era necessário testar o valor da variável "A" para tomar a decisão de seguir o laço ou parar.
  O comando IF realiza um teste lógico de verdadeiro ou falso, a partir de um ou mais valores de entrada fornecidos (constante ou uma variável).

  Sintaxe do IF:
IF expressao_logica THEN decisão_caso_verdadeiro ELSE decisão_caso_falso
  A "expressão_lógica" é quem irá conter os valores de entradas a serem testados por meio dos operadores relacionais ou lógicos (vide capítulo de operadores).

  Exemplo:
A=6 
IF A > 4 THEN PRINT"Maior que 4" ELSE PRINT"Menor ou igual a 4" 
Maior que 4
Ok
  A expressão lógica nesse caso é: "A > 4".
  Como "A" tem o valor armazenado igual a 6, e 6 é maior que 4, o teste retorna verdadeiro.
  Em caso de verdadeiro, ele executa a sentença relativa ao THEN:
A=6 
IF A > 4 THEN PRINT"Maior que 4" ELSE PRINT"Menor ou igual a 4"
Maior que 4
Ok

  Caso o teste retornasse um valor falso, a sentença do ELSE é quem era executada:
A=3 
IF A > 4 THEN PRINT"Maior que 4" ELSE PRINT"Menor ou igual a 4" 
Menor ou igual a 4
Ok

  Outros exemplos:
IF 4 < A THEN PRINT"Maior que 4" ELSE PRINT"Menor ou igual a 4" 
Maior que 4
Ok

IF 3 > 6 THEN PRINT"Três é maior que seis" ELSE PRINT"Três é menor ou igual a seis" 
Três é menor ou igual a seis
Ok
  A expressão lógica no primeiro caso é "4 < A". Já no segundo, é "3 > 6".


  IFs em cascata

  Pode-se realizar testes IF em castata. Para ilustrar isso, vamos corrigir o primeiro exemplo, de modo que capte também a situação de quando o número for igual a 4:
10 INPUT"A";A
20 IF A > 4 THEN PRINT"Maior que 4" ELSE IF A = 4 THEN 
PRINT"Igual a 4" ELSE PRINT"Menor que a 4"
30 GOTO 10
  Saída:
  A? 6
  Maior que 4
  A? 4
  Igual a 4
  A? 2
  Menor que 4

  Nesse caso, podemos tomar 3 decisões distintas a partir do mesmo valor a ser testado.

  Para a primeira situação (A > 4), temos:
IF A > 4 THEN PRINT"Maior que 4" ELSE IF A = 4 THEN 
PRINT"Igual a 4" ELSE PRINT"Menor que a 4"

  Para a segunda situação (A = 4), temos:
IF A = 4 THEN PRINT"Igual a 4" ELSE PRINT"Menor que a 4"

  Caso não se encaixe em nehuma das duas situações (A < 4), temos:
ELSE PRINT"Menor que a 4"

  Como saber quais os testes que devo fazer? Depende de cada situação.
  No exemplo anterior, queríamos testar um número qualquer com o valor 4. Há 3 possibilidades para isso: ser maior, igual ou menor.
  O teste do IF vei tentanto achar o caminho correto, de acordo com os testes realizados.
  No caso de A=2 do exemplo acima, os dois primeiros testes falharam. Logo, a resposta está no último caminho. O fluxograma abaixo ilustra isso.
   Lê A
     |
     |  f→
    A>4----+
     |v     |
     |↓     |  f→
     |     A=4----+
     |      |v     |
     |      |↓     |
     |      |      |
 Decisão Decisão Decisão
    1       2       3

  O uso do tratamento de falha (ELSE) é facultativo. Entretanto, o tratamento para o sucesso do teste (THEN) é obrigatório. Ex:
IF A > 4 THEN PRINT "Maior que 4"

  Podemos utilizar mais de um comando para o tratamento de cada evento, separados por dois pontos. Ex:
A=6 
IF A>4 THEN PRINT"A":PRINT"B" ELSE PRINT"C":PRINT"D" 
A
B
Ok

IF A<4 THEN PRINT"A":PRINT"B" ELSE PRINT"C":PRINT"D" 
C
D
Ok

  Para tratamentos mais complexos, podemos utilizar o recurso de chamadas à sub-rotinas através dos comandos GOSUB RETURN. Ex:
10 IF A>4 THEN GOSUB 500 ELSE GOSUB 1000

  Caso deseje-se utilizar o desvio com o GOTO, pode-se colocar apenas o número da linha desejada. Ex:
IF A>7 THEN 50 ELSE 150
  Nesse caso, não será mais possível retornar ao ponto de partida. No caso do uso da instrução RETURN, a mensagem "RETURN without GOSUB" é emitida.


  ON GOSUB / ON GOTO

  O objetivo do ON GOSUB ou do ON GOTO é testar uma varável e, de acordo com o valor lido, tomar uma decisão. Essas expressões lembram o comando case of do Pascal ou o switch do C.

  Sintaxes:
ON variável GOSUB caso=1, caso=2, caso=3, ...
ON variável GOTO caso=1, caso=2, caso=3, ...

  A diferença entre GOSUB e GOTO é que a primeira possui ponto de retorno e a segunda não.

  Exemplo:
10 INPUT"Opção 1-3";OP
20 IF OP<1 OR OP>3 THEN 10
30 ON OP GOSUB 50,70,90
40 END
50 PRINT"Opção 1"
60 RETURN
70 PRINT"Opção 2"
80 RETURN
90 PRINT"Opção 3"
100 RETURN


  READ / DATA

  A instrução DATA permite o armanezamento de dados dentro do programa, para posterior leitura deste em uma variável, através da instrução READ.

  A instrução READ não é executável, ou seja, quando o interpretador Basic encontra essa instrução, ele a ignora e passa à instrução seguinte.
  A instrução DATA pode ser colocada em qualquer parte do programa e a ordem de leitura dos dados é a ordem de aparição das instruções DATA.
  As strings não precisam estar entre aspas. Entretanto, se possuirem vírgula ou dois pontos, deverão aparecer entre aspas.

  Sintaxe:
READ variavel_1, variável_2, ...

  Seja o seguinte programa que armazena o nome de três itens:
10 IA$="Tomate"
20 IB$="Cebola"
30 IC$="Pimentão"
40 PRINT "Item 1: "; IA$
50 PRINT "Item 2: "; IB$
60 PRINT "Item 3: "; IB$

  Utilizando-se a instrução DATA, o armazenamento dos dados fica mais organizado:
10 FOR F=1 TO 3
20 READ I$
30 PRINT "Item" + STR$(F) + ": ";I$
40 NEXT F
50 DATA Tomate, Cebola, Pimentão

  Saída em ambos os casos:
  Item 1: Tomate
  Item 2: Cebola
  Item 3: Pimentão

  Conforme dito anteriormente, a ordem de leitura dos dados da instrução DATA é a ordem de aparição dela no programa. Veja o exemplo a seguir:
10 DATA 1,2,3
20 FOR I=1 TO 8
30 DATA 4,5
40 READ A
50 PRINT A;" ";
60 DATA 6,7,8
70 NEXT I
  Saída:
  1 2 3 4 5 6 7 8

  Podemos colocar diferentes tipos de dado nas instruções DATA. Entretanto, a instrução READ deverá ler o tipo de dado correspondente ao tipo variável que está sendo utilizada.
  Veja o exemplo a seguir:
10 FOR F=1 TO 3
20 READ I$, P
30 PRINT "Item" + STR$(F) + ": ";I$;" -";P
40 NEXT F
50 DATA Tomate, 1.25, Cebola, 0.88, Pimentão, 2.35
  Saída:
  Item 1: Tomate - 1.25
  Item 2: Cebola - .88
  Item 3: Pimentão - 2.35

  A instrução RESTORE indica em que linha a próxima instrução READ irá ler os dados. Ex:
10 PRINT"Você quer que eu liste 5 cidades de qual estado?"
20 PRINT"1- Rio de Janeiro"
30 PRINT"2- São Paulo"
40 PRINT"3- Minas Gerais"
50 INPUT E
60 IF E=1 THEN RESTORE 120 ELSE IF E=2 THEN RESTORE 130 ELSE RESTORE 140
70 FOR I=1 TO 5
80 READ C$
90 PRINT C$
100 NEXT I
110 PRINT : GOTO 10
120 DATA Angra dos Reis, Cabo Frio, Petrópolis, Itaperuna, Parati
130 DATA Jaú, Bauru, Campinas, Santos, Aparecida
140 DATA Juiz de Fora, Tiradentes, Uberlândia, Uberaba, Poços de Calda



MARMSX/CURSOS/Basic