Curso de Basic
Código Limpo


  O conceito de código limpo está relacionado à um conjunto de boas práticas de programação, que tem como por objetivo garantir a qualidade do software criado. Envolve aspectos como:   Devido às características da linguagem Basic, é importante aprender desde cedo essas regras, para que o seu programa não se torne algo "monstruoso".

  Aqui vão algumas dicas de como estruturar seu programa em Basic:
  Criar variáveis com nomes relacionados aos dados

  O Basic do MSX tem a limitação de apenas 2 caracteres para dar nome a uma variável. Entretanto, podemos ainda assim observar essa regra.
  Imagine que três variáveis deverão armazenar os seguintes dados: nome, idade e sexo. Veja o seguinte programa:
10 INPUT"NOME";G$
20 INPUT"IDADE";HJ
30 INPUT"SEXO";D$
40 PRINT G$ + " é do sexo " + D$ + " e possui" + STR$(HJ) + " anos"
  Se observarmos apenas a linha 40, fica difícil identificar o significado de cada variável. Reescrevendo o programa da forma correta, ficaria:
10 INPUT"NOME";N$
20 INPUT"IDADE";I
30 INPUT"SEXO";S$
40 PRINT N$ + " é do sexo " + S$ + " e possui" + STR$(I) + " anos"
  O que torna mais simples a identificação das variáveis.


  Procurar seguir o padrão da linguagem

  No capítulo de variáveis, vimos que podemos definir uma variável como string através do comando DEFSTR. Esse mecanismo permite que tenhamos variáveis alfanuméricas com nomes sem o sinal de dólar "$" ao final. Ex:
10 DEFSTR N
20 N="MarMSX"

  Entretanto, é uma convenção do Basic utilizar o dólar ao final de variáveis ou funções do tipo string. No programa anterior, a variável "N" poderia causar uma certa confusão, forçando ao programador identificar o tipo dela através de uma análise minuciosa no código.
  Quando atribuímos a uma variável do tipo string um valor numérico, ou vice-versa, acontece um erro de tipo (Type mismatch). O programador observa a variável "N" sem o dólar ao final e fica se questionando o porquê desse erro.


  Evitar duplicidade de código

  Escrever mais de uma vez a mesma sub-rotina é um erro muito comum para muitos principiantes. Além de deixar o código mais extenso e menos legível, ocupa memória desnecessariamente. No MSX, a área de memória do Basic é bem limitada.
  Exemplo de duplicidade de código: um programa para ler 5 nomes e imprimir o resultado na tela.
10 INPUT"NOME";N$
20 PRINT"Nome 1: "+N$
30 INPUT"NOME 2";N$
40 PRINT"Nome 1: "+N$
50 INPUT"NOME";N$
60 PRINT"Nome 3: "+N$
70 INPUT"NOME";N$
80 PRINT"Nome 4: "+N$
90 INPUT"NOME";N$
100 PRIN "Nome 5: "+N$

  Solução para melhorar o código acima:
10 FOR I=1 TO 5
20 INPUT"NOME";N$
30 PRINT"Nome"+STR$(I)+": ";N$
40 NEXT I

  Outro exemplo é quando temos um trecho de código que é utilizado mais de uma vez pelo programa. Quando isso acontecer, separe o trecho de código que se repete em um bloco a parte (sub-rotina ou função) e o chame através do recurso de GOSUB-RETURN. O capítulo de funções entra em detalhes de como criar esse mecanismo.
  Para exemplificar, seja o código abaixo que desenha 3 estrelas na tela:
10 SCREEN 2
20 LINE(50,30)-(38,35),15
30 LINE(50,30)-(38,24),15
40 LINE(36,10)-(38,24),15
50 LINE(36,10)-(26,20),15
60 LINE(13,18)-(26,20),15
70 LINE(13,18)-(20,29),15
80 LINE(13,41)-(20,29),15
90 LINE(13,41)-(26,39),15
100 LINE(36,49)-(26,39),15
110 LINE(36,49)-(38,35),15
120 LINE(148,85)-(136,90),15
130 LINE(148,85)-(136,79),15
140 LINE(134,65)-(136,79),15
150 LINE(134,65)-(124,75),15
160 LINE(111,73)-(124,75),15
170 LINE(111,73)-(118,84),15
180 LINE(111,96)-(118,84),15
190 LINE(111,96)-(124,94),15
200 LINE(134,104)-(124,94),15
210 LINE(134,104)-(136,90),15
220 LINE(220,150)-(208,155),15
230 LINE(220,150)-(208,144),15
240 LINE(206,130)-(208,144),15
250 LINE(206,130)-(196,140),15
260 LINE(183,138)-(196,140),15
270 LINE(183,138)-(190,149),15
280 LINE(183,161)-(190,149),15
290 LINE(183,161)-(196,159),15
300 LINE(206,169)-(196,159),15
310 LINE(206,169)-(208,155),15
320 GOTO 320
  Observe o tamanho do código resultante. Além disso, dá para identificar aqui que são 3 estrelas sendo desenhadas na tela?

  O código acima poderia ser melhorado:
10 SCREEN 2
20 X=30:Y=30:R=20:RI=10:GOSUB 100
30 X=128:Y=85:R=20:RI=10:GOSUB 100
40 X=200:Y=150:R=20:RI=10:GOSUB 100
50 GOTO 50
100 '
110 ' Desenha estrela
120 '
130 PI=3.14159:AN=PI*2/5
140 FOR A=0 TO 2*PI-.1 STEP AN
150 LINE(X+R*COS(A), Y-R*SIN(A))-(X+RI*COS(A-AN/2), Y-RI*SIN(A-AN/2)),15
160 LINE(X+R*COS(A), Y-R*SIN(A))-(X+RI*COS(A+AN/2), Y-RI*SIN(A+AN/2)),15
170 NEXT A
180 RETURN
  Agora o código é mais elegante, além do programador poder facilmente desenhar quantas estrelas quiser e do tamanho que quiser. Basta forncer as coordenadas centrais X e Y, os raios externos e interno R e RI e chamar a sub-rotina de desenhar a estrela.
  O primeiro código é específico para cada estrela. Já o segundo é genérico e serve para desenhar uma estrela em qualquer lugar da tela. Um bom exemplo de simplicidade de código.


  Evitar sub-rotinas muito longas

  Uma sub-rotina deve tentar preocupar-se somente com as suas responsabilidades. Quando esta possuir muitas tarefas, deverão ser criadas outras sub-rotinas que realizem essas tarefas, desafogando a sub-rotina em questão.
  Exemplo:
10 OP=1:S=100:T=10:GOSUB 100
20 PRINT"Velocidade:";V
30 END
100 '
110 ' Rotina geral
120 '
130 IF OP=1 THEN V = S/T ELSE 150
140 RETURN
150 IF OP=2 THEN M = (A+B)/2 ELSE 170
160 RETURN
170 A = L^2
180 RETURN

  Correção:
10 S=100:T=10:GOSUB 100
20 PRINT"Velocidade:";V
30 END
100 '
110 ' Calcula a velocidade
120 '
130 V = S/T
140 RETURN
150 '
160 ' Calcula a média
170 '
180 M = (A+B)/2
190 RETURN
200 '
210 ' Calcula a área do quadrado
220 '
230 A = L^2
240 RETURN
  Agora cada sub-rotina é responsável por sua tarefa específica.


  Separar as sub-rotinas em blocos contíguos no código

  Devemos evitar trechos de códigos relacionados à solução de um determinado problema intercalados, pois assim fica muito mais difícil entender a lógica do programa.
  Exemplo: o programa a seguir denha um hexágono e um quadrado.
10 SCREEN 2
20 LINE(50,30)-(40,47),15
30 LINE(40,12)-(50,30),15
40 LINE(100,100)-(150,100),15
50 LINE(20,12)-(40,12),15
60 LINE(150,100)-(150,120),15
70 LINE(10,29)-(20,12),15
80 LINE(150,120)-(100,120),15
90 LINE(100,120)-(100,100),15
100 LINE(19,47)-(10,29),15
110 LINE(40,47)-(19,47),15
  O código de desenho do hexágono está misturado com o código de desenho do quadrado. Que confusão!

  Corrigindo:
10 SCREEN 2
20 ' Hexágono
30 LINE(50,30)-(40,47),15
40 LINE(40,12)-(50,30),15
50 LINE(20,12)-(40,12),15
60 LINE(10,29)-(20,12),15
70 LINE(19,47)-(10,29),15
80 LINE(40,47)-(19,47),15
90 ' Quadrado
100 LINE(100,100)-(150,100),15
110 LINE(150,100)-(150,120),15
120 LINE(150,120)-(100,120),15
130 LINE(100,120)-(100,100),15


  Colocar uma identificação logo no inicio das sub-rotinas, utilizando-se de comentários

  A listagem do código do Basic do MSX não possui etiquetas de marcação para que possamos discriminar trechos de código. Dessa forma, utilizamos o recurso de comentários para marcar o inicio de sub-rotinas. O comentário no Basic é feito através do comando REM ou do símbolo de aspas simples '.
  Um exemplo de código com sub-rotinas sem marcação:
10 S=100:T=10:GOSUB 100
20 PRINT"Velocidade:";V
30 A=2:B=4:GOSUB 120
40 PRINT"Média:";M
50 L=10:GOSUB 140
60 PRINT"Área:";A
70 END
100 V = S/T
110 RETURN
120 M = (A+B)/2
130 RETURN
140 A = L^2
150 RETURN

  Agora, com a marcação:
10 S=100:T=10:GOSUB 100
20 PRINT"Velocidade:";V
30 A=2:B=4:GOSUB 150
40 PRINT"Média:";M
50 L=10:GOSUB 200
60 PRINT"Área:";A
70 END
100 '
110 ' Calcula a velocidade
120 '
130 V = S/T
140 RETURN
150 '
160 ' Calcula a média
170 '
180 M = (A+B)/2
190 RETURN
200 '
210 ' Calcula a área do quadrado
220 '
230 A = L^2
240 RETURN
  Agora fica mais fácil discriminar o código e localizar as sub-rotinas.


  Evitar desvios desnecessários

  O Basic é uma linguagem não estruturada, de execução seqüêncial e que utiliza bastante instruções de desvio. Dessa forma, o programa poderá se tornar um "código espaguete".
  Um "código espaguete" é aquele que possui diversos desvios de forma desordenada, onde o fluxo de execução se assemelha a um prato de espaguete, onde os fios de macarrão estão todos entrelaçados.

  Exemplo de código espaguete:
10 CLS
20 GOSUB 90
30 PRINT"Nome: "+N$
40 GOSUB 110
50 PRINT"Idade:";I
60 GOSUB 130
70 PRINT"Profissão: "+P$
80 END
90 INPUT"Nome";N$
100 RETURN 
110 INPUT"Idade";I
120 RETURN
130 INPUT"Profissão";P$
140 RETURN

  O código reescrito sem desvios:
10 CLS
20 INPUT"Nome";N$
30 INPUT"Idade";I
40 INPUT"Profissão";P$
50 PRINT"Nome: "+N$
60 PRINT"Idade:";I
70 PRINT"Profissão: "+P$



MARMSX/CURSOS/Basic