Prévia do material em texto
Linguagem Java: conceitos
essenciais de desenvolvimento para
dispositivos móveis
Apresentação
Para o desenvolvimento de aplicativos Android é utilizada a linguagem de programação Java que,
não por acaso, é uma das linguagens de programação mais utilizada no mundo. De certa forma foi
uma escolha lógica para a plataforma Android, levando em conta que Java é uma linguagem de
programação poderosa, gratuita, com o código-fonte aberto e milhões de desenvolvedores já
conhecem a linguagem.
A linguagem Java é orientada a objetos e conta com uma ampla biblioteca de classes, que ajuda o
desenvolvedor a construir aplicações poderosas em menor tempo, visto que fornece recursos
prontos para o desenvolvedor configurá-las e utilizá-las da forma que achar adequado.
Nesta Unidade de Aprendizagem, você vai conhecer a linguagem Java, seu conceito de classes e
seus principais tipos de dados. Também irá estudar o conceito de orientação a objetos em Java,
analisando vários recursos disponíveis na linguagem, visando a desenvolver uma visão sólida da
linguagem Java aplicada ao desenvolvimento de aplicativos Android.
Bons estudos.
Ao final desta Unidade de Aprendizagem, você deve apresentar os seguintes aprendizados:
Descrever as características da linguagem Java: classes e tipos de dados.•
Identificar os principais conceitos de programação orientada a objetos com Java.•
Operacionalizar a utilização do Java como linguagem-base para o desenvolvimento de
aplicações Android.
•
Infográfico
Recursos em um dispositivo móvel atualmente podem não ser extremamente limitados como no
passado. Porém, o seu uso consciente é recomendável por vários motivos. Um exemplo é o
consumo de bateria que, normalmente, é um recurso crítico do dispositivo móvel. Logo, alto
processamento e grandes quantidades de memoria RAM em uso consomem quantidades
substanciais de bateria do dispositivo, limitando o seu tempo útil sem a necessidade de recarregar a
bateria.
Confira, no Infográfico, mais informações sobre como minimizar o uso de processamento e
memória RAM consumidos por seu aplicativo Android, utilizando de forma consciente os tipos de
dados disponíveis no Java.
Aponte a câmera para o
código e acesse o link do
conteúdo ou clique no
código para acessar.
https://statics-marketplace.plataforma.grupoa.education/sagah/d815ba0b-e6ce-4fc8-aa80-454eee539694/8a9c9250-7b01-455b-80d8-07b7f7d6e45e.jpg
Conteúdo do livro
Existem diversas linguagens de programação disponíveis no mercado, cada uma com suas
características e funcionalidades. Dentre todas as possibilidades, o Android selecionou o Java como
a linguagem indicada para o desenvolvimento de seus aplicativos. É possível elencar diversos
motivos para isso. Antes mesmo do Android existir, o Java já era uma das linguagens de
programação mais utilizadas no mundo e já tinha versões destinadas às mais diversas áreas,
inclusive dispositivos móveis.
Logo, a escolha do Java para o Android foi um ponto chave para a plataforma, uma vez que já era
uma linguagem madura, utilizada na área em que o Android iria atuar e tinha as características de
uma linguagem de programação moderna, possibilitando, por exemplo, a orientação a objetos. Java
já tinha uma ampla quantidade de bibliotecas, fornecendo recursos e funcionalidades para o
desenvolvedor criar aplicações complexas em um curto espaço de tempo.
No capítulo Linguagem Java: conceitos iniciais, da obra Desenvolvimento para dispositivos móveis,
você vai conhecer as características da linguagem de programação Java, identificando as
funcionalidades de suas classes e os seus diversos tipos de dados disponíveis para utilização.
Também irá compreender, por meio de exemplos práticos, o conceito de linguagem de
programação orientada a objetos, bem como as funcionalidades que tais características
disponibilizam ao desenvolvedor. Verá ainda as funções presentes na linguagem para realização de
operações, tomada de decisão e diversos outros recursos imprescindíveis para o desenvolvimento
de um aplicativo Android.
Boa Leitura.
DESENVOLVIMENTO
PARA DISPOSITIVOS
MÓVEIS
Diego Bittencourt de Oliveira
Linguagem Java:
conceitos essenciais
Objetivos de aprendizagem
Ao final deste texto, você deve apresentar os seguintes aprendizados:
� Descrever as características da linguagem Java, como suas classes e
tipos de dados.
� Identificar os principais conceitos de programação orientada a objetos
com Java.
� Operacionalizar a utilização do Java como linguagem base para o
desenvolvimento de aplicações Android.
Introdução
Neste capítulo você conhecerá a linguagem de programação Java, que
é a linguagem de programação nativa da plataforma Android. Por ser
muito popular, esta linguagem foi a escolha mais adequada como lin-
guagem de programação padrão da plataforma. Isso se deve ao fato de
existirem muitos desenvolvedores experientes nesta linguagem. Assim,
a plataforma já inicia com milhões de desenvolvedores especializados
em sua linguagem de programação base.
O Java também é uma linguagem de programação potente, sendo
totalmente orientada a objetos, além de possuir uma enorme biblioteca
de classes muito sólida e atualizada de forma regular. No decorrer deste
capítulo, conheceremos melhor as características das classes Java, bem
como os tipos de dados que a linguagem de programação disponibiliza
para o seu desenvolvedor.
Veremos, também, os conceitos de programação orientada a objetos
com Java e aprenderemos, ainda, a utilizar Java como linguagem padrão
para o desenvolvimento de aplicações para Android.
Linguagem Java: classes e tipos de dados
Segundo Deitel, Deitel e Deitel (2015), a linguagem Java para aplicativos
Android é semelhante e, ao mesmo tempo, muito diferente de outras aplicações
desenvolvidas nesta linguagem. Um desenvolvedor com experiência em Java
terá facilidade em desenvolver aplicativos para Android, mas compreenderá
a diferença mencionada. Já um desenvolvedor com pouca experiência nesta
linguagem deve buscar se familiarizar.
Como já mencionado, Java é uma linguagem de programação orientada a
objetos, ou seja, baseada na modelagem de objetos e na comunicação que estes
possuem entre si. Em uma situação de analogia a um objeto real, pode-se definir
o objeto caneca, algumas de suas propriedades seriam a cor, a capacidade
máxima e a quantidade de café que possui. Em uma linguagem orientada a
objetos, podemos definir objetos canecas e acessar suas propriedades.
Poderíamos também enviar mensagens para os objetos, questionando-
-os sobre a quantidade de café existente em cada caneca. Assim, é possível
observar que é possível criar e manipular qualquer objeto, fazendo com que
estes realizem diversas funções em um aplicativo.
Em uma situação mais cotidiana da plataforma Android, temos o objeto
câmera, que representa a câmera física do dispositivo. Por meio deste objeto,
podemos manipular a câmera para que tire uma foto com base nas propriedades
que definimos e nos métodos que chamamos para configurá-la.
Antes de criarmos uma classe que represente um objeto, temos de estudar
os tipos de dados disponíveis, uma vez que a programação é basicamente
um trabalho com dados. Segundo Goodrich e Tamassia (2013), Java possui
basicamente dois grupos de tipos de dados:
� tipos primitivos — correspondem a dados mais simples ou escalares;
� tipos por referência — correspondem a tipos de dados representados
por classes, ou seja, todos os outros tipos de dados não primitivos.
Na Figura 1, podemos observar os tipos primitivos de dados existentes
na linguagem Java, bem como os limites de valores que estes tipos podem
armazenar. Por exemplo, uma variável do tipo byte não pode armazenar o
valor 400, visto que esta só armazena dados até 127 positivo.
Linguagem Java: conceitos essenciais2
Figura 1. Tipos primitivos de dados.
Fonte: Schützer e Massago (2008, documento on-line).
Os tipos por referência são classes, conforme já citamos e, por convenção
denomenclatura, as classes em Java são nomeadas com a primeira letra do
nome em maiúsculo. Por exemplo, Goodrich e Tamassia (2013) relatam que
String é um dos tipos de dados por referência mais comuns da linguagem
Java, sendo que a String é basicamente uma lista de elementos char.
Ou seja, podemos armazenar a frase “Android é uma boa plataforma” em
uma variável do tipo String, em que cada uma das letras seria um char.
3Linguagem Java: conceitos essenciais
Na linguagem Java você pode inserir frases e comentários junto ao código do seu
aplicativo, sem que estas informações realizem qualquer interferência no fluxo do
programa. Abaixo temos um exemplo:
//Este é um comentário de uma linha
O texto após as // não é interpretado pelo compilador do Java, ou seja, serve para
que os desenvolvedores escrevam informações pertinentes no código, seja para
identificar o que um determinado trecho de código faz ou outra informação qualquer.
Também podemos criar comentários de várias linhas em Java. Neste caso, o comentário
é realizado utilizando um bloco, conforme exemplo abaixo (o comentário inicia com
/* e é finalizado com */):
/* Início do comentário,
Segunda linha do comentário e o
Final do comentário */
Uma variável é basicamente um recipiente que possui um determinado
tipo, sendo que este define o tipo de dado que a variável irá armazenar. Isso se
deve ao fato de a linguagem Java ser estaticamente “tipada”, ou seja, devemos
informar ao Java o tipo da variável que estamos definindo. Abaixo temos um
exemplo:
String Cliente = "Alberto Ribeiro";
No exemplo acima, criamos uma variável do tipo String, cujo nome é
Cliente. Ainda podemos identificar o operador de atribuição = (veremos
adiante outros operadores, sendo o operador de atribuição = um dos mais
básicos da linguagem Java) e o valor que está sendo atribuído Alberto
Ribeiro, no final temos o identificador do final do comando ;. Ou seja,
na variável Cliente temos o texto indicado, sendo o valor armazenado na
variável que criamos.
Linguagem Java: conceitos essenciais4
O conceito básico de uma classe é apresentado abaixo, em que temos
uma classe Pessoa com um atributo do tipo String chamado nome e um
construtor (void Pessoa(String nome)) que inicializa o atributo nome
com o valor, passado no construtor:
class Pessoa {
String nome;
Pessoa(String nome) {
this.nome = nome;
}
}
Observe, no exemplo acima, a declaração this. Quando utilizamos essa
declaração, estamos informando que o atributo utilizado está declarado na
classe. Logo, this.nome pertence à classe e nome se refere ao parâmetro
passado ao construtor.
Abaixo, podemos observar um modelo conceitual de classes,
[class|abstract|interface] [Nome da Classe] {
[Construtor]
[Atributos ou Variáveis]
[Métodos]
}
em que:
� [class|abstract|interface] — refere-se ao tipo, que pode ser
class, ou seja, uma classe do tipo class, ou uma interface, sendo que
este define uma espécie de padrão ou interface padrão que uma classe
deve implementar. Ainda possuímos a abstract class, que é uma
classe abstrata, sendo que esta pode conter métodos implementados e
não implementados (os conceitos de interface e classe abstrata serão
desenvolvidos no decorrer deste capitulo);
� [Nome da Classe] — deve ser único no pacote atual e seguir as
mesmas regras de nomenclatura dos métodos;
5Linguagem Java: conceitos essenciais
� [Construtor] — um método que é chamado por padrão ao utilizar
(instanciar) uma classe, sendo que este método pode inicializar os
atributos da classe ou simplesmente não conter implementação alguma.
Deve possuir o mesmo nome da classe e sua existência é obrigatória,
mesmo que não contenha implementação, no caso de se tratar de uma
interface que não possui nenhum construtor;
� [Métodos] — segue o padrão já mencionado anteriormente para
métodos, com a diferença de que, em interfaces, não temos a imple-
mentação do método, apenas sua definição. Os exemplos ficariam
void Calcula ();, float ValorPI(); e float Total (int
Qtd, flota Preco); e a classe que implementar essa interface
deve também realizar a implementação destes métodos.
As classes em Java, além das variáveis e dos atributos, possuem ainda
métodos, sendo que os métodos podem realizar diversos comandos. A estrutura
de um método pode ser observada abaixo:
[retorno] [nome do método]([tipo dos dados] [nome do parâme-
tro], …) {
[código do método]
[return] [valor do retorno]
}
Observe, a seguir, o que significa cada termo da estrutura de um método,
como vimos acima:
� [retorno] — é o tipo de dado (seja ele primitivo ou do tipo referência)
que o método irá retornar. Uma vez informado, é obrigatório que seja
retornado um valor. Para não retornar nenhum valor, informamos ao
invés do tipo da variável a palavra void, que significa que nada será
retornado;
� [nome do método] — nome que remeta à funcionalidade do método.
As únicas ressalvas ao nomear o método são que caracteres especiais
e espaços não devem ser utilizados e o nome do método não pode
conter espaços. Neste caso, podemos utilizar o caractere underline (por
exemplo, Nome _ Pessoa);
� [tipo dos dados] [nome do parâmetro] — um método pode
não possuir parâmetros. Neste caso, utilizam-se os ( ), sem nenhuma
informação entre os parênteses. Porém, podemos informar um ou mais
Linguagem Java: conceitos essenciais6
parâmetros, em que o tipo de dados deve ser informado logo após o nome
do parâmetro, que segue a mesma regra de nomenclatura do método,
sendo que as várias declarações de parâmetros devem ser separadas
por ,. Observe que os parâmetros devem receber diferentes nomes;
� [código do método] — conjunto de códigos que o método realiza;
� [return] [valor do retorno] — esta linha pode não existir se
o retorno do método for void. Porém, caso um retorno seja informado,
o comando return seguido do valor ou da variável do mesmo tipo do
retorno deve ser também informado.
Exemplo 1 Exemplo 2 Exemplo 3
class Area {
float area;
float lado;
void
Calcula (){
this.Area
= this.Lado
* this.Lado
}
}
class Valores {
float
ValorPI(){
return 3.14f;
}
}
class Produto {
float Total
(int Qtd,
float Preco){
return
Qtd * Preco;
}
}
Quadro 1. Exemplos de métodos
No Quadro 1 observamos três exemplos de possíveis métodos:
� exemplo 1 — o this indica que as variáveis do método pertencem
à classe a qual o método também pertence e, no caso, o método está
atribuindo ao atributo area o resultado da operação de multiplicação
(representada pelo operador de multiplicação *) do atributo lado por
ele mesmo (possivelmente seria a área de um quadrado, portanto os
lados seriam iguais, assim basta armazenar o tamanho de um lado);
� exemplo 2 — método que retorna um valor do tipo float, no qual temos
o retorno do valor 3.14f , em que f indica que o valor é do tipo float;
� exemplo 3 — o método Total recebe dois parâmetros Qtd e Preco,
realizando a multiplicação desses valores, retornando o resultado deste
cálculo.
7Linguagem Java: conceitos essenciais
Conceitos e modificadores
Segundo Deitel, Deitel e Wald (2016), na linguagem Java está disponível um
recurso muito importante para o desenvolvimento e a estruturação de um pro-
jeto: os moderadores de acesso. Estes são empregados para restringir o acesso
a um método, atributo ou até a uma classe. Entretanto, independentemente do
moderador escolhido, um atributo ou método é sempre acessível, isto é, pode
ser chamado, a partir de qualquer outro método contido na mesma classe. Os
moderadores de acesso mais comuns do Java são os seguintes:
� public — um atributo ou método que utiliza este moderador é público
e pode ser chamado a partir de métodos contidos em qualquer outra
classe, sendo esta a condição de menor restrição da linguagem;
� protected — utilizando este moderador, o atributo ou método pro-
tegido pode ser chamado por todas as classes existentes no pacote da
classeem questão;
� private — quando um atributo ou um método é privativo na classe
que o contém e seu uso é vedado a qualquer outra classe, ou seja, so-
mente métodos da própria classe podem executar uma chamada a este.
Java é uma linguagem amplamente utilizada em diversas áreas, não somente para
programação Android, mas também em desenvolvimentos para desktops, Web e
outros. Nos links a seguir você pode acessar o site oficial do Java, além da página com
a documentação da linguagem e outras informações.
https://qrgo.page.link/E4PEm
https://qrgo.page.link/yaAq8
Além dos moderadores de acesso, os métodos e atributos ainda possuem
outros modificadores, voltados a outras características. Um destes modifica-
dores é o modificador static, que pode ser utilizado em classes, métodos
e atributos. Uma vez utilizado em um método, este poderá ser acessado por
qualquer classe (observando o moderador de acesso) sem a necessidade de
instanciá-la. Um método static não pode acessar qualquer variável decla-
Linguagem Java: conceitos essenciais8
rada dentro de uma classe, exceto no caso de a variável também ser declarada
como static. Mas a situação contrária é permitida: um método comum pode
acessar métodos e atributos static.
Abaixo, temos um exemplo de método do tipo static com o nome getPI.
Observe que não instanciamos a classe Area:
public class Area {
public static float getPI(){
return 3.14f;
}
}
// Podemos utilizá-lo da seguinte maneira:
Area.getPI();
Outro detalhe sobre o modificador static é que, uma vez utilizado em
uma classe (static class), obrigatoriamente toda a classe (incluindo
métodos e atributos) deve ser declarada com o modificador static.
Segundo Goodrich e Tamassia (2013), alguns dos conceitos mais importan-
tes da linguagem Java são o encapsulamento, a herança e o polimorfismo. O
encapsulamento é uma característica muito importante que trata da capacidade
de isolar informações do restante do programa. Assim, uma vez construída
uma determinada classe, o desenvolvedor não precisa mais se preocupar com
suas características internas, já que realiza as chamadas dos métodos. Caso
seja necessário realizar alguma alteração em um método, ao realizar esta
alteração todos os pontos que o utilizam automaticamente irão receber tais
alterações. Dessa forma, o desenvolvedor pode garantir que a informação não
será corrompida acidentalmente pelo resto do programa, tornando-a robusta
e confiável.
Para um desenvolvedor experiente, o conceito de modificadores pode ser muito
simples, mas para desenvolvedores sem tanta experiência, o uso de modificadores
pode ser bem confuso. Ao iniciar a programação de aplicativos sem conhecer a fundo
a linguagem de programação, procure utilizar modificadores mais simples, como o
public e o private. À medida que for adquirindo experiência, aventure-se a utilizar
modificadores mais complexos.
9Linguagem Java: conceitos essenciais
A herança é um conceito importante da linguagem Java. Nesse processo,
uma classe que implementa ou é estendida a outra herda todos os seus métodos
e atributos. Na Figura 2 temos um exemplo clássico de herança, em que a
classe Animal é estendida à classe Mamífero, que por sua vez é estendida
à classe Cachorro. Ao instanciar uma classe Cachorro, este poderá utilizar
os métodos nascer, morrer e mamar, pois estes serão herdados das classes
Animal (métodos nascer e morrer) e Mamífero (método mamar).
Para criar uma classe Gato, por exemplo, seria necessário apenas estendê-la
à classe Mamífero e implementar o método miar.
Figura 2. Exemplo de classes Java, demonstrando o conceito
de herança.
Linguagem Java: conceitos essenciais10
Temos, ainda, o modificador abstract, no qual é possível declarar um
método sem o implementar. Dessa forma, uma classe que implementa a classe
que contém métodos abstract deve repetir sua declaração abstrata, imple-
mentando-a ou não; porém, em algum momento ela deve ser implementada.
Funciona como uma espécie de lembrete para que alguma classe derivada
complete a declaração fornecendo um corpo.
Na Figura 3 temos um exemplo de classe abstrata, em que a classe Animal
é do tipo abstract e já possui os métodos nascer e mamar implemen-
tados. No entanto, os métodos voz e alimentar são abstratos e devem ser
implementados em classes que forem estendidas à classe Animal. No caso, a
classe Cachorro foi estendida à classe Animal e implementou os métodos
abstratos voz e alimentar com a implementação adequada.
Figura 3. Exemplo de classes Java, demonstrando o conceito
de classe abstrata.
11Linguagem Java: conceitos essenciais
O modificador final identifica que nenhuma classe derivada pode alterar
ou redefinir este método ou atributo. Dessa forma, um método declarado
como final deve ser obrigatoriamente implementado. No exemplo abaixo, uma
classe estendida à classe Area não poderá criar uma nova implementação
para o método getPI.
public class Area {
public final float getPI(){
return 3.14f;
}
}
Segundo Deitel, Deitel e Deitel (2015), a interface é uma funcionalidade
da orientação ao objeto utilizado em Java que define ações que devem ser
obrigatoriamente executadas, mas que cada classe pode executar de forma
diferente. As interfaces contém valores constantes ou assinaturas de métodos
que devem ser implementados dentro de uma classe.
No caso da Figura 4, podemos observar ainda uma utilização prática das
interfaces, em que a interface InterfacePessoa prevê todos os métodos
necessários para uma determinada implementação, sendo que esta interface
foi implementada pela classe abstrata Pessoa, que implementou os métodos
getIdade e setIdade, visto que em uma implementação das classes
Mulher e Homem os métodos indicados teriam uma implementação idêntica
para ambos os objetos, podendo, dessa forma, serem herdados por estes.
Uma peculiaridade está no método getSexo, cuja implementação se deu
na classe Mulher e Homem, em virtude dessa informação ser diferente em
ambos os casos.
Linguagem Java: conceitos essenciais12
Figura 4. Exemplo de classes Java, demonstrando a utilização de interfaces.
Um dos conceitos mais utilizados da linguagem Java é o polimorfismo,
que promove a reutilização contínua dos códigos, ou seja, possibilita que
algo assuma várias formas. No contexto da programação orientada a objetos
(sendo o Java, conforme já mencionado, uma linguagem totalmente orientada a
objetos), ele nos mostra como um método pode assumir formas diferentes das
inicialmente implementadas e agir de modo que possa ser utilizado por outra
classe. Na Figura 2, em que observamos o conceito de herança (os conceitos de
herança e polimorfismo trabalham lado a lado na linguagem Java), podemos
observar o conceito de polimorfismo também quando a classe Pessoa assume
a forma das classes Homem e Mulher.
13Linguagem Java: conceitos essenciais
Na Figura 5 podemos identificar outra face do polimorfismo. No exemplo,
os métodos ImprimeIdade, ImprimeSexo e ImprimeSexoIdade
recebem, por parâmetro, uma classe Pessoa, sendo que esta pode ser do tipo
Mulher ou Homem e, de acordo com essa passagem de parâmetros, podemos
ter a impressão do respectivo sexo e idade (a idade, no caso, depende do valor
atribuído à variável Idade, presente na classe Pessoa). Essa passagem de
parâmetro genérica se dá pelo fato de que uma mulher ou um homem são
pessoas, caracterizando um conceito do polimorfismo.
Figura 5. Exemplo de classes Java, demonstrando o conceito de polimorfismo.
Outro conceito do polimorfismo presente na Figura 5 é a sobrecarga, em
que possuímos na classe Auxiliar três métodos imprime e somente é
possível possuir estes três métodos com o mesmo nome, em virtude dos métodos
possuírem parâmetros diferentes. No caso, o método imprime, que realiza a
impressão da idade, recebe um parâmetro do tipo int, enquanto o método que
realiza a impressão do sexo recebe um parâmetro do tipo String. Frente à
Linguagem Java: conceitos essenciais14sobrecarga prevista no polimorfismo, eles são diferentes; logo, são permitidos.
Ainda temos o caso do método Imprime, que recebe dois parâmetros que
se diferenciam ainda mais dos outros e, com isso, também se tornam válidos.
Java na prática: operadores, condicionais,
laços de repetição
Na linguagem Java é muito comum a realização de cálculos matemáticos ou uma
comparação entre variáveis, assim como a repetição de uma determinada rotina
até que uma condição seja atingida. Para que isso seja possível, o Java possui
operadores. Na Figura 6 podemos observar esses operadores disponíveis na lingua-
gem Java (na ilustração eles estão divididos em grupos, conforme suas funções).
Figura 6. Tipos de operadores disponíveis na linguagem Java.
Fonte: Schützer e Massago (2008, documento on-line).
Segundo Deitel, Deitel e Deitel (2015), os operadores de atribuição, como
o próprio nome sugere, são capazes de atribuir um determinado valor a algo,
normalmente uma variável. Um exemplo seria uma variável x do tipo inteiro
(no caso int), à qual podemos atribuir o valor 10 utilizando a simples ex-
pressão x = 10. Aliado a este operador de atribuição, temos os operadores
de adição, subtração e divisão. Na Figura 7 é possível observar operações
de adição (operador +), subtração (operador -), multiplicação (operador *)
e divisão (operador /), além de uma operação envolvendo duas variáveis.
Existe, ainda, o operador módulo %, que calcula o resto de uma divisão. Por
exemplo, x = 5 % 2, em que x ao final da operação será igual a 1, visto
que este é o resto da divisão.
15Linguagem Java: conceitos essenciais
Podemos, ainda, utilizar o operador de atribuição = combinado aos ope-
radores matemáticos, resultando em expressões mais simples. Por exemplo,
a expressão de soma x = x + 10 (operação de soma existente na Figura 7)
poderia ser codificada utilizando o operador de soma combinado ao operador
de atribuição, gerando a expressão x += 10, que é exatamente o mesmo que
x = x + 10, sendo que este pode ser realizado com as demais operações
matemáticas.
Figura 7. Operador de atribuição = em operações matemáticas.
Também temos operações de atribuição que não utilizam o operador =.
Neste caso, estamos falando dos operadores de incremento e decremento. Por
exemplo, a operação x = x + 1, que também é idêntica à operação x += 1,
pode ser escrita de forma ainda mais simplificada, utilizando o operador
unário de incremento, resultando em x++. Em todos os exemplos citados serão
somados 1 ao valor já existente em x.
Os sinais unários são utilizados para identificar se um número é positivo
(sinal unário +) ou negativo (sinal unário -), sendo que ao não informar o
sinal unário de um número, o programa irá entender que se trata de um nú-
mero positivo. Vamos imaginar a variável do tipo byte recebendo o valor 10
negativo. Neste caso, teríamos o código byte z = -10, ou seja, a variável
z será igual a 10 negativo.
Linguagem Java: conceitos essenciais16
Ao declarar os nomes de variáveis e classes, você deve tomar cuidado para não uti-
lizar as palavras reservadas da linguagem Java. Por exemplo, a palavra int deve ser
utilizada somente em seu propósito original, ou seja, declarar uma variável deste
tipo. Portanto, você não pode colocar o nome de uma variável como int. A seguir,
temos uma lista de palavras reservadas da linguagem: abstract, continue, for,
new, switch, assert, default, goto, package, synchronized, boolean,
do, if, private, this, break, double, implements, protected, throw,
byte, else, import, public, throws, case, enum, instanceof, return,
transient, catch, extends, int, short, try, char, final, interface,
static, void, class, finally, long, strictfp(2), volatile, const,
float, native, super e while.
Deitel, Deitel e Deitel (2015) definem os operadores de comparação como
ferramentas de suma importância para o desenvolvimento de qualquer software,
seja ele um aplicativo Android ou outro. Essa afirmação se deve ao fato de
que estes operadores fornecem a linguagem o poder de dar ao código a to-
mada de decisão. Por exemplo, se você deseja comprar um produto que custa
R$ 12,00 mas possui apenas R$ 10,00 na carteira, a compra não pode ser
concluída, visto que você não possui dinheiro suficiente. Para inserirmos essa
tomada de decisão em um código Java, utilizamos a cláusula condicional if,
que significa “se”. Assim, em uma linguagem formal, já podemos escrever
o exemplo, ficando “se o dinheiro na carteira for maior ou igual ao valor do
produto, então a compra pode ser realizada; caso contrário, você não possui
dinheiro suficiente”. Em Java, teríamos:
float produto = 12f;
float carteira = 10f;
if (carteira >= produto) {
// Entao você possui dinheiro suficiente
}
else {
//Você não pode comprar, dinheiro insuficiente
}
//Segue o fluxo do programa
17Linguagem Java: conceitos essenciais
Dessa forma, já introduzimos também o operador de comparação maior
ou igual >=. Podemos utilizar também os demais operadores de comparação:
� >: compara se um valor é maior que outro;
� <: compara se um valor é menor que outro;
� <=: compara se um valor é menor ou igual a outro;
� ==: comparação simples entre dois valores, verificando se ambos são
iguais e apenas iguais;
� !=: comparação simples entre dois valores, verificando se ambos são
diferentes.
A cláusula if pode possuir várias operações de comparação utilizando a
cláusula elseif(comparação), ou seja, podemos ter o if(comparação 1)
com a sua comparação, seguido de quantos elseif(comparação2..3..4)
forem necessários para a lógica do programa, podendo finalizar com o else,
que significando que caso nenhuma comparação seja satisfeita, o código
da cláusula else será executado, observando também que somente o if
é obrigatório. Portanto, podemos utilizar o elseif e o else apenas se na
lógica da rotina for necessário.
Dentro das cláusulas condicionais, ainda possuímos a cláusula switch, que pode
simplificar a execução de várias comparações de uma variável. No link a seguir você
pode obter mais informações sobre a cláusula switch.
https://qrgo.page.link/ungAZ
Para completar este conjunto de operações visto até então, temos os laços
de repetição, sendo o mais simples deles o while, que em uma linguagem
formal seria “enquanto uma comparação for satisfeita, repete um conjunto
de código”.
Linguagem Java: conceitos essenciais18
Figura 8. Exemplos de operação de “while” e de “do...while”.
Fonte: Schützer e Massago (2008, documento on-line).
Na Figura 8, encontramos alguns exemplos do bloco de repetição while,
sendo:
� exemplo 1 — a rotina presente no while é executada enquanto o
valor de k for menor que 10, ou seja, será executado até que k seja
incrementado pelo operador unário ++ e atingir o valor 10;
� exemplo 2 — nesta rotina, h é inicializado com zero e a rotina presente
no while será executada até que h mude para outro valor, sendo que,
no caso, isso ocorrerá somente quando o teste if for satisfeito;
� exemplo 3 — a variável i é inicializada com o valor 10 e, assim, o
bloco while não é executado, pois somente seria executado caso i
fosse menor ou igual a cinco. Dessa forma, o programa segue seu fluxo
normal após o while;
� exemplo 4 — no do while, a rotina presente neste bloco é executada
pelo menos uma vez, podendo repetir novamente se ao final da primeira
execução o teste do while for satisfeito. No exemplo, a rotina será
executada apenas uma vez.
19Linguagem Java: conceitos essenciais
O laço de repetição for tem uma complexidade um pouco maior. Na Figura 9
temos um exemplo ilustrado de uma implementação do laço for. Para um
melhor entendimento, vejamos mais informações abaixo:
� int x = 0; — este código é executado apenas uma vez e é chamado
de inicialização. Nesta inicialização temos a declaração da variável x
e sua inicialização com o valor zero, sendo que ela não será executada
novamente. Observe que a variável x poderia estar declarada em outro
locale, neste caso, ela poderia ser inicializada apenas com x = 0; ou
nem ser inicializada, contando apenas com a presença do ;;
� x <= 10; — esta é a condição que verifica se o laço deve ser repetido.
Após a inicialização ele é verificado e, caso seja satisfeito, a rotina do
laço é executada uma vez;
� x++ — este é o incremento (poderia ser decrementado, também utili-
zando -- ou outros operadores, como o += 10) ao final da execução
da rotina do laço de repetição. A variável x é incrementada e após o
seu incremento a condição (x <= 10) é verificada, ou seja, quando x
atingir o valor 11, o laço de repetição não será repetido e o programa
seguirá seu fluxo.
Figura 9. Ilustração do uso do for.
Fonte: Schützer e Massago (2008, documento on-line).
É importante salientar que os laços de repetição while e for também
podem ser interrompidos a qualquer momento, executando o comando break;.
Linguagem Java: conceitos essenciais20
DEITEL, P.; DEITEL, H.; DEITEL, A. Android: como programar. 2. ed. Porto Alegre: Book-
man, 2015. 690 p.
DEITEL, P.; DEITEL, H.; WALD, A. Android 6 para programadores: uma abordagem baseada
em aplicativos. 3. ed. Porto Alegre: Bookman, 2016. 618 p.
GOODRICH, M. T.; TAMASSIA, R. Estruturas de dados e algoritmos em Java. 5. ed. Porto
Alegre: Bookman, 2013. 736 p.
SCHÜTZER, W.; MASSAGO, S. Tipos de dados. In: SCHÜTZER, W.; MASSAGO, S. Tutorial
de programação Java. São Carlos: Departamento de Matemática, Universidade Federal
de São Carlos, 2008. Disponível em: https://www.dm.ufscar.br/profs/waldeck/curso/
java/part22.html. Acesso em: 16 jun. 2019.
Leitura recomendada
SCHILDT, H. Java para iniciantes: crie, compile e execute programas Java rapidamente.
6. ed. Porto Alegre: Bookman, 2015. 704 p.
21Linguagem Java: conceitos essenciais
Dica do professor
Conhecer todas as funcionalidades da linguagem de programação é muito imporante para o
desenvolvedor. Porém, alguns aspectos também devem ser levados em consideração como, por
exemplo, a organização do código desenvolvido, além da escrita de informações que ajudam os
desenvolvedores envolvidos no projeto a compreenderem o código-fonte que compõe o projeto.
Confira, na Dica do Professor, informações para organizar o código, inserir informações pertinentes
do seu desenvolvimento, além de práticas que podem ajudar o iniciante em linguagem de
programação a minimizar problemas desnecessários, aumentando a velocidade da sua curva de
aprendizagem.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://fast.player.liquidplatform.com/pApiv2/embed/cee29914fad5b594d8f5918df1e801fd/e3dd43e1e6c8f51b534518475c365526
Saiba +
Para ampliar o seu conhecimento a respeito desse assunto, veja abaixo as sugestões do professor:
Polimorfismo
Você sabe o que é o polimorfismo? Se não sabe ou caso queira saber mais, então não deixe de
acessar este conteúdo e compreender esse conceito essencial para desenvolver códigos Java com
qualidade.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Vetores em Java
No artigo a seguir você irá saber mais sobre vetores em Java, recursos essencial para se trabalhar
com listas, arrays, além de fornecer muitas possibilidades de aplicação.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Boas práticas de programação
Em programação, boas práticas sempre são bem-vindas, uma vez que elas tendem a facilitar a vida
do desenvolvedor de softwares. Confira no artigo a seguir algumas boas práticas de programação
voltadas à linguagem Java.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
http://www.dsc.ufcg.edu.br/~jacques/cursos/p2/html/oo/o_que_e_polimorfismo.htm
https://www.devmedia.com.br/vetores-em-java/21449
https://www.devmedia.com.br/boas-praticas-de-programacao/21137
Programação orientada a objetos: Java,
C++ e C#
Apresentação
Assim como a linguagem natural, que permite expressar por meio da fala os anseios, os sentimentos
e os objetivos, a linguagem de programação surgiu para que fosse possível padronizar a
comunicação de instruções para um computador. Por meio dela, o programador especifica
precisamente onde o computador vai atuar, o que ele vai armazenar e transmitir a partir dos
comandos do usuário.
A competitividade do mercado atual exige um conhecimento funcional muito elevado por parte dos
desenvolvedores. De acordo com a comunidade de programação TIOBE, que avalia a popularidade
das linguagens de programação, as linguagens Java, C e C++ foram as três linguagens mais
populares no ano de 2008. De lá para cá, diversas outras surgiram, inclusive a C#, que é uma
continuação da C++, com melhorias voltadas para performance e experiência do usuário, o que não
extingue a importância das três mencionadas anteriormente, tendo em vista características
importantes que as fazem continuar entre as mais funcionais e robustas no mercado do
desenvolvimento (SEBESTA, 2011, p. 24).
Nesta Unidade de Aprendizagem, você irá conhecer as linguagens de programação Java e as suas
características e também irá acompanhar a análise e o funcionamento das linguagens C++ e C#.
Bons estudos.
Ao final desta Unidade de Aprendizagem, você deve apresentar os seguintes aprendizados:
Identificar as principais características da linguagem Java.•
Analisar a Linguagem C++.•
Descrever a linguagem C# e as suas particularidades.•
Infográfico
Java é uma linguagem de programação orientada a objetos criada por um grupo de engenheiros na
década de 1990. No ano de 2008, ela foi adquirida pela empresa Oracle e, atualmente, é a
linguagem mais utilizada entre os desenvolvedores, pois Java não é apenas uma linguagem, ela é
uma plataforma, ou seja, um ambiente computacional que permite o desenvolvimento de aplicações
na linguagem Java.
Neste Infográfico, veja algumas características traduzidas para um fácil entendimento dessa
importante linguagem de programação.
Conteúdo do livro
As linguagens de programação, de um modo geral, expressam de forma escrita instruções que
precisam ser realizadas pelo computador. Cada uma é apropriada para determinados tipos de
aplicação, permitindo que cada vez mais problemas sejam resolvidos por meio desse tipo de
construção. Quando uma nova linguagem surge, é muito comum que os seus criadores tenham se
baseado em uma linguagem já existente para essa nova construção. Isso aconteceu com o Java e o
C#, que se valeram da linguagem C e C++ para criá-las.
No capítulo Programação orientada a objetos: Java, C++ e C#w, da obra Paradigmas de
programação, você estudará sobre essas três linguagens, o que permitirá que você tenha uma
pequena noção desse vasto universo, trazendo o conhecimento e a curiosidade para você dar
continuidade na busca do conhecimento no que diz respeito ao desenvolvimento de sistemas.
PARADIGMAS DE
PROGRAMAÇÃO
Marcia Cristina Domingues Leite
Programação orientada a
objetos: Java, C++ e C#
Objetivos de aprendizagem
Ao final deste texto, você deve apresentar os seguintes aprendizados:
� Identificar as principais características da linguagem Java.
� Analisar a linguagem C++.
� Descrever a linguagem C# e suas particularidades.
Introdução
De modo geral, uma linguagem de programação (LP) é um conjunto de
regras sintáticas e semânticas que definem o que um computador deverá
fazer. Historicamente, a primeira LP para computadores pessoais (chamada
linguagem de alto nível) foi Fortran, criada em 1954. Desde então, muitas
outras linguagens surgiram, algumas ainda continuam sendo utilizadas,
pois suas características as mantêm no mercado do desenvolvimento por
fatores como segurança, multiplataformas, tipagem e orientação a objetos
(OO). Outras, deram origem ou influenciaram as linguagens conhecidas
atualmente. A linguagem C, por exemplo, influenciou linguagens como
Java e C#. Esta última, incorpora a OO à linguagem C que,por sua vez, é
basicamente procedural, baseada em rotinas, métodos e funções.
Neste capítulo, você conhecerá um pouco sobre essas três impor-
tantes LPs, suas características, particularidades e de que forma elas
influenciaram grande parte das linguagens de programação utilizadas
hoje no mercado mundial de desenvolvimento.
Paradigma da orientação a objetos
Machado, Franco e Bertagnolli (2016) explicam que a OO trata de conceitos cujo
objetivo principal é a resolução de problemas por meio da sua decomposição
em partes menores, utilizando métodos como abstração e modularização.
Quando os primeiros computadores surgiram, buscava-se uma maior
eficiência, sem que isso tomasse grande parte da memória, em razão das
limitações de hardware daquela época. Os programadores da época dividiam
seus programas em blocos, de modo a realizar essa economia de recursos.
A partir disso, foram criadas técnicas para resolução de problemas, divi-
dindo um grande problema em diversos problemas menores. Essa técnica é
realizada por meio da modularização, que permite resolver e entender proble-
mas complexos e reutilizar códigos. Para que se possa a OO é importante saber
que esse tipo de programação atende a quatro aspectos principais, descritos
nos itens a seguir.
Abstração
É o aproveitamento de aspectos relevantes de cada um dos “problemas” resol-
vidos dentro de um código. Portanto, cada módulo representa uma abstração
existente no todo do problema.
Sabemos que a OO trata de representações de um objeto real, mas é im-
portante entender o que esse objeto irá realizar nessa abstração. Em geral,
objeto é a representação de algo que existe. No desenvolvimento, os objetos
possuem as seguintes características: identidade, estado e comportamento.
Encapsulamento
Dentro do contexto da OO, o encapsulamento é utilizado a todo momento,
conforme se trabalha com propriedades e métodos de alguns componentes, sem
ver como está implementado. Um exemplo disso é a utilização de application
programming interface (API), utilizadas para requisitar informações sobre
uma página Web, por exemplo, ou um banco de dados.
Grande parte das linguagens que utilizam a OO encapsulam seu código em
propriedades privadas, com métodos chamados getters e setters. Esses métodos,
respectivamente, retornam e definem o valor da propriedade adicionando uma
camada de segurança à aplicação, evitando, assim, o acesso direto ao objeto.
Programação orientada a objetos: Java, C++ e C#2
Métodos nada mais são do que instruções que damos ao objeto, por exemplo:
criar um cliente. Na prática, os métodos get ou set trabalham da seguinte forma:
a aplicação faz uma requisição utilizando qualquer um deles. Por exemplo, um
usuário busca seu cadastro em determinada aplicação, como isso é feito não
pode ser visualizado, mas está acontecendo por trás da interface.
Herança
Permite que se utilize uma classe com suas propriedades e métodos, incluindo
outras propriedades e métodos existentes em outra classe que está sendo criada.
A herança é uma das grandes vantagens da programação OO, pois ela
otimiza em muito o projeto do software, tanto no que diz respeito ao tempo,
como em linhas de código.
Polimorfismo
Podemos tratar um objeto A que herdou características de outro objeto B como
se ele fosse o próprio objeto B, ou seja, um objeto pode se comportar como se
fosse outro objeto, do qual ele herdou atributos e métodos. Toda e qualquer
alteração de um método herdado de um objeto pai caracteriza o polimorfismo.
Outro aspecto importante em OO, é que algumas partes do objeto são
privadas e outras, públicas. Geralmente, utiliza-se métodos públicos na in-
terface do usuário.
No escopo de um software, a classe descreve que propriedades ou atributos
o objeto terá. A definição de uma classe descreve o comportamento que o
objeto terá e de que forma ele funcionará na aplicação.
� Atributos: são propriedades que compõe uma classe, como nome, tipo,
valor e visibilidade (público, privado ou protegido).
� Métodos: são as funcionalidades da classe, como nome, tipo, argumentos
e visibilidade.
A Figura 1 demonstra a construção de uma classe bem como a declaração
de variáveis dentro dela.
3Programação orientada a objetos: Java, C++ e C#
Figura 1. Exemplo de classe em Java.
Linguagem Java e seu histórico
Historicamente, a LP Java foi criada em 1991 pelos engenheiros da Sun
Microsystems, que tinham como missão criar uma linguagem que pudesse ser
utilizada em pequenos equipamentos domésticos, como telefones, geladeiras,
controles de TV, etc. A intenção era que esses aparelhos pudessem se comunicar
entre si (MACHADO; FRANCO; BERTAGNOLLI, 2016).
Com o advento da World Wide Web (WWW), os engenheiros da Sun
passaram a investir em novos conceitos para essa linguagem, que atualmente
lidera o ranking das LP mais utilizadas no mundo do desenvolvimento.
A LP Java é OO, e os programas são compilados, interpretados e trans-
formados em uma linguagem intermediária chamada bytecode. O bytecode
é multiplataforma e passa por um interpretador Java todas as vezes que o
programa é executado. Isso se deve em razão da máquina virtual Java vir-
tual machine (JVM) que permite que todos os produtos consigam executar
programas em Java, basta que a plataforma possua a JVM.
A Figura 2 demonstra com a JVM funciona na execução dos programas
em Java nas mais diversas plataformas.
Programação orientada a objetos: Java, C++ e C#4
Figura 2. JVM.
Fonte: Adaptada de DreamStockIcons/Shutterstock.com.
Class OláMundo{
public static void main (string args){
system.out.printin(*Olá Mundo!*)
}
}
Programa Java Compilador
JVM
JVM
JVM
Olá
Mundo!
Olá
Mundo!
Olá
Mundo!
MacOS
Android
Windows
Linguagem C++
No escopo da programação, a linguagem C++ é uma evolução da linguagem
C e, assim como a primeira, influenciou muitas outras linguagens presentes
no dia a dia dos usuários, desde a linguagem JavaScript que é executada no
navegador a cada página acessada, ou ainda na linguagem Java que é executada
nos smartphones. Muitas linguagens que são utilizadas hoje foram construídas
com C++ no que se refere à sintaxe ou ao compilador.
A linguagem C++ é composta por bibliotecas estáveis, que servem de base
para diversas outras linguagens. Sua influência pode ser notada nos maiores
sistemas operacionais e programas do mundo, o que permite concluir que
entender a linguagem C++ é o primeiro passo para entender muitas outras
linguagens atuais.
Horstmann (2005) explica que a linguagem C++ ultrapassou a linguagem C
com o acréscimo da programação OO e não procedural, como era C. Ele explica
também que a linguagem C++ é sensível a letras maiúsculas e minúsculas,
entretanto, espaços e quebras de linha não fazem diferença na estrutura do
código, podendo o programa ser escrito em uma única linha. Outro detalhe
importante é que cada linha de comando precisa terminar em ponto e vírgula,
caso contrário o código não irá rodar.
5Programação orientada a objetos: Java, C++ e C#
A seguir, veja algumas das características da linguagem C++.
� Melhoramento da linguagem C — a linguagem C++ é uma continuação
da linguagem C, com melhorias e novos recursos que otimizaram ainda
mais a linguagem.
� Estaticamente tipada — nesse caso é necessário definir o tipo de cada
variável de forma explícita. Por exemplo, caso seja necessário declarar
uma variável que irá armazenar números, é preciso dizer que é do tipo
inteiro (int); ou se a variável for armazenar caracteres, será necessário
dizer que ela é do tipo caracter (char).
� Compilada — significa que o código é verificado quanto à sintaxe,
passa por um processo de parsing, que verifica a estrutura gramatical
do código, para somente, então, ser compilado. Feito isso é gerado o
código assembler, no qual todas as instruções são traduzidas para o
código de máquina.
� Multiparadigma — é possível programar OO, ou utilizar a programação
funcional. Com essa linguagem é possível fazerprogramas embarcados
que trabalham diretamente com a comunicação com o hardware. Por
isso, dizemos que a linguagem C++ trabalha tanto com a programação
de alto como com a programação de baixo nível, sendo esta última, a
mais próxima do hardware.
� OO — esse é o seu grande diferencial em relação à linguagem C, pois
essa linguagem utiliza recursos como abstração, herança, encapsula-
mento e polimorfismo para construção do software.
A programação OO recomenda que um objeto tenha sua estrutura e seus métodos
tão privativos quanto for possível. Isso significa conhecer a especificação do método
sem ter os detalhes de como a execução realizada por ele é implementada.
Programação orientada a objetos: Java, C++ e C#6
Variáveis
Em C++ é possível declarar uma variável em qualquer momento do código,
dentro de uma instrução ou entre duas instruções.
Quanto à visibilidade, existem duas abordagens possíveis para uma variável:
local ou global.
� Variáveis locais: podem ser acessadas apenas dentro do bloco de ins-
truções no qual estão declaradas. Cada bloco compreende instruções
dentro de duas chaves {...}.
� Variáveis globais: podem ser acessadas em qualquer parte do código
ou arquivo. Para isso, basta que seja declarada onde se desejar. Quando
uma variável é global, dizem que está inserida no escopo do arquivo,
pois pode ser acessada em qualquer parte do todo.
Biblioteca stream
Para possibilitar a entrada (input) e a saída (output) de dados utilizando a
linguagem C++, é necessária a inclusão da biblioteca iostream.h, conforme
exemplo a seguir:
#include <iostream.h>
Para imprimir uma variável na tela, por exemplo podemos dizer da seguinte
forma:
#include <iostream.h>
int x = 20;
cout << "x é igual a " << x << endl;
A saída na sua tela será: x é igual a 20.
A linguagem C++ utiliza o cin para o comando de entrada de dados pelo
teclado e cout para a saída de dados na tela.
7Programação orientada a objetos: Java, C++ e C#
Constantes
É possível declarar uma constante dentro de um projeto C++. Você pode
tornar constantes: valores, ponteiros, conteúdo de um ponteiro e parâmetros
de uma função. Vale lembrar que, ao declarar um valor como constante não
é possível alterá-lo.
Exemplo: const float pi = 3,1415926.
Para montar seu ambiente de desenvolvimento, recomenda-se a utilização de integrated
development enviroment (IDE) — ou ambientes de desenvolvimento integrado, que
facilitam a rotina do projeto. Manusear arquivos grandes via prompt de comando ou
editor de textos não é uma tarefa aconselhável. Nesses casos, você pode contar com
algumas ferramentas que auxiliam nesse sentido. Uma delas é o CodeBlocks, cujo link
para instalação encontra-se a seguir. Um detalhe importante é que ao instalar a IDE
CodeBlocks, o compilador é instalado automaticamente. Para instalar no Linux, basta
escrever o seguinte comando no seu terminal:
$ sudo apt install codeblocks
https://bit.ly/2ejIyqR
Conhecendo a linguagem C#
Assim, como a linguagem C++, a LP C# é baseada na linguagem C, com
melhorias e características que unem a linguagem original com novos con-
ceitos e recursos. Trata-se de uma linguagem fortemente tipada, imperativa,
declarativa e OO.
A linguagem C# foi desenvolvida por Anders Hejlsberg e, atualmente,
pode ser encontrada na versão 8.0. É utilizada dentro do ambiente de desen-
volvimento .NET da Microsoft e tem muita aceitação no mercado, pois atende
diversas especificações para criação de softwares, como desenvolvimento Web,
mobile, metodologias ágeis como information technology infrastructure library
(ITIL) e até mesmo machine learning (aprendizado de máquina) que trata de
questões de mineração de dados em grandes bases, conhecidas como Big Data.
Programação orientada a objetos: Java, C++ e C#8
Deitel et al. (2007) explicam que C# é uma LP projetada para ser utilizada
na plataforma .NET e que, por ser baseada nas linguagens C, C++ e Java,
torna a migração dos desenvolvedores mais fácil, ao passo que seus recursos
se adaptam a cada uma das linguagens citadas e ainda acrescentam suas
capacidades próprias.
Essa plataforma é uma API feita para quem utiliza o sistema operacional
Windows. Já em sistemas operacionais Unix, é possível desenvolver por meio
do terminal ou de ferramentas como o Visual Studio Code e outras plataformas.
Sharp (2011) compara a adaptabilidade da LP C# a componentes quando
afirma que, enquanto a linguagem C desempenha importante papel no desen-
volvimento UNIX, devido a sua compatibilidade, a linguagem C# também é
compatível com diversos outros formatos, como eXtensible Makup Language
(XML) e o eXtensible Application Markup Language (XAML).
O Microsoft Visual Studio é um dos principais pacotes de programas de desenvolvi-
mento da plataforma .NET. Trata-se de um conjunto de ferramentas, utilizadas para o
desenvolvimento de aplicações móveis, para desktop, servidores Web e aplicações Web.
Você pode fazer o download dessa importante ferramenta para auxiliar na sua
experiência com o desenvolvimento utilizando C# no link a seguir.
https://qrgo.page.link/s8UrU
Plataforma ASP.NET
A plataforma ASP.NET foi criada pela Microsoft para solucionar problemas
de compilação e execução de aplicativos Web, além de fornecer ferramentas
que facilitassem o desenvolvimento de aplicações Web (SANTANA FILHO;
ZARA, 2002).
A plataforma ASP.NET permite também a criação de diversos tipos de
web services (serviços Web), que são aplicações que podem ser utilizadas na
internet. O usuário tem a sua disposição uma interface com métodos definidos,
na qual ele faz requisições a esses métodos a partir de protocolos da internet.
A Microsoft define web service como uma classe escrita em uma linguagem
9Programação orientada a objetos: Java, C++ e C#
suportada pela plataforma .NET, que é acessada via hypertext transfer protocol
(HTTP) (HADDAD, 2008).
Declaração de variáveis em C#
A declaração de variáveis nessa LP se assemelha à linguagem C e C++, con-
forme podemos ver no exemplo:
� Tipo + nome da variável = int MinhaVariável.
Deve-se sempre inicializar uma variável, atribuindo um valor inicial a
ela, assim:
� int MinhaVariável = 0;
As variáveis alocam determinadas quantidades de espaço na memória para
que seja possível armazenar os valores. O gerenciamento da memória nessa
linguagem é feito em duas áreas, como segue:
� stack — compreende um pequeno espaço de memória e funciona em
formato de pilha, o que em estrutura de dados significa que a inserção
e a remoção ocorrem em formato de pilha, o último elemento a entrar
é o primeiro a sair;
� heap — compreende uma área de memória bem grande e seu tamanho
muda de forma dinâmica, de acordo com o que está sendo utilizado.
Laços de repetição
No contexto da lógica de programação, laços de repetição são estruturas
de decisão que estão presentes em todas as linguagens de programação que
conhecemos. Possuem variações sintáticas, mas, de forma geral, fazem com
que um bloco de instruções se repita até que uma condição seja satisfeita.
Cada uma delas é utilizada conforme a necessidade dentro do código. Para
um melhor entendimento, você verá a seguir alguns tipos e em quais situações
podem ser utilizados.
Programação orientada a objetos: Java, C++ e C#10
Laço for
Nesta estrutura de repetição a lógica funciona da seguinte forma:
for (int i = 0; i <= 100; i++)
{
MessageBox.Show ("A variável alcançou o valor " +
i.ToString());
}
Esse bloco de repetição diz o seguinte:
� Para cada i (inteiro), enquanto a variável i for menor que 100, acrescente
1 até que i seja igual a 100. Quando o valor de i for 100, mostre na
tela a mensagem: “A variável alcançou o valor 100”.
Laço while
Essa estrutura basicamente diz que, enquanto a condição esperada não ocorrer,
o loop continuará a ser executado.
É muito comum ocorrerem erros de sintaxe durante a escrita do código que resultam no
chamado loop infinito, ou seja, a condição ficará sendo executado de modo contínuoe não irá satisfazer a premissa determinada.
Laço do while
É semelhante ao laço while, porém, nessa estrutura, a condição é testada
no fim do laço. A diferença essencial entre os dois é o que se deseja fazer
dentro do código.
11Programação orientada a objetos: Java, C++ e C#
Laço for each
Sua principal função é varrer um array e todos os objetos que nele estão
contidos. O laço for each recebe em cada loop um elemento do array.
A Microsoft disponibiliza treinamento para todos os seus produtos, inclusive sobre a
plataforma .NET, bem como outros serviços, por exemplo a hospedagem de aplicações
Web por meio do Azure. Clique no link a seguir e confira.
https://qrgo.page.link/z6wbj
DEITEL, H. M. et al. C#: como programar. São Paulo: Pearson Education; Makron Books,
2007. 1153 p.
HADDAD, R. Web Services. Microsoft Docs, Redmond, 9 set. 2008. Disponível em: https://
docs.microsoft.com/pt-br/previous-versions/technical-articles/cc564893(v=msdn.10).
Acesso em: 28 ago. 2019.
HORSTMANN, C. Conceitos de computação com o essencial de C++. 3. ed. Porto Alegre:
Bookman, 2005. 712 p.
MACHADO, R. P.; FRANCO, M. H. I.; BERTAGNOLLI, S. C. Desenvolvimento de software III:
programação de sistemas web orientada a objetos em Java. Porto Alegre: Bookman,
2016. 220 p. (Série Tekne; Eixo Informação e Comunicação).
SANTANA FILHO, O. V.; ZARA, P. M. Microsoft .net: uma visão geral para programadores.
São Paulo: Senac, 2002. 124 p.
SHARP, J. Microsoft Visual C# 2010. Porto Alegre: Bookman, 2011. 776 p. (Série Passo a Passo).
Leituras recomendadas
PERRY, J. S. Construções para aplicativos do mundo real: recursos de linguagem Java mais
avançados. IBM Developer, Armonk, 22 fev. 2016. Disponível em: https://www.ibm.com/
developerworks/br/java/tutorials/j-introtojava2/index.html. Acesso em: 28 ago. 2019.
PERRY, J. S. Fundamentos da Linguagem Java: programação orientada a objetos na pla-
taforma Java. IBM Developer, Armonk, 22 jan. 2016. Disponível em: https://www.ibm.com/
developerworks/br/java/tutorials/j-introtojava1/index.html. Acesso em: 28 ago. 2019.
Programação orientada a objetos: Java, C++ e C#12
Dica do professor
Mais do que conhecer as diversas linguagens de programação, bem como a orientação a objetos, é
importante entender que durante a vida profissional serão encontrados os mais diversos programas
e que eles precisam, de certa forma, comunicar-se entre si.
Neste sentido, o Web Service é importantíssimo, pois, por meio desse tipo de implementação, o
profissional de Tecnologia conseguirá permitir que todo o arranjo de sistemas que constituem uma
organização troque informações.
Na Dica do Professor, você poderá entender um pouco sobre Web Services, conceitos, padrões e
exemplos práticos.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://fast.player.liquidplatform.com/pApiv2/embed/cee29914fad5b594d8f5918df1e801fd/a0175d9bd8e8681968fa72f463f9f3d1
Saiba +
Para ampliar o seu conhecimento a respeito desse assunto, veja abaixo as sugestões do professor:
ARM REHABILITATION: serious game para apoio à
reabilitação utilizando interfaces naturais
Atualmente, a tecnologia e o desenvolvimento não estão somente ligados ao entretenimento e às
situações de felicidade. O link a seguir demonstra o desenvolvimento de um jogo sério para auxiliar
pessoas que necessitam usar próteses a estimularem a prática. A ferramenta foi desenvolvida
utilizando a linguagem C#. Confira no link.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
GUJ: debates e discussões sobre programações
Você conhece o GUJ??? Este é uma das maiores comunidades virtuais quando o assunto é Java. Lá,
você encontra debates, discussões e suporte de conhecimento sobre a linguagem. Clique para
conferir.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
The RedMonk Programming Language Rankings
A empresa de análise de dados RedMonk mantém o mercado de desenvolvimento atualizado sobre
o ranking das linguagens de programação mais populares. Confira a colocação das linguagens
estudadas nesta Unidade de Aprendizagem.
https://docplayer.com.br/45002408-Arm-rehabilitation-serious-game-para-apoio-a-reabilitacao-utilizando-interfaces-naturais.html
https://www.guj.com.br/
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
A programação orientada a objetos como ferramenta para o
aprendizado e auxílio em projetos de engenharia
Clique para conhecer este estudo, que denota a importância da orientação a objetos não somente
para o profissional da TI, mas para outras grandes áreas.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://redmonk.com/sogrady/2019/07/18/language-rankings-6-19/?utm_source=rss&utm_medium=rss&utm_campaign=language-rankings-6-19
http://meusite.mackenzie.com.br/edsonbarros/publicacoes/COBENGE_2005_Galerias.pdf
Testes de caixa-preta
Apresentação
Sempre em busca de entregas de produtos de software com maior qualidade final para evitar
retrabalho relacionado a operações de correções sobre defeitos, empresas por todo o mundo usam
as técnicas de testes de software como crivo obrigatório para garantir a correta entrega de seus
projetos. Isso prova que a etapa de testes de software é de fundamental importância tanto para a
sua qualidade como um todo quanto para o aspecto econômico de um projeto.
Nesta Unidade de Aprendizagem, você aprenderá sobre a técnica de teste de software do tipo
caixa-preta. Essa é uma técnica de abordagem tradicional largamente utilizada na área de testes de
software e que tem por objetivo descobrir os defeitos relacionados às funcionalidades do software
antes de seu uso em produção.
Bons estudos.
Ao final desta Unidade de Aprendizagem, você deve apresentar os seguintes aprendizados:
Definir teste de caixa-preta e suas características.•
Demonstrar um teste de caixa-preta.•
Aplicar testes de caixa-preta utilizando Java.•
Infográfico
O teste de software é uma disciplina da engenharia de software que tem como objetivo avaliar se
um programa está funcionando corretamente de acordo com as suas especificações.
No Infográfico a seguir, você irá conhecer o fluxo comum da criação de casos de testes para um
sistema e suas características, juntamente com os critérios utilizados em sua composição.
Aponte a câmera para o
código e acesse o link do
conteúdo ou clique no
código para acessar.
https://statics-marketplace.plataforma.grupoa.education/sagah/0670ec10-26ad-43fd-ad8c-ba4fca2460a6/65a112ad-98c4-4c8d-a41a-9024da489034.png
Conteúdo do livro
Quando se fala em testes de software, sabe-se que existem técnicas de abordagem para vários
modelos de projeto. Os testes de caixa-preta, também chamados de testes funcionais, são muito
conhecidos e aplicados atualmente.
Na obra Testes de software e gerência de configuração, base teórica para esta Unidade de
Aprendizagem, leia o capítulo Testes de caixa-preta e conheça mais sobre esse teste, suas
características e seus critérios de aplicação.
TESTES DE
SOFTWARE E
GERÊNCIA DE
CONFIGURAÇÃO
Breno Cristóvão Rocha
Testes de caixa-preta
Objetivos de aprendizagem
Ao final deste texto, você deve apresentar os seguintes aprendizados:
Definir teste de caixa-preta e suas características.
Demonstrar um teste de caixa-preta.
Aplicar testes de caixa-preta utilizando Java.
Introdução
O teste de caixa-preta é uma técnica de teste conhecida e amplamente
utilizada por fábricas de software para realizar avaliações sobre o sistema.
A ideia é garantir que os comportamentos resultantes de ações imputadas
sejam consonantes com os objetivos das especificações.
Também conhecido como teste funcional, o teste de caixa-preta
tem como base as especificações do sistema, que são elementos do
projeto que alimentam o projeto de teste. Existem critérios de aplicação
dos testes adequados para cadacaso. Isso quer dizer que os testes de
caixa-preta têm uma amplitude razoável para que o software atinja a
qualidade desejada e o funcionamento adequado.
Por isso, é muito importante conhecer os detalhes de cada critério e
entender a aplicação no mundo real. Neste capítulo, você vai conhecer
as características do teste de caixa-preta e também os critérios utilizados
para a aplicação em cada caso de teste.
Teste de caixa-preta e suas características
O teste de caixa-preta também é conhecido como teste funcional ou teste
baseado em especifi cação. Afi nal, o seu principal objetivo é assegurar que
as funcionalidades do sistema sejam atendidas da maneira correta após o
seu desenvolvimento e se comportem como previsto nas especifi cações dos
requisitos.
É comum que os testes de caixa-preta sejam projetados com informações
extraídas a partir da própria base de especificação do sistema, como:
manuais do sistema;
diagramas de caso de uso;
documento de requisitos funcionais e não funcionais.
Para se garantir a qualidade que determina um bom projeto de testes,
é essencial haver uma fonte de requisitos adequada. Posteriormente, são
necessárias a análise e a interpretação corretas do analista de testes que vai
projetar os casos de teste. Enganos na interpretação das especificações e/ou má
qualidade do material sobre o sistema, bem como falta de atualização diante
de mudanças, podem resultar em não conformidades e falhas. Nesse sentido,
a cobertura dos testes pode ser impactada caso alguma funcionalidade esteja
ausente. Dessa forma, parte do sistema pode ficar “descoberta”.
Para o teste de caixa-preta, não interessa como acontece o funcionamento
interno ou a forma como foi feita a implementação do sistema. Isso ocorre
porque a técnica analisa o funcionamento do sistema e não o que está dentro
da “caixa” da qual não se conhecem os detalhes. Na Figura 1, a seguir, você
pode ver como acontece a entrada e a saída na caixa-preta.
Figura 1. Demonstração de entrada e saída em caixa-preta.
O desconhecimento do funcionamento interno é um dos motivos pelos quais
os testes relacionados às funcionalidades mais críticas do sistema devem ser
priorizados pela equipe de testes junto aos analistas de requisitos e stakeholders.
Afinal, os critérios do teste não identificam o que é crítico ou não.
Os testes de caixa-preta são independentes da linguagem de programação ou
do paradigma utilizado para o desenvolvimento da aplicação. Eles seguem um
Testes de caixa-preta2
roteiro específico projetado para cada funcionalidade, que pode ser executado
de modo manual ou com ferramentas de automação. Além disso, as técnicas
de testes caixa-preta permitem derivar séries de condições de entrada que
utilizarão completamente todos os requisitos funcionais para um programa
(PRESSMAN; MAXIM, 2016).
O teste de caixa-preta é mais comumente aplicado em nível de sistema,
mas pode ser utilizado também em outros níveis, como unidade, integração
e sistema. Veja na Figura 2, a seguir.
Figura 2. Níveis de aplicação de testes.
O projeto de testes, que também pode ser considerado um roteiro de testes,
consiste na elaboração de casos de teste e no agrupamento por funcionalidades.
Um roteiro de teste pode incluir vários casos de teste que verificam uma parte
do sistema. Por sua vez, um caso de teste é um subconjunto planejado de en-
tradas e saídas predefinidas, que são executadas em um ambiente controlado
de modo a se observar o resultado da ação.
Os testes de caixa-preta utilizam critérios para determinar quais casos de
teste são necessários. Esses critérios são:
1. partição de equivalência;
2. análise de valor limite;
3. tabela de decisão;
4. grafo de causa e efeito;
5. teste de caso de uso.
3Testes de caixa-preta
A seguir, veja como cada um deles implementa as regras do caso de teste.
Partição de equivalência
A partição de equivalência consiste em dividir as entradas de dados para o
sistema em grupos ou classes de dados similares que podem ser tratados da
mesma forma. Isso possibilita a redução do número de testes a serem escritos,
já que um único teste nesse grupo de dados permite descobrir se o proces-
samento está correto ou incorreto para todo o restante. Nesse sentido, há a
partição válida e a partição inválida, que agrupa os valores de entrada para
o teste. Como exemplo, considere uma entrada de valor para informação do
mês, sendo que a faixa permitida é de 1 até 12. Veja a seguir.
Partição válida:
■ valores maiores que 0;
■ valor 1;
■ valor 12.
Partição inválida:
■ valores menores que 1.
■ valores maiores que 12.
Partição inválida:
■ números reais.
■ caracteres não numéricos.
Portanto, não é necessário testar todos os dias do mês para descobrir se o
processamento do valor informado está correto ou incorreto. Basta realizar o
teste com o grupo de entrada de valores da partição válida e da partição inválida
nesse caso em que a condição de entrada especifica um intervalo de valores.
Para identificar as classes de equivalência, considere o seguinte:
exigência de uma entrada por intervalo de valores — definir uma classe
de equivalência válida e duas inválidas;
exigência de uma entrada específica de valor — definir uma classe de
equivalência válida e duas inválidas;
exigência de uma entrada de um membro de um conjunto — definir
uma classe de equivalência válida e uma inválida;
exigência de uma entrada booleana — definir uma classe de equivalência
válida e uma inválida.
Testes de caixa-preta4
Análise de valor limite
A técnica de análise de valor limite para os projetos de testes complementa
a técnica de partição de equivalência. Ela conduz o teste selecionando dados
nos limites de um intervalo da partição de equivalência. Observe a Figura 3,
a seguir.
Figura 3. Limites da borda nas partições de equivalência.
A análise do valor limite pode ser aplicada em vários níveis de teste e é
considerada uma técnica relativamente fácil de se utilizar, com alta capacidade
para encontrar defeitos. Como exemplo, considere uma entrada de valor no
sistema, sendo que a faixa permitida é de 1 até 12. Veja a seguir.
Entradas válidas: 1 até 12;
Fronteiras válidas: 1 como menor número e 12 como maior;
Fronteiras não válidas: 0 no limite inferior e 13 no limite superior.
Existe ainda uma variação da técnica que testa três valores na fronteira
definida. No exemplo que você acabou de ver, essa busca seria para o limite
inferior 0, 1, 2 e para o limite superior 11, 12, 13. Portanto, a técnica de análise
de valor limite se concentra nas fronteiras em que existe maior probabilidade
de ocorrerem defeitos.
5Testes de caixa-preta
Tabela de decisão
O critério por tabela de decisão é uma boa alternativa para avaliar requisitos
de sistema que trabalham com condições lógicas em regras de negócio mais
complexas. As condições de entrada e saída são determinadas na tabela de
decisão, que dispara a combinação de verdadeira ou falsa para obter o resul-
tado da ação. Cada coluna da tabela pode representar uma regra de negócio
diferente. Observe o Quadro 1, a seguir.
Condição
Cenário
1
Cenário
2
Cenário
3
Cenário
4
Cenário
5
Cenário
6
Cenário
7
Idade <18 18 >18 0 Vazio Negativo Acima
do limite
Resultado
esperado
Menor Maior Maior Inválido Inválido Inválido Inválido
Quadro 1. Tabela de decisão
Transição de estados
O critério de teste por transição de estados é utilizado para validar as transições
que acontecem dentro de um sistema ao se aplicar uma ação que depende
do estado atual ou do estado anterior. Os testes podem ser elaborados para
validar se uma sequência típica de estados está ocorrendo de forma correta
ou se alguma transição inválida pode acontecer no fl uxo.
Um exemplo muito comum é a transição de estados quando um sistema
de banco é acessado por um usuário que realiza uma compra e deseja pagar
com um cartão de crédito. Na Figura 4, a seguir, veja um fluxo simples que
demonstra astransições de estado.
Testes de caixa-preta6
Figura 4. Fluxo de transição de estado simples.
Teste de caso de uso
Os testes que utilizam o critério caso de uso são geralmente especifi cados a
partir de casos de uso e/ou cenários de negócio. Os casos de uso, por exem-
plo, representam a interação do ator com o sistema. O resultado é bastante
relevante para o usuário.
Dessa forma, os testes derivados de casos de uso são muito importantes na
descoberta de defeitos no fluxo de utilização do sistema no mundo real. Eles
podem contribuir para o aceite do produto pelo usuário final e, em casos de
integração, revelar problemas por interferência de outros componentes que
um teste individual de componente não detectou.
7Testes de caixa-preta
Demonstração de um teste de caixa-preta
Partição de equivalência
O modelo de caso com critério baseado em partição de equivalência usa grupos
ou classes de dados para validar o processamento de uma faixa de valores sem
a necessidade de testar todos os valores. Assim, é possível testar a partição
válida e a partição inválida para assegurar o resultado esperado.
Segundo Pressman e Maxim (2016), o particionamento por equivalência
é um método de teste que divide o domínio de entrada de um programa em
classes de dados. A partir dessa divisão, é possível criar os casos de teste.
Para compreender melhor, observe o Quadro 2, a seguir.
Caso de teste Validar mês selecionado
Passo Ação Resultado esperado
1 Inserir o valor “8” O mês de agosto foi selecionado.
2 Inserir o valor “0” O número inserido para o mês é
inválido.
3 Inserir o valor “13” O número inserido para o mês é
inválido.
4 Inserir o valor “XPTO” Somente é permitido número
inteiro.
Quadro 2. Partição de equivalência
Limite de valor
O modelo de caso de teste baseado em critério de valor limite valida se o sistema
identifi ca corretamente o mês digitado pelo usuário. Além disso, valida se a
regra de negócio para essa função tem tratativa para outros valores fora da
faixa defi nida de 1 a 12. Como você pode ver no Quadro 3, foi usada a técnica
de três valores nas bordas do limite, pois dessa forma é possível validar os
valores dentro, na borda e fora dela.
Testes de caixa-preta8
Caso de teste Validar mês selecionado
Passo Ação Resultado esperado
1 Inserir o valor “0” O número inserido para o mês é
inválido.
2 Inserir o valor “1” O mês de janeiro foi selecionado.
3 Inserir o valor “2” O mês de fevereiro foi selecionado.
4 Inserir o valor “11” O mês de novembro foi selecionado.
5 Inserir o valor “12” O mês de dezembro foi selecionado.
6 Inserir o valor “13” O número inserido para o mês é inválido.
Quadro 3. Limite de valor
Tabela de decisão
O modelo de caso de teste baseado no critério de tabela de decisão utiliza,
como o próprio nome já diz, uma tabela contendo as combinações necessárias
para que o sistema apresente um comportamento determinado de acordo com
o que a regra de negócio especifi ca. Veja no Quadro 4.
Caso de teste Validar maioridade
Passo Ação Resultado esperado
1 Inserir o valor “–1” Inválido
2 Deixar o valor vazio Inválido
3 Inserir o valor “0” Inválido
4 Inserir o valor “15” Menor de idade
5 Inserir o valor “18” Maior de idade
6 Inserir o valor “42” Maior de idade
7 Inserir o valor “170” Inválido
Quadro 4. Tabela de decisão
9Testes de caixa-preta
Transição de estados
O teste baseado no critério de transição de estados pode ser escrito também
com uma estrutura de tabela que aponta os estados após determinada ação
no sistema. Dessa forma, você pode realizar a ação e observar se o resultado
é compatível com o estado determinado como requisito. Veja o Quadro 5.
Caso de teste Autorizar pagamento
Estados
Transições
Insere
cartão
Senha
válida
Senha
inválida
ES1 — Iniciar ES2 — —
ES2 — Esperar — — —
ES3 — Tentativa 1 — ES6 ES4
ES4 — Tentativa 2 — ES6 ES5
ES5 — Tentativa 3 — ES6 ES7
ES6 — Aprovar — — —
ES7 — Bloquear ES1 — —
Quadro 5. Transição de estados
Caso de teste por caso de uso
Os testes que usam critério por caso de uso derivam dos casos de uso e são
relativamente simples de escrever, uma vez que a especifi cação já fornece
praticamente o modelo parecido. Veja no Quadro 6, a seguir.
Testes de caixa-preta10
Caso de teste Cadastrar cliente
Pré-condição O usuário deve estar autenticado no sistema.
Pós-condição A transferência deve ser efetivada.
Fluxo principal
Passo Ação Resultado esperado
1 Consultar saldo em
conta
Exibição de saldo em conta
2 Cadastrar beneficiário Beneficiário cadastrado
3 Realizar transferência de
valor
Emitir recibo de confirma-
ção de transferência
Fluxo alternativo
Passo Ação Resultado esperado
1 Cadastrar beneficiário Beneficiário cadastrado
2 Realizar transferência Emitir recibo de confirma-
ção de transferência
Quadro 6. Caso de teste por caso de uso
As técnicas de teste por partição de equivalência e valor limite podem ser combinadas
para um teste mais efetivo. Por um lado, você define os grupos de equivalência e dessa
forma elimina a necessidade de testes extensivos. Por outro, você testa os limites para
identificar de forma mais crítica se existem defeitos.
Aplicação de testes de caixa-preta com Java
Os testes de caixa-preta podem ser programados também em Java e executados por
softwares automatizados. Esses softwares têm a capacidade de executar comandos
11Testes de caixa-preta
para testar uma aplicação web, por exemplo, de maneira automática. O analista ou
desenvolvedor pode programar um teste na linguagem Java e facilmente executar
esse teste para obter os resultados esperados. Também é possível executar um caso
de teste manualmente e usar os softwares de automação para gravar os testes.
Esses testes podem ser salvos em código e versionados juntamente aos requisitos.
Essa versatilidade abre um leque de possibilidades para os testes e aprimora
o teste de caixa-preta, pois, via programação, comandos mais avançados podem
ser escritos. Também é possível usar JavaScript, por exemplo, e frameworks
open source, além de aplicar uma pré-condição ou uma pós-condição, executar
algum código de limpeza de dados e aplicar determinado estado em um banco
de dados para preparação do ambiente simulado ou remoção de cookies.
A seguir, observe a Figura 5. Ela mostra um exemplo de código Java que
é capaz de abrir o navegador Firefox, acessar o Google e realizar a busca dos
termos “Teste de busca no Google”.
Figura 5. Código Java.
Testes de caixa-preta12
Para executar esse código, é necessário instalar o Selenium WebDriver e
o Geckodriver, que vão executar o código, aplicar o teste e retornar com os
resultados. Existem outros softwares que também possuem agentes de testes
que trabalham de forma automática. São robôs programados para executar
testes como o demonstrado na Figura 5 de forma totalmente automática.
Isso possibilita, por exemplo, uma automação baseada em liberações,
de modo que o software é testado funcionalmente de forma automática
sempre que uma nova versão é publicada no servidor. Esse sistema é muito
útil para testes de regressão em que uma massa muito grande de testes é
executada para validar o impacto de novas mudanças ou melhorias sobre o
restante do sistema.
PRESSMAN, R. S.; MAXIM, B. R. Engenharia de software: uma abordagem profissional. 8.
ed. Porto Alegre: AMGH, 2016.
Leituras recomendadas
DELAMARO, M. E.; MALDONADO, J. C.; JINO, M. Introdução ao teste de software. 2. ed.
São Paulo: Elsevier, 2016.
IEEE COMPUTER SOCIETY. Guide to the software engineering body of knowledge. 2004.
Disponível em: https://www.computer.org/web/swebok/. Acesso em: 24 fev. 2019.
MOLINARU, L. Testes funcionais de software. São Paulo: Visual Books, 2008.
PFLEEGER, S. L. Engenharia de software: teoria e prática. 2. ed. São Paulo: Prentice Hall,
2004.
SOUZA, E. et al. Base de conhecimento em testes de software. São Paulo: Martins Fontes,
2007.
Referência
13Testes de caixa-preta
Dica do professor
O teste decaixa-preta é uma das técnicas mais usadas para validar as funcionalidades de um
software, pois trabalha com base na documentação que especifica o sistema, sem adentrar nos
modos de operação internos – por isso tem o nome de caixa-preta.
Na Dica do Professor, você vai ver os tipos de critérios usados no teste de software caixa-preta e
comparar como cada um pode ser usado em diversas situações.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://fast.player.liquidplatform.com/pApiv2/embed/cee29914fad5b594d8f5918df1e801fd/c3f19582861160acd9d8d7e1c91df056
Saiba +
Para ampliar o seu conhecimento a respeito desse assunto, veja abaixo as sugestões do professor:
Um metodo para geração de testes baseado em maquina finita
de estado estendida combinando tecnicas de teste caixa preta
O aumento da necessidade de sistemas cada vez mais confiáveis faz com que a demanda de
métodos e ferramentas que possibilitem a validação desses sistemas também cresça. Leia essa
dissertação e saiba mais sobre o assunto.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Testes de software – testes de caixa-branca e caixa-preta
Esse vídeo apresenta as principais diferenças entre esses dois tipos de teste.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Geração de casos de teste a partir de especificações B
Essa dissertação de mestrado apresenta um estudo sobre um método de geração de testes a partir
de especificações formais.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://1library.org/document/yd97vwgz-geracao-testes-baseado-maquina-finita-estendida-combinando-tecnicas.html
https://www.youtube.com/embed/QyXN_zAhqJA
https://repositorio.ufrn.br/jspui/bitstream/123456789/18005/1/FernandaMS_DISSERT_cad.pdf
Programação declarativa
Apresentação
A programação declarativa tem como principal característica a possibilidade de programar de
acordo com o objetivo a ser atingido. Assim, a programação acontece a partir do resultado que se
deseja obter com o programa e não com foco no que será executado, para atingir o resultado
esperado. É um tipo de programação em que o programa deve declarar os objetivos da sua
execução.
Nesta Unidade de Aprendizagem, você vair definir conceitualmente
o que é programação declarativa, identificar algumas linguagens
de programação declarativa e verificar algumas aplicações
desse paradigma.
Bons estudos.
Ao final desta Unidade de Aprendizagem, você deve apresentar os seguintes aprendizados:
Definir programação declarativa.•
Identificar as linguagens de programação declarativa.•
Aplicar a programação declarativa.•
Infográfico
A programação declarativa surgiu como uma forma de construção de código focado em especificar
o que você deseja alcançar e não em como. Oriunda de estudos matemáticos de alguns
pesquisadores e com o objetivo de atender demandas mais específicas, como a Inteligência
Artificial, ela vem sendo utilizada desde então. E, ao longo do tempo, algumas linguagens surgiram
como expoentes nesse paradigma.
Confira, no Infográfico, um pouco mais sobre os conceitos desse paradigma e algumas linguagens
que se aplicam aos tipos funcional e lógico.
Aponte a câmera para o
código e acesse o link do
conteúdo ou clique no
código para acessar.
https://statics-marketplace.plataforma.grupoa.education/sagah/914a14c8-b050-4b7c-824c-b2c90514a20d/a7cd9c8a-e292-4cc9-92ca-aa5a021b4136.jpg
Conteúdo do livro
As linguagens de programação que seguem o paradigma declarativo têm como característica a
construção dos programas orientados para a meta que devem alcançar e não como executarão o
passo a passo para alcançarem essas metas. Por isso, são linguagens que se tornam mais fáceis de
aprender, além de serem amplamente utilizadas no mercado, como SQL, por exemplo.
No capítulo Programação declarativa, da obra Paradigmas de Programação, você vai compreender o
significado do paradigma de programação declarativa, identificando as linguagens de programação
mais utilizadas e suas respectivas aplicações.
Boa leitura.
PARADIGMAS DE
PROGRAMAÇÃO
Fabricio Machado da Silva
Programação declarativa
Objetivos de aprendizagem
Ao final deste texto, você deve apresentar os seguintes aprendizados:
� Definir programação declarativa.
� Identificar as linguagens de programação declarativa.
� Aplicar a programação declarativa.
Introdução
Na década de 1970, a programação declarativa surgiu como um novo
paradigma para a área da programação, diferente dos já existentes, pois
exigia que o programador informasse quais os objetivos pretendidos
com a computação. Essa ação era contrária a apenas escrever algoritmos
detalhados descrevendo como os objetivos poderiam ser alcançados.
Dessa forma, a programação declarativa se constituiu como um para-
digma em que as linguagens de programação mantêm a característica de
aprendizagem mais fácil do que a linguagem de programação imperativa.
Neste capítulo, você entenderá melhor as características da progra-
mação declarativa e identificará algumas linguagens declarativas e sua
aplicação.
Programação declarativa
A linguagem de programação declarativa surgiu como um novo paradigma
de construção de programas, diferente da linguagem de programação impe-
rativa, na qual a construção de um programa ocorre por meio da construção
de algoritmos complexos que descrevem passo a passo como um determinado
resultado é alcançado, nesse paradigma, o foco está em descrever quais os
resultados devem ser alcançados. Segundo SEBESTA (2018), a programação
declarativa requer que o programador foque nos objetivos da computação, e
não em como esses objetivos serão alcançados.
As aplicações construídas seguindo o paradigma da linguagem declarativa
são classificadas em dois domínios principais, conforme descrito a seguir.
� Aplicações de inteligência artificial: no campo da inteligência artificial é
fácil imaginar porque esse paradigma se adapta bem, pois são aplicações
que se preocupam com os objetivos, utilizando regras e lógicas. Nesse
domínio a linguagem Prolog tem sido um destaque.
� Aplicações de acesso de informações em banco de dados: os maiores
usos de linguagens de programação declarativa estão concentrados no
domínio de consultas e manipulação de dados em sistemas de gestão
de base de dados (SGBD), a structured query language (SQL), por
exemplo, se tornou o expoente desse uso.
Na programação declarativa, podemos dizer que um programa é um con-
junto de declarações, por exemplo, verdade, falso, satisfaz restrição etc. O
conceito fundamental e o foco devem estar sempre na declaração, mas a sequ-
ência não importa. Além disso, é comum dizer que a programação declarativa
se distingue da programação imperativa no sentido de apenas especificar o
que, ao contrário de especificar o como.
As linguagens de programação declarativas ainda podem ser subdividas em
funcional e lógica. O Prolog se destaca como um exemplo de linguagem decla-
rativa e lógica no paradigma de linguagem declarativa e funcional. Linguagens
de cálculos, como o LISP é um exemplo disso (TUCKER; NOONAN, 2009).
A Figura 1 ilustra os diferentes tipos de programação declarativa.
Figura 1. Diferentes tipos de programação declarativa.
Fonte: Adaptada de Botelho (2015).
Programação declarativa2
Ainda no escopo de programação lógica, que é um dos tipos de programa-
ção declarativa, um programa é um conjunto de afirmações sobre as várias
entidades do domínio da aplicação. Já na programação funcional pura, um
programa é constituído por apenas um conjunto de definições de funções, e
cada função é definida sempre em razão de outras funções.
Linguagens de programação declarativa
A primeira linguagem de programação funcional a surgir foi inventada para
fornecer recursos para o processamento de listas, uma necessidade impulsionada
pelo surgimento das primeirasaplicações na área de inteligência artificial. A
programação lógica é caracterizada pelo uso de uma notação lógica formal para
comunicar processos computacionais para um computador. O cálculo de predi-
cados é, atualmente, a notação utilizada nas linguagens de programação lógica.
As linguagens de programação funcionais e lógicas são tipos de linguagens
de programação. A seguir vamos detalhar mais as linguagens funcionais LISP
e lógica Prolog, que são as principais nos seus respectivos tipos.
Linguagem de programação LISP
O interesse na área de inteligência artificial no início dos anos de 1950 fomentou
a necessidade do processamento de listas, provindas a partir da linguística, da
psicologia e da matemática (SEBESTA, 2018). Cada área tinha seu interesse
específico, os linguistas estavam interessados no processamento da linguagem
natural, os psicólogos em modelar o comportamento e os matemáticos em
mapear processos de raciocínio mental. Todos chegaram a uma conclusão em
comum: era necessário criar uma forma de permitir o processamento dados
simbólicos em listas encadeadas pelo computador. Na época, a maior lista da
computação era constituída por dados numéricos armazenados em vetores.
A linguagem de programação LISP surgiu dos estudos realizados por John
McCarthy no Massachusetts Institute of Technology (MIT). Sua primeira
versão foi chamada de LIST puro, por ser uma linguagem puramente funcional.
Essa versão do LIPS trabalhava com apenas três tipos de dados:
� Átomos, que são símbolos com a forma de identificadores ou literais
numéricos.
3Programação declarativa
� Listas, que são especificadas com a delimitação de seus elementos
com parênteses, nos quais os elementos são restritos a átomos, tendo
o seguinte formato: (A B C D).
� Estruturas de listas aninhadas, também especificadas com parênteses,
por exemplo, (A (B C) D (E (F G))), que é composta de quatro elemen-
tos. O primeiro elemento é o átomo A; o segundo, é a sub lista (B C);
o terceiro, é o átomo D; e o quarto, é a sub lista (E (F G)), que tem como
seu segundo elemento a sub lista (F G).
Como LISP foi projetada no conceito de programação funcional, todas as
computações são realizadas por meio da aplicação de função a argumentos. A
sintaxe do LISP é, portanto, muito diferente de linguagens imperativas, como
C++ ou Java. Por exemplo, em Java, a sintaxe é uma mistura de inglês e álgebra,
ao passo que em LISP, a sintaxe é um modelo simplista, o código e os dados
dos programas têm exatamente a mesma forma: listas dentro de parênteses.
Considere mais uma vez a lista (A B C D). Quando interpretada como dados,
ela é uma lista de quatro elementos, mas se vista como código, é a aplicação
da função chamada A para os três parâmetros B, C e D.
A Figura 2 demonstra a representação interna de duas listas em LISP.
Figura 2. Representação interna de duas listas em LISP.
Fonte: Adaptada de Sebesta (2018).
Programação declarativa4
Veja a seguinte função de exemplo em LISP. O código a seguir define
uma função de predicado em LISP que recebe duas listas como argumentos
e retorna True, se as duas listas forem iguais, ou NIL (false) caso contrário.
(DEFUN equal _ lists (lis1 lis2)
(COND
((ATOM lis1) (EQ lis1 lis2))
((ATOM lis2) NIL)
((equal _ lists (CAR lis1) (CAR lis2))
(equal _ lists (CDR lis1) (CDR lis2)))
(T NIL)
)
)
Linguagem de programação Prolog
O Prolog é baseado em cláusulas de Horn (um subconjunto da lógica de primeira
ordem), e é provavelmente a linguagem mais famosa na família de programação
lógica. Foi um projeto colaborativo de Alain Colmerauer, Phillipe Roussel
(ambos da Universidade de Aix-Marselha) e Robert Kowalski (Universidade
de Edimburgo). Sua primeira versão apareceu, como Smalltalk e C, em 1972.
Seu nome é uma abreviatura de programmation en logique (francês para
programação em lógica).
Para Nicoletti (2003, p. 35), o Prolog tem sido muito influente nos domínios
das provas de teoremas, sistemas especialistas, processamento de linguagem
natural e no campo da inteligência artificial (notavelmente o IBM Watson2)
em geral. Além disso, influenciou de forma significativa o desenvolvimento
da linguagem de programação Erlang.
Para Sebesta (2018), o Prolog é uma linguagem de programação de alto
nível baseada em lógica formal. Ao contrário das linguagens de programação
tradicionais, baseadas na execução de sequências de comandos, o Prolog é
baseado na definição e na solução de fórmulas lógicas. Por vezes, é chamado
de linguagem declarativa ou baseada em regras, porque seus programas con-
sistem em uma lista de fatos e regras. É, também, amplamente utilizado para
aplicações de inteligência artificial, em particular para sistemas especialistas.
5Programação declarativa
O Prolog possui quatro blocos de construção:
� lógico or;
� lógico and;
� reescrita de termos;
� unificação.
Combinando esses quatro blocos, é possível executar qualquer computação.
O Prolog, assim como o SQL, tem dois aspectos principais, um para expressar
os dados e outro para consultá-los. As construções básicas da programação
lógica, termos e declarações são herdadas da lógica. Existem três declarações
básicas:
� fatos, que são afirmações fundamentais sobre o domínio do problema
(por exemplo, “Sócrates é um homem.”);
� regras, que são inferências sobre fatos no domínio (por exemplo, “Todos
os homens são mortais.”);
� consultas, que são perguntas sobre esse domínio (por exemplo,
“É Sócrates mortal?”).
Fatos e regras são armazenados em uma base de conhecimento que o
compilador Prolog transporta para uma forma mais eficiente para consulta.
Quando “fazemos” uma pergunta, o Prolog faz uma pesquisa exaustiva por
meio do banco de dados de fatos e regras até encontrar um resultado, usando
o backtracking internamente.
Aprenda pelo menos uma nova linguagem de programação a cada ano. Diferentes
linguagens resolvem os mesmos problemas de maneiras diferentes, ao aprender várias
abordagens, você amplia seu pensamento e evita “ficar preso” em uma mesma rotina.
Além disso, aprender linguagens de programação é muito mais fácil atualmente, pois
há muitos softwares disponíveis gratuitamente na Internet.
Programação declarativa6
A escolha de linguagens declarativas, seja do tipo lógica ou funcional,
é sempre uma questão ligada ao contexto da solução que se deseja atender.
Linguagens declarativas são de excelente aplicação em contextos mais abs-
tratos, como consultas a banco de dados e questões que envolvam áreas da
inteligência artificial.
Para conhecer os pilares e conceitos do paradigma de programação orientada a
objetos acesse o link a seguir.
https://qrgo.page.link/JBCZA
BOTELHO, L. M. Inteligência artificial: apontamentos para as aulas. Lisboa: Departamento
de Ciências e Tecnologias da Informação, Instituto Superior de Ciências do Trabalho
e da Empresa, 2015. 10 p. Disponível em: http://home.iscte-iul.pt/~luis/aulas/ia/Co-
nhecimento%20declarativo%20em%20programacao%20em%20logica.pdf. Acesso
em: 21 ago. 2019.
NICOLETTI, M. C. A cartilha Prolog. São Carlos: Edufscar, 2003. 124 p. (Série Apontamentos).
SEBESTA, R. W. Conceitos de linguagem de programação. 11. ed. Porto Alegre: Bookman,
2018. 758 p.
TUCKER, A. B.; NOONAN, R. E. Linguagens de programação: princípios e paradigmas. 2.
ed. Porto Alegre: AMGH, 2009. 630 p.
Leituras recomendadas
EDELWEISS, N.; LIVI, M. A. C. Algoritmos e programação: com exemplos em Pascal e C.
Porto Alegre: Bookman, 2014. 476 p. (Série Livros Didáticos Informática UFRGS).
LEDUR, C. L. Desenvolvimento de sistemas com C#. Porto Alegre: SAGAH, 2018. 268 p.
MACHADO, R. P.; FRANCO, M. H. I.; BERTAGNOLLI, S. C. Desenvolvimento de software III:
programação de sistemas web orientada a objetos em Java. Porto Alegre: Bookman,
2016. 220 p. (Série Tekne; Eixo Informação e Comunicação).
7Programação declarativa
MILETTO, E. M.; BERTAGNOLLI, S. C. Desenvolvimento de software II: introduçãoao de-
senvolvimento web com HTML, CSS, JavaScript e PHP. Porto Alegre: Bookman, 2014.
276 p. (Série Tekne; Eixo Informação e Comunicação).
OKUYAMA, F. Y.; MILETTO, E. M.; NICOLAO, M. Desenvolvimento de software I: conceitos bá-
sicos. Porto Alegre: Bookman, 2014. 236 p. (Série Tekne; Eixo Informação e Comunicação).
PINHEIRO, F. A. C. Elementos de programação em C: em conformidade com o padrão
ISO / IEC 9899. Porto Alegre: Bookman, 2012. 548 p.
Programação declarativa8
Dica do professor
A programação funcional é uma maneira de pensar sobre a construção de software, criando funções
puras. As linguagens funcionais são declarativas, pois usam expressões e declarações, em vez de
execução de instruções. São, portanto, linguagens que apresentam características de abstração
e previsibilidade, entre outras vantagens.
Na Dica do Professor, você verá um pouco mais sobre as características da linguagem funcional e
por que ela se enquadra como um dos tipos de linguagem declarativa.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://fast.player.liquidplatform.com/pApiv2/embed/cee29914fad5b594d8f5918df1e801fd/0ea695661f58e8eb1f7dd68aa73dfbfd
Saiba +
Para ampliar o seu conhecimento a respeito desse assunto, veja abaixo as sugestões do professor:
Imperativo ou Declarativo?
Confira, neste artigo, uma comparação didática sobre as diferenças entre os Paradigmas
Declarativo e Imperativo.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
A linguagem SQL
Este artigo apresenta uma introdução sobre a linguagem declarativa SQL. Confira essa descrição e
por que essa linguagem se tornou a mais explícita do paradigma declarativo.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Introdução à Linguagem de Programação PROLOG
Confira, no vídeo, uma breve apresentação sobre a linguagem declarativa PROLOG, uma das
primeiras linguagens de programação declarativa que surgiu.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://medium.com/opensanca/imperativo-ou-declarativo-3e6dffbf301c
http://excript.com/python/introducao-sql-sqlite.html
https://www.youtube.com/embed/omLANiMqbuY
Ferramentas de teste
Apresentação
São muitas as ferramentas de software que servem para automatizar a realização dos testes.
Algumas das ferramentas são adquiridas de forma gratuita, por serem open source, e outras
necessitam de pagamento para liberação da licença.
Cabe ao gestor definir aquelas ferramentas que serão utilizadas em um determinado projeto de
software, pois a disponibilidade é muita, e é preciso adaptar cada uma à complexidade do projeto, à
experiência da equipe de testadores em programação, e ainda à linguagem de programação que foi
utilizada. Assim, é muito importante conhecer as ferramentas de teste de software mais utilizadas
pelos profissionais da área de qualidade de software.
Nesta Unidade de Aprendizagem, você vai estudar as principais ferramentas de teste de software,
sua importância, e ainda como aplicar o JUnit em testes de software em Java.
Bons estudos.
Ao final desta Unidade de Aprendizagem, você deve apresentar os seguintes aprendizados:
Identificar as ferramentas de software.•
Descrever as principais ferramentas de teste de software.•
Aplicar o teste de software com uso do JUnit e testes com JAVA.•
Infográfico
A ferramenta de testes de software JUnit é utilizada, preferencialmente, quando o software for
desenvolvido na linguagem de programação Java, pois essa é a ferramenta mais conhecida para ser
utilizada com o Java, mas se aplica também ao C++, SmallTalk, entre outras.
Veja, neste Infográfico, como se dá o teste de software com uso do JUnit.
Aponte a câmera para o
código e acesse o link do
conteúdo ou clique no
código para acessar.
https://statics-marketplace.plataforma.grupoa.education/sagah/1dc766f2-bc50-4e70-816d-17f1e38d1288/84e33300-eaea-4712-9af2-e5d57ae928ec.png
Conteúdo do livro
A lista de ferramentas que auxiliam na automatização dos testes de software é praticamente
infinita. Existem ferramentas com licença comercial e outras gratuitas, ou seja, umas são pagas e
outras são open source. A tarefa de definir uma só ferramenta de teste de software que se aplique a
todos os projetos de desenvolvimento de software é impossível, pois a ferramenta deve ser
escolhida dependendo da complexidade do projeto, da experiência da equipe de testadores em
programação, e, ainda, da linguagem de programação que foi utilizada.
Apesar disso, é importante conhecer as ferramentas mais conhecidas e mais utilizadas pelos
profissionais da área de qualidade de software.
No capítulo Ferramentas de teste, da obra Testes de software e gerência de configuração, você vai
estudar a importância das ferramentas de software, as principais ferramentas disponíveis no
mercado, e ainda a aplicação do JUnit para os testes de software com Java.
Boa leitura.
TESTES DE
SOFTWARE E
GERÊNCIA DE
CONFIGURAÇÃO
Jeanine dos Santos Barreto
Ferramentas de teste
Objetivos de aprendizagem
Ao final deste texto, você deve apresentar os seguintes aprendizados:
Identificar as ferramentas de software.
Descrever as principais ferramentas de teste de software.
Aplicar o teste de software com o uso do JUnit e testes com Java.
Introdução
As ferramentas de teste servem para automatizar as atividades de teste de
software, garantindo maior produtividade e mais rapidez na sua execução.
Existem muitas ferramentas que podem ser utilizadas em qualquer projeto
de desenvolvimento de software. Há opções com licenças pagas ou gratuitas,
mas nenhuma pode ser definida como a melhor. Cabe ao gestor do projeto
definir a ferramenta mais adequada, o que depende do artefato produzido.
Nesse sentido, é importante que você conheça as ferramentas mais
utilizadas pelos profissionais da área de qualidade de software. Neste capítulo,
você vai estudar as ferramentas de software, as principais ferramentas de teste
de software e ainda a aplicação do JUnit para os testes de software com Java.
Ferramentas de software
A realização dos testes, durante o desenvolvimento de um software, é a ativi-
dade que assegura a entrega de um produto de qualidade ao usuário fi nal. Isso
ocorre principalmente quando os testes são feitos ao longo de todo o ciclo de
vida do projeto, pois eles garantem o alinhamento aos requisitos do software.
O teste de software é um aspecto do projeto que exige planejamento, tempo,
conhecimento técnico, recursos, infraestrutura adequada e principalmente
comprometimento — tanto dos gestores do projeto quanto dos analistas que
trabalharão como testadores.
Como você pode imaginar, quanto mais tarde ocorre a correção de proble-
mas identificados nos testes, maior é o custo decorrente dessas correções, tanto
financeiros quanto de imagem perante os usuários finais. Daí a importância
da realização dos testes desde o início do projeto de software (PRESSMAN;
MAXIM, 2016). Apesar disso, ainda existem muitas empresas que ignoram
essa realidade e não dedicam tempo e recursos suficientes para a realização
de testes de software. Isso gera incerteza, insegurança e falta de confiança dos
clientes devido à presença de problemas na execução das aplicações.
É comum que os fabricantes de software deixem a realização dos testes
para o final do projeto, após o término da codificação. Nesse momento, pode
ser que muitos problemas identificados já não possam mais ser resolvidos, pois
envolvem aspectos iniciais do projeto, como é o caso de um mal-entendido
relacionado aos requisitos. Além disso, mesmo que os testes sejam realizados
ao longo de todo o projeto, é praticamente impossível garantir que sejam
identificados todos os problemas do software. Ou seja, quanto antes os testes
se iniciarem, maior será a cobertura de problemas identificados.
Testar um software significa fazeraveriguações e questionamentos em seu código-
-fonte e em sua interface com base em um planejamento de testes. A ideia é analisar
as respostas obtidas e, assim, verificar se estão de acordo ou não com o produto
idealizado inicialmente pelos usuários.
Existem basicamente três problemas que podem ser encontrados durante
a realização dos testes em um software, como você pode ver a seguir (PRES-
SMAN; MAXIM, 2016).
Erro: normalmente é causado por algo que o ser humano fez de errado.
Pode ser um trecho de código de programação incorreto, um design
inadequado em uma parte da interface, entre outros exemplos.
Defeito: decorre de um erro, pois quando uma codificação ou um
design são elaborados de maneira incorreta, isso gera um problema de
documentação, codificação ou design de interface.
Falha: decorre de um defeito, ou seja, quando um defeito ocorrer,
pela tentativa de execução de uma parte do código ou da interface
com problema, uma falha de sistema vai acontecer e o sistema não vai
funcionar corretamente, podendo até mesmo sofrer uma interrupção
na sua execução.
Ferramentas de teste2
Com usuários cada vez mais exigentes e um mercado cada vez mais competitivo,
entregar softwares de qualidade para o cliente final não é mais uma preocupação
de poucos, mas de todos os fabricantes. Afinal, a qualidade agora é um requisito
fundamental para que o software garanta a sua sobrevivência no mercado.
Hoje, as empresas fabricantes de software mais competitivas são aquelas
que buscam melhorar continuamente seus processos para garantir um aumento
crescente no nível de qualidade dos produtos oferecidos. Nesse sentido, é
interessante adotar ferramentas que possam prestar suporte a esse processo
de melhoria contínua. Atualmente, existem ferramentas que auxiliam durante
todo o ciclo de vida do projeto de desenvolvimento de software, desde o seu
início até a sua implantação junto ao usuário final.
As ferramentas de software permitem maior cobertura de identificação
de problemas e diminuem o esforço dos testadores e de toda a equipe, tanto
no apontamento dos problemas quanto na sua correção. Essas ferramentas
podem ser divididas nas categorias listadas a seguir. Elas são utilizadas ao
longo do ciclo de vida de desenvolvimento do software, como você pode ver
na Figura 1 (CAETANO, 2007).
Ferramentas para gestão de defeitos
Ferramentas para gestão de testes
Ferramentas para gestão de projetos
Ferramentas para automação de testes funcionais e de aceitação
Ferramentas para automação de testes de performance
Ferramentas para controle de versões
Ferramentas de apoio
Figura 1. Utilização das ferramentas de software ao longo do ciclo de vida do produto.
Fonte: Adaptada de Caetano (c2019, documento on-line).
3Ferramentas de teste
A utilização de ferramentas na realização das atividades de testes de
software proporciona alguns benefícios muito importantes (CAETANO,
2007). Veja:
os testes podem ser repetidos em sua integralidade, de maneira exaustiva,
sem que isso torne a atividade incômoda e maçante para os testadores;
os casos de teste podem ser armazenados e executados, e seus resultados
podem ser documentados de maneira facilitada, ficando disponíveis para
que os demais integrantes da equipe de projeto os utilizem em seu trabalho;
os testes podem ser reproduzidos de maneira fiel, pois existe documen-
tação para cada atividade realizada no âmbito da ferramenta;
são gerados arquivos de log apontando tudo o que foi feito no decorrer
das atividades de teste, com indicação dos problemas encontrados.
Assim como a maneira de desenvolver softwares se modifica ao longo do
tempo, as ferramentas e tecnologias também mudam. O objetivo das mudanças
é aumentar a produtividade e a qualidade e garantir a satisfação do cliente por
meio da entrega de um produto confiável.
Principais ferramentas de teste de software
Existem incontáveis ferramentas de teste de software disponíveis no mer-
cado. Várias delas são pagas e outras tantas são open source. Não existe uma
ferramenta que possa ser indicada como a melhor de todas, mas é possível
destacar as principais delas, por serem as mais utilizadas. Cabe aos analistas
responsáveis pelo projeto decidir que ferramenta se adapta melhor a cada caso.
Open source (código aberto) é um modelo de desenvolvimento que libera o licen-
ciamento para o design ou a codificação de um produto de software, permitindo a
sua distribuição universal e ainda a consulta, a análise e a modificação do produto.
Para isso, não é necessário pagar uma licença, o que torna esse tipo de produto uma
produção intelectual colaborativa.
Ferramentas de teste4
Não existe uma ferramenta ideal para ser aplicada em todos os casos.
Contudo, uma ferramenta automatizada de teste de software precisa envolver
necessariamente os seguintes aspectos para ser considerada um instrumento
de auxílio na realização das atividades de teste (CAETANO, 2007):
cada uma das menores partes do software que precisa ser testada deve
ser executada de maneira isolada e independente de todas as outras
unidades testadas;
todos os erros, defeitos e falhas identificados devem ser documentados;
a definição de cada unidade de teste, ou menor parte do software que
precisa ser testada, deve ser definida de maneira simples e não complexa.
TestLink
O TestLink é uma ferramenta automatizada de testes de software open source
escrita na linguagem de programação PHP. O principal objetivo dessa ferra-
menta é dar suporte às atividades realizadas para a gestão de testes. Como
padrão, o TestLink é instalado na língua inglesa, mas é possível alterar essa
confi guração para o idioma português.
Por meio do TestLink, você pode elaborar planos de testes e gerar relató-
rios com diversas informações para acompanhar a realização das atividades
de testes. Essa ferramenta também possibilita registrar e organizar todos os
requisitos levantados junto ao usuário no início do projeto e, posteriormente,
associar cada caso de teste criado ao requisito correspondente.
Para fazer o download e saber mais sobre a ferramenta de testes TestLink, acesse o
link a seguir.
https://goo.gl/1WBFFE
As principais funcionalidades oferecidas pela ferramenta TestLink são
(CAETANO, 2007):
controle de acesso e níveis de permissão, dependendo do perfil do
usuário (por exemplo, testador ou gerente de projeto);
5Ferramentas de teste
organização dos casos de teste em pacotes hierárquicos que podem ser
organizados por prioridade;
classificação dos casos de teste por palavras-chave, a fim de facilitar a
pesquisa e organizar ainda mais a disposição dos casos de teste;
criação ilimitada de projetos e de casos de teste dentro de cada projeto,
ou seja, não há limite de quantidade para nenhum deles;
atribuição dos planos e casos de teste a testadores específicos;
geração de relatórios e gráficos com informações sobre os testes que
podem ser exportadas para diversas extensões, como CSV, PDF, Mi-
crosoft Excel e Microsoft Word;
possibilidade de integração com outras ferramentas automatizadas de
gestão de testes e de defeitos, como o Mantis.
Selenium
A ferramenta de testes de software chamada Selenium surgiu nos anos 2000,
evoluiu ao longo dos anos e atualmente é uma das mais conhecidas ferramentas
de automação de teste open source para aplicativos web (CAETANO, 2007).
Para fazer o download e saber mais sobre a ferramenta de testes Selenium, acesse o
link a seguir.
https://goo.gl/52Qs4M
O Selenium é multiplataforma, ou seja, funciona em diversos sistemas
operacionais, como Windows, Mac e Linux, e ainda em diversos navegadores
web, como Chrome, Internet Explorer e Firefox. Além disso, os seus scripts
de teste podem ser escritos em diversas linguagens de programação, como
Python, Ruby, Perl e Java.
Apesar de o Selenium poder ser utilizado em diversos ambientes de pro-
gramação diferentes, além de suportar casos de teste complexos que atendema altos níveis de complexidade de sistemas, é necessário ter muito conheci-
mento técnico para trabalhar com ele. É preciso ter habilidades avançadas
Ferramentas de teste6
de programação. Além disso, é requerido bastante esforço para a criação de
estruturas automatizadas e bibliotecas que atendam às necessidades de teste,
por mais simples que sejam.
IBM Rational Functional Tester
A ferramenta de teste chamada IBM Rational Functional Tester é paga e serve
para a realização de testes funcionais e testes de regressão. Os scripts dos
casos de teste são escritos em Visual Basic, .NET e Java (CAETANO, 2007).
Para fazer o download e saber mais sobre a ferramenta de testes IBM Rational Functional
Tester, acesse o link a seguir.
https://goo.gl/oEAWD1
O IBM Rational possui um recurso inédito entre as ferramentas de teste: o
teste do storyboard. Nele, as ações dos usuários e testadores são registradas
e podem ser visualizadas posteriormente no formato de storyboard, feito por
meio de capturas da tela da ferramenta.
TestComplete
O TestComplete é uma ferramenta de testes paga considerada muito poderosa
para a realização de testes em aplicações web, dispositivos móveis e desktops.
Essa ferramenta suporta a elaboração de scripts de casos de teste em JavaScript,
VBScript, C++ e Python (CAETANO, 2007).
Para fazer o download e saber mais sobre a ferramenta de testes TestComplete, acesse
o link a seguir.
https://goo.gl/UBu3QL
7Ferramentas de teste
A ferramenta TestComplete possibilita que os testadores realizem testes
orientados por palavras-chave e dados. Além disso, oferece um recurso que
permite a gravação dos testes realizados e a sua reprodução, de maneira
simples e fácil de usar.
Teste de software com JUnit e testes com JAVA
Na área da engenharia de software, uma das atividades mais importantes é
o teste de software. Ele precisa ser feito ao longo de todo o ciclo de vida do
projeto de desenvolvimento do software. Isso se torna mais evidente quando
a equipe de projeto trabalha com extreme programming, que tem uma visão
voltada principalmente para os testes (CAETANO, 2007).
A eXtreme Programming (XP), que em português significa “programação extrema”,
é uma metodologia ágil de desenvolvimento de software. Ela é aplicada principal-
mente quando a equipe desenvolvedora do sistema não conta com requisitos muito
precisos, ou ainda quando os requisitos sofrem mudanças constantes, como no caso
de softwares financeiros.
Na metodologia XP, a codificação e os testes são realizados e acompanhados de
maneira constante e contínua, para que os ajustes sejam feitos ao longo do projeto
de desenvolvimento. Na metodologia ágil, ou no desenvolvimento ágil de software,
o produto de software é fabricado aos poucos, em pedaços e períodos predefinidos,
na tentativa de diminuir o máximo possível os riscos com o desenvolvimento.
Quando o produto de software precisa ser desenvolvido na linguagem
de programação Java, os testes de software podem ser implementados por
meio do JUnit. Atualmente, ele é um dos frameworks mais conhecidos para
a realização de testes em Java.
O JUnit é um framework que pertence a uma família de ferramentas de testes
de software chamada xUnit. Essas ferramentas são aplicadas em produtos de
software desenvolvidos em C++, SmallTalk, Java e outras linguagens de progra-
mação. Apesar de o JUnit ser bem simples de se utilizar, ele traz um ambiente
completo para a realização dos testes unitários e dos testes de regressão em
códigos escritos na linguagem Java, facilitando o trabalho do desenvolvedor.
Ferramentas de teste8
Os testes unitários, que são aqueles realizados por meio do JUnit, asseguram
que cada método projetado trabalhe da maneira como se espera, averiguando
as menores partes do código desenvolvido, que, no caso da metodologia ágil,
são os métodos.
Para entender melhor o que significam essas menores partes do código, basta você
imaginar um sistema de uma escola em que existe uma classe chamada Aluno, com os
métodos calcularMedia() e calcularMensalidade(). Para averiguar se existe algum erro
que envolva esses métodos, é necessário testar cada um deles a fim de entender de
onde o problema está vindo. Para a realização desses testes unitários, uma boa saída
são os testes automatizados, que aumentam a produtividade do desenvolvedor pois
diminuem o tempo gasto com testes.
Essa ferramenta é dividida em duas partes: uma com métodos e anotações
que servem para a elaboração dos casos de teste; e outra que serve para realizar
a execução dos casos de teste criados pela primeira parte (CAETANO, 2007).
A execução dos testes, por meio do JUnit, é feita de forma totalmente
automatizada e sem que seja necessária a intervenção humana. Além disso,
a apresentação do resultado dos testes realizados pelos testadores é feita por
meio de algo semelhante a um semáforo: a cor verde significa que o teste foi
executado da maneira como estava escrito no caso de teste; a cor azul significa
que o teste apresentou algum erro de validação; e a cor vermelha significa que
houve algum erro de exceção na escrita do código em Java.
Para trabalhar com o JUnit, você deve tomar algumas precauções durante o
planejamento dos testes (BITTENCOURT; TESSMANN; SCHIRMER, 2019):
definir um pacote em que fiquem armazenadas todos os casos de teste;
levar em consideração que cada caso de teste é responsável pelos testes
de uma classe do sistema;
criar vários procedimentos de teste, de modo que cada um deles realize
pequenos testes.
9Ferramentas de teste
Tomando essas medidas, a cobertura e a identificação dos testes serão
muito mais abrangentes. Caso sejam encontrados problemas ou erros, eles
poderão ser identificados de maneira muito mais rápida e simples ao longo
dos casos de teste.
Para começar a trabalhar com o JUnit, você precisa fazer o download do framework,
que está disponível de maneira gratuita no link a seguir. É comum também que os
ambientes de desenvolvimento integrado (Integrated Development Environments — IDEs)
mais utilizados pelos desenvolvedores já tragam o JUnit embutido em seus pacotes
(BITTENCOURT; TESSMANN; SCHIRMER, 2019).
https://junit.org
Na versão atual, o JUnit se divide em sete classes e interfaces, que são
Assert, TestResult, Test, TestListener, TestCase, TestSuite e BaseTestRunner.
As principais são a TestCase, a TestSuite e a BaseTestRunner.
Para testar o código, o JUnit oferece o método assert, que é muito fácil de
entender. Um método de asserção, ou assert, recebe o valor que é o esperado
como resultado para o teste, ou seja, o valor correto, e um outro que é o resul-
tado obtido pelo teste. A comparação entre eles é realizada e o teste falha se
os valores forem diferentes, mas é realizado com sucesso se eles forem iguais.
Conhecendo esse conceito de assert, é possível realizar o teste em todo o
código desenvolvido. É preciso apenas conhecer os requisitos do sistema (a
ponto de saber quais valores devem ser retornados em cada teste) e os resultados
obtidos com os testes (para tecer as comparações).
Uma boa maneira de escrever um teste unitário eficiente é colocar asser-
ções para os valores realmente críticos ou relevantes para o sistema. Ou seja,
talvez não seja necessário testar valores intermediários das classes, apenas
resultados finais. Porém, outras vezes talvez os resultados intermediários
interfiram diretamente no resultado final e seja interessante inserir asserções
para eles também.
Ao adicionar casos de teste no JUnit, você deve ter em mente que um valor
pode corresponder a qualquer objeto Java. Por isso, é fundamental implementar
Ferramentas de teste10
o equals e o hashcode dos objetos de resposta que precisarão ser testados com
o JUnit (BITTENCOURT; TESSMANN; SCHIRMER, 2019).
Como exemplo de implementação de método de teste no JUnit, considere
o seguinte:
Como o método criado é um void, ele não vai receber nenhum argumento, ou
seja, será uma classe de testemesmo. A partir disso, é preciso inserir asserções
para que se possa compreender o funcionamento do método:
Nesse código, o primeiro argumento é a mensagem que vai aparecer caso
o teste falhe. Para visualizar a mensagem de erro, basta alterar o último ar-
gumento para que traga um resultado incorreto. Essa é a maneira mais fácil e
básica de entender como os testes são realizados por meio do JUnit.
Caso o teste precise envolver elementos mais complexos, o script do caso
de teste pode se parecer com o que é mostrado na Figura 2, a seguir.
Figura 2. Script mais complexo para testes com JUnit.
Fonte: Bittencourt, Tessmann e Schirmer (2019, p. 10).
11Ferramentas de teste
É importante você observar que a string é inicializada e recebe valor null
por três vezes, porque existem três métodos de teste. Os métodos @Before
são executados antes dos métodos de teste, e o @After é executado depois
deles. As anotações @Before e @After, da maneira como foram utilizadas,
permitem criar cenários de teste sempre zerados e corretamente inicializados
a cada ciclo de teste (BITTENCOURT; TESSMANN; SCHIRMER, 2019).
BITTENCOURT, G.; TESSMANN, P. V.; SCHIRMER, T. Teste de software: uma introdução
ao uso do JUnit em testes unitários. [2019]. Disponível em: https://www.academia.
edu/17303382/Teste_de_Software_Uma_introdu%C3%A7%C3%A3o_ao_uso_do_Ju-
nit_em_testes_unit%C3%A1rios?auto=download. Acesso em: 09 mar. 2019.
CAETANO, C. Automação e gerenciamento de testes: aumentando a produtividade com
as principais soluções open source e gratuitas. São Paulo: Novatec, 2007.
CAETANO, C. Automação e gerenciamento de testes: aumentando a produtividade
com as principais soluções open source e gratuitas (2a edição). c2019. Disponível em:
http://www.linhadecodigo.com.br/artigo/1566/automacao-e-gerenciamento-de-
-testes-aumentando-a-produtividade-com-as-principais-solucoes-open-source-e-
-gratuitas-2a-edicao.aspx. Acesso em: 09 mar. 2019.
PRESSMAN, R. S.; MAXIM, B. R. Engenharia de software: uma abordagem profissional.
8. ed. Porto Alegre: AMGH, 2011.
Ferramentas de teste12
Dica do professor
Existem muitas ferramentas que servem para automatizar as atividades de testes de software. Não
existe uma ferramenta que seja a mais importante ou a mais acertada para ser utilizada em todos os
projetos de software, pois algumas ferramentas são pagas e outras são gratuitas. Em vista disto, é
preciso que os gestores de projeto escolham as ferramentas que serão utilizadas, dependendo das
características do projeto em questão.
Nesta Dica do Professor, você vai aprender sobre as principais ferramentas de teste de software.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://fast.player.liquidplatform.com/pApiv2/embed/cee29914fad5b594d8f5918df1e801fd/8121167073a67489abbb91b4847aeed9
Saiba +
Para ampliar o seu conhecimento a respeito desse assunto, veja abaixo as sugestões do professor:
Escolhendo quais testes rodar através do JUnit e profiles do
Maven
Leia este artigo para saber mais sobre quando utilizar a ferramenta open source de testes JUnit,
quais testes rodar, e como escrever códigos simples de testes.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
SOAPUI Uma ferramenta muito útil para quem desenvolve
webservices
Leia o artigo publicado na página 22, da edição 59, da revista Programar, que fala sobre o SoapUI e
a ajuda que essa ferramenta presta para os profissionais da área de qualidade de software que
trabalham desenvolvendo webservices.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Teste automatizado de software Selenium IDE
Veja este tutorial sobre a ferramenta de teste automatizado de software Selenium IDE.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://docplayer.com.br/49911054-Escolhendo-quais-testes-rodar-atraves-do-junit-e-profiles-do-maven.html
https://www.revista-programar.info/static/downloads/download.php?t=site&e=59
https://www.youtube.com/embed/kzBs4EUn4Oo
Teste automatizado com Selenium e Cucumber
Leia esta matéria para saber mais sobre os testes automatizados com a ferramenta Selenium, da
IBM, para assegurar que uma aplicação web funcione da maneira esperada.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://www.ibm.com/developerworks/br/library/a-automating-ria/index.html
Programação estruturada
Apresentação
A programação estruturada é um paradigma de programação cujo princípio é a construção de
códigos legíveis, de fácil entendimento e manutenção. É um paradigma independente de linguagem
de programação que fez grande sucesso entre os desenvolvedores por estabelecer uma disciplina
rígida de padronização e construção de programas.
Nesta Unidade de Aprendizagem, você vai compreender os princípios e fundamentos da
programação estruturada, vai ainda conhecer algumas linguagens de programação que
implementam esse paradigma e a sua aplicação em casos reais.
Bons estudos.
Ao final desta Unidade de Aprendizagem, você deve apresentar os seguintes aprendizados:
Reconhecer a programação estruturada.•
Descrever as linguagens de programação estruturada.•
Aplicar a programação estruturada.•
Infográfico
Nos anos 70, em decorrência da crise do software das décadas antecessoras, surgiram avanços na
linguagem de programação, como a programação estruturada. A programação estruturada,
portanto, foi a consequência de melhorias no padrão de desenvolvimento de software.
A seguir, no Infográfico, veja, de forma sintetizada, alguns eventos de melhoria nas linguagens que
surgiram nessa época e que estão relacionados com a programação estruturada.
Aponte a câmera para o
código e acesse o link do
conteúdo ou clique no
código para acessar.
https://statics-marketplace.plataforma.grupoa.education/sagah/0d30b93c-7e68-43a5-8be5-6a6ce02e9697/5233d460-bb21-4205-92b2-4389b1926ac8.png
Conteúdo do livro
A crise do software, cujo ápice foi na década de 60, fez com que a indústria do ramo desenvolvesse
novas formas de construção de software voltadas a uma fácil manutenção e entendimento dos
programas de computadores. Neste cenário, surgem novas formas de se estruturar o código e
outras linguagens para suportar novas estruturas de programação. Assim, surgem os conceitos que
formariam os fundamentos do paradigma de programação estruturada.
Leia o capítulo Programação estruturada, da obra Paradigmas da Programação, e aprenda o
significado de programação estruturada, vendo também algumas linguagens percursoras
do paradigma e como são implementados programas com os conceitos de programação
estruturada.
Boa leitura.
PARADIGMAS DE
PROGRAMAÇÃO
Fabricio Machado da Silva
Programação estruturada
Objetivos de aprendizagem
Ao final deste texto, você deve apresentar os seguintes aprendizados:
� Reconhecer a programação estruturada.
� Descrever as linguagens de programação estruturada.
� Aplicar a programação estruturada.
Introdução
O paradigma de programação estruturada se refere a construção de
programas que permitem uma clareza lógica na implementação de seu
código. Esse paradigma, implementado por muitas linguagens, como
Pascal, C, Fortran e Cobol, foi muito utilizado em programas nas décadas
de 1970 e 1980.
A programação estruturada tem como princípio a estruturação do
código por intermédio de apenas três estruturas de controle básicas.
Neste capítulo, você entenderá melhor os conceitos da programação
estruturada, a sintaxe de algumas das linguagens que utilizam esse tipo
de programação e a sua aplicação em alguns programas.
Programação estruturada
Para entender a motivação que originou a programação estruturada, é funda-
mental lembrar que tudo começou com a famosa crise do software na década de
1960. Nessa época, Edsger W. Dijkstra, por meio do seu artigo A Case against
the GO TO Statement,criticou o uso excessivo desse comando na programação.
O comando GO TO, amplamente utilizado pelas linguagens de programação da
época, trata-se de uma estrutura de controle para permitir saltos de instruções.
Sua ampla utilização pelos programadores gerava um número considerável de
programas praticamente impossíveis de serem entendidos, e a consequência
disso era a dificuldade de manutenção dos programas.
Essa declaração foi originalmente essencial para a programação no Basic,
pois os intérpretes mais antigos apenas permitiam que as instruções if fossem
executadas em uma linha e não tinham manipulação mais avançada dos loops
for ou while. Nas versões modernas do Basic, você verá o GOTO, grafado
como uma única palavra, usado apenas para retornar ao topo de um loop
principal (SEBESTA, 2018, p. 267). No exemplo a seguir, você pode observar
a implementação do comando GOTO no Basic, que fica lendo um valor na tela
e retornando à instrução para ler o novo número.
10 READ R
20 PRINT "R ="; R;
30 A = 3.14*R^2
40 PRINT "AREA ="; A
50 GOTO 10
Segundo Tucker e Noonan (2009, p. 168), “A controvérsia do comando
Go To começou com uma nova carta de Dijkstra, desta vez para o editor da
Communications of the ACM, intitulada Go To Statement Considered Harmful
(Declaração Go To considerada prejudicial). Com essa carta, a revolução da
programação estruturada estava lançada.
A partir de então, inicia-se uma revolução na forma de construção de
códigos para programas, que seria a base para o surgimento da programação
estruturada. De modo geral, esse paradigma de programação, com o objetivo
de corrigir os problemas citados, embasava o projeto de programas com prin-
cípios básicos por meio da utilização de apenas três estruturas de controle:
� Sequência — implementa os passos de processamento necessários
para a descrição de qualquer programa, por exemplo, um segmento
de código em que é enviado o comando ''faça tarefa 1'' e,
logo após, o comando ''faça tarefa 2'', pode ser representado
com a sequência de dois retângulos, ou em um pseudocódigo que seria
denotado pela expressão das duas tarefas uma após a outra.
� Seleção — possibilita que o fluxo de processamento seja selecionado
com base em sentenças lógicas, para isso são usadas duas formas de
condicional; a primeira seria o uso da condicional if then, e a
segunda, switch.
� Iteração — possibilita que segmentos do programa tenham a sua exe-
cução repetida até que uma determinada cláusula seja satisfeita. São
implementados por comandos while ou for, por exemplo.
Programação estruturada2
Na Figura 1 são demonstrados um exemplo de cada condicional de seleção.
Figura 1. Exemplo de condicionais if e switch.
Fonte: Monteiro (2018, documento on-line).
Outra razão importante para o início do movimento pela programação
estruturada foi a mudança no custo maior da computação de hardware para
de software, o que, consequentemente, exigia uma maior preocupação com a
construção e a manutenção de programas de computador (SEBESTA, 2018,
p. 40).
De forma geral, a programação estruturada foi um sucesso e os objetivos
foram alcançados. Os programadores abandonaram o uso irrestrito do comando
Go To e passaram a utilizar as construções em condições de laços e condições,
tanto que é raro encontrar o uso do comando Go To, apesar de ele ainda ser
utilizado em algumas poucas linguagens de programação. A evolução na pro-
gramação e o surgimento de novos paradigmas também tiveram uma grande
influência nos princípios básicos que originaram o paradigma da programação
estruturada. Muitas linguagens implementaram seus conceitos, mas algumas
tiveram maior influência na divulgação deles.
O desenvolvimento das linguagens C, Fortran 77 e Pascal no final da década
de 1960 estimularam o sucesso da programação estruturada. Diferentemente
de Fortran 66, essas linguagens permitiam o uso de laços e condicionais,
incluindo os laços com teste no início e teste no final do bloco de execução
laços for, comandos if-then-else e comandos switch/case, junto
ao comando composto que permitia o alinhamento dessas construções. C
também incluiu formas restritas de comandos Go To, englobando os comandos
return, break e continue.
3Programação estruturada
A seguir, você verá como as linguagens Fortran e Pascal implementam os
conceitos da programação estruturada e como foram fundamentais na ampla
divulgação e implementação do seu paradigma pelos desenvolvedores ao longo
da evolução da programação.
Linguagens de programação estruturadas
Agora que você já viu o que significa o paradigma de programação estruturada,
vamos explicar um pouco sobre as linguagens Fortran 77 e Pascal, conside-
radas, juntamente a linguagem C, como as linguagens-chave no processo de
implantação do conceito de programação estruturada.
Fortran surgiu como linguagem de programação de propósito geral, mas
foi muito utilizada em aplicações na área de engenharia. Sua primeira versão
foi em 1957, mas sem dúvida a versão mais utilizada é a 77, que implementa
os conceitos de programação estruturada (FARRER et al., 1992, p. 35).
A grande inovação foi que muitos compiladores Fortran 77 admitem sub-
conjuntos de comandos, isto é, aceitam extensões fora do padrão estabelecido
pelo American National Standards Institute (ANSI). Um programa em Fortran
77 básico é composto por uma sequência de linhas de texto que devem obe-
decer a uma determinada sintaxe para ser reconhecido como programa em
Fortran válido. A Figura 2 mostra um exemplo de um programa em Fortran
simplificado.
Figura 2. Exemplo de programa em Fortran.
Fonte: Farrer et al. (1992, p. 45).
Programação estruturada4
Segundo Farrer et al. (1992, p. 35) um programa em Fortran 77 deve
seguir algumas regras e restrições para a escrita de seu código fonte, ou seja,
podemos verificar regras que obedecem aos princípios e conceitos propostos
pela programação estruturada. Para que uma linguagem de programação seja
considerada estruturada é importante que, além do conceito de sequência,
também sejam implementadas as condicionais e comandos interativos. Em
Fortran 77, a estrutura condicional é alcançada pela instrução if-else. É
muito comum o uso da instrução if em Fortran, podendo ser empregada
de formas diferentes. O comando executável if (expressão lógica) deve ser
escrito em uma linha; no exemplo a seguir ela determina o valor absoluto de x:
if (x .LT. 0 ) x = -x
Se mais de um comando tiver de ser escrito dentro de if, então a seguinte
sintaxe será adotada:
if (expressão lógica) then
comandos
endif
Sendo assim, a estrutura geral de uma condicional if tem o seguinte
aspecto:
if (expressão lógica) then
comandos
elseif (expressão lógica) then
comandos
:
:
else
comandos
end if
Com relação a comandos interativos, o Fortran 77 tem apenas uma forma
de construção de loop, chamada do-loop. O do-loop corresponde ao que é
conhecido como for-loop em outras linguagens.
5Programação estruturada
A forma geral do comando do-loop é a seguinte:
do label var = expr1, expr2, expr3
comandos
label continue
onde:
var é uma variável do tipo integer (geralmente chamada de índice do loop);
expr1 especifica o valor inicial de var;
expr2 é o limite terminal do-loop;
expr3 é o incremento ou passo do-loop.
A variável do comando do-loop nunca deve ser modificada por outro comando dentro
do loop, pois isso causaria uma grande confusão. Muitos compiladores Fortran 77
permitem que do-loops sejam encerrados com o comando enddo. A vantagem é que o
comando label pode então ser omitido. A construção do loop com enddo é largamente
usada, mas não é um componente do Fortran 77 ANSI.
A linguagem C foi outra linguagem que teve importante papel na divulgação
da programação estruturada. Foi projetada inicialmente para ser implemen-
tada no sistema operacional UNIX nos laboratórios Bell, por Ken Thompson
e Dennis Ritchie, que participavam ativamente do desenvolvimento de um
avançado sistema operacional e que, aocontrário dos sistemas operacionais
criados, estava sendo escrito em Programming Language One (PL/I), em vez
de Assembly (OKUYAMA; MILETTO; NICOLAO, 2014, p. 78).
Após o laboratório Bell desistir do projeto do sistema operacional, Thomp-
som e Ritchie continuaram o desenvolvimento de um sistema de documentação,
que seria independente de máquina e possibilitava a execução em minicompu-
tadores baratos do final de 1960. Nascia, assim, o sistema operacional UNIX.
A linguagem C foi utilizada na construção desse sistema operacional, incial-
mente baseada na linguagem Basic Combined Programming Language (BCPL),
que não possuía tipo (OKUYAMA; MILETTO; NICOLAO, 2014, p. 79).
Programação estruturada6
A partir disso, a linguagem C foi muito utilizada, principalmente em
ambientes acadêmicos, tendo, inclusive, impacto no surgimento de inúme-
ras outras linguagens conhecidas atualmente, como Java, Python e C++
(PINHEIRO, 2012, p. 68).
A Common Business Oriented Language (Cobol) é uma linguagem de
programação que foi amplamente utilizada em organizações nas décadas
de 1970 e 1980. Outra linguagem de programação que teve importância na
disseminação do paradigma de programação estruturada foi a linguagem
Pascal, desenvolvida entre 1968 e 1970 por Nicklaus Wirth, da Universidade de
Zurique, na Suíça. Pascal tem grande relevância na programação estruturada,
porque um de seus objetivos era justamente segundo Farrer et al. (1999, p. 35)
“desenvolver uma linguagem de programação disciplinada de alto nível para
ensinar programação estruturada. Esta linguagem foi batizada com o nome
de Pascal, em homenagem a Blaise Pascal, filósofo e matemático francês que
viveu entre 1623 e 1662”.
Pascal obteve uma grande adesão, principalmente na comunidade acadê-
mica, sendo utilizada como linguagem de apresentação ao desenvolvimento
de programas por universidades nas décadas seguintes.
Todo programa construído em Pascal é basicamente subdividido em três
partes distintas, conforme detalhado a seguir.
� Cabeçalho do programa: é a área do código utilizada para se fazer a
identificação do programa, é atribuído pela instrução program seguido
de um nome, por exemplo, program CALCULA_AREA.
� Área de declarações: é utilizada para validar o uso de qualquer tipo
de identificador que não seja pré-definido, estando subdividida em
sete subáreas: uses, label, const, type, var, procedure e
function, por exemplo, A, B, C: integer.
� Corpo do programa: é o local em que o programa propriamente está
escrito, tem início com a instrução begin e é finalizado pela instrução
end, seguida do símbolo ponto (.). O uso dessas instruções caracteriza
o que chamamos de bloco.
7Programação estruturada
A Figura 3 mostra um exemplo de programa em Pascal.
Figura 3. Exemplo de programa em Pascal.
Fonte: Farrer et al. (1999, p. 41).
Pascal trabalha com estruturas condicionais representadas pelo comando
if, que tem por finalidade tomar uma decisão e desviar o fluxo de processa-
mento com base em uma sentença lógica.
if (x > 10) then
writeln("O valor da variável X é 10");
As estruturas de repetição em Pascal são implementadas pelos comandos
for, while e repeat, que tem por objetivo repetir a execução de um
bloco de instruções enquanto uma sentença for válida. Veja um exemplo de
estrutura for em Pascal:
for variavel := <início> to/downto <fim> do
begin
instrução1;
instrução2;
instrução3;
end;
Programação estruturada8
E, agora, um exemplo de estrutura while em Pascal:
while <condição> do
begin
<instruções para condição verdadeira>;
end;
E uma estrutura repeat em Pascal:
repeat
<comando1>;
<comando2>;
<comando3>;
until <condição>;
A seguir, analisaremos alguns exemplos da aplicação da programação
estruturada em algoritmos para fixar o entendimento.
Desenvolvendo e aplicando programação
estruturada
Para ajudar a elucidar o conceito de programação estruturada, vamos come-
çar analisando o código em Pascal, apresentado na Figura 4. Esse exemplo
demonstra a criação de um programa que solicita um número e, em seguida,
escreve uma tabuada de multiplicação desse número, caso for digitado o
número 0, o programa é finalizado.
9Programação estruturada
Figura 4. Algoritmo em Pascal que escreve a multiplicação de um número.
Fonte: Farrer et al. (1999, p. 97).
No código apresentado, você pode perceber a utilização dos comandos
sequenciais em Pascal, nos quais o código comanda ao compilador que digite
o número por meio do comando (write) e, depois, leia o número digitado
pelo comando (read).
É possível identificar também o uso de estrutura de repetição por meio do
comando repeat, nesse código são usadas estruturas de repetição aninhadas,
pois dentro da estrutura de repetição repeat existe uma segunda estrutura
de repetição while (FARRER et al., 1999, p. 95).
Vamos, agora, comparar por meio do exemplo demonstrado pela Figura 5,
a sintaxe de um algoritmo em linguagem C, que consiste em ler um número e
imprimir a sua tabuada, assim como no exemplo anterior, em Pascal. É possível
perceber as características da programação estruturada como a estrutura de
repetição while.
Programação estruturada10
Figura 5. Algoritmo em C que escreve a multiplicação de um número.
Fonte: Cunha (2012, documento on-line).
A seguir, vamos analisar o trecho de um código de um programa escrito
em Cobol 74. A Figura 6 ilustra o trecho do código em Cobol demonstrando,
como nos exemplos em C e Pascal, como fazer a tabuada de um número.
11Programação estruturada
Figura 6. Algoritmo em Cobol que escreve a multiplicação de um número.
Fonte: Danflits (2010, documento on-line).
Neste caso, também é podemos verificar o uso de estruturas condicionais,
ou seja, o paradigma de programação estruturada alcançou seu objetivo de
estruturar e organizar o código dos programas de computador.
Programação estruturada12
CUNHA, R. S. Tabuada da Multiplicação. iMasters, São Paulo, 27 mar. 2012. Disponível em:
https://forum.imasters.com.br/topic/460715-tabuada-de-multiplica%C3%A7%C3%A3o/.
Acesso em: 4 set. 2019.
DANFITS. Código Programa de Tabuada. Cobol — Códigos e Comentários, [S. l.], 28 jul.
2010. Disponível em: http://cobolflits.blogspot.com/2010/07/codigo-programa-de-
-tabuada.html. Acesso em: 4 set. 2019.
FARRER, H. et al. Fortran estruturado: Fortran 77. Rio de Janeiro: Guanabara Koogan,
1992. 194 p. (Programação Estruturada de Computadores).
FARRER, H. et al. Pascal estruturado: Turbo Pascal. 3. ed. Rio de Janeiro: LTC, 1999. 279 p.
(Programação Estruturada de Computadores).
MONTEIRO, L. P. Linguagem de programação: classificações. Universidade da Tecnolo-
gia, São Paulo, 16 fev. 2018. Disponível em: https://universidadedatecnologia.com.br/
linguagem-de-programacao-classificacoes/. Acesso em: 4 set. 2019.
OKUYAMA, F. Y.; MILETTO, E. M.; NICOLAO, M. Desenvolvimento de software I: conceitos bá-
sicos. Porto Alegre: Bookman, 2014. 236 p. (Série Tekne; Eixo Informação e Comunicação).
PINHEIRO, F. A. C. Elementos de programação em C: em conformidade com o padrão
ISO / IEC 9899. Porto Alegre: Bookman, 2012. 548 p.
SEBESTA, R. W. Conceitos de linguagem de programação. 11. ed. Porto Alegre: Bookman,
2018. 758 p.
TUCKER, A. B.; NOONAN, R. E. Linguagens de programação: princípios e paradigmas.
2. ed. Porto Alegre: AMGH, 2009. 630 p.
Leituras recomendadas
DIJKSTRA, E. W. A Case against the GO TO Statement. Department of Computer Science –
University of Texas, Austin, 2011. Disponível em: http://www.cs.utexas.edu/users/EWD/
transcriptions/EWD02xx/EWD215.html. Acesso em: 4 set. 2019.
DIJKSTRA, E. W. Go To Statement Considered Harmful. Communications of the ACM, [S.
l.], v. 11, n. 3, p. 147–148, Mar. 1968. Disponível em: https://homepages.cwi.nl/~storm/
teaching/reader/Dijkstra68.pdf. Acesso em: 4 set. 2019.
EDELWEISS, N.; LIVI, M. A. C. Algoritmos e programação: com exemplos em Pascal e C.
Porto Alegre: Bookman, 2014. 476 p. (Série Livros Didáticos Informática UFRGS).LEDUR, C. L. Desenvolvimento de sistemas com C#. Porto Alegre: SAGAH, 2018. 268 p.
MACHADO, R. P.; FRANCO, M. H. I.; BERTAGNOLLI, S. C. Desenvolvimento de software III:
programação de sistemas web orientada a objetos em Java. Porto Alegre: Bookman,
2016. 220 p. (Série Tekne; Eixo Informação e Comunicação).
NICOLETTI, M. C. A cartilha Prolog. São Carlos: Edufscar, 2003. 124 p. (Série Apontamentos).
13Programação estruturada
Dica do professor
A utilização de fluxogramas como técnica para esboço de linha de pensamento ou de raciocínio é
muito bem-vinda em diversas áreas do conhecimento. A situação não seria diferente na
computação, principalmente se as ideias forem organizadas de forma estruturada para a construção
de uma lógica.
A seguir, na Dica do Professor, aprenda sobre a construção de algoritmos estruturados e a
utilização de fluxogramas.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://fast.player.liquidplatform.com/pApiv2/embed/cee29914fad5b594d8f5918df1e801fd/0813faf03d86acba6082010ccb72dc7a
Saiba +
Para ampliar o seu conhecimento a respeito desse assunto, veja abaixo as sugestões do professor:
Conhecendo a Programação Estruturada
Veja a seguir um resumo dos conceitos e da história da Programação Estruturada.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Programação Estruturada em 10 minutos
O vídeo a seguir apresenta uma explicação sobre Programação Estruturada. São 10 minutos sobre
os conceitos do paradigma.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Fluxogramas e Programação Estruturada
O vídeo a seguir aborda fluxogramas e Programação Estruturada, mostrando os fundamentos e as
vantagens do paradigma.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://www.devmedia.com.br/introducao-a-programacao-estruturada/24951
https://www.youtube.com/embed/ngeAfwrEALg
https://www.youtube.com/embed/kcic0UK-MMY
Programação de microcontroladores
II
Apresentação
As interrupções são de grande ajuda no desenvolvimento de programas complexos. Elas permitem
que os microcontroladores se libertem de parte do processamento e possam delegar serviços a
outros módulos. Programar utilizando interrupções, no entanto, não é tão simples. Além das
configurações naturais aos módulos, existirão também configurações de sinalizadores, habilitadores
e priorizadores de interrupção e, com eles, novos registradores a serem controlados. A dificuldade
em boa parte se deve à interação entre as diversas interrupções. À medida que mais módulos
utilizam este mecanismo, mais complexo se torna o controle adequado do programa.
Nesta Unidade de Aprendizagem, você aprenderá, a partir de exemplos, a programar interrupções
em diferentes microcontroladores, com e sem controle de prioridades. Além disso, poderá
acompanhar a análise de códigos maiores, em que é esperado que o hardware reaja perante os flags
de interrupção. Por fim, serão detalhadas situações de teste e depuração comuns no cotidiano do
programador, especialmente devido à interferência da depuração na execução normal do código.
Bons estudos.
Ao final desta Unidade de Aprendizagem, você deve apresentar os seguintes aprendizados:
Aplicar a programação Assembly com interrupções.•
Analisar a programação Assembly com interrupções.•
Testar interrupções com a programação Assembly.•
Infográfico
Para um programador iniciante, pode não ser tão evidente a necessidade das interrupções. Menos
ainda são as situações em que esta é apenas outra forma mais eficiente ou flexível de realizar a
mesma coisa.
Neste Infográfico, você vai ver algumas das situações, assim como os módulos utilizados no
desenvolvimento de sistemas embarcados com interrupções.
Aponte a câmera para o
código e acesse o link do
conteúdo ou clique no
código para acessar.
https://statics-marketplace.plataforma.grupoa.education/sagah/91a9a7e1-a43c-4524-9b12-7f28ac4f88ff/cdb6f904-59f6-4618-bf1e-9b0c03e96a7c.png
Conteúdo do livro
A dinâmica e a flexibilidade de um sistema embarcado permite que inúmeras soluções sejam
obtidas para um mesmo problema. O que não quer dizer que todas elas terão o mesmo impacto
sobre o microcontrolador ou a mesma eficiência.
No capítulo Programação de microcontroladores II, da obra Microprocessadores, base teórica desta
Unidade de Aprendizagem, você vai aprender, a partir de exemplos, a programar interrupções em
diferentes microcontroladores, com e sem controle de prioridades. Além disso, vai acompanhar a
análise de códigos maiores, em que é esperado que o hardware reaja perante os flags de
interrupção. Por fim, vão ser detalhadas situações de teste e depuração comuns no cotidiano do
programador, especialmente devido à interferência da depuração na execução normal do código.
Boa leitura.
MICROPROCESSADORES
Maikon Lucian Lenz
Programação de
microcontroladores II
Objetivos de aprendizagem
Ao final deste texto, você deve apresentar os seguintes aprendizados:
� Aplicar a programação Assembly com interrupções.
� Analisar a programação Assembly com interrupções.
� Testar interrupções com a programação Assembly.
Introdução
Neste capítulo, você irá aprender, a partir de exemplos, a como programar
interrupções em diferentes microcontroladores, com e sem controle de
prioridades. Em um segundo momento, você poderá acompanhar a
análise de códigos maiores, em que é esperado que o hardware reaja
perante os flags de interrupção. Por fim, serão detalhadas situações de
teste e depuração comuns no cotidiano do programador, especialmente
devido à interferência da depuração na execução normal do código. Você
também aprenderá a contornar algumas das dificuldades enfrentadas.
Programando interrupções
A programação de rotinas com interrupção requer a configuração dos pa-
râmetros específicos de funcionamento do hardware que irá gerar a inter-
rupção, a habilitação das máscaras necessárias e o controle de prioridade,
quando houver.
Habilitando a interrupção do Timer0 do PIC16F877A (MICROCHIP TECHNOLOGY, 2003).
BCF INTCON,TMR0IF ; Limpa o flag como garantia
BSF INTCON,TMR0IE ; Habilita a interrupção do Timer0
BSF INTCON,GIE ; Habilita a máscara global
No PIC18F4550 é possível optar pela alta prioridade (MICROCHIP TECHNOLOGY, 2009).
BSF INTCON2,TMR0IP ; Configura TMR0IF em alta prioridade
No PIC24FJ256GA412 a prioridade pode ser configurada em até oito níveis (MICROCHIP
TECHNOLOGY, 2016).
BSF IPC0,T1IP2 ; Configura TMR1IF em prioridade máxima
BSF IPC0,T1IP1 ; Configura TMR1IF em prioridade máxima
BSF IPC0,T1IP0 ; Configura TMR1IF em prioridade máxima
Além das diferenças no controle de prioridade, os microcontroladores tam-
bém podem apresentar vetores de interrupção individuais ou compartilhados.
No último caso, o vetor de interrupção ainda pode ser separado em níveis de
prioridade, criando mais do que um grupo.
Com apenas um vetor de interrupção, como é o caso do PIC16F877A, todas
as interrupções são direcionadas para um mesmo endereço de memória e é
somente por meio dos bits sinalizadores ( flags) que será possível individualizar
o tratamento de diferentes fontes de interrupção. O programador, neste caso,
deverá testar os flags das diferentes fontes possíveis para direcionar o código
no tratamento adequado em cada situação.
Programação de microcontroladores II2
PIC16F877A utilizando interrupções do temporizador (Timer0 de sinalizador de TMR0IF)
e do conversor analógico-digital (ADC de sinalizador ADIF).
ORG 0x0004 ; Endereço do vetor de
interrupção
ISR: ; Label do vetor de interrupção
BTFSC TMR0IF ; Pula 1 instrução se TMR0IF
= 0
CALL TRATAR _ TIMER0 ; Chama rotina de tratamento
do Timer0
BTFSC ADIF ; Pula 1 instrução se ADIF = 0
CALL TRATAR _ CONVERSOR ; Chama rotina de tratamento
do conversor
BCF INTCON,TMR0IF ; Limpa o flag de interrupção
do Timer0
BCF PIR1,ADIF ;Limpa o flag de interrupção
do ADC1
RETFIE ; Retorno do vetor de
interrupção
Este também é o caso dos microcontroladores com dois ou mais vetores
de interrupção separados por níveis de prioridade, como o PIC18F4550 (MI-
CROCHIP TECHNOLOGY, 2009). Ainda que parte das interrupções sejam
desviadas para um endereço e outra parte para outro, somente será possível
definir as fontes pela avaliação dos flags. De qualquer forma, o processamento
será parcialmente reduzido, já que ao dividir as interrupções em dois níveis,
somente metade dos testes serão necessários em cada vetor.
3Programação de microcontroladores II
PIC18F4550, utilizando interrupções do temporizador 0 (Timer0 de sinalizador de
TMR0IF) e do conversor analógico-digital (ADC de sinalizador ADIF). O primeiro com
prioridade alta e o segundo, baixa.
ORG 0x0008 ; Interrupções de alta
prioridade
ISR _ HIGH: ; Label do vetor de
interrupção
BTFSC TMR0IF ; Pula 1 instrução se
TMR0IF = 0
CALL TRATAR _ TIMER0 ; Se não, tratamento do
Timer0
BCF INTCON,TMR0IF ; Limpa o flag de inter-
rupção do Timer0
RETFIE
ORG 0x0018
ISR _ LOW:
BTFSC ADIF ; Pula 1 instrução se ADIF
= 0
CALL TRATAR _ CONVERSOR ; Se não, tratamento do
conversor
BCF PIR1,ADIF ; Limpa o flag de inter-
rupção do ADC
RETFIE ; Retorno do vetor de
interrupção
Já em microcontroladores com vetores de interrupção individual, como
é o caso do PIC24FJ256GA412, há um endereço de memória para cada fonte
(MICROCHIP TECHNOLOGY, 2016). Com isso, os flags poderão ser dis-
pensados, dependendo da situação. Isso porque, ao entrar no respectivo vetor
de interrupção individual, já se sabe que aquele flag está ativado, caso con-
trário, não teria ocorrido o desvio, exceto em erros provocados ou não pelo
programador.
Programação de microcontroladores II4
PIC24FJ256GA412, utilizando interrupções do temporizador 1 (Timer1 de sinalizador
de T1IF) e do conversor analógico-digital (ADC1 de sinalizador AD1IF) — cada qual
em um endereço específico de desvio.
ORG 0x001A ; Vetor de interrupção do
Timer1
ISR _ TMR1: ; Label do vetor de in-
terrupção do Timer1
BTFSC T1IF ; Pula 1 instrução se T1IF
= 0
CALL TRATAR _ TIMER1 ; Se não, tratamento do
Timer1
BCLR IFS0,TMR1IF ; Limpa o flag de inter-
rupção do Timer1
RETFIE ; Retorno do vetor de in-
terrupção Timer1
ORG 0x002E ; Vetor de interrupção do
ADC1
ISR _ ADC1: ; Label do vetor de in-
terrupção do ADC1
BTFSC AD1IF ; Pula 1 instrução se
AD1IF = 0
CALL TRATAR _ CONVERSOR ; Se não, tratamento do
conversor
BCLR IFS0,AD1IF ; Limpa o flag de inter-
rupção do ADC1
RETFIE ; Retorno do vetor de in-
terrupção ADC1
Uma vez disparada uma interrupção pelo hardware, o flag (bit sinalizador)
é ligado e não há como prever quando esta será tratada ou de que forma isso
irá ocorrer.
5Programação de microcontroladores II
Sendo imprevisível, é importante que após o tratamento de qualquer in-
terrupção o programador tenha sempre o cuidado de desligar o respectivo
flag. Do contrário, o microcontrolador, apesar de retornar para o programa
principal, entrará novamente no vetor de interrupção pelo mesmo flag que
gerou o desvio anterior (MIYADAIRA, 2009).
Deve-se considerar também que a imprevisibilidade é característica intrínseca
às interrupções, podendo ocorrer a qualquer momento sem ponderar se alguma
operação importante ou processamento prolongado está em execução. Neste
caso, qualquer que seja a informação presente nos registradores W (acumulador),
STATUS e outros que servem como auxiliares no processamento de dados,
estas seriam perdidas se não fosse feita uma cópia antes de iniciar o tratamento.
O processo de guardar os dados de registradores que deverão ter seus valores
restaurados ao retornar de uma interrupção é conhecido como salvamento de
contexto (PEREIRA, 2007).
O salvamento de contexto deve ocorrer antes do tratamento das interrupções e a
forma mais fácil de fazer isso é executando o processo a partir da primeira linha do
vetor de interrupção.
STATUS EQU 0x0003 ; Endereço do registrador
STATUS
BACKUP _ W EQU 0x0071 ; Onde será salvo o re-
gistrador W
BACKUP _ STATUS EQU 0x0072 ; Onde será salvo STATUS
ORG 0x0004 ; Endereço do vetor de
interrupção
ISR: ; Label para o vetor de
interrupção
MOVWF BACKUP _ W ; Move o valor de W para
BACKUP _ W
MOVF STATUS ; Move o valor de STATUS
para W
MOVWF BACKUP _
STATUS
; Move o valor de STATUS
para W
Programação de microcontroladores II6
Após o salvamento de contexto, o tratamento da interrupção pode ser executado
sem problemas. Ao final, antes da instrução RETFIE que ordenará o retorno ao programa
principal, o contexto deverá ser restaurado, seguindo o procedimento inverso.
MOVF BACKUP _ STATUS ; Move BACKUP _ STATUS para W
MOVWF STATUS ; Move W para STATUS
MOVF BACKUP _ W ; Move BACKUP _ W para W
RETFIE ; Procedimento de retorno
Alguns microcontroladores dispõem de um salvamento de contexto via
hardware, utilizando um mecanismo similar a uma pilha. Os registradores W
e STATUS (dependendo do microcontrolador, outros registradores também)
serão armazenados assim que o microcontrolador entrar no vetor de interrupção
e restaurados junto ao comando de retorno (MIYADAIRA, 2009).
Enquanto o microcontrolador PIC16F877A utiliza 2 bits no registrador STATUS (RP0 e RP1)
para selecionar o banco de memória, outros microcontroladores, como o PIC18F4550,
possuem um registrador inteiro dedicado à seleção do banco de memória. Neste mo-
delo, trata-se do registrador BSR (bank select register) (MICROCHIP TECHNOLOGY, 2009).
O modelo PIC18F4550 conta com uma pilha denominada Fast Register
Stack para salvar os registradores W, STATUS e BSR (MICROCHIP TECH-
NOLOGY, 2009).
A pilha Fast é acionada na chamada de sub-rotinas graças à instrução
CALL com dois operandos, um para o endereço a ser chamado e um bit para
indicar o uso ou não da pilha Fast. O retorno, neste caso, também possuirá
um operando para indicar o uso do Fast. O mesmo cuidado deverá ser tomado
no retorno das interrupções, já que o hardware sempre efetuará o salvamento
de contexto, cabendo ao programador decidir se utiliza a restauração via Fast
ou não, isto porque essa metodologia está limitada a apenas uma interrupção
por vez.
7Programação de microcontroladores II
Salvamento de contexto via hardware em uma chamada de sub-rotina.
CALL ROTINA, FAST ; Desvio com salvamento de contexto
... ; Corpo da função
RETURN FAST ; Retorno restaurando o contexto
Nas interrupções, o salvamento de contexto no Fast é automático, mas a restauração
deve ser explícita.
ISR: ; Label do vetor de interrupção
... ; Tratamento da interrupção
RETFIE FAST ; Retorno com uso do FAST.
A limitação do Fast se deve ao controle de prioridades do microcontrolador.
Caso o controle de prioridades esteja habilitado, poderão ocorrer interrupções
dentro de outra interrupção ainda em tratamento, o que certamente sobres-
creveria os dados da pilha Fast.
Analisando as interrupções
Para gerar uma interrupção, o módulo em questão ativa o seu flag. Este sinal
digital passará por um circuito de combinações composto de várias máscaras
para determinar se o processador deve ser informado ou não.
Na Figura 1 é possível comparar o diagrama de interrupção do Timer0 para
dois microcontroladores diferentes, um sem controle de prioridade (Figura
1a) e outro com controle em dois níveis (Figura 1b).
Programação de microcontroladores II8
Figura 1. (a) Diagrama lógico de interrupção sem prioridade. (b) Diagrama lógico com
dois níveis de prioridade.
Para a Figura 1a, basta que o TMR0IF seja igual a 1 e as máscaras TMR0IE
(habilitação da interrupção no módulo) e GIE (interrupção global) também
sejam, para que o sinal seja detectado pelo processador.
A primeira máscara é combinada em uma operação lógica AND (porta
1) com o flag, situação em que ambas as entradas precisam ser de nível alto
para que a saída também seja. A segunda porta lógica permite que outras
fontes possamser comparadas com a máscara seguinte, a GIE. Na porta 3,
mais uma vez ambas as entradas devem ser de nível alto e só então a saída é
encaminhada ao processador.
Na Figura 1b, a relação é mais complexa. O TMR0IF pode ser validado
em duas situações: quando a porta AND (porta 5), cujas demais entradas são
TMR0IE (habilitação da interrupção no modulo) e TMR0IP (prioridade alta),
forem de nível alto; ou quando apenas o TMR0IE for de nível alto, indicando
uma interrupção de baixo nível detectada pela AND de número 6, situação
em que o TMR0IP, apesar de 0, é invertido pela porta 4.
9Programação de microcontroladores II
As portas 7 e 8 funcionam da mesma maneira que a porta 2 para o primeiro
caso, permitindo que outras interrupções aproveitem a máscara seguinte.
Para interrupções de baixa prioridade, a porta AND de número 9 terá de
ser de nível alto, em outras palavras, a GIEL poderá bloquear ou não este
nível de interrupção.
Ao final, as interrupções de alto nível serão validadas por GIE/GIEH na
porta 10 que, caso esteja ativado, não permitirá que interrupções de baixo
nível ocorram, já que seu sinal invertido (porta 11) serve de entrada para a
máscara final das interrupções de baixo nível (porta 12).
Para microcontroladores com mais níveis de prioridade, a combinação
se torna ainda mais extensa, aumentando consideravelmente o tamanho do
circuito e, consequentemente, o preço e consumo de energia.
Lembre-se de que, ao sair de uma interrupção, o programador deve sempre
limpar o flag para evitar que a mesma interrupção já tratada continue sendo
detectada, o que costuma ser feito no início ou fim da interrupção. Entretanto,
não há como garantir que a primeira atitude do usuário seja esta, pois micro-
controladores que possuem apenas um vetor de interrupção podem necessitar
vários passos até que seja identificada a fonte geradora.
Como impedir que, após cada instrução, o microcontrolador não retorne
para o início do vetor de interrupção , pelo mesmo motivo que o levou até lá?
A resposta está mais uma vez na máscara global de interrupções.
Ao iniciar o tratamento de qualquer interrupção, o microcontrolador desabi-
litará automaticamente o bit GIE, que permite ou bloqueia todas as interrupções.
Ao final, quando for solicitado o retorno, será reabilitado automaticamente
(MIYADAIRA, 2009).
Dessa forma, os flags podem ser desativados no momento mais oportuno
para o programador, durante o tratamento das interrupções, com a garantia
de que o código fluirá naturalmente.
A configuração básica do Timer0 no PIC18F4550 inclui seleção de prioridade, fonte
de clock, borda de acionamento, tamanho de contagem, valor inicial, além de uso e
fator de multiplicação do prescaler.
A sequência a seguir aciona o Timer0 com clock interno sem prescaler para uma
contagem de 200 ciclos de máquina (8 bits e valor inicial de 56) em alta prioridade.
Programação de microcontroladores II10
BCF INTCON,TMR0IF ; Limpa o flag como garantia
BSF INTCON2,TMR0IP ; Configura TMR0IF em alta
prioridade
BSF T0CON,T08BIT ; Configura o Timer0 para 8 bits
BCF T0CON,T0CS ; Configura o Timer0 para clock
interno
BSF T0CON,PSA ; Desabilita o prescaler
CLRF TMR0H ; Zera byte mais significativo
do Timer0
MOVLW 0x0038 ; Move o valor decimal 56 para
o reg. W
MOVWF TMR0L ; Move 56 de W para o Timer0
BSF INTCON,TMR0IE ; Habilita a interrupção do
Timer0
BSF INTCON,GIE ; Habilita a mascara global
BSF T0CON,TMR0ON ; Liga o modulo Timer0
Ao terminar a contagem, o módulo do temporizador Timer0 irá habilitar o bit TMR0IF,
fazendo com que o hardware que controla as interrupções sinalize a necessidade de
um desvio para o vetor de interrupção de alto nível do microcontrolador, como na
imagem a seguir, em que são destacadas as linhas com nível lógico alto.
Após um período de latência do microcontrolador, em que são necessários os
armazenamentos de endereço na pilha para retorno e mudanças no contador de
programa, o microcontrolador executaria o código presente no endereço de memória
do vetor de interrupção de nível alto.
11Programação de microcontroladores II
ORG 0x0008 ; Interrupções de alta
prioridade
ISR _ HIGH: ; Label do vetor de
interrupção
BTFSC TMR0IF ; Pula 1 instrução se
TMR0IF = 0
CALL TRATAR _ TIMER0 ; Se não, tratamento do
Timer0
RETFIE
TRATAR _ TIMER0: ; Label da rotina de
tratamento do Timer0
... ; Instruções desejadas
na interrupção
CLRF TMR0H ; Zera byte mais signi-
ficativo do Timer0
MOVLW 0x0038 ; Move o valor decimal
56 para o reg. W
MOVWF TMR0L ; Move 56 de W para o
Timer0
BCF INTCON,TMR0IF ; Limpa o flag de inter-
rupção do Timer0
BSF INTCON,TMR0IE ; Habilita novamente a
interrupção
RETURN
Imediatamente após a entrada no vetor de interrupção, o GIE seria desabilitado,
impossibilitando que qualquer outra interrupção ocorra ou que o mesmo flag cause
novos desvios durante o tratamento.
Testando as interrupções
Para depurar sistemas que usem interrupção, o programador precisará ter bom
conhecimento da estrutura desenvolvida, de maneira que possa contornar os
desvios desnecessários à sua depuração.
Programação de microcontroladores II12
Imagine, por exemplo, que você esteja tentando avaliar a movimentação de
dados em um buffer do módulo de comunicação enquanto um temporizador
com um tempo curto está habilitado para uma contagem de poucos ciclos
de máquina. É provável que ao tentar avançar pequenos passos durante a
depuração você seja surpreendido constantemente com desvios de rotina para
tratamento do temporizador.
A situação pode ficar ainda mais desconfortável caso a quantidade de
módulos em interrupção seja grande, ou quando muitas delas não podem ser
desabilitadas para que alguma outra rotina seja depurada. Nestas situações, o
programador deve fazer a seleção eficiente de pontos de quebra (breakpoints)
que lhe permitam avançar em uma depuração razoavelmente fluida com a
menor quantidade de intervenções possíveis.
Outra situação desconfortável ocorre quando a própria depuração pode
exigir o uso de níveis de pilha, memória e processamento, limitando os recursos
disponíveis e, em alguns casos, até mesmo inviabilizando a depuração.
Quando não houver alternativa, o programador poderá fazer alterações
no sistema, adicionando instruções e/ou diretrizes que terão serventia ao
processo de depuração, como um conjunto de testes após determinada etapa
de depuração, que ligará ou não um determinado bit, conforme sejam atendi-
das. Dessa forma é possível reduzir a quantidade de intervenções externas no
microcontrolador sem deixar de buscar as informações que necessita.
Outra situação comum ao programador ocorre quando módulos não podem
ser interrompidos por tempo prolongado. Na maioria das vezes, esta não é uma
limitação interna, do próprio microcontrolador, mas de algum outro compo-
nente externo que depende deste módulo para operar. Uma das situações mais
frequentes é o uso do gerador de PWM para acionar alguma carga chaveada.
Caso a depuração interrompa a execução do programa enquanto o PWM estiver
em ciclo ativo, a carga que deveria receber uma potência menor (chaveada)
receberá a potência máxima enquanto o programador avança pequenas etapas,
uma a uma, podendo danificar o circuito.
Em situações críticas, o programador pode recorrer a sinais visuais, externos
ou o uso dos módulos de comunicação do microcontrolador para coletar infor-
mações em etapas que não permitam ou sejam demasiadamente críticas para
ter seu funcionamento interrompido por um tempo prolongado. Por exemplo,
um LED pode ser usado para testar o funcionamento de um temporizador,
invertendo-se seu estado a cada entrada.
13Programação de microcontroladores II
Para evitar interferências no sistema, um LED pode inverter o estado sempre que entrar
no vetor de interrupção do módulo específico. Basta adicionar as rotinas necessárias
de controle do pino após o teste do flag.
ORG 0x0004 ; Interrupções de alta prioridade
ISR: ; Label do vetor de interrupçãoBTFSC TMR0IF ; Pula 1 instrução se TMR0IF = 0
BSF PORTB,0 ; Liga o LED conectado ao pino RB0
RETFIE
Caso a interrupção seja demasiadamente rápida para ser visualizada, a
técnica ainda pode ser utilizada com o auxílio de um osciloscópio, como na
Figura 2, para observar o tempo com que cada interrupção está ocorrendo e
se está ocorrendo alguma interrupção.
Muitos osciloscópios possuem a função de gatilho para congelar a imagem no
momento em que a tensão passar de determinado nível pré-configurado, o que
pode facilitar ainda mais seu uso junto ao microcontrolador que se está testando.
Figura 2. Osciloscópio para avaliar o comportamento da tensão em um
ponto específico do circuito.
Fonte: Artsplav/Shutterstock.com.
Programação de microcontroladores II14
Por fim, o programador poderá validar a lógica do seu código com o uso
de um simulador. A desvantagem é que não será possível determinar se o har-
dware como um todo está se comportando como esperado ou imaginado pelo
desenvolvedor. O simulador apresentará níveis lógicos ideais nos momentos
sugeridos pelo desenvolvedor, o que pode mascarar alguns problemas.
Para ativar o simulador no ambiente de desenvolvimento do MPLAB, basta
alterar a configuração do Hardware Tool (ferramenta de gravação) utilizado,
conforme vemos na Figura 3. Esta opção está presente durante o assistente de
construção de um novo projeto, ou ainda no menu File – Project Properties
(arquivo – propriedades do projeto).
Figura 3. Habilitação do simulador.
Todas as demais ferramentas disponíveis durante a depuração convencional
também estão presentes no simulador, com a diferença de que valores recebidos
por algum elemento externo, como conversões de sinal analógico-digital, estado
de pinos de entrada digital, entre outros, terão de ser informados manualmente.
O processo consiste em alterar o valor do registrador na aba Watches do painel
de tarefas, como mostra a Figura 4.
15Programação de microcontroladores II
Figura 4. Processo de simulação de estados e valores no MPLAB X IDE.
Algumas das opções da depuração relevantes incluem os elementos listados
a seguir.
� Forma de início: pode-se optar por iniciar a execução e somente parar em
um breakpoint, ou iniciar com o microcontrolador parado no endereço
do vetor de reinício para avançar por passos desde o início.
� Seleção de frequência do oscilador simulado.
� Contador de ciclos de máquina para determinar o tempo decorrido
entre um breakpoint e outro.
� Visualização de registradores genéricos.
MICROCHIP TECHNOLOGY. PIC16F87XA Data Sheet: 28/40/44-Pin Enhanced Flash Mi-
crocontrollers. Chandler, 2003. 234 p. Disponível em: http://ww1.microchip.com/
downloads/en/DeviceDoc/39582b.pdf. Acesso em: 30 jul. 2019.
Programação de microcontroladores II16
MICROCHIP TECHNOLOGY. PIC18F2455/2550/4455/4550 Data Sheet: 28/40/44-Pin, High-
-Performance, Enhanced Flash, USB Microcontrollers with nanoWatt Technology.
Chandler, 2009. 438 p. Disponível em: http://ww1.microchip.com/downloads/en/
DeviceDoc/39632e.pdf. Acesso em: 30 jul. 2019.
MICROCHIP TECHNOLOGY. PIC24FJ256GA412/GB412 Family: 16-Bit Flash Microcontrollers
with Dual Partition Flash Memory, XLP, LCD, Cryptographic Engine and USB On-The-
-Go. Chandler, 2016. 558 p. Disponível em: http://ww1.microchip.com/downloads/en/
DeviceDoc/30010089d.pdf. Acesso em: 30 jul. 2019.
MIYADAIRA, A. N. Microcontroladores PIC18: aprenda e programe em linguagem C. São
Paulo: Érica, 2009. 400 p.
PEREIRA, F. Microcontroladores PIC: técnicas avançadas. 6. ed. São Paulo: Érica, 2007. 368 p.
Leituras recomendadas
NULL, L.; LOBUR, J. Princípios básicos de arquitetura e organização de computadores. 2.
ed. Porto Alegre: Bookman, 2011. 822 p.
PEREIRA, F. Microcontrolador PIC 18 detalhado: hardware e software. São Paulo: Érica,
2010. 304 p.
PINHEIRO, F. A. C. Elementos de programação em C: em conformidade com o padrão
ISO/IEC 9899. Porto Alegre: Bookman, 2012. 548 p.
SOUZA, D. J. Desbravando o PIC: ampliado e atualizado para PIC16F628A. 6. ed. São
Paulo: Érica, 2003. 268 p.
WEBER, R. F. Fundamentos de arquitetura de computadores. 4. ed. Porto Alegre: Bookman,
2012. 424 p. (Série Livros Didáticos Informática UFRGS).
17Programação de microcontroladores II
Dica do professor
É muito importante saber configurar o depurador, de modo que ele seja mais eficiente na
depuração com interrupções, pois estas podem interferir umas nas outras.
Nesta Dica do Professor, você vai acompanhar a depuração e a análise de um código no ambiente
de desenvolvimento MPLAB X IDE.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://fast.player.liquidplatform.com/pApiv2/embed/cee29914fad5b594d8f5918df1e801fd/ed4d2b7aa38e11b2d6239eaff9a6b474
Saiba +
Para ampliar o seu conhecimento a respeito desse assunto, veja abaixo as sugestões do professor:
Interrupção x polling
Neste vídeo, você vai ver o comparativo de um sistema programado para temporizar via
interrupção e outra temporização via delay.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Projeto de automação residencial utilizando um
microcontrolador da família 8051 e supervisionado por uma
plataforma desenvolvida no Elipse E3
Este editorial apresenta outras linguagens de programação utilizadas em microcontroladores, assim
como as vantagens de se utilizar cada uma delas. Confira.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Simulando entrada e saída de interrupção
Neste vídeo, você vai ver um processo de entrada e saída de uma interrupção, utilizando a
ferramenta de simulação do MPLAB.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://www.youtube.com/embed/L_c0s2OpNtM
https://docplayer.com.br/1353299-Projeto-de-automacao-residencial-utilizando-um-microcontrolador-da-familia-8051-e-supervisionado-por-uma-plataforma-desenvolvida-no-elipse-e3.html
https://www.youtube.com/embed/tXHZS1F6xyc
Linguagens de programação para scripts
Apresentação
O termo script, em um contexto de computação, aparece no início dos anos 1970. Isso quando os
criadores do sistema operacional UNIX usaram o termo shell script para se referenciar a uma
sequência de comandos que eram lidos a partir de um arquivo como se tivessem sido digitados no
teclado.
Os scripts ficaram conhecidos como arquivos de texto que deveriam ser executados diretamente,
em vez de serem compilados. Para a criação de scripts, eram usadas as linguagens scripts. Elas se
distinguem das linguagens de programação tradicionais por não serem compiladas e por darem
preferência à velocidade do desenvolvimento mais do que à eficiência do tempo de execução.
As linguagens de programação tradicionais são projetadas para a criação de aplicações completas e
suas estruturas focam na eficiência em compilação e na execução dos seus programas. Para as
tarefas de menor escala, como criação de rotinas, integração entre aplicações, existem as
linguagens scripts.
Nesta Unidade de Aprendizagem, você vai aprender o que são as linguagens de programação para
scripts, suas características mais comuns e os tipos de linguagens de programação para scripts.
Bons estudos.
Ao final desta Unidade de Aprendizagem, você deve apresentar os seguintes aprendizados:
Descrever o que são linguagens de programação para scripts.•
Identificar as características mais comuns em programação para scripts.•
Reconhecer os tipos de linguagens de programação para scripts.•
Infográfico
Uma linguagem de programação tradicional é uma maneira organizada de se comunicar com um
computador, usando um conjunto de comandos e instruções. Já uma linguagem de programação
para script é uma linguagem que suporta scripts e é capaz de ser executada sem ser compilada com
antecedência.
No Infográfico a seguir, veja uma breve comparação entre ambas as linguagens.
Aponte a câmera para o
código e acesse o link do
conteúdoou clique no
código para acessar.
https://statics-marketplace.plataforma.grupoa.education/sagah/b294f4f7-6a1d-4d3c-8e5c-e9aef32e407c/00ab1814-7881-4d31-bfdd-bb5424c786a9.jpg
Conteúdo do livro
A distinção entre linguagens scripts e linguagem de programação é útil, porque o tipo de
programação para o qual as linguagens de script são usadas é qualitativamente diferente da
programação convencional. As linguagens de programação convencionais, como C ++ e C,
abordam o problema de desenvolver grandes programas, com uma equipe de programadores
profissionais, iniciando com especificações bem definidas e atendendo às restrições de
desempenho explicitadas.
As linguagens de script, por outro lado, abordam problemas diferentes: construir aplicativos a partir
de componentes prontos para uso, controlar aplicações que têm uma interface programável, e
a escrita de programas em que a velocidade do desenvolvimento é mais importante que a eficiência
do tempo de execução.
Talvez a diferença mais importante seja que as linguagens de script incorporam recursos que
aumentam a produtividade do usuário de uma maneira ou de outra, sendo mais acessíveis em
relação à programação convencional.
No capítulo Linguagens de programação para scripts, da obra Programação em Ambientes de Redes
de Computadores, você vai conhecer as linguagens de programação para scripts, suas características
mais comuns e os tipos de linguagens de programação para scripts.
Boa leitura.
Programação em
Ambientes de
Redes de
Computadores
Rafael Albuquerque
Linguagens de
programação para scripts
Objetivos de aprendizagem
Ao final deste texto, você deve apresentar os seguintes aprendizados:
� Descrever o que são linguagens de programação para scripts.
� Identificar as características mais comuns em programação para scripts.
� Reconhecer os tipos de linguagens de programação para scripts.
Introdução
De modo geral, as linguagens de programação são projetadas para criação
de aplicações completas e stand-alone. Conforme Sebesta (2018), o uso de
linguagens de programação se justifica nos computadores pela grande
escalabilidade em tarefas que estes podem executar, desde controlar
usinas até desenvolver determinado aplicativo para smartphones. Hoje,
existem linguagens para os diversos campos de aplicação — como o
uso do Fortran, para a academia; Java e C# para uso comercial; Lisp, R e
Prolog para inteligência artificial —, além das linguagens em script para
distribuições Web, como Python, JavaScript, PHP, Perl, Lua, etc.
As linguagens de programação constituem instruções lógicas para
criar programas com alguma finalidade. Uma vez utilizada, uma linguagem
pode ser compilada ou interpretada, ou ambas. Uma linguagem compilada,
em geral, representa uma linguagem cujas instruções são traduzidas para
linguagem de máquina, para, então, ser executada. Já uma interpretada terá
seu código traduzido para uma linguagem intermediária (p. ex., bytecode),
sendo interpretada apenas pelo seu próprio interpretador.
Uma linguagem de programação visa à eficiência em seu nível de
compilação. Linguagens em script, por sua vez, não são compiladas,
sendo interpretadas, e estão associadas a tarefas de menor escala, como
a criação de rotinas e aplicação entre aplicações. Os scripts têm como
vantagem ser mais flexíveis e possibilitar a criação de programas por
meio da combinação de componentes já existentes.
Linguagens para programação em scripts
Por meio de linguagens para scripts, que têm ganhado cada vez mais evidência
entre os programadores, é possível desenvolver diversas atividades, seja para
administração de sistemas operacionais, seja para sistemas Webs, ou até
mesmo para criação de aplicações móveis. Segundo Barron (2000), o uso da
programação em scripts existe desde a década de 1970, quando, por meio do
sistema operacional Unix, o termo “Shell Script” foi introduzido. Seu uso foi
estendido para instruções (ou comandos) para sequências de comandos para
outras linguagens, Ruby, Lua, Perl, PHP, etc.
De acordo com Barron (2000), os scripts podem ser usados de três diferentes
maneiras. A primeira está relacionada à inovação na programação, que permite
a criação de aplicações de maneira mais fluida que os métodos tradicionais,
além de maior flexibilidade quanto a mudanças em requerimentos de usuários.
O exemplo clássico é o uso da linguagem Visual Basic (VB) para interfaces
gráficas de usuário por meio de controles visuais pré-compilados.
A segunda maneira está mais ligada a tarefas de gerenciamento de sistemas,
por meio da manipulação, da personalização e das facilidades em automatizar
um sistema existente, como o ECMAScript. Nesse caso, o script é usado para
controlar uma aplicação a fim de prover uma interface programável, como o
emprego de scripts do lado cliente e HTML dinâmicos, os quais possibilitam
a criação de páginas Web interativas.
A terceira maneira consiste em usar uma linguagem de script que substitua
as linguagens de programação convencional, pela fácil manipulação e pelas
funcionalidades que uma linguagem script pode oferecer. Administradores
de sistemas Unix têm usado bastante a linguagem de script para tarefas de
manutenção de sistemas. Na Figura 1, são ilustradas algumas das linguagens
de script mais utilizadas; em seguida, comentaremos algumas das linguagens
em script e seus propósitos.
Linguagens de programação para scripts2
Figura 1. Algumas linguagens de programação para scripts.
Fonte: Adaptada de Rodrigues (2019, documento on-line).
Embora em um mundo ideal seja preferível o uso de apenas uma das carac-
terísticas — compilada ou interpretada —, pode haver uma regra de negócio
escrita em uma linguagem compilada e uma manipulação de alto nível feita
por uma linguagem interpretada, embora claramente uma ferramenta que
intermediasse todo esse processo seria necessária.
Existem ferramentas, como a SWIG (simplified wrapper and interface
generator), que fazem todo esse trabalho pesado de vinculação de linguagem.
Trata-se de uma ferramenta de desenvolvimento de programas com a finalidade
de conectar programas escritos em C e C++ em linguagens de mais alto nível,
como JavaScript, C#, Perl, PHP, Python, Tcl, Ruby, etc.
Para fins de exemplificação da ferramenta SWIG, supondo que a ferramenta
esteja em funcionamento, a partir da Figura 2, podemos acompanhar o processo
de compilação, ligação e interpretação, conforme as etapas apresentadas.
3Linguagens de programação para scripts
Figura 2. Utilização da ferramenta SWIG.
1. A etapa 1 representa o arquivo em linguagem C com duas funções e uma variável.
2. Na etapa 2, cria-se o código que faz a ligação do módulo 'exemplo' com o
mapeio de variável e funções expressas na linguagem em C. Perceba que até aqui
só há dois arquivos.
3. Com o comando swig –python exemplo.i, há um arquivo exemplo_
wraper.c que contém uma versão mais robusta do código original em C com
vários controles de erros. Além disso, é gerado um arquivo em Python chamado
exemplo.py, que será o módulo importado no script Python criado.
4. Aqui, são duas linhas de comandos. O comando: gcc -c -fpic gfg_wrap.c
gfg.c -I/use/include/python2.7 será responsável por gerar os arquivos
objetos exemplo_wrap.o e exemplo.o. Repare o uso do argumento –fpic,
que viabiliza o uso do PIC (código independente de posição, em inglês), que, por
sua vez, tem a vantagem de poder ser carregado em diferentes localizações na
memória, tornando-se útil para bibliotecas compartilhadas, pois permite ao link
dinâmico movê-las quando múltiplas bibliotecas disputarem o mesmo endereço.
5. Na etapa 5, é criado o script em Python importando a biblioteca em C que criamos
com o nome de exemplo.
6. Apresenta o resultado da interpretação da etapa anterior.
Linguagens de programação para scripts4
Quando falamos em linguagem compilada, significa dizer que existe um programa de
computador que fará a leitura do código fonte e produzirá um códigode máquina (binário).
Já em uma linguagem interpretada, como é o caso de scripts, sua leitura é feita linha a
linha por um programa de computador, chamando as funcionalidades correspondentes
em seu próprio código.
Características em programação para script
As linguagens de programação para scripts podem ser usadas para realizar
interações com o sistema operacional, tanto os sistemas proprietários quanto os
open source, os quais, em geral, suportam uma boa quantidade de diferentes lin-
guagens de scripts. Por exemplo, os sistemas baseados em Linux com frequência
usam o shell script, e o sistema Windows Server utiliza os scripts PowerShell
para realizar interações e configurações, como exemplificado na Figura 3.
Figura 3. Exemplo do PowerShell e do Shell Script.
Fonte: Dias, Geelen e Rendón (2018, documento on-line) e Couto (2010, documento on-line).
5Linguagens de programação para scripts
Além de realizarem interações com os sistemas operacionais, as lingua-
gens de programação para scripts são usadas para os mais diversos tipos de
script; no entanto, apresentam muitos recursos em comum, que servem para
definir um conceito geral de uma linguagem de programação para script
e diferenciá-lo do conceito de linguagem de programação convencional.
A seguir, são apresentados alguns dos recursos que caracterizam as linguagens
de programação para scripts, conforme Barron (2000).
Compilação integrada e execução
Conforme Barron (2000), a compilação e execução integradas talvez sejam
a característica mais importante, pois linguagens em script comumente se
caracterizam como linguagens interpretadas. Isso significa que a operação
se dá sob uma base de execução imediata, sem a necessidade de compilar um
programa para somente então poder executá-lo. Como os scripts são interativos,
atividades experimentais geralmente não se ajustam ao ciclo da programação
convencional editar-compilar-linkar-executar.
Poucas linguagens de programação são puramente interpretadas, como
UNIX Shell e Tcl, já que a maioria emprega técnicas híbridas, compilando
para uma forma intermediária (geralmente para um bytecode) para então ser
interpretada.
Baixos custos e facilidade de uso
As linguagens de programação para script se esforçam para não ficar entre o
usuário e os problemas, ou seja, elas mantêm o mínimo de desordem, como a
declaração de variáveis opcional e o número de tipos de dados limitado, sendo
os tipos de dados geralmente uma string, com conversão automática em
número (ou vice-versa) quando o contexto exigir. O número de estruturas de
dados diferentes também é limitado — geralmente, as únicas estruturas de
dados são matrizes associativas em vez de matrizes indexadas convencionais.
Funcionalidade aprimorada
Normalmente, as linguagens de programação para script funcionam melhor
em algumas áreas, como em linguagens com alto poder de manipulação em
tipos de dados string por meio de expressões regulares, enquanto outras
Linguagens de programação para scripts6
fornecem acessos mais fáceis a sistemas de operações para baixo nível ou
provêm uma API (Application Programming Interface) ou algum modelo de
objeto exportado por uma aplicação.
Eficiência não é um problema
Esse fato se explica, pois muitos dos scripts construídos por administradores
de sistemas serão usados uma única vez. Já os scripts que apresentam alguma
interação gráfica serão usados com mais frequência, mas com a prerrogativa de
não necessitarem de alta performance, visto se tratar de comando sequenciais
que são executados sem a necessidade de compilação.
Desenvolver aplicativos usando uma variedade de bibliotecas e estruturas JavaScript,
como Angular, Node, jQuery e React, tem facilitado bastante o domínio de sua aplica-
ção. Por sua sintaxe flexível e fácil de entender, a linguagem JavaScript é vista como
uma linguagem de programação amigável para iniciantes. Se você pretende ser um
programador profissional, JavaScript é uma linguagem que, se conseguir dominá-la,
se dará bem, principalmente para criar aplicativos móveis com o Flutter.
Tipos de linguagens de programação
para scripts
Unix Shell
Antes das apresentações gráficas, recheadas de ícones e janelas, a interação
com o computador era estritamente realizada por meio de comandos. Conforme
Negus e Bresnahan (2010, p. 144), no sistema Unix, do qual se originaram
os sistemas Linux, o programa usado para interpretar o gerenciador de na-
vegação via comandos é conhecido como shell, que oferece uma maneira de
criar arquivos e scripts executáveis, executar programas, manipular siste-
mas de arquivos, compilar código de computador e gerenciar o computador.
E, ainda, o uso do shell se estende a comandos executados em sistemas DOS
ou no Prompt de comandos cmd, do Windows.
7Linguagens de programação para scripts
No universo de scripts em Shell, existem derivados desse interpretado,
como o bash, uma abreviação em homenagem ao seu criador, Stephen Bourne
(Bourne Again Shell). E o bash não é o único, embora seja o interpretador-
-padrão para várias distribuições Linux, como Debian, Fedora e Ubuntu.
Outros shells estão habilitados, como o shell C (csh), muito conhecido entre
os usuários da distribuição BSD Unix, o shell Korn (ksh), popular entre os
usuários da distribuição Unix System V, o shell dash, utilizado em distribui-
ções Ubuntu e projetado para operar e oferecer maior velocidade que o próprio
bash. A maioria das distribuições Linux, por padrão, inclui o shell bash.
O bash pode ser executado via terminal, mas seus comandos estar con-
tidos em um arquivo, o que facilita a manutenção de um código. A extensão
de arquivo se dá no formato .sh. Em breve, veremos uma pequena listagem
de alguns de seus exemplos. Os comandos no terminal apresentado estão
localizados após a cerquilha (#).
Exemplo-base do comando echo, que, literalmente, imprime alguma mensagem
desejada. Veja na Figura 4 como ele funciona.
Figura 4. Uso do comando echo.
Como já mencionado, uma boa prática de escrever instruções bash se dá
por meio de arquivos, que podem ser alterados conforme a necessidade. Para
fins de comparação, a Figura 5 apresenta os passos de criação de um arquivo
.sh que executa internamento comandos bash e imprime uma mensagem.
Linguagens de programação para scripts8
Figura 5. Comando echo dentro de um arquivo.
O passo (1) abre o programa nano como editor de texto. Perceba que, na
etapa (2), no topo do editor de texto, está declarada a linguagem de script que
será usada, por meio do cabeçalho #!/bin/bash. Na etapa (3), executa-se
o arquivo e, logo abaixo, é apresentada a mensagem declarada. A etapa (4)
apresenta uma forma alternativa da execução de arquivos .sh. Perceba que
no resultado dispõe da mensagem de permissão negada, que é contornada pelo
comando chmod na etapa (5), que altera as permissões para o arquivo possa
ser executado, permitindo, assim, que seja executado na etapa (6).
Exemplo de remoção de um arquivo: o comando rm é responsável por remover
qualquer arquivo. O exemplo da Figura 4 apresenta o procedimento desde a criação
do script de remoção até a sua execução.
Novamente, há o processo de exemplificação da criação de um shell script
com o cabeçalho bash. O exemplo explorado na Figura 6 envolve sete passos,
com seus respectivos resultados apontados por uma seta verde, conforme
apresentado a seguir. Deve-se lembrar que todos esses passos foram executados
dentro do mesmo diretório.
9Linguagens de programação para scripts
Figura 6. Script de remoção de qualquer arquivo.
1. Criação do arquivo remover_arquivo.sh com o editor de texto nano.
2. Script de remoção, no qual é utilizado o recurso read para obtenção da variável
fn, que receberá o nome do arquivo que será removido pelo comando rm –i,
complementado pela variável $fn contendo o nome do arquivo.
3. Lista os arquivos contidos no diretório atual.
4. Executa o script por meio do comando bash, seguido do arquivo que contém o
script de remoção.
5. Umavez executado o script, é solicitado ao usuário que digite o nome do arquivo
que será removido. Escolhemos o arquivo teste.txt.
6. Aqui, é feita uma checagem de segurança, para que tenhamos certeza da ação
em execução.
7. Por fim, é feita a listagem de verificação, na qual não é mais possível apresentar o
arquivo teste.txt.
A principal vantagem do shell reside no fato de que quase todas as variantes
do Unix vêm com ele, ou seja, o usuário quase nunca precisará instalar alguma
dependência. No entanto, o shell não é recomendado para nenhuma tarefa de
programação, mas somente para tarefas mais simples.
Linguagens de programação para scripts10
Visual Basic Script
O Visual Basic Script (VBScript) introduziu uma grande abordagem para o
desenvolvimento de aplicações com interface. O poder dessa linguagem está
relacionado a tecnologias de instrumentação do gerenciamento do Windows
(WMI) e às interfaces de serviço do Active Directory (ADSI). Ao utilizar o
VBScript com essas tecnologias, é possível escrever um script de até 10 mil
linhas. E o que torna o VBScript tão atrativo para administradores de sistemas
refere-se à simplicidade que oferece, mesmo em soluções de gerenciamento
empresarial, como ilustrado no exemplo apresentado na Figura 7, em que o
script de três linhas coleta informações de espaço livre em disco da unidade
C, no qual cada linha executa determinada tarefa:
1. Usa a função VBScript GetObject para se conectar à WMI pela
biblioteca de scripts WMI (um objeto de automação).
2. Usa o método Get, fornecido pelo objeto de automação WMI, para
recuperar as propriedades da unidade C.
3. Usa o método Echo do Windows Script Host (WSH) para relatar a
quantidade de espaço livre em disco na unidade C. Aliás, o WSH é
apenas outro objeto de automação.
Figura 7. Verificação de espaço livre na unidade de disco C.
Caso tenha dificuldades com usuários que utilizam muito espaço em disco
na unidade C de seus computadores, o script da Figura 5 apresenta uma solução
personalizada para identificar os computadores com pouco espaço livre em
disco, de maneira local.
11Linguagens de programação para scripts
Uma das vantagens do VBScript reside no fato de que, no caso de o script
não atender completamente às suas necessidades, ele pode ser facilmente
modificado, sem a necessidade de criar um novo script a partir do zero.
É possível criar scripts bem simples e adicionar recursos a ele conforme suas
necessidades forem mudando.
Uma das características do VBScript consiste no seu funcionamento com
objetos. Tal funcionalidade possibilita a administradores de determinado sis-
tema criar scripts complexos por meio de recursos de programação avançados,
como árvore de decisão, loop, tratamento de erros, e sub-rotinas, chamadas
de funções. Infelizmente, o VBScript não apresenta funções internas para
a interrupção de serviços, para a recuperação de eventos em logs ou para a
execução de outras tarefas do interesse de administradores de sistemas.
Existem outras formas para efetuar chamadas para interrupção, leituras de
logs, etc. usando VBScript pelo uso de objetos de automação. Esses objetos
de automação, também conhecidos pela sigla COM (modelo de objeto com-
ponente), representam um estilo-padrão de aplicativos (arquivos .exe) ou
bibliotecas de programação (arquivos .ddl), no qual apresentam seus recursos
na forma de objetos. Tais facilidades são bem recebidas por programadores,
que podem incluir os objetos em seus próprios projetos. Com a automação,
não se utiliza diretamente o próprio objeto. Para evitar erros, é criada uma
referência ao objeto, usando GetObject ou CreateObject e atribuindo
o objeto a uma variável.
O VBScript tem todo um aglomerado de instruções para seu funciona-
mento, como a declaração de variáveis, interações por meio do For Each,
coleções, matrizes, tomadas de decisões com If-Then ou If-Then-Else
e tratamento de erros.
Python
Python é uma linguagem de programação cada vez mais em evidência, muito
pela comunidade em aprendizado de máquina, que tem explorado essa lin-
guagem de alto nível. Trata-se de uma linguagem fácil, gratuita e de código
fonte aberto, além de ter múltiplo paradigma e suporte à herança múltipla.
Linguagens de programação para scripts12
Para que um código na linguagem Python seja reconhecido como um script,
deve passar por três etapas, conforme demonstrado na Figura 8.
Figura 8. Etapas de um script em Python.
Fonte: Klein (2018, documento on-line).
1. Processa as instruções do script de maneira sequencial.
2. Compila o código-fonte para um formato intermediário, conhecido como bytecode,
que constitui uma tradução de código para uma linguagem de baixo nível, que
fornece suporte independente de plataforma. Isso auxilia o interpretador a não
compilar o código-fonte da próxima vez que for executado.
3. Envia o código para execução. Esse código de execução é conhecido como Python
virtual machine (PVM), sendo o motor de execução do Python ou interpretador.
Python é uma linguagem que visa à rapidez quando implementado um
programa. Isso suporta estruturas de dados complexas, de modo a deixar
o código transparente e fácil. Sua sintaxe de programação dispõe de uma
estrutura pouco usual de estrutura em blocos, controlada por endentação, em
vez do uso de chaves que marcam o começo e o fim de um bloco.
A distribuição-padrão de Python inclui bibliotecas de clientes para a maioria
dos protocolos importantes da internet (SMTP, FTP, POP3, IMAP, HTTP)
e classes de gerador para HTML, o que o torna muito adequado para criar
robôs de protocolo e scripts de administração de rede. Também é adequado
para escrever páginas CGI dinâmicas e concorre com sucesso com o Perl no
final de alta complexidade dessa área de aplicação (o Google, por exemplo,
emprega amplamente a linguagem Python).
13Linguagens de programação para scripts
JavaScript
O JavaScript teve origem como uma linguagem de script da Web no mundo
Netscape, usada para implementar páginas da Web interativas usando script
do lado do cliente e criar páginas dinâmicas da Web com o script do lado
do servidor. Trata-se de uma linguagem de script geral capaz de controlar
aplicativos com script além dos navegadores e servidores da Web.
Como brevemente afirmado, e ainda de acordo com Barron (2000), a lin-
guagem JavaScript foi criada em 1995 por Brendan Eich, enquanto trabalhava
na Netscape Communications Corporation. Originalmente projetada para rodar
no Netscape Navigator, tinha o propósito de dinamizar determinados processos
de páginas Web. Um ano depois de seu lançamento, a Microsoft adicionou a
linguagem ao seu navegador, o que ajudou a consolidar a linguagem e torná-la
uma das tecnologias mais importantes e utilizadas na internet.
Os scripts em JavaScript, em vez de rodarem remotamente em servidores,
têm como característica rodarem programas localmente do lado do cliente.
Dessa forma, o JavaScript fornece às páginas Web a possibilidade de programar,
transformar e utilizar dados enviados e recebidos, interagindo com a marca-
ção e a exibição de conteúdo da linguagem HTML e com a estilização desse
conteúdo proporcionada pelo CSS nessas páginas, como mostrado na Figura 9.
Figura 9. Uso do JavaScript junto ao HTML.
Fonte: Silva (2015, documento on-line).
Linguagens de programação para scripts14
Os scripts de código escritos nessa linguagem e executados em um nave-
gador possibilitam, por exemplo, atualizar parte do conteúdo de uma página
Web sem carregá-la totalmente após preencher um formulário. Atualmente,
além de desenvolver sites e aplicativos, está presente no desenvolvimento de
aplicativos para smartphones e até mesmo programas desktop.
BARRON, D. W. The world of scripting languages. New York: Wiley, 2000. 492 p. (Worldwide
Series in Computer Science).
COUTO, E. Variáveis – Shell Script. GNU/Linux-BR.com, [S. l.], 18 mar. 2010. Disponível em:
https://gnulinuxbr.wordpress.com/tag/variaveis-shell-script/. Acesso em: 24 set. 2019.DIAS, I.; GEELEN, P.; RENDÓN, D. Powershell: Primeiros passos. Microsoft TechNet, Re-
dmond, 2 mar. 2018. Disponível em: https://social.technet.microsoft.com/wiki/pt-br/
contents/articles/51256.powershell-primeiros-passos.aspx. Acesso em: 24 set. 2019.
KLEIN, B. Execute a Python script. Python Course, [S. l.], 2018. Disponível em: https://www.
python-course.eu/python3_execute_script.php. Acesso em: 24 set. 2019.
NEGUS, C.; BRESNAHAN, C. Linux, a bíblia: o mais abrangente e definitivo guia sobre
Linux. 8. ed. Rio de Janeiro: Alta Books, 2014. 852 p.
RODRIGUES, F. Como praticar com 16 linguagens de programação sem instalar nada.
Sempre Update – Portal Comunitário, [S. l.], 4 set. 2019. Disponível em: https://sempreu-
pdate.com.br/como-praticar-com-16-linguagens-de-programacao-sem-instalar-nada/#.
Acesso em: 24 set. 2019.
SEBESTA, R. W. Conceitos de linguagem de programação. 11. ed. Porto Alegre: Bookman,
2018. 758 p.
SILVA, G. O que é e como funciona a linguagem JavaScript? CanalTech, São Bernardo
do Campo, 8 jan. 2015. Disponível em: https://canaltech.com.br/internet/O-que-e-e-
-como-funciona-a-linguagem-JavaScript/. Acesso em: 24 set. 2019.
15Linguagens de programação para scripts
Dica do professor
As linguagens scripts podem ser utilizadas com vários objetivos. Entre eles, automatizar tarefas e
rotinas repetitivas e desgastantes ao ser humano, o que agiliza as atividades e garante que elas
estejam sempre em execução. No entanto, as linguagens scripts também podem criar scripts
maliciosos, com o intuito criminoso.
Nesta Dica do Professor, você irá aprender mais sobre como funciona um script malicioso.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://fast.player.liquidplatform.com/pApiv2/embed/cee29914fad5b594d8f5918df1e801fd/93ecf00c916918cc6bfe9c468330200e
Saiba +
Para ampliar o seu conhecimento a respeito desse assunto, veja abaixo as sugestões do professor:
A Linguagem de Programação Lua
Conheça Lua, uma linguagem de programação script desenvolvida por uma equipe de brasileiros.
Confira.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Linguagens de programação compiladas e linguagens de
programação interpretadas
Quando se está codificando um sistema, nem sempre se preocupa com o trabalho feito por trás
daquela programação. Neste vídeo, entenda como funcionam os métodos de tradução.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Comece a usar o Python no Windows para scripts e automação
Neste link, você poderá conferir o passo a passo para configurar um ambiente de desenvolvimento
e usar o Python para criar scripts e automatizar operações do sistema de arquivos no Windows.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://www.lua.org/portugues.html
https://www.youtube.com/embed/YtcC8R-2urI
https://docs.microsoft.com/pt-br/windows/python/get-started/python-for-scripting
Programação imperativa
Apresentação
O imperativo é o mais antigo dos paradigmas da computação e se consagrou como o mais utilizado
e de maior sucesso, visto que a maioria das linguagens de programação implementam-no, mesmo
que também implementem outros paradigmas como o orientado a objetos ou o estruturado, por
exemplo. O paradigma imperativo alcançou sucesso também pelo fato de se adaptar ao modelo
clássico de Von Neumann, em que o programa e seus dados são alocados na mesma memória, o
que facilita o processamento das instruções pelo compilador.
Nesta Unidade de Aprendizagem, você irá conhecer o que é a programação imperativa, como
distinguir as linguagens de programação imperativa e exemplos de sua aplicação.
Bons estudos.
Ao final desta Unidade de Aprendizagem, você deve apresentar os seguintes aprendizados:
Explicar o que é a programação imperativa.•
Distinguir as linguagens de programação imperativa.•
Aplicar a programação imperativa.•
Infográfico
O paradigma de programação imperativo é o mais estabilizado e utilizado pela maioria das
linguagens de programação. Ele se baseia no modo de funcionamento do computador, ou seja, é
influenciado por sua arquitetura. Consequentemente, isso se reflete na execução sequencial
baseada em comandos e no armazenamento de dados alteráveis, conceitos que são baseados na
maneira pela qual computadores executam os programas em nível de linguagem de máquina. O
termo “imperare”, do Latim, significa “comandar”.
O paradigma imperativo foi predominante nas linguagens de programação, pois estas são mais
fáceis de traduzir para uma forma adequada de execução na máquina.
No Infográfico a seguir, você irá conhecer os principais conceitos que caracterizam uma linguagem
de programação imperativa e as primeiras linguagens que implementaram esse paradigma.
Aponte a câmera para o
código e acesse o link do
conteúdo ou clique no
código para acessar.
https://statics-marketplace.plataforma.grupoa.education/sagah/005a514a-fbd7-4a3b-996c-d3b0f6972866/abd704fb-ffd0-452c-8c74-912332ec928c.png
Conteúdo do livro
O paradigma de programação caracteriza-se por se basear no próprio funcionamento do
computador, que, por sua vez, baseia-se no modelo de Von Neumman. Essa característica é
perceptível no modo de instrução sequencial e alteração do estado de variáveis, conceitos
fundados na forma como os computadores executam programas em nível de linguagem de
máquina. Isso justifica certamente o grande sucesso desse paradigma e o grande número de
linguagens de programação que implementam suas características.
Na obra Paradigmas de programação, base teórica para essa Unidade de Aprendizagem, leia o
capítulo Programação Imperativa e conheça um pouco mais sobre o paradigma imperativo, as
principais características de linguagens de programação que implementam esse paradigma e alguns
exemplos de aplicação.
Boa Leitura.
PARADIGMAS DE
PROGRAMAÇÃO
Fabricio Machado da Silva
Programação imperativa
Objetivos de aprendizagem
Ao final deste texto, você deve apresentar os seguintes aprendizados:
� Explicar o que é a programação imperativa.
� Distinguir as linguagens de programação imperativa.
� Aplicar a programação imperativa.
Introdução
O paradigma imperativo na computação tem em seu nome a semelhança
com o padrão imperativo das linguagens naturais que expressam ordens.
Portanto, linguagens de programação (LP), que implementam esse padrão,
são caracterizadas por programas construídos a partir de algoritmos
que expressam uma sequência de comandos a serem executados pelo
computador para alcançar determinado resultado.
O paradigma imperativo é o mais antigo dos paradigmas da com-
putação e o que obteve, até então, o maior sucesso. Esse sucesso
pode ser relacionado à própria arquitetura de processamento dos
computadores.
Neste capítulo, você entenderá do que se trata o paradigma im-
perativo, algumas das linguagens mais utilizadas e um pouco da sua
aplicação.
Paradigma imperativo
O paradigma de programação imperativo surgiu na década de 1940, quando
John von Neumann e colaboradores percebem que tanto um programa de
computador como seus dados poderiam compartilhar a memória principal.
Essa descoberta foi um conceito inovador, devido ao fato de que os primeiros
computadores armazenavam seus programas fora da memória. Com a pos-
sibilidade de armazenar um programa na memória, foi possível alcançar um
novo patamar de versatilidade e computação.
A arquitetura do modelo de von Neumann se tornou, então, a base do
conceito do paradigma de programação imperativa, na qual a memória da
máquina contém tanto as instruções do programa que está executando como
os valores dos dados (armazenamento dos dados). Além disso, no centro dessa
arquitetura, encontra-se outra característica clássica do paradigma imperativo:
alterar o valor de um local de memória e destruir o seu valor anterior, ou seja,
o conceito de atribuição.Segundo Tucker e Noonan (2009, p. 277):
Já que elas surgiram do modelo de von Neumann-Eckert, todas as linguagens
imperativas incluem a atribuição como um elemento central. Além disso, elas
suportam declarações de variáveis, expressões, comandos condicionais, laços
e abstração procedural.
Em LP imperativas, as expressões são interpretadas conforme a recuperação
de valores correntes de variáveis por meio de nomes que referenciam seus
respectivos endereços na memória.
A Figura 1 ilustra o exemplo clássico da estrutura do modelo de von
Neumman e como programas em linguagens imperativas são executados
pelo computador.
Programação imperativa2
Figura 1. Arquitetura de von Neumann e o paradigma de LP imperativa.
Fonte: Linguagem... (2018, documento on-line).
Ainda utilizando como base a arquitetura de von Neumman, programas
construídos em linguagens imperativas tem seus comandos executados na
ordem em que aparecem na memória, embora os comandos condicionais e as
ramificações possam alterar um pouco esse fluxo de execução. No início, os
comandos de uma linguagem imperativa eram apenas abstrações simplifica-
das de instruções em máquinas de von Neumman, padrão que englobavam
comandos de atribuição, condicionais e ramificações.
Boa parte dos computadores mais populares nos últimos anos foi projetada com base
na arquitetura proposta por von Neumann. Nela, dados e programas são armazenados
na mesma memória. A unidade central de processamento (UCP), que executa realmente
as instruções, é separada da memória.
3Programação imperativa
Dessa forma, podemos sintetizar que a fundamentação da programação
imperativa se resume a três conceitos:
� Estado de uma máquina, relacionado aos valores de um conjunto de
variáveis.
� Expressões, compostas pela relação entre esses valores ou o resultado
de operações entre esses valores.
� Comandos de atribuição e controle, que manipulam esses estados das
variáveis.
Em outras palavras, um programa escrito em uma linguagem imperativa
é representado por um conjunto de dados que determinam o seu estado e, por
meio da manipulação desses dados (leitura, criação de expressões e geração
de novos valores), o seu estado vai sendo alterado até o resultado esperado
ser alcançado.
Linguagens de programação imperativas
Agora, você verá um pouco mais sobre as características que definem se uma
linguagem se enquadra no paradigma de programação imperativa e alguns
exemplos de linguagens imperativas. Além das características já comentadas
em relação à implementação de instruções e comandos que um programa em
linguagem imperativa especifica para que o computador alcance determinado
resultado, uma linguagem imperativa é classificada completa quanto a Turing
quando possibilita a implementação de qualquer algoritmo que possa ser
projetado (TUCKER; NOONAN, 2009).
Ser completa quanto a Turing é uma característica que permite mensurar se
uma linguagem consegue implementar qualquer situação, incluindo situações
comuns que envolvam:
� estruturas de controle;
� entrada e saída de dados;
� manipulação de exceções e erros;
� abstração procedural;
� expressões e atribuição;
� suporte de bibliotecas para estrutura de dados.
Programação imperativa4
Para definir melhor este conceito, vamos analisar a implementação dessas
características do ponto de vista de duas linguagens imperativas, a linguagem
C e a linguagem Ada. A linguagem C foi projetada inicialmente para ser
implementada no sistema operacional UNIX, nos laboratórios Bell, por Ken
Thompson e Dennis Ritchie, que participavam ativamente do desenvolvimento
de um avançado sistema operacional que, ao contrário dos sistemas operacionais
criados, estava sendo escrito em programming language one (PL/I) em vez
de assembly (OKUYAMA; MILETTO; NICOLAO, 2014).
Após o laboratório Bell desistir do projeto do sistema operacional, Thomp-
son e Ritchie continuaram o desenvolvimento de um sistema de documentação,
que seria independente de máquina e possibilitava a execução em minicompu-
tadores baratos do final de 1960, nascia assim o sistema operacional UNIX.
A linguagem C foi utilizada na construção desse sistema operacional, incial-
mente baseada na linguagem basic combined programming language (BCPL)
que não possuía tipo (OKUYAMA; MILETTO; NICOLAO, 2014).
A partir disso, a linguagem C foi amplamente utilizada, principalmente
em ambientes acadêmicos, tendo, inclusive, impacto no surgimento de inú-
meras outras linguagens conhecidas atualmente, como Java, Python e C++
(PINHEIRO, 2012).
A linguagem C possui comandos de atribuição, sequência e os condicionais
if e switch, laços while, for e do e chamadas a funções. Com relação à estrutura
de dados, a linguagem C permite trabalhar com matrizes, ponteiros, estrutu-
ras (registros) e tipos de dados de união. Como uma linguagem imperativa,
o C não possui:
� iteradores;
� manipulação de exceções;
� sobrecarga;
� genéricos.
Veja um exemplo de código em C que define uma estrutura com nome, ano
de matrícula, curso e média de entrada de um aluno e, logo após, implementa
uma função de receber como parâmetro um apontador para uma estrutura do
tipo definido, criando dinamicamente uma estrutura. Para a nova estrutura,
devem ser copiados os dados da estrutura recebida. A função retorna o apon-
tador para a nova estrutura ou NULL, caso não consiga reservar memória.
5Programação imperativa
typedef struct aluno {
char nome[40];
int ano;
char curso[40];
float media;
} aluno;
aluno * copia _ aluno( aluno * a)
{
aluno *t;
t=(aluno *)malloc(sizeof(aluno));
if (t==NULL)
return t;
*t = *a;
/* ou:
strcpy(t->nome,a->nome);
t->ano = a->ano;
strcpy(t->curso,a->curso);
t->media = a->media;
*/
return t;
}
Outro bom exemplo de linguagem imperativa, é a linguagem Ada. Ela foi
desenvolvida no final da década de 1970 pelo departamento de defesa norte-
-americano para ser usada em grandes sistemas de controle e comando e em
sistemas embarcados em tempo real. Caracteriza-se por ser uma LP imperativa
de alto nível e baseada em Pascal.
Seu principal projetista foi o francês Jean Ichbiah. A linguagem foi pa-
dronizada pela American National Standards Institute (ANSI) em 1983 e,
em 1985, pela International Organization for Standardization (ISO). Um fato
curioso acerca da linguagem Ada é que, em 1995, a ISO padronizou uma
versão melhorada chamada de Ada 95, que se tornou a primeira LP orientada
a objeto (OO) padronizada internacionalmente (TUCKER; NOONAN, 2009).
Programação imperativa6
A estrutura básica de um programa em Ada é a seguinte:
-- Declarações de bibliotecas
Procedures nome _ do _ programa is
-- Declarações de variáveis
begin
-- Corpo do programa
end nome _ do _ programa;
Pela estrutura demonstrada, você pode perceber as características do
paradigma imperativo na linguagem. Vamos analisar o seguinte:
� Linguagens imperativas permitem a troca de valor de variáveis no
trecho do código do programa, logo após a sua criação é designado um
espaço para a declaração das variáveis.
� Linguagens imperativas permitem que as variáveis sejam manipuladas
e as instruções e os comandos sejam repassados para o computador,
explicando como fazer para chegar a um determinado resultado, logo
após o comando begin é necessário especificar o que o programa
deverá fazer.
Desenvolvendo e aplicando programação
imperativa
Para ajudar a elucidar o conceito de programação imperativa, analise o código
em Ada, apresentado na Figura 2. Esse exemplo demonstra a aplicação do
paradigma imperativo por meio da criação de um algoritmo que escreve a
tabuada.
7Programação imperativa
Figura 2. Algoritmo em Ada que escreve a tabuada.
Fonte: Leal (2012, documento on-line).
No algoritmo apresentado na Figura 2, você pode perceber que a linguagem
Ada possibilita outros recursos de linguagens imperativas, como os comandos
interativos,nesse caso representados pelo comando FOR.
Segundo Tucker e Noonan (2009), as linguagens com a maior influência
sobre Ada foram Algol e Pascal. Exemplos dessa influência abundam: desde
o uso do símbolo := para atribuição até o uso de begin-end para blocos.
Sintaticamente, as duas maiores diferenças dessas linguagens predecessoras
foram o uso de símbolos de término únicos para estruturas compostas; e o
uso do ponto e vírgula como um símbolo de término de comando, em vez de
um separador de comandos.
Podemos também perceber que a sintaxe da linguagem Ada exige bem mais
comandos do que a linguagem C. O exemplo da escrita da média demanda
bem mais comandos em Ada do que seria necessário na linguagem C.
Programação imperativa8
Vamos, agora, comparar por meio do exemplo demonstrado na Figura 3,
a sintaxe de um algoritmo em linguagem C, que consiste em ler números, um
de cada vez, e, então, contar e somar. Por último, o algoritmo verifica se o
número analisado é o novo número mínimo ou máximo da lista. Perceba que
a sintaxe usa comandos imperativos e uso de variáveis.
Figura 3. Algoritmo em C que faz contagem, soma e análise de números em sequência.
Fonte: Tucker e Noonan (2009, p. 288).
O programa usa uma declaração de atribuição múltipla para inicializar sum
e ct e, posteriormente, min e max. Atribuições condicionais são usadas para
atualizar min e max. A entrada e a saída que utilizam códigos de formatos
também são utilizadas.
Para finalizar, analise um exemplo em outra linguagem imperativa, o Perl.
Segundo Tucker e Noonan (2009, p. 296), “Perl é uma linguagem de scripting
amplamente usada, que é uma linguagem de alto nível interpretada em tempo
de execução em vez de compilada em linguagem de máquina”.
9Programação imperativa
O exemplo da Figura 4 é um script em Perl que envia as notas de alunos
por e-mail; esse é um bom exemplo de casos em que linguagem de scripting
imperativa Perl é empregada. Perceba, também a utilização das características
imperativas no código.
Figura 4. Script em Perl que envia por e-mail as notas de alunos.
Fonte: Tucker e Noonan (2009, p. 304).
Em todos os exemplos, é perceptível, apesar das diferenças e aplicações
das linguagens, que todas seguem os princípios do paradigma imperativo,
deixando clara a sua importância para a computação.
Programação imperativa10
Veja, no link a seguir, alguns vídeos nos quais são feitas comparações entre os para-
digmas imperativo, funcional e OO.
https://qrgo.page.link/jtDar
LEAL, C. Linguagem de Programação Ada. Mostre ao Mundo, Campinas, 19 out. 2012.
Disponível em: http://www.mostreaomundo.com.br/2012/10/linguagem-de-progra-
macao-ada.html. Acesso em: 28 ago. 2019.
LINGUAGEM de programação: classificações. Universidade da Tecnologia, [S. l.], 16 fev.
2018. Disponível em: https://universidadedatecnologia.com.br/linguagem-de-progra-
macao-classificacoes/. Acesso em: 28 ago. 2019.
OKUYAMA, F. Y.; MILETTO, E. M.; NICOLAO, M. Desenvolvimento de software I: conceitos bá-
sicos. Porto Alegre: Bookman, 2014. 236 p. (Série Tekne; Eixo Informação e Comunicação).
PINHEIRO, F. A. C. Elementos de programação em C: em conformidade com o padrão
ISO / IEC 9899. Porto Alegre: Bookman, 2012. 548 p.
TUCKER, A. B.; NOONAN, R. E. Linguagens de programação: princípios e paradigmas.
2. ed. Porto Alegre: AMGH, 2009. 630 p.
Leituras recomendadas
EDELWEISS, N.; LIVI, M. A. C. Algoritmos e programação: com exemplos em Pascal e C.
Porto Alegre: Bookman, 2014. 476 p. (Série Livros Didáticos Informática UFRGS).
LEDUR, C. L. Desenvolvimento de sistemas com C#. Porto Alegre: SAGAH, 2018. 268 p.
MACHADO, R. P.; FRANCO, M. H. I.; BERTAGNOLLI, S. C. Desenvolvimento de software III:
programação de sistemas web orientada a objetos em Java. Porto Alegre: Bookman,
2016. 220 p. (Série Tekne; Eixo Informação e Comunicação).
MILETTO, E. M.; BERTAGNOLLI, S. C. Desenvolvimento de software II: introdução ao de-
senvolvimento web com HTML, CSS, JavaScript e PHP. Porto Alegre: Bookman, 2014.
276 p. (Série Tekne; Eixo Informação e Comunicação).
NICOLETTI, M. C. A cartilha Prolog. São Carlos: Edufscar, 2003. 124 p. (Série Apontamentos).
SEBESTA, R. W. Conceitos de linguagem de programação. 11. ed. Porto Alegre: Bookman,
2018. 758 p.
11Programação imperativa
Dica do professor
Certamente você já desenvolveu, em alguma linguagem de programação que implementou, o
paradigma imperativo, ou, então, se ainda não implementou, certamente irá implementar. Apesar
de seu grande sucesso e das características que o tornam um paradigma estável, existem vantagens
e desvantagens que todo profissional precisa conhecer.
Na Dica do Professor de hoje, conheça as principais características do paradigma imperativo e suas
principais vantagens e desvantagens.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://fast.player.liquidplatform.com/pApiv2/embed/cee29914fad5b594d8f5918df1e801fd/1946528b89c12fc3a09a7d58959907bc
Saiba +
Para ampliar o seu conhecimento a respeito desse assunto, veja abaixo as sugestões do professor:
Diferença entre as programações Orientação-objetos,
Imperativa e Funcional
Neste site, leia este excelente material que faz um comparativo da programação imperativa com
outros paradigmas de programação.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Introdução à lógica de programação imperativa
Para saber mais, assista a esse vídeo, que mostra uma introdução à lógica de programação
imperativa.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Introdução a Lógica de programação Imperativa
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://devpleno.com/orientacao-objetos-imperativa-e-funcional/
https://www.youtube.com/embed/PAJnIdM8vyc
https://www.youtube.com/watch?v=PAJnIdM8vyc
Métodos de programação
Apresentação
Conhecer e entender os métodos e tipos de programação é um desafio instigante e, de certa forma,
um compromisso de todo profissional de desenvolvimento de software. Ao compreender os
conceitos que levam ao desenvolvimento de diferentes paradigmas, é possível apresentar maior
discernimento quanto à adoção de uma linguagem de programação que atenda a uma determinada
necessidade.
Nesta Unidade de Aprendizagem, você vai conhecer a evolução
dos principais tipos de métodos de programação e o seu histórico
de desenvolvimento.
Bons estudos.
Ao final desta Unidade de Aprendizagem, você deve apresentar os seguintes aprendizados:
Definir métodos de programação.•
Sintetizar o histórico dos métodos de programação.•
Identificar os tipos de métodos de programação.•
Infográfico
Aprender sobre a evolução dos paradigmas de programação e entender o caminho percorrido até
os recursos atuais de programação é, além de instigante, necessário para o profissional de
programação.
A seguir, no Infográfico, veja a evolução das linguagens e dos paradigmas de programação e os
desafios já transpostos ao longo dos anos pelos projetistas, engenheiros de computação
e comunidade de desenvolvedores.
Aponte a câmera para o
código e acesse o link do
conteúdo ou clique no
código para acessar.
https://statics-marketplace.plataforma.grupoa.education/sagah/93c6d0b2-e003-4399-8091-2ae86439b816/2643a068-5459-43be-b95a-9915102b3760.png
Conteúdo do livro
Os métodos de programação fazem parte da história da programação, assim como as linguagens e
tecnologias relacionam-se à arte de programação. Esses paradigmas contam muito da evolução e de
como a ciência ao longo do tempo desenvolveu meios mais próximos das necessidades de
programação propostas à comunidade.
Leia o capítulo Métodos de programação, da obra Paradigmas de programação, e conheça um pouco
mais sobre a evolução dos paradigmas de programação, veja os tipos existentes e entenda seus
conceitos e sua relação com aslinguagens que surgiram ao longo do tempo.
Boa leitura.
PARADIGMAS DE
PROGRAMAÇÃO
Fabricio Machado da Silva
Métodos de programação
Objetivos de aprendizagem
Ao final deste texto, você deve apresentar os seguintes aprendizados:
� Explicar o que são métodos de programação.
� Sintetizar o histórico dos métodos de programação.
� Identificar os tipos de métodos de programação.
Introdução
Em geral, quando se trata do tema paradigmas de programação, não
se atribui a devida importância para o assunto. Todo o profissional de
programação de computadores deveria se atentar aos diferentes para-
digmas, pois eles são a base para as diferentes linguagens que existem
e existiram ao longo da evolução da programação.
É comum pensar, como estudantes ou profissionais, quais os be-
nefícios de entender os conceitos de linguagens de programação em
uma área com tantos temas muito pertinentes, mas saber como uma
linguagem funciona para interpretar as instruções e a evolução de lin-
guagens e conceitos ao longo do tempo, sem dúvidas, traz vantagens
na construção de softwares.
Neste capítulo, você aprenderá o que são os métodos de programa-
ção, quais são os diferentes tipos e como ocorreu a sua evolução.
Paradigmas de programação
Como seres humanos, sentimos necessidade de expressar nossos pensamentos,
seja de forma verbal, utilizando o nosso poder de comunicação, ou escrita,
escrevendo textualmente o que estamos pensando. A linguagem de progra-
mação, assim como a nossa linguagem natural, permite nossa comunicação
com as máquinas. Dessa maneira, podemos instruir, por meio de linhas de
comandos, as máquinas a executarem determinada instrução.
No entanto, para Tucker e Noonan (2009), as linguagens de programação
se diferem das linguagens naturais de duas maneiras importantes. Apesar
de permitirem a comunicação entre humanos e máquinas, elas possuem um
domínio de expressão mais reduzidos do que as linguagens naturais, pois
seu objetivo é permitir a compreensão de ideias computacionais, ou seja, se
propõem a atender diferentes requisitos das linguagens naturais.
Toda a linguagem de programação está construída sobre um paradigma.
Mas, afinal, o que é um paradigma? Um paradigma representa um padrão de
pensamento que guia um conjunto de atividades relacionadas, trata-se de um
padrão que define um modelo para a resolução de problemas e regra, basica-
mente, toda e qualquer linguagem de programação existente. Os paradigmas
de programação estão classificados em quatro diferentes tipos, que evoluíram
ao longo das últimas décadas:
� programação imperativa;
� programação funcional;
� programação lógica;
� programação orientada a objetos.
A Figura 1 ilustra de forma hierárquica os diferentes paradigmas de pro-
gramação atuais e sua derivação dos paradigmas imperativo e declarativo.
Figura 1. Paradigmas de programação.
Fonte: Adaptada de Simão (2018).
Paradigma de programação
Paradigma imperativo Paradigma declarativo
Paradigma
procedimental
Paradigma
funcional
Programação
baseada em
regras
Paradigma
lógico
Paradigma
orientado a
objetos
Programação
orientada a
eventos
Métodos de programação2
Algumas linguagens de programação foram projetadas para suportar diferentes
paradigmas. Um exemplo disso, é o da linguagem de programação C++, que foi
projetada para ser uma linguagem imperativa e orientada a objetos.
No início da programação, o único meio de conseguir programar um
computador era inserindo um código binário de programas para a sua me-
mória principal, o que representava uma grande probabilidade de erros e uma
manutenção praticamente impossível. Nessa época, escrevia-se programas
utilizando linguagens de baixo nível, porém, com a popularidade dos computa-
dores, as demandas por softwares se tornaram enormes. Então, as linguagens
necessitaram evoluir para um paradigma de nível mais alto, sendo a evolução
dos métodos e linguagens uma consequência dessa demanda.
Na próxima seção, você verá um pouco da evolução dos paradigmas de
programação ao longo das décadas e o surgimento de diferentes linguagens
que possibilitaram o desenvolvimento de softwares com melhor compreensão
e manutenção do que os existentes no início da programação.
Histórico dos métodos de programação
No início da programação de computadores, as primeiras linguagens disponí-
veis eram as de máquinas e as próprias linguagens de construção (Assembly)
dos primeiros computadores. A partir delas, muitas linguagens de programa-
ção e dialetos foram desenvolvidos, algumas obtiveram sucesso e inclusive
influência sobre outras linguagens e, naturalmente, outras tiveram um tempo
de vida limitado Sebesta (2018).
A programação de computadores não tem uma data correta de início. Na
década de 1930, surgiram os primeiros computadores elétricos; já em 1948,
Konrad Zuse publicou sua criação, a linguagem de programação Plankalkül.
Nessa época, ela ainda não tinha muita utilidade, então, foi esquecida. Con-
tudo, antes da programação passar para o computador, eram usados cartões
de papelão, que eram perfurados, criando códigos.
3Métodos de programação
Os paradigmas da programação foram criados, em sua maioria, na década
de 1970. Nessa época surgiram as seguintes linguagens:
� Simula — inventada nos anos de 1960 por Nygaard e Dahl, foi a primeira
linguagem a suportar o conceito de classes;
� C — foi uma das primeiras linguagens de programação de sistemas,
criado por Dennis Ritchie e Ken Thompson, tem uma das maiores
influências no mundo atual;
� Prolog — projetada em 1972, foi a primeira linguagem de programação
com paradigma lógico;
� Pascal — foi muito importante, mas atualmente está quase sem uso;
� C++ — criada para ser compatível com C, foi muito importante, pois
é mais simples e dinâmica;
� Perl — é uma boa linguagem para trabalhar em níveis de sobrecarga
grandes.
Nos anos de 1990, a internet surgiu como um furacão, mudando totalmente
o rumo da programação. As linguagens Java e JavaScript foram criadas nessa
época, ambas relacionadas à internet. Na mesma época, surgiram a Visual
Basic e o Object Pascal.
Java é uma linguagem relativamente simples, orientada a objetos, criada com
o intuito de revolucionar as linguagens de programação. Já PHP (acrônimo para
“pré-processador de hipertexto”) é muito importante para o desenvolvimento
de aplicativos para Web, é a linguagem que, cada vez mais, toma conta dos
websites (MILETTO; BERTAGNOLLI, 2014).
Na Figura 2, você verá um breve resumo histórico da evolução e da in-
fluência de algumas linguagens de programação sobre outras. Apesar desse
histórico não ser completo, é possível perceber alguns eventos e tendências
mais influentes.
Métodos de programação4
Figura 2. Resumo da história das linguagens de programação.
Fonte: Tucker e Noonan (2009, p. 7).
A década de 1950 marcou a chegada das linguagens de alto nível. Essas
linguagens se diferenciavam das linguagens de máquina por não estarem dire-
tamente dependentes de uma arquitetura específica. As primeiras linguagens
que chegaram com essa característica foram Fortran, Cobol, Algol e Lisp.
Fortran e Cobol foram linguagens que alcançaram um grande sucesso e
possuem, até hoje, um grande legado de sistemas escritos que atuam inclusive
em grandes organizações, como segmento financeiro. Já Lisp foi caindo em
desuso e Algol praticamente sumiu (MILETTO; BERTAGNOLLI, 2014).
5Métodos de programação
Certamente, o maior motivador para o desenvolvimento das linguagens
e métodos de programação nas últimas décadas tem sido o rápido desenvol-
vimento dos recursos computacionais e o surgimento de novas e emergentes
tecnologias, entre as quais podemos destacar as seguintes áreas:
� inteligência artificial;
� World Wide Web ;
� sistemas e redes;
� dispositivos móveis.
Ao contrário do que costumamos imaginar, a programação funcional não é o oposto
de programação orientada a objetos. São tipos diferentes de programação, mas
podem, inclusive,ser usadas em uma mesma aplicação, principalmente em linguagens
multiparadigmas, como o JavaScript.
O projeto de uma nova linguagem de programação é algo bem complexo,
o projetista deve se preocupar com inúmeros desafios e adotar soluções es-
pecíficas, que se proponham a atender esses desafios. Os principais desafios
envolvidos no projeto de uma nova linguagem de programação são:
� arquitetura;
� requisitos técnicos;
� padrões.
Entre os desafios propostos aos projetistas, vamos destacar os padrões.
Sempre que uma linguagem de programação tem um amplo uso entre os
desenvolvedores, é natural que novo processo de padronização surja, ou
seja, a comunidade define um padrão de construção independentemente da
máquina da linguagem e que todos os seus programadores devem aderir. Isso
é importante porque o método de padronização, entre outras vantagens, busca
a estabilização em diferentes plataformas, possibilitando a portabilidade dos
programas construídos a partir dela.
Métodos de programação6
Se observarmos essa evolução, é possível perceber que algumas lingua-
gens que obtiveram sucesso foram projetadas por comunidades ou grupos de
desenvolvedores, exigindo uma certa padronização quanto aos programas
construídos.
Tipos de programação
Os tipos de programação estão diretamente relacionados ao conceito do para-
digma no qual a linguagem foi concebida, por exemplo é impossível utilizar
uma linguagem linear como Ada ou Assembly e tentarmos construir um
programa com blocos de funções. Isso acontece porque o paradigma desse
tipo de linguagem não provê recursos que o paradigma procedural possibilita,
permitindo o reuso de código por meio de funções (blocos que executam uma
determinada funcionalidade).
Portanto, é importante entender e conhecer bem os tipos de paradigmas de
programação e seus conceitos, para que ao utilizar uma linguagem se saiba
como, de acordo com o tipo de paradigma em que ela foi concebida, devem
ser estruturados os códigos. A seguir você verá os tipos de paradigmas que
surgiram ao longo da evolução da programação.
Paradigma imperativo
Após a geração de programação linear com linguagens de máquina, houve
um grande avanço com o advento das linguagens procedurais. Esse tipo de
paradigma foi o primeiro que apresentou as linguagens de alto nível, que
permitiam a utilização de um vocabulário mais próximo ao natural para
construção de programas. Esse paradigma recebe o nome de imperativo pela
forma como as instruções nos códigos são repassadas para o compilador:
� Faça isso.
� Depois faça aquilo.
7Métodos de programação
É uma forma imperativa de dar ordens para que a máquina execute as
instruções dadas, e ela executará cada uma, passo a passo, com o propósito
de chegar no resultado esperado. Uma linguagem imperativa suporta algumas
características comuns:
� atribuições, declarações e expressões;
� estruturas de controle;
� abstração procedural.
Basicamente, os códigos são construídos obedecendo a estrutura de de-
clarações e as instruções. A linguagem mais popular desse paradigma é a
linguagem C (MILETTO; BERTAGNOLLI, 2014).
Paradigma declarativo
A principal característica das linguagens com programação declarativa é o
foco não estar em como uma execução vai ocorrer, mas sim no resultado a
ser atingido. Um dos melhores exemplos para entender esse paradigma são
as instruções structured query language (SQL), pois nela são passados para
o banco de dados apenas o que se pretende, sem a preocupação sobre como
o banco de dados vai executar a instrução, o foco é somente o retorno ou
resultado da consulta.
Atualmente, uma das principais linguagens de programação utilizada, o
framework JavaScript Angular, é um exemplo de implementação desse para-
digma, que, aliás, é muito utilizado em razão do advento dos sistemas Web,
no qual o código submete uma execução e espera o retorno.
Paradigma estruturado
No sentido mais restrito, o conceito de programação estruturada se refere à
forma do programa e do processo de codificação. É um conjunto de convenções
que o programador pode seguir para produzir o código estruturado, e suas
regras de codificação impõem limitações sobre o uso das estruturas básicas
de controle, estruturas de composição modular e documentação.
Métodos de programação8
As características do paradigma estruturado são:
� programação sem GOTO (eliminação completa ou parcial do comando
GOTO, que significa “ir para”);
� programação com apenas três estruturas básicas de controle — sequên-
cia, seleção e iteração;
� forma de um programa estruturado;
� aplicação de convenções de codificação estruturada a uma linguagem
de programação específica.
Algumas linguagens com esse paradigma são Pascal e C.
Paradigma orientado a objetos
O paradigma de orientação a objetos surge como o advento da reutilização de
código e a facilidade na manutenção. No paradigma de orientação a objetos,
o princípio é a construção de código, implementando as entidades do mundo
real por meio do conceito de classes que possuem relação entre si.
Como o desempenho das aplicações não é uma das grandes preocupações
na maioria delas (devido ao poder de processamento dos computadores atuais),
a programação orientada a objetos se tornou muito difundida. A programação
orientada a objetos está embasada em quatro pilares.
� Abstração: como estamos lidando com objetos do mundo real, por exem-
plo, carro, casa, pessoa etc.), precisamos imaginar como esses objetos
vão se integrar dentro do nosso sistema e modelar seu comportamento
abstraindo comportamento e características específicas de cada um.
� Encapsulamento: não importa para um código que invoca um método
saber como outro vai ser executado, trata-se de uma característica que
traz principalmente segurança ao código.
� Herança: assim como no mundo real, a herança em programação orientada
a objetos seria a capacidade de uma classe herdar de outra métodos e atri-
butos, sendo, portanto, uma característica relacionada ao reuso de código.
� Polimorfismo: existem animais capazes de se adaptar a algumas ne-
cessidades do mundo real e se comportar de forma diferenciada em
alguns casos, essa particularidade também é possível no paradigma
de orientação a objetos. Mesmo herdando o comportamento de outra
classe, a classe herdeira pode modificar o seu comportamento em de-
terminadas situações.
9Métodos de programação
Por ser algo muito abstrato, a programação orientada a objetos é difícil de aprender.
Vários conceitos são artificiais e isso torna o aprendizado bastante complicado. O
resultado que se vê é muito código não orientado ao objeto, mas escrito em linguagens
orientadas a objetos.
Para atender a diversidade e complexidade do universo da programação
é que os paradigmas são divididos. É importante salientar que não existe um
paradigma vinculado à determinada linguagem de programação, o paradigma
tem que ser independente de linguagem. Por exemplo, a orientação a objetos
é um paradigma criado para a solução de problemas de desenvolvedores e
não tem uma ligação de necessidade com nenhuma linguagem, quem aborda
esses paradigmas são as linguagens de programação. Você pode observar
que várias linguagens de programação abordam vários tipos de paradigma
de programação.
A escolha do melhor paradigma é necessariamente relacionada ao tipo de
problema que precisa ser solucionado.
Veja no link a seguir um site sobre os pilares e conceitos do paradigma de programação
orientada a objetos.
https://qrgo.page.link/JBCZA
MILETTO, E. M.; BERTAGNOLLI, S. C. Desenvolvimento de software II: introdução ao de-
senvolvimento web com HTML, CSS, JavaScript e PHP. Porto Alegre: Bookman, 2014.
276 p. (Série Tekne; Eixo Informação e Comunicação).
SEBESTA, R. W. Conceitos de linguagem de programação. 11. ed. Porto Alegre: Bookman,
2018. 758 p.
Métodos de programação10
SIMÃO, J. M. Orientação a objetos: programação em C++. Curitiba: Departamento Acadê-
mico de Eletrotécnica, UniversidadeFederal Tecnológica do Paraná, 2018. 26 p. (Notas
de aula). Disponível em: http://www.dainf.ct.utfpr.edu.br/~jeansimao/Fundamentos1/
LinguagemC++/Fundamentos1-2-SlidesC++1-A-2018-08-01.pdf. Acesso em: 25 ago. 2019.
TUCKER, A. B.; NOONAN, R. E Linguagens de programação: princípios e paradigmas.
2. ed. Porto Alegre: AMGH, 2009. 630 p.
Leituras recomendadas
EDELWEISS, N.; LIVI, M. A. C. Algoritmos e programação: com exemplos em Pascal e C.
Porto Alegre: Bookman, 2014. 476 p. (Série Livros Didáticos Informática UFRGS).
LEDUR, C. L. Desenvolvimento de sistemas com C#. Porto Alegre: SAGAH, 2018. 268 p.
MACHADO, R. P.; FRANCO, M. H. I.; BERTAGNOLLI, S. C. Desenvolvimento de software III:
programação de sistemas web orientada a objetos em Java. Porto Alegre: Bookman,
2016. 220 p. (Série Tekne; Eixo Informação e Comunicação).
NEGRESIOLO, L. Tudo o que você precisa (e deveria) saber sobre Programação Orien-
tada a Objetos. Gizmodo Brasil, São Paulo, 22 jan. 2019. Disponível em: https://gizmodo.
uol.com.br/tudo-sobre-programacao-orientada-a-objetos/. Acesso em: 25 ago. 2019.
OKUYAMA, F. Y.; MILETTO, E. M.; NICOLAO, M. Desenvolvimento de software I: conceitos bá-
sicos. Porto Alegre: Bookman, 2014. 236 p. (Série Tekne; Eixo Informação e Comunicação).
PINHEIRO, F. A. C. Elementos de programação em C: em conformidade com o padrão
ISO / IEC 9899. Porto Alegre: Bookman, 2012. 548 p.
11Métodos de programação
Dica do professor
Para desenvolver uma solução é necessário que se conheça tanto o problema quanto os tipos de
paradigmas de programação existentes. Apenas assim, pode ser entregue um produto que atenda
aos objetivos determinados.
A seguir, na Dica do Professor, saiba um pouco mais sobre a importância dos paradigmas de
programação.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://fast.player.liquidplatform.com/pApiv2/embed/cee29914fad5b594d8f5918df1e801fd/a90227a5bde925a16cafcbdae65c3262
Saiba +
Para ampliar o seu conhecimento a respeito desse assunto, veja abaixo as sugestões do professor:
Informações sobre paradigmas de programação
No vídeo a seguir, você vai encontrar de forma resumida e didática algumas informações
relacionadas aos paradigmas de programação.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Definições de programação imperativa, declarativa e reativa
Neste artigo, você vai encontrar uma definição sucinta de programação imperativa, programação
declarativa e de programação reativa, um paradigma relativamente novo.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
História da programação
Neste artigo, você vai conhecer um pouco da história da programação, passando por décadas de
evolução, diferentes paradigmas e linguagens.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://www.youtube.com/embed/X_n988KTXmY
https://medium.com/alexandre-malavasi/descomplicando-programa%C3%A7%C3%A3o-imperativa-declarativa-e-reativa-a481baa87742
http://www.programador.com.br/historia-da-programacao.html
Programação de scripts em sistemas open
source
Apresentação
Antes dos computadores terem interfaces amigáveis, como se conhece atualmente, todas as ações
eram enviadas ao sistema operacional por meio de comandos em um terminal. Todo sistema
operacional tem um interpretador de comandos, no caso dos sistemas baseados em UNIX, esse
interpretador de comandos é chamado de shell. Por intermédio dele, o usuário digita e envia
comandos ao
sistema operacional.
Nesta Unidade de Aprendizagem, você vai aprender a utilizar o terminal e os principais comandos
para trabalhar em ambientes Linux/UNIX. Além disso, irá aprender a criar arquivos shell scripts, para
automatizar tarefas utilizando os comandos e estruturas de controle.
Bons estudos.
Ao final desta Unidade de Aprendizagem, você deve apresentar os seguintes aprendizados:
Identificar comandos básicos na programação para scripts
em sistemas open source.
•
Reconhecer estruturas de controle na programação de scripts em sistemas open source.•
Aplicar funções na programação de scripts em sistemas open source.•
Infográfico
Podem-se criar arquivos de scripts para automatizar tarefas repetitivas no dia a dia. Muitas vezes, o
desenvolvedor despende muito tempo em ações desse tipo, como abrir os mesmos programas
diariamente, verificar se serviços e processos estão rodando, etc. Um script é um algoritmo
desenvolvido para realizar uma determinada tarefa, utilizando os comandos shell específicos.
Confira, no Infográfico, alguns dos comandos mais utilizados para automatizar tarefas diárias.
Aponte a câmera para o
código e acesse o link do
conteúdo ou clique no
código para acessar.
https://statics-marketplace.plataforma.grupoa.education/sagah/546a288f-df03-480a-a330-65a5c26b30c6/8bccbe0d-50d2-472b-979c-43a3180fa424.jpg
Conteúdo do livro
O shell é um interpretador de comandos, por meio do qual é possível realizar tarefas no Linux.
Um shell script é um arquivo com várias instruções, para serem executadas pelo terminal do Linux;
com isso, é possível automatizar diversas tarefas.
No capítulo Programação de scripts em sistemas open source, da obra Programação em ambientes de
redes de computadores, que é base teórica desta Unidade de Aprendizagem, você irá conhecer os
principais comandos de ambientes UNIX/Linux. Primeiramente, serão apresentados os comandos
básicos para executar tarefas no terminal do Linux, depois, arquivos para automatizar tarefas,
utilizando shell script.
Boa leitura.
Programação em
Ambientes de
Redes de
Computadores
Raiza Artemam de Oliveira
Programação de scripts
em sistemas open source
Objetivos de aprendizagem
Ao final deste texto, você deve apresentar os seguintes aprendizados:
� Identificar comandos básicos na programação para scripts em sistemas
open source.
� Reconhecer estruturas de controle na programação de scripts em
sistemas open source.
� Aplicar funções na programação de scripts em sistemas open source.
Introdução
Quando os primeiros computadores surgiram com sistemas operacionais
com poucas funcionalidades e bem menos modernos que os existentes
atualmente, todas as operações eram realizadas por meio de terminais.
Não havia mouse e botões para clicar antes de os computadores dispo-
rem de interfaces amigáveis como conhecemos hoje, a partir das quais
facilitou a operação de um computador por qualquer pessoa, embora
os terminais ainda estejam presentes nos sistemas operacionais.
Em sistemas operacionais baseados no sistema Unix, como Ubuntu,
CentOS e Mint, o terminal ou interpretador de comandos é chamado
de shell e exerce a função de um programa que conecta e interpreta os
comandos digitados pelo usuário. Existem vários interpretadores shell,
entre os quais se destaca o interpretador bash (bourne again shell), por
sua popularidade.
Neste capítulo, você aprenderá sobre linha de comando no sistema
Linux, os principais comandos para trabalhar no terminal e a escrever
arquivos shell script e como aplicá-los no ambiente de trabalho.
Programação script: principais comandos
O terminal Linux é um programa que recebe os comandos do usuário a partir
do teclado e os repassa às camadas de baixo nível do sistema operacional
(NEGUS; BRESNAHAN, 2014). Dessa forma, pode-se defini-lo como um
mecanismo que provê a interação do usuário com o sistema operacional. Por
meio do terminal, o usuário executa um comando, que é enviado e interpretado
pelo sistema operacional; portanto, o terminal Linux é o instrumento que,
propriamente, nos permite utilizar os componentes do computador, motivo
até mesmo pelo qual os comandos representam a maneira mais abrangente
para acessar os recursos avançados do sistema.
Os comandos podem ser enviados de duas maneiras para o interpretador
(NEVES, 2008): interativa, na qual os comandossão digitados no terminal
e interpretados individualmente e o computador depende do usuário para
executar uma tarefa ou um próximo comando; e não interativa, na qual os
comandos são salvos em um arquivo classificado como script, que depois é
executado pelo terminal, e o computador executa os comandos contidos no
arquivo sequencialmente; dependendo do término do comando, o script pode
checar qual será o próximo comando a ser executado.
É possível executar qualquer tarefa no Linux via terminal. De acordo com
Negus e Bresnahan (2014), os principais comandos são descritos a seguir.
Comandos para diretórios
ls (list): lista o conteúdo do diretório atual e informações relativas aos ar-
quivos. Sua sintaxe é:
ls [opções]
O comando ls pode ser executado sozinho ou com parâmetros, cujos
parâmetros aceitos são:
� -l: lista ordenada pelo nome e em formato longo;
� -F: mostra barra de diretórios;
� -R: mostra o conteúdo de todos os subdiretórios;
� -x: lista o resultado em várias colunas na horizontal;
� -a: lista todos os arquivos, inclusive os ocultos;
� -t: lista em ordem cronológica em função da hora da última modificação;
� -1: lista somente os nomes dos arquivos ordenados.
Programação de scripts em sistemas open source2
pwd (print working directory/imprimir o diretório de trabalho): apresenta o
diretório atual.
cd (change directory/mudar de diretório): muda o diretório atual. Sua sintaxe é:
cd [opções]
Os parâmetros aceitos por este comando compreendem:
� cd /: vai para o diretório raiz;
� cd ..: vai para o diretório pai;
� cd: vai para o diretório home do usuário;
� cd -: vai para o último diretório acessado.
mkdir (make directory/criar diretório): consegue criar diretórios. Sua sintaxe é:
mkdir [opções] <diretório>
Os parâmetros aceitos por esse comando consistem em:
� -m modo: seleciona o modo de criação dos diretórios para modo e,
então, usa o modo-padrão como ponto de partida;
� -p: cria diretórios pai faltante para cada argumento diretório;
� –verbose: imprime uma mensagem para cada diretório criado.
rmdir (remove directory/remover diretório): remove diretórios vazios. Sua
sintaxe é:
rmdir <diretório>
Comandos para manipular arquivos
find (encontrar): realiza uma busca de arquivos de acordo com o nome.
A sintaxe para executá-lo é:
find [nome _ do _ arquivo].
3Programação de scripts em sistemas open source
cat: (conCATenate/concatenar) concatena e/ou exibe arquivos na saída, além
de poder exibir o conteúdo de vários arquivos em sequência. A sintaxe para
utilizá-lo é:
cat [opção] <arquivos>.
Suas principais opções compreendem:
� -n: enumera as linhas;
� -E: exibe $ ao final de cada linha;
� -A: exibe todo o conteúdo, incluindo caracteres especiais, como acentos
e espaços na forma de códigos.
cp (copy/copiar): copia arquivos ou diretórios. Para utilizá-lo, a sintaxe é a
seguinte:
cp [opções] <origem> <destino>
em que <origem> indica o arquivo a ser copiado, e <destino> corres-
ponde ao nome da cópia a ser criada. Caso se esteja fazendo uma cópia para
o mesmo diretório, então obrigatoriamente o nome do <destino> deve
ser diferente do nome do arquivo de <origem>. No caso em que o arquivo
<destino> exista e não seja um diretório, seu conteúdo será sobrescrito.
O comando cp aceita os seguintes parâmetros:
� -i: pede confirmação para copiar o arquivo;
� -p: mantém os dados, como permissões e datas, do arquivo original;
� -r: copia os arquivos e diretórios recursivamente.
rm (remove/remover): remove arquivos ou diretórios. A sintaxe para aplicá-lo é:
rm [opções] <arquivo>
Ainda, aceita as seguintes opções como parâmetro:
� -f: remove todos os arquivos mesmo não tendo permissão de escrita
sem pedir confirmação do usuário;
� -i: remove o arquivo após a confirmação do usuário;
� -r: remove um diretório e todo o seu conteúdo recursivamente.
Programação de scripts em sistemas open source4
mv (move/mover): pode ser usado para mover ou renomear arquivos. A sintaxe
para aplicá-lo é:
mv [opção] <origem> <destino>
Ainda, existem duas possibilidades de executá-lo: (i) se <destino>
for um diretório, então o arquivo <origem> será movido para o diretório
<destino>; (ii) se <destino> não for um diretório, então o arquivo
<origem> será renomeado para <destino>.
diff (differentiate/diferenciar): pode ser usado para exibir a diferença entre
dois arquivos. Sua sintaxe de execução é:
diff [opção] <arquivo1> <arquivo2>
Algumas de suas opções consistem em:
� -b: ignora espaços e caracteres de tabulação;
� -i: não diferencia maiúscula de minúscula;
� -r: processa subdiretórios quando diretórios são comparados.
Outros comandos
df (disk free/disco livre): mostra o espaço total livre no disco, e sua sintaxe é:
df [opções]
Aceita os seguintes parâmetros:
� -a: mostra o espaço ocupado por todos os arquivos;
� -b: mostra o espaço ocupado em bytes;
� -c: faz uma totalização de todo o espaço listado;
� -D: não conta links simbólicos;
� -k: mostra o espaço ocupado em kilobytes;
� -m: mostra o espaço ocupado em megabytes;
� -S: não calcula o espaço ocupado por subdiretórios.
5Programação de scripts em sistemas open source
du (disk usage/uso de disco): exibe o espaço utilizado por arquivos e diretórios
do diretório atual. A sintaxe para utilizá-lo consiste em:
du [opções]
Ainda, aceita os seguintes parâmetros:
� -s: mostra o número de blocos ocupados;
� -a: mostra o tamanho de cada arquivo;
� -k: lista o tamanho em kilobytes.
echo (ecoar): exibe uma mensagem no terminal. Sua sintaxe é:
echo [mensagem]
chmod (change mode/mudar modo): muito utilizado quando se trabalha com
arquivos, altera a permissão de acesso aos arquivos. A sintaxe para executá-lo
é apresentada a seguir:
chmod [opção] [número] <arquivo>
Alguns dos parâmetros aceitos pelo comando chmod compreendem:
� -R: se o arquivo for um diretório, o comando muda recursivamente o
modo de acesso a todos os seus arquivos e subdiretórios;
� -c: mostra o resultado do uso do comando após seu uso.
No Quadro 1, exibem-se os valores que podem ser passados para o comando
chmod, bem como qual tipo de permissão cada número representa. O símbolo
mais (+) associado ao chmod é usado para acrescentar permissões, e o símbolo
menos (-) aplicado para retirar permissões. Por exemplo, ao executar o comando
chmod -R 777 dir _ A
o diretório identificado como dir_A receberá total permissão no sistema
operacional, ou seja, será possível ler, editar e executar qualquer arquivo
ou diretório filho de dir_A. O responsável por conceder permissão total
é o código 777, e o parâmetro –R indica que o comando deve ser aplicado
recursivamente a todos os arquivos e diretórios de dir_A.
Programação de scripts em sistemas open source6
Número Permissão
000 ---------
400 r--------
444 r--r--r--
600 rw-------
620 -rw--w----
640 -rw-r-----
644 rw-r--r--
645 -rw-r--r-x
646 -rw-r--rw-
650 -rw-r-x---
660 -rw-rw----
661 -rw-rw---x
662 -rw-rw--w-
663 -rw-rw—wx
664 -rw-rw-r--
666 rw-rw-r--
700 rwx------
750 rwxr-x---
755 rwxr-xr-x
777 rwxrwxrwx
4711 -rws--x—x
Quadro 1. Códigos de parâmetros para permissões de arquivos com o comando chmod.
Os caracteres r indica permissão para leitura, w indica permissão para escrita e x indica
permissão para execução
7Programação de scripts em sistemas open source
Os comandos apresentados até aqui são os mais comuns para trabalhar no
terminal em sistemas Linux, no entanto, caso tenha alguma dúvida em rela-
ção à sua utilização ou de outros comandos, é possível consultar os manuais
disponíveis no sistema. Nas principais distribuições Linux, os manuais de
comandos podem ser encontrados no diretório /usr/man. Para consultá-los,
basta digitar no terminal o seguinte:
man <commando>
Trabalhar executando comandos no terminal constitui uma maneira rá-
pida de executar pequenas operações, no entanto, quando se deseja executar
tarefas que exigem uma sequência de comandos, pode ser exaustivo digitar os
comandos individualmente.Para contornar esse problema, é possível enviar
comandos ao sistema operacional de forma não interativa, como mencionado,
na qual os comandos são salvos em um arquivo script, que poderá ser executado
pelo terminal, inclusive mais de uma vez, ficando salvo para utilização sempre
que o usuário quiser repetir a tarefa.
Os scripts são relevantes para a automatização de processos. Por exemplo,
para instalar um programa em um sistema Linux, você deve executar uma
sequência de comandos. Para facilitar essa tarefa, é possível escrever a sequ-
ência de comandos necessários em um script e disponibilizá-la, executando,
desse modo, um comando que será a chamada do script.
Criando arquivos shell scripts
Nesta seção, você aprenderá a criar arquivos shell script, uma tarefa simples,
mas que segue algumas regras. A primeira regra é que todo arquivo deve ter
na primeira linha o identificador do interpretador a ser utilizado; por exemplo,
um interpretador comumente utilizado é o bash:
#!/bin/bash
Outro passo importante na criação de um arquivo shell script consiste
em dar as permissões necessárias para o funcionamento do script. Para isso,
deve-se usar o comando chmod:
chmod +x script.sh
Programação de scripts em sistemas open source8
O parâmetro +x do comando chmod indica permissão de execução, en-
viando, desse modo, uma mensagem ao sistema operacional dizendo que o
arquivo script.sh pode ser executado. Outra maneira de executar um script
é usando o comando bash. Para isso, basta digitar no terminal:
bash caminho _ para _ o _ arquivo/script.sh
Assim, não é necessário haver a identificação do interpretador na primeira
linha do script. Também não é preciso executar o comando chmod para dar
permissão de execução ao arquivo.
Cuidado ao apagar os arquivos com o comando rm, pois ele não envia arquivos para
a lixeira, não sendo possível recuperar o arquivo.
Programação script: estruturas de controle
Toda linguagem de programação apresenta um conjunto de estruturas de
controle, que se referem à ordem em que as instruções são executadas ou
avaliadas (SEBESTA, 2018). Em shell script, existem dois tipos diferentes
de estruturas de controle: a estrutura de decisão e estruturas de repetição,
brevemente descritas a seguir.
Toda linguagem de programação apresenta instruções para orientar tomadas
de decisão, chamadas de estruturas de decisão. Geralmente, são formadas
por meio do comando if, que vem acompanhado de uma condição — se a
expressão for verdadeira, o bloco de código associado a ele é executado; caso
seja falsa, pode ser executado, ou não, outro bloco de código (SEBESTA, 2018).
Para compor as expressões a serem verificadas, as linguagens de programação
fornecem alguns operadores lógicos e matemáticos. Na linguagem shell script,
esses operadores são representados da seguinte maneira:
� -eq: (equal) igual à;
� -ne: (not equal) diferente de;
9Programação de scripts em sistemas open source
� -lt: (less than) menor que;
� -gt: (greater than) maior que;
� -le: (less or equal) menor ou igual a;
� -ge: (greater or equal) maior ou igual a;
� !: não lógico (not);
� -a: e lógico (and);
� -o: ou lógico (or).
A sintaxe do comando if na linguagem shell script é apresentada a seguir:
if [ condição ]
then
#Bloco de instruções
fi
A palavra reservada then marca o início do bloco de código condicionado,
e a palavra fi (if ao contrário) indica que o bloco de código do if acabou.
Se a condição for verdadeira, todas as instruções entre as duas palavras (then
e fi) serão executadas. A seguir, veja um exemplo real da instrução if que
testa se 10 é menor ou igual a 4:
if [ 10 -le 4 ]
then
echo "Este bloco não será executado"
fi
Repare que é necessário manter espaços entre os colchetes e os números,
ou variáveis. As expressões exibidas são mais comuns para tratar números.
Para fazer comparações com textos, use os seguintes operadores.
� = : igual a;
� !=: diferente de;
� -n: string existe e não é vazia;
� -z: string existe e é vazia.
Veja um exemplo com strings.
Programação de scripts em sistemas open source10
#!/bin/bash
echo "Digite seu nome: "
read nome
if [ -z $nome ]
then
echo "Você não digitou seu nome!"
else
echo "Olá, $nome"
fi
Além dos operadores já apresentados, o shell script oferece as seguintes
opções para a construção de comandos de tomada de decisão if:
� -s : arquivo existe, não vazio;
� -f : arquivo existe, não é um diretório;
� -d : diretório existe;
� -w : arquivo, com permissão de escrita;
� -r : arquivo, com permissão de leitura;
� -x : arquivo, com permissão de execução.
#!/bin/bash
arquivo="/tmp/Log.txt"
if [ -f "$arquivo" ]
then
echo "Continuando log..." >> "$arquivo"
else
echo "Criando log..." > "$arquivo"
fi
11Programação de scripts em sistemas open source
Também é possível realizar diversas comparações em sequência com o
uso da instrução elif, que compreende uma conjunção da condição if com
else, sendo equivalente a usar um if após um else da seguinte forma:
#!/bin/bash
echo "Digite um número"
read numero
if [ $numero -gt 0 ]
then
echo "Número positivo"
else
if [ $numero -lt 0 ]
then
echo "Número negativo"
else
if [ $numero -eq 0 ]
then
echo "Número é zero"
else
echo "O valor fornecido não é um número!"
fi
fi
fi
Programação de scripts em sistemas open source12
A seguir, exibe-se o mesmo exemplo usando a instrução elif. Observe,
que no exemplo a seguir, a instrução elif [ $numero -lt 0 ] tem
a mesma função que as instruções else if [ $numero -lt 0 ] no
exemplo anterior. A instrução elif representa apenas uma contração de else
if que torna mais claro o tratamento de várias alternativas, encadeando as
condições.
#!/bin/bash
echo "Digite um número"
read numero
if [ $numero -gt 0 ];
then
echo "Número positivo"
elif [ $numero -lt 0 ]
then
echo "Número negativo"
elif [ $numero -eq 0 ]
then
echo "Número é zero"
else
echo "O valor fornecido não é um número!"
fi
Além do comando if, o shell oferece opções como o bloco case ... esac
(case ao contrário) para controle de fluxo, usado para executar um bloco de
código de acordo com o valor de uma variável. Esse comando é interessante,
pois pode definir diversas opções diferentes sem usar uma estrutura com
diversos comandos if, elif e else. Veja um exemplo a seguir.
13Programação de scripts em sistemas open source
#!/bin/bash
echo "Bom dia ou Boa tarde?"
while :
do
read INPUT _ STRING
case $INPUT _ STRING in
"Bom dia")
echo "Bom dia!"
break
;;
"Boa tarde")
echo "Boa tarde!"
break
;;
*)
echo "Bom dia ou Boa tarde?"
;;
esac
done
Este script exibe uma mensagem e, então, pede uma informação do usuário.
O usuário digitará alguma letra e, assim, o comando case entrará em ação,
verificando qual valor foi digitado pelo usuário e executando os blocos de
código relativos a cada opção. A primeira opção é a padrão, por isso é executada
mesmo que o usuário não digite um valor. Cada bloco do case é iniciado por
um valor que a variável analisada pode ter, ou vários valores, separados por
um pipe (|). A instrução break indica o fim de cada bloco, forçando a saída
de um laço condicional, seja ele um case (como no exemplo), seja qualquer
outro laço (p. ex., um laço for). Sem a instrução break, todas as outras
opções dentro do switch seriam avaliadas. Os blocos são finalizados por
uma sequência de dois caracteres ponto-e-vírgula (;;).
Programação de scripts em sistemas open source14
Outra estrutura de controle importante para trabalhar com shell refere-se
às estruturas de repetição, importantes pelo fato de permitirem a realização
de iterações sobre alguma instrução. No shell, existem três estruturas de
repetição: for, do while e until do, descritas a seguir.
A estrutura de controle for itera sobre um conjuntode valores. Sua sintaxe
é:
for variavel in lista do
#instruções
done
em que a lista pode ser uma lista de dados, fixa ou retornada por outro
comando (como o ls), ou uma sequência de qualquer tipo de dado. Veja o
exemplo a seguir, em que se exibe uma sequência de números.
#!/bin/bash
for i in 1 2 3 4 5
do
echo $i
done
A estrutura while tem a mesma função de repetição do for, no entanto
o while repete um comando até que uma condição seja satisfeita. A sintaxe
para utilizá-la consiste em:
while [condição]
do
#instruções
done
15Programação de scripts em sistemas open source
Para compreender melhor como essa estrutura funciona, veja o exemplo
a seguir.
#!/bin/bash
echo "Digite um número"
read numero
while [ "$numero" != "5" ]
do
echo "Digite um número"
read numero
done
No exemplo apresentado, será pedido para que o usuário digite um número.
A instrução para que o usuário digite o número será repetida enquanto o
número lido for diferente de 5, ou seja, enquanto a condição for verdadeira o
laço continua se repetindo. Quando o usuário digitar o número 5, o programa
sai da estrutura while, pois a condição se torna falsa. A estrutura de controle
until se assemelha à do while, no entanto faz exatamente o contrário, ou
seja, continua repetindo as instruções enquanto a condição seja satisfeita. Neste
caso, a condição se torna verdadeira e o programa sai da estrutura until.
A sintaxe do until é:
until [condição ]
do
#instruções
done
Um exemplo de utilização do comando until é apresentado a seguir.
Programação de scripts em sistemas open source16
#!/bin/bash
echo "Digite um número: "
read numero
until [ $numero == 5 ]
do
#Repete até que o número digitado seja 5
echo "Digite um número: "
read numero
done
Programação script: aplicação de funções
Os programas escritos em shell script podem ser organizados em módulos,
chamados funções, cujo uso facilita a compreensão do arquivo (NEVES,
2008). A sintaxe de uma função em shell script tem duas possibilidades,
apresentadas a seguir; a primeira requer o comando function seguido pelo
nome_da_função, e a segunda consiste no próprio nome_da_função
seguida de parênteses vazios (COOPER, 2014). Nos próximos exemplos, os
dois modos serão utilizados:
function nome _ da _ função {
#corpo da função
}
ou
nome _ da _ função() {
#corpo da função
}
Os parênteses vazios após nome_da_função no segundo caso indicam
que estamos definindo uma função. Para compreender melhor este conceito,
veja a seguir um exemplo de uma função que imprime a mensagem Hello
world.
17Programação de scripts em sistemas open source
#!/bin/bash
function imprime {
echo "Hello world"
}
Para realizar uma chamada a uma função, basta escrever o nome dela
dentro do script da seguinte forma:
imprime
Em muitos casos, é preciso passar parâmetros para uma função. Por exem-
plo, a função imprime apenas exibe a mensagem Hello world na tela,
no entanto pode-se passar uma mensagem para que a função a exiba. Para
acessar parâmetros na linguagem shell script, basta digitar ${n}, em que
n representa o número do parâmetro. Veja como ficaria uma nova função,
chamada cumprimenta, recebendo um parâmetro.
#!/bin/bash
function cumprimenta{
if [$1 = ""] then
echo "Olá, pessoa!"
else
echo "Olá, ${1}!"
fi
}
Programação de scripts em sistemas open source18
Para passar um parâmetro para uma função em shell script, basta chamar, no
mesmo script, o nome da função seguido dos parâmetros da seguinte maneira:
echo "Qual é seu nome?"
read nom
cumprimenta $nom
A função cumprimenta recebe um nome como parâmetro e o exibe na
tela, junto de “Olá” Se o usuário der Enter sem digitar nada, o cumprimento
será Olá, pessoa!
O shell trata as funções como se fossem mini scripts completos, inclusive
com um status de saída. Dessa forma, é possível gerar status de saída e retornar
valores para as funções de três maneiras diferentes.
1. O status de saída padrão: é retornado pelo último comando executado
dentro da função. Após a função terminar, pode-se verificar o valor
desse status por meio da variável $?. Veja o exemplo no script a seguir.
#!/bin/bash
func-status() {
ls -la /home
}
func-status
echo "O status de saída da função é $?"
2. Em shell, considera-se o valor 0 uma execução bem-sucedida. Qualquer
outro valor representa erro. No exemplo anterior, o status de saída será
zero se o último comando da função funcionar corretamente; caso
contrário, será um valor diferente de zero. Se a função tiver vários
comandos, e algum deles falhar, sem que seja o último, o status retor-
nado ainda seria zero.
19Programação de scripts em sistemas open source
3. O comando return: permite especificar um valor inteiro para definir o
status de saída da função, sem depender do último comando executado
dentro da função. Veja o exemplo a seguir.
#!/bin/bash
function quadrado {
read -p "Digite um número entre 2 e 10: " valor
while [ ${valor} -lt 2 -o ${valor} -gt 10 ]
do
read -p "Digite um número entre 2 e 10: " valor
done
echo "Vamos calcular o quadrado do número digitado"
return $[ $valor * $valor ]
}
quadrado
echo "status de saída da função: $?"
4. O status da função retornado neste exemplo é o valor retornado pelo
comando return. Ao usar o comando return em uma função, tome os
seguintes cuidados:
■ o valor do status de saída deve ser capturado em uma variável assim
que a função terminar, para não perdê-lo caso outra instrução seja
executada;
■ os status de saída somente podem ser valores entre 0 e 255.
5. Usando a saída da função: é possível capturar a saída de uma fun-
ção em uma variável do shell atribuindo a função a uma variável:
statusValor=`função`.
Programação de scripts em sistemas open source20
#!/bin/bash
quadrado() {
read -p "Digite um número entre 2 e 10: " numero
while [ ${numero} -lt 2 -o ${numero} -gt 10 ]
do
read -p "Digite um número entre 2 e 10: " numero
done
echo $[ $numero * $numero ]
}
valor=̀ quadradò
echo "O valor é $valor"
6. Neste caso, não existe a limitação de valor entre 0 e 255, além de ser
possível retornar strings e pontos flutuantes.
Para saber mais sobre programação shell e boas práticas na escrita de funções e
códigos, acesse os links a seguir.
https://qrgo.page.link/WdwQn
https://qrgo.page.link/cG5fh
NEGUS, C.; BRESNAHAN, C. Linux, a bíblia: o mais abrangente e definitivo guia sobre
Linux. 8. ed. Rio de Janeiro: Alta Books, 2014. 856 p.
NEVES, J. C. Programação shell Linux. 7. ed. Rio de Janeiro: Brasport, 2008. 450 p.
21Programação de scripts em sistemas open source
SEBESTA, R. W. Conceitos de linguagem de programação. 11. ed. Porto Alegre: Bookman,
2018. 758 p.
Leituras recomendadas
COOPER, M. Advanced Bash-Scripting Guide: An in-depth exploration of the art of shell
scripting. The Linux Documentation Project, [S. l.], 10 Mar. 2014. Disponível em: http://
www.tldp.org/LDP/abs/html/index.html. Acesso em: 9 out. 2019.
JARGAS, A. M. Shell script profissional. São Paulo: Novatec, 2008. 480 p.
Programação de scripts em sistemas open source22
Dica do professor
Há muitos casos em que é necessário usar comandos shell para administrar serviços e processos.
Quando se trabalha remotamente com servidores, saber utilizar e aplicar corretamente os
comandos é de extrema importância, pois, muitas vezes, seu único modo de acesso ao servidor é
por meio de um terminal.
Na Dica do Professor, você verá como verificar se um processo no servidor está ativo, por meio de
comandos shell, além de como pará-lo e iniciá-lo sem ficar dependente da conexão.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://fast.player.liquidplatform.com/pApiv2/embed/cee29914fad5b594d8f5918df1e801fd/b590d794544ab18926f22a4383370a91
Saiba +
Para ampliar o seu conhecimento a respeito desse assunto, veja abaixo as sugestões do professor:Shell Scripting
Neste site, você encontra um treinamento em linguagem shell script.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Apêndice do livro Shell script profissional com lista de
comandos
Neste site, você poderá encontrar muitas dicas e exemplos de como escrever shell scripts de
maneira profissional. Essa construção pode ser realizada em diversos níveis.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Aplicação de shell script para formatação de arquivos de dados
originados em instrumentos de medição
Neste trabalho, você vai conhecer como os autores aplicaram shell script para eliminar informações
consideradas desnecessárias, coletadas por meio de sensores de medição.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
http://www.bosontreinamentos.com.br/shell-script/
https://aurelio.net/shell/canivete/
https://seer.dppg.cefetmg.br/index.php/revistadameta/article/download/875/720
Programação funcional: currying
Apresentação
Currying é uma técnica muito utilizada por linguagens de programação funcional para informar
parâmetros de forma parcial a uma função.
Essa técnica possibilita transformar uma função que originalmente receberia uma dupla com
múltiplos parâmetros em um encadeamento de funções que recebe um só parâmetro cada.
Linguagens funcionais contêm, em sua estrutura de controle básica, a função. Muitas vezes, utilizar
uma função com diversos parâmetros pode ser inviável; portanto, linguagens com suporte a
closures podem ser utilizadas para currying.
Nesta Unidade de Aprendizagem, você irá entender a técnica de currying e suas vantagens, além de
ver aplicações práticas.
Bons estudos.
Ao final desta Unidade de Aprendizagem, você deve apresentar os seguintes aprendizados:
Explicar como é a técnica de currying.•
Discutir as vantagens da técnica de currying.•
Aplicar a técnica de currying.•
Infográfico
Currying é uma maneira de construir funções que permite a aplicação parcial dos argumentos de
uma função. Isso significa que você pode passar todos os argumentos que uma função está
esperando e obter o resultado, ou passar um subconjunto desses argumentos e recuperar uma
função que está aguardando o restante dos argumentos. A técnica está relacionada a closures, uma
forma de implementar a ligação de escopo entre funções aninhadas.
No Infográfico a seguir, você vai entender um pouco mais sobre currying e sua relação com closures
e linguagens funcionais.
Aponte a câmera para o
código e acesse o link do
conteúdo ou clique no
código para acessar.
https://statics-marketplace.plataforma.grupoa.education/sagah/99655a1f-1a73-4886-ae5d-334429db1bd8/90fb74a9-d5fe-471d-8967-b11ff015d4aa.jpg
Conteúdo do livro
Na programação funcional, trabalhar com funções que recebam somente um parâmetro é comum.
Em muitos casos, apesar da necessidade de avaliação de mais argumentos, e pela característica
desse paradigma de programação, não é possível obter todos os argumentos no mesmo momento.
Sendo assim, a aplicação de técnica de currying, em que funções tradicionalmente construídas
recebendo mais de um argumento são construídas a partir de um aninhamento de funções,
possibilita que os argumentos sejam enviados parcialmente e o resultado final seja obtido.
No capítulo Programação funcional: currying, da obra Paradigmas de programação, você vai conhecer
mais sobre a técnica de currying e suas vantagens, além de ver exemplos de sua aplicação utilizando
as linguagens Haskell e JavaScript.
Boa leitura.
PARADIGMAS DE
PROGRAMAÇÃO
Fabricio Machado da Silva
Programação
funcional: currying
Objetivos de aprendizagem
Ao final deste texto, você será capaz de:
� Explicar a técnica de currying.
� Discutir as vantagens do currying.
� Aplicar o currying.
Introdução
O currying é uma técnica utilizada em programação funcional, que consiste
basicamente em transformar uma função originalmente com múltiplos
parâmetros em uma que aceite apenas um. Isso é possível em linguagens
que implementam closure, fazendo um encadeamento de funções, em
que uma retorna a outra a qual recebe outro parâmetro, e assim suces-
sivamente até que o resultado esperado seja alcançado.
Inventada independentemente, como uma homenagem ao matemá-
tico Haskell Curry — por isso a origem do nome —, tem sua importância
devido à motivação prática da frequente utilização de funções obtidas
por meio de apenas algum dos parâmetros. Algumas linguagens de
programação, como Haskell, ML e JavaScript, possuem suporte sintático
nativo à técnica de currying.
Neste capítulo, você conhecerá um pouco mais sobre o que é a
técnica de currying, suas vantagens e aplicabilidades em programação
funcional.
Definição da técnica currying
Currying é uma técnica de transformação de uma função originalmente com
múltiplos parâmetros em uma avaliação parcial dos argumentos. A nomencla-
tura é uma homenagem a Haskell Curry, que estudava o método (FLANAGAN,
2013).
Segundo Flanagan (2013, p. 140), “métodos podem definir múltiplas listas
de parâmetros. Quando um método é chamado com uma lista menor de parâ-
metros, então será retornada uma função que recebe a lista de parâmetros que
falta como argumentos”. Podemos dizer, então, que o processo de currying
consiste em quebrar funções de n parâmetros em n funções, onde cada uma
deve receber apenas um parâmetro e retornar outra função que espera os
parâmetros restantes — logo, uma função representada originalmente por:
int, int -> int
Ao aplicarmos a técnica de currying, essa função teria o seu tipo alterado,
passando a ser representada por:
int -> int -> int
Para facilitar o entendimento, vamos analisar a Figura 1, a seguir, que
mostra originalmente um código em JavaScript de uma função que recebe os
parâmetros x e y e retorna a soma de x e y.
Figura 1. Função originalmente escrita em JavaScript
sem a técnica de currying.
Fonte: Adaptada de Lima (2016).
var add = function (x,y) {
add(1, 2) //3
return x + y;
};
Programação funcional: currying2
Agora, passamos à análise da Figura 2, que mostra exatamente a mesma
função, com a aplicação da técnica de currying.
Figura 2. Função com aplicação da técnica
de currying.
Fonte: Adaptada de Lima (2016).
var add = function(x) {
add(1)(2); //3
return function(y) {
return x + y;
};
};
Ao realizarmos uma análise mais superficial, em um primeiro momento,
apenas parece que estamos adicionando mais dificuldade sem nenhum ganho
específico. Mas já temos um grande retorno, pois estamos transformando o
código em pequenas partes mais expressivas e com maior possibilidade de
reuso (FLANAGAN, 2013). Pense em uma aplicação que necessite verificar
duas variáveis e retornar as duas em ordem alfabética. Porém, apenas uma
delas é recebida, usando uma função normal — certamente o retorno seria
um erro, pois não seria possível a comparação.
Ao aplicar a técnica de currying, poderia ser retornada uma função que
espere que a segunda variável seja enviada e, somente após, ordenasse e
realizasse o retorno com as variáveis em ordem alfabética.
3Programação funcional: currying
Tanto currying quanto a aplicação parcial são conceitos muito poderosos e que podem
facilitar muito suas tarefas no dia a dia, mesmo em linguagens que não são totalmente
funcionais. Todavia, a aplicação parcial é um pouco diferente do processo de currying,
mas também envolve a questão dos tipos de uma função.
Como pudemos percebemos, a técnica de currying tem suas vantagens e,
por isso, uma grande importância em linguagens de programação funcionais.
Na próxima seção, discutiremos e conheceremos um pouco mais sobre as
vantagens dessa aplicação (FLANAGAN, 2013).
Vantagens do currying
Para entendermos as vantagens da utilização do currying, faz-se necessário
conhecer e estar ciente do termo aridade, que representa o número de argu-
mentos usados poruma função. Uma função que aceita um único argumento
tem aridade de um; uma função que recebe três argumentos tem uma aridade
de três (OLIVEIRA, 2017).
Além do fato de facilitar o processo de leitura de código, o currying oferece
aos desenvolvedores mais controle sobre suas funções. Em resumo, você será
capaz de escrever um código mais descritivo que se parece com um idioma
simples e, também, de mais fácil reutilização. Além disso, o currying é útil
quando você usa funções complexas e deseja ocultar sua implementação.
As funções podem ser classificadas com base no número de entradas que
aceitam: como se a função binária recebesse duas entradas, enquanto uma
função unária, apenas uma única entrada. Segundo Oliveira (2017, p. 142),
“em Haskell, toda função recebe apenas uma entrada, ou seja, toda função
em Haskell pode ser considerada unária”. Então, não é possível implementar
uma função que aceite vários parâmetros? Isso é possível, utilizando currying.
Programação funcional: currying4
Podemos, também, ver o currying como uma especialização, uma maneira tradicional
de lidar com funções n-árias gerais, desde que as únicas que você possa definir sejam
unárias.
Para Ayala-Rincón e Moura (2014, p. 98):
No cálculo lambda (a partir do qual as linguagens de programação funcio-
nal derivam), existem apenas abstrações de uma variável (que se traduz em
funções unárias nas linguagens funcionais). Em relação ao cálculo lambda,
acho mais fácil provar coisas sobre esse formalismo, já que você não precisa
lidar com o caso de funções n-árias (uma vez que você pode representar
qualquer função n-ária com várias funções unárias através do currying).
Não podemos compor diretamente funções que usam vários parâmetros.
Como a composição da função é um dos principais conceitos da programação
funcional, usando a técnica currying, podemos compor funções que usam
vários parâmetros.
Em um exemplo prático, veja a utilização e a vantagem de currying.
O framework de JavaScript angular tem uma implementação de curry que
permite “definir” parâmetros na função original e, posteriormente, passar um
número infinito de parâmetros adicionais. O exemplo apresentado na Figura 3,
a seguir, é o mesmo que é usado na documentação do framework.
Figura 3. Exemplo do framework angular.
5Programação funcional: currying
Considerando que f tem três argumentos curry, podemos chamá-la
novamente sem ter que os repetir, poupando, assim, a referida repetição de
código e argumentos:
// alerta "1, 2, 3, c, d"
f('c', 'd');
Currying é, na prática, vantajoso com a reutilização de código. Na próxima
seção, você verá alguns exemplos de aplicação de currying com as linguagens
de programação Haskell e JavaScript.
Aplicação do currying
Nas seções anteriores, entendemos o que é o currying e as vantagens de sua
aplicação. Para ilustrar, veremos um exemplo de aplicação da técnica utilizando
Haskell (OLIVEIRA, 2017).
Sendo PLUS uma função que adiciona dois números, queremos, então,
adicionar os números X e Y. X como a entrada da função PLUS, que retor-
nará uma função chamada PLUS X. A função PLUS X pega um número e
adiciona X a ele.
Agora, a entrada para essa função será Y, e a saída final será X + Y.
A Figura 4, a seguir, ilustra a função PLUS em uma implementação normal
e em sua versão currying.
Figura 4. Função PLUS em versão normal e aplicando currying.
X
X
Y
PLUS PLUS
PLUS X
X + Y
Y
X + Y
Programação funcional: currying6
Pelo uso da função em currying, podemos resolver muitos problemas
facilmente. Por exemplo, precisamos criar uma função que use uma lista e
outra função como entrada. Aplique essa função a cada elemento dessa lista
e retorne à nova lista. Segundo Oliveira (2017, p. 146), “em Haskell, isso pode
ser feito com muita facilidade usando a função currying embutida, chamada
map.Definition”:
map :: (a -> b) -> [a] -> [b]
map _ [ ] = [ ]
map f (x : xs) = f x : map f xs
Analisando o código em Haskell, temos que:
� a primeira linha é a inicialização da função;
� o símbolo :: significa que "é do tipo";
� [a] representa uma lista de elementos semelhantes, entidade escrita
após a última -> é sempre o tipo de retorno da função;
� uma função em Haskell sempre retorna apenas uma entidade;
� (a-> b) define uma função de a a b;
� [] indica lista vazia, e _ indica "qualquer coisa";
� a segunda linha mostra que, se uma lista vazia e qualquer função for
inserida, a saída será uma lista vazia;
� x: xs é usado para remover os elementos um a um da lista, x é o
primeiro elemento (cabeça) e xs é a lista restante (cauda) – : significa
concatenação;
� a terceira linha está pegando cada elemento da lista e aplicando a função
f neles e concatenando-o com a lista restante;
� map (+7) [1, 2, 3, 4, 5] deverá retornar a lista [8, 9,
10, 11, 12], onde +7 é a função.
Passamos, então, à análise de outro exemplo de aplicação de currying,
utilizando a linguagem JavaScript. Imaginemos uma função que cumprimente
alguém. Essa função simples de saudação recebe um nome e uma saudação
e registra a saudação com o nome no console:
var greet = function(greeting, name) {
console.log(greeting + ", " + name);
};
greet("Olá", "Usuário"); //"Olá, Usuário"
7Programação funcional: currying
Essa função requer que o nome e a saudação sejam passados como argumen-
tos para funcionar corretamente. Mas podemos reescrevê-la usando currying
aninhado simples, para que a função básica exija apenas uma saudação e retorne
outra função que leve o nome da pessoa a ser cumprimentada.
O código reescrito aplicando currying é:
var greetCurried = function(greeting) {
return function(name) {
console.log(greeting + ", " + name);
};
};
Essa modificação na maneira como escrevemos a função permite-nos criar
uma nova função para qualquer tipo de saudação e transmitir a ela o nome da
pessoa que queremos cumprimentar:
var greetHello = greetCurried("Olá");
greetHello("Usuário"); //"Olá, Usuário"
greetHello("Usuário Novo"); //"Olá, Usuário Novo"
Também podemos chamar a função ao currying original diretamente. Isso
é feito apenas passando cada um dos parâmetros em um conjunto separado
de parênteses, um após o outro:
greetCurried("Olá")("Usuário"); //"Olá, Usuário"
O interessante é que, agora que entendemos como modificar nossa função
tradicional para usar currying e lidar com argumentos, podemos fazer isso
com quantos argumentos quisermos:
var greetDeeplyCurried = function(cumprimento) {
return function(separador) {
return function(enfase) {
return function(nome) {
console.log(cumprimento + separador + nome + enfase);
};
};
};
};
Programação funcional: currying8
O currying é uma técnica incrivelmente útil para programação funcional.
Ele permite gerar uma biblioteca de funções pequenas e facilmente confi-
guradas, que se comportam de maneira consistente, são rápidas de usar e
podem ser entendidas ao ler seu código. A adição de currying à sua prática
de codificação incentivará o uso de funções parcialmente aplicadas em todo o
código, evitando muitas repetições em potencial e ajudando você a ter melhores
hábitos de nomeação e tratamento de argumentos de função.
Acesse o link a seguir e veja comentários sobre a técnica de currying na programação.
https://qrgo.page.link/nzFzF
AYALA-RINCÓN, M.; MOURA, F. L. C. Fundamentos da programação lógica e funcional: o
princípio de resolução e a teoria de reescrita. Brasília: Finatec; UnB, 2014. 232 p.
FLANAGAN, D. JavaScript: o guia definitivo. 6. ed. Porto Alegre: Bookman, 2013. 1080 p.
LIMA, M. Entendendo Programação Funcional em JavaScript de uma vez. [S. l.], 3 mar. 2016.
Medium: tableless. Disponível em: https://medium.com/tableless/entendendo-
-programa%C3%A7%C3%A3o-funcional-em-javascript-de-uma-vez-c676489be08b.
Acesso em: 24 out. 2019.
OLIVEIRA, A. G. Haskell: uma introdução à programação funcional. São Paulo: Casado
Código, 2017. 161 p.
9Programação funcional: currying
Dica do professor
Currying é o processo de pegar uma função que aceita n argumentos e transformá-la em n funções
que aceitam, cada uma, um único argumento. A aplicação parcial é usada para criar funções com
alguns dos parâmetros "já preenchidos". É como aplicar uma função, mas apenas para alguns dos
parâmetros; ou seja, aplicar parcialmente uma função.
Ambos os conceitos parecem idênticos, confundindo até mesmo alguns profissionais; no entanto,
existem diferenças.
Nesta Dica do Professor, você vai ver alguns exemplos de aplicação parcial e currying para facilitar o
entendimento das diferenças entre esses conceitos.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://fast.player.liquidplatform.com/pApiv2/embed/cee29914fad5b594d8f5918df1e801fd/844845a40e6a1d6ad845e2dfcedd26e1
Saiba +
Para ampliar o seu conhecimento a respeito desse assunto, veja abaixo as sugestões do professor:
Currying: uma técnica interessante usada em programação
funcional
Neste vídeo, acompanhe uma explicação sobre a técnica de currying utilizada em programação
funcional.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Currying
Leia mais sobre Currying
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Transparência referencial, currying e closures em Java
Veja os conceitos da programação funcional em Java (transparência referencial, currying e closures)
e como podem ajudar a criar softwares mais robustos na programação do dia a dia.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://www.youtube.com/embed/rec4I8zfYjc
https://javascript.info/currying-partials
https://www.devmedia.com.br/transparencia-referencial-currying-e-closures-em-java/33045
Expressões regulares para programação
de scripts
Apresentação
Expressões regulares são composições de caracteres com funções especiais (metacaracteres) que,
agrupados entre si, com caracteres literais e números, podem formar uma sequência, isto é, uma
expressão que pode ter diversos usos, como buscas, filtros, etc. Essas expressões podem ser
utilizadas em linguagens de programação, planilhas, editores de texto, bancos de dados e em
diferentes sistemas operacionais, como Unix, Linux, Windows e Mac.
Nesta Unidade de Aprendizagem, você saberá o que são e como criar expressões regulares, bem
como identificará os principais comandos para trabalhar tanto em ambientes proprietários quanto
em ambientes open source.
Bons estudos.
Ao final desta Unidade de Aprendizagem, você deve apresentar os seguintes aprendizados:
Descrever o que são expressões regulares.•
Identificar as principais expressões regulares para programação de scripts em sistemas
proprietários.
•
Reconhecer as principais expressões regulares para programação de scripts em sistemas open
source.
•
Infográfico
Expressões regulares estão inseridas na teoria de linguagens formais e autômatos que pertencem
à área de teoria da computação. Trata-se de um método formal capaz de especificar um padrão de
texto. É uma ferramenta poderosa que pode ser aplicada em diferentes áreas para buscar, verificar
e validar cadeias de caracteres.
Veja, no Infográfico, importantes informações sobre expressões regulares, sua história e algumas
expressões úteis.
Aponte a câmera para o
código e acesse o link do
conteúdo ou clique no
código para acessar.
https://statics-marketplace.plataforma.grupoa.education/sagah/7b6db3fa-1f95-4427-91b8-d2e3228814af/17d35f5c-a8aa-4343-87b2-264c9b248cf7.jpg
Conteúdo do livro
Expressões regulares estão presentes em todas as linguagens de programação, editores de texto,
clientes de e-mail, bem como na linha de comando do Linux, em servidores, entre outros. Dessa
forma, profissionais e usuários de diferentes áreas e níveis de conhecimento trabalham e usam
expressões regulares no seu dia a dia.
No capítulo Expressões regulares para programação de scripts, da obra Programação em ambientes
de redes de computadores, você irá saber como surgiram expressões regulares e como reconhecê-las
e criá-las em ambientes Windows e Linux.
Boa leitura.
PROGRAMAÇÃO EM
AMBIENTES DE
REDES DE
COMPUTADORES
Raiza Artemam de Oliveira
Expressões regulares para
programação de scripts
Objetivos de aprendizagem
Ao final deste texto, você deve apresentar os seguintes aprendizados:
� Descrever expressões regulares.
� Identificar as principais expressões regulares para programação de
scripts em sistemas proprietários.
� Reconhecer as principais expressões regulares para programação de
scripts em sistemas open source.
Introdução
Muitas vezes, é necessário realizar buscas por determinadas palavras
ou mesmo trechos de código em um arquivo e, a partir dessa procura,
realizar algumas alterações. As expressões regulares surgem como uma
maneira de especificar um padrão existente entre essas palavras, para
que não seja preciso procurar cada uma separadamente.
Ao se aplicar métodos de pesquisa comuns com texto normal, torna-
-se praticamente impossível fazer com que um software busque, por
exemplo, todas as palavras de um documento que comecem com “B”
e terminem com “a”. As expressões regulares fazem uso de caracteres
especiais com funções específicas e, por meio de sua combinação, obtêm
uma espécie de “fórmula algébrica” capaz de realizar eficientes buscas
complexas.
Neste capítulo, você aprenderá o que são e como surgiram expres-
sões regulares, bem como identificar as principais expressões regulares
em ambientes proprietários e open source. Ainda, aprenderá como criar
expressões regulares e como aplicá-las no ambiente de trabalho.
Expressões regulares
O estudo inicial que originou a ideia de expressões regulares foi publicado no
ano de 1943, quando dois neurologistas escreveram um artigo que teorizava
de forma matemática o funcionamento dos neurônios. Alguns anos depois,
um matemático descreveu algebricamente os modelos descritos no artigo e
usou símbolos para representar os grupos regulares (JARGAS, 2012). A partir
da notação proposta por Stephen Kleene, surgiram as expressões regulares
amplamente estudadas por matemáticos da época. E, em 1968, as expressões
regulares passaram a ser utilizadas na computação.
O editor de texto padrão dos primeiros sistemas Unix, chamado Ed, usava
expressões regulares em um algoritmo de busca, dispondo do comando de
contexto g, que aceitava expressões regulares, e um comando p. Sua sintaxe
era descrita como g/RE/p (globally search a regular expression and print),
que deu origem ao aplicativo grep, um utilitário de linha de comando es-
crito para uso com o sistema operacional Unix. O grep pega uma expressão
regular na linha de comando, lê a entrada-padrão ou uma lista de arquivos
e imprime as linhas que contêm correspondências para a expressão regular.
Outros aplicativos que usavam expressões regulares também surgiram naquela
época. O grande avanço se deu quando, em 1986, foi criado um pacote na
linguagem C chamado Regex, por meio do qual qualquer programador poderia
incluir o tratamento de expressões regulares em seus programas (NEGUS;
BRESNAHAN, 2014).
De acordo com Menezes (1998), uma expressão regular é um método formal
de especificar um padrão de texto, ou seja, uma combinação de caracteres e
símbolos com funções especiais, que, agrupados entre si, formam uma ex-
pressão. Essa expressão é interpretada como uma regra que indicará sucesso
se uma entrada de dados qualquer casar com essa regra, ou seja, obedecer
exatamente a todas as suas condições.
Trata-se, portanto, de uma composição de caracteres com funções especiais
(metacaracteres) que, agrupados entre si com caracteres literais (de A a Z)
e números, podem formar uma sequência, uma expressão que o shell e os
editores de texto conseguem entender e buscar. As expressões regularessão
úteis para buscar ou validar textos variáveis, como:
� número de endereço IP;
� máscara de rede;
Expressões regulares para programação de scripts2
� endereço de e-mail;
� senhas;
� números de telefone;
� endereço de internet (URL);
� dados na coluna em um texto;
� dados que estão entre <tags></tags> de uma linguagem, como
HTML;
� número de CNPJ (Cadastro Nacional de Pessoa Jurídica), RG (Registro
Geral), CPF (Cadastro de Pessoas Físicas), etc.;
� data e horário.
Para compreender melhor esse conceito, considere que você tem uma lista
diária de acesso de usuários que entraram em seu sistema, e que, em cada
linha dessa lista, tem o horário do acesso e o login do usuário:
05:15 ernesto
08:39 ricardo
10:32 patricia
Caso precise buscar automaticamente quais usuários acessaram o sistema
entre 12 e 18 horas, é possível usar a expressão regular ^1[2-8]. O metaca-
ractere circunflexo ^ marca o início da expressão regular, e que, nesse caso,
associado ao número 1, indica que a expressão regular somente combinará com
palavras que iniciem com 1. O metacaractere lista com intervalo [2-8] indica
que imediatamente após o 1 deverá se dar um número entre 2 e 8. Uma maneira
menos elaborada de fazer isso é com a expressão ̂ 1[2,3,4,5,6,7,8], que
tem o mesmo significado de ̂ 1[2-8]. Esses metacaracteres serão explicados
mais detalhadamente adiante.
Expressões regulares são amplamente populares e estão presentes em
diferentes sistemas operacionais. Além disso, existem vários programas e
pacotes para interpretar expressões regulares, o que pode levar a um problema
de falta de padronização, ou seja, os metacaracteres e símbolos podem apre-
sentar significados diferentes de acordo com cada plataforma. Para contornar
esse problema, o Institute of Electrical and Electronic Engineers (IEEE)
definiu uma família de normas para padronizar comportamentos esperados
de sistemas operacionais, à qual deu o nome de POSIX (Portable Operating
System Interface).
3Expressões regulares para programação de scripts
POSIX
Nas décadas de 1970 e 1980, começaram a surgir várias iniciativas de sistemas
operacionais, e, com isso, cada empresa passou a fazer suas próprias interfaces.
Pela necessidade de haver uma padronização, a fim de tornar os programas
mais compatíveis entre vários sistemas operacionais, o POSIX foi escrito.
POSIX, que, em português, significa “interface portável entre sistemas
operacionais”, é uma família de normas definidas pelo IEEE para a manutenção
de compatibilidade entre sistemas operacionais. O POSIX nada mais é que uma
maneira de ditar várias características esperadas de um sistema operacional,
cujas regras definem chamadas de sistema, comandos básicos (como awk e
echo), um interpretador de comandos compatível com shell script e vários
comportamentos esperados do sistema, como sinais, pipes, gerenciamento
básico de processos, etc. No Quadro 1, são apresentados alguns metacaracteres
para expressões regulares definidos de acordo com o POSIX.
Fonte: Adaptado de Institute of Electrical and Electronics Engineers e The Open Group (2018).
Classe POSIX Similar Significado
[:upper:] [A-Z] Letras maiúsculas
[:lower:] [a-z] Letras minúsculas
[:alpha:] [A-Za-z] Letras maiúsculas e minúsculas
[:alnum:] [A-Za-z0-9] Letras e números
[:digit:] [0-9] Números
[:xdigit:] [0-9A-Fa-f] Números hexadecimais
[:punct:] [.' !?: ... ] Sinais de pontuação
[:blank:] [ \t] Caractere vazio
[:space:] [ \t\n\r\f\v] Espaço e tab
[:cntrl:] [A \t\n\r\f\v] Caracteres de controle
Quadro 1. Metacaracteres POSIX
Expressões regulares para programação de scripts4
Note que os colchetes fazem parte da classe e não são os mesmos da lista;
por exemplo, para definir uma expressão regular para caracteres maiúsculas,
o correto é [[:upper:]], ou seja, um [:upper:] dentro de uma lista [].
Principais expressões regulares para
programação de scripts em sistemas
proprietários
Nesta seção, exploraremos os principais caracteres e metacaracteres suportados
pela linguagem .NET, engine, que também é base para expressões regulares no
sistema operacional Windows. O primeiro passo para compreender expressões
regulares consiste em analisar como os caracteres estão divididos em classe.
Uma classe de caracteres define um conjunto de caracteres, os quais podem
ocorrer em uma cadeia de caracteres de entrada para uma correspondência
bem-sucedida. A linguagem de expressões regulares no .NET dá suporte às
classes de caracteres apresentadas a seguir.
� Grupos de caracteres positivos: um caractere na cadeia de caracteres
de entrada deve corresponder a um de um conjunto especificado de
caracteres.
� Grupo de caracteres negativos: um caractere na cadeia de caracteres
de entrada não deve corresponder a um de um conjunto especificado
de caracteres.
� Bloco nomeado: um caractere na cadeia de caracteres de entrada deve
ser um membro de uma categoria de Unicode específica ou estar dentro
de um intervalo contíguo de caracteres Unicode para uma correspon-
dência bem-sucedida.
� Bloco nomeado negativo: um caractere na cadeia de caracteres de entrada
não deve ser um membro de uma categoria de Unicode específica ou
estar dentro de um intervalo contíguo de caracteres Unicode para uma
correspondência bem-sucedida;
� Caractere de palavra: um caractere na cadeia de caracteres de entrada
pode pertencer a qualquer uma das categorias Unicode apropriadas
para caracteres usados em palavras.
� Caractere não pertencente a palavras: um caractere na cadeia de carac-
teres de entrada pode pertencer a qualquer categoria Unicode que não
seja um caractere de palavra.
5Expressões regulares para programação de scripts
� Caractere de espaço em branco: um caractere na cadeia de caracteres
de entrada pode ser qualquer caractere separador Unicode, bem como
qualquer um entre vários caracteres de controle.
� Caractere diferente de espaço em branco: um caractere na cadeia de
caracteres de entrada pode ser qualquer caractere que não seja um
caractere de espaço em branco.
� Dígito decimal: um caractere na cadeia de caracteres de entrada pode
ser qualquer um entre vários caracteres classificados como dígitos
decimais Unicode.
� Dígito não decimal: um caractere na cadeia de caracteres de entrada
pode ser qualquer coisa que não seja um dígito decimal Unicode.
A expressão regular \b[A-Z]\w*\b é definida como:
� \b: inicia em um delimitador de palavra;
� [A-Z]: corresponde a qualquer caractere maiúsculo de A a Z;
� \w*: corresponde a zero ou mais caracteres de palavras e números;
� \b: corresponde a um delimitador de palavra.
Utilizando expressões regulares, é possível realizar diversas comparações
em sequência:
[*^caractere*]
em que caractere é uma lista dos caracteres individuais que não podem
aparecer na cadeia de caracteres de entrada para uma correspondência bem-
-sucedida. Além disso, ele pode ser gerado a partir de qualquer combinação de
um ou mais caracteres literais, caracteres de escape ou classes de caracteres.
A sintaxe para especificar um intervalo de caracteres é:
[̂ *PrimeiroCaractere*-*UltimoCaractere*]
em que PrimeiroCaractere é o caractere que inicia o intervalo e Ulti-
moCaractere é aquele que encerra o intervalo. Um intervalo de caracteres
Expressões regulares para programação de scripts6
é uma série adjacente de caracteres definida pela especificação do primeiro
caractere na série, um hífen (-) e o último caractere na série. Para que dois
caracteres sejam considerados adjacentes, devem apresentar valores de código
Unicode adjacentes. PrimeiroCaractere precisa ser o caractere com o
menor valor de código, enquanto UltimoCaractere o caractere com o
maior valor de código.
Alguns padrões de expressões regulares comuns que contêm grupos de
caracteres negativos são:
� [^aeiou]: corresponde a todos os caracteres, exceto vogais;
� [^\p{P}\d]: corresponde a todos os caracteres, exceto de pontuação
e dígitos decimais.
Muitas vezes, é precisoencontrar e considerar caracteres especiais e com
valores, ou funções, na expressão regular. Por exemplo, para representar uma
nova linha em linguagens de programação, é comum usar o \n, um caractere
de escape. O caractere de barra invertida (\) em uma expressão regular indica
que o próximo caractere é especial ou deve ser interpretado literalmente. No
Quadro 2, apresenta-se uma lista com os escapes de caracteres com suporte
das expressões regulares em .NET.
Caractere
com escape
Descrição Padrão
\a Corresponde a um caractere
de sino, \u0007
\a
\b Em uma classe de caractere, corresponde
a um backspace, \u0008
[\b]{3,}
\t Corresponde a uma tabulação, \u0009 (\w+)\t
\r Corresponde a um carriage return, \
u000D. (\r não é equivalente ao
caractere de nova linha, \n.)
\r\n(\w+)
\v Corresponde a uma tabulação
vertical, \u000B
[\v]{2,}
Quadro 2. Caracteres com escape suportadas pela engine de expressões regulares da
linguagem .NET
(Continua)
7Expressões regulares para programação de scripts
Fonte: Adaptado de Linguagem... (2017, documento on-line).
Quadro 2. Caracteres com escape suportadas pela engine de expressões regulares da
linguagem .NET
Caractere
com escape
Descrição Padrão
\f Corresponde a um avanço
de página, \u000C
[\f]{2,}
\n Corresponde a uma nova linha, \u000A \r\n(\w+)
\e Corresponde a um escape, \u001B \e
\ nnn Usa representação octal para
especificar um caractere (nnn consiste
em dois ou três dígitos).
\w\040\w
\x nn Usa representação hexadecimal para
especificar um caractere (nn consiste
exatamente em dois dígitos)
\w\x20\w
\c X
\c x
Corresponde ao caractere de controle ASCII
especificado por X ou x, em que X ou x é
a letra do caractere de controle
\cC
\u nnnn Corresponde a um caractere Unicode
usando representação hexadecimal
(exatamente quatro dígitos, como
representado por nnnn).
\w\
u0020\w
\ Quando seguido por um caractere
não reconhecido como um caractere
de escape nesta e em outras tabelas
deste tópico, corresponde a esse
caractere. Por exemplo, \* é igual a \
x2A, e \. é igual a \x2E. Isso permite
que o mecanismo de expressões regulares
remova ambiguidades de elementos da
linguagem (como * ou ?) e caracteres
literais (representados por \* ou \?).
\d+[\+-
-x\*]\
d+
(Continuação)
Expressões regulares para programação de scripts8
Visto que um grupo de caracteres negativos pode incluir um conjunto de caracteres
e um intervalo de caracteres, um caractere de hífen (-) é sempre interpretado como
o separador de intervalo, a menos que seja o primeiro ou último caractere do grupo.
Expressões regulares para programação de
scripts em sistemas open source
Para trabalhar com expressões regulares, utilizam-se metacaracteres, caracteres
que representam um conjunto de outros caracteres ou que estipulem regras
para a busca. No Quadro 3, apresentamos uma lista de metacaracteres para
sistemas open source.
Metacaractere Nome
. Ponto
[] Lista
[^] Lista negada
? Opcional
* Asterisco
+ Mais
{} Chaves
^ Circunflexo
$ Cifrão
\b Borda
\ Escape
| Ou
Quadro 3. Metacaracteres para expressões regulares
(Continua)
9Expressões regulares para programação de scripts
Fonte: Adaptado de Jargas (2012).
Quadro 3. Metacaracteres para expressões regulares
Metacaractere Nome
() Grupo
\1 Retrovisor
(Continuação)
Os metacaracteres dividem-se de acordo com as características comuns
entre eles, dando origem a quatro grupos distintos de metacaracteres: Repre-
sentantes, Quantificadores, Âncoras e Outros.
Grupo Representante
Os metacaracteres desse grupo têm a função de representar um ou mais
caracteres. Também podem ser encarados como apelidos, links ou qualquer
outra elemento que lhe lembre essa associação entre elementos. Todos os
metacaracteres desse tipo casam a posição de um único caractere, e não mais
que um. A seguir, há uma breve descrição de cada metacaractere desse grupo.
O ponto, um metacaractere representante, pode representar qualquer carac-
tere, constituindo um número, uma letra ou um símbolo. Considere a seguinte
expressão regular: vel.+?\b no poema de Cruz e Souza — “Violões que
choram” a seguir. Essa expressão regular vel.+?\b é capaz de casar com
todas as palavras que apresentam a cadeia “vel”, ou seja, as palavras “veladas”,
“veludosas”, “velhos” e “velozes” (TAVARES, 2005, p. 26):
Vozes veladas, veludosas vozes,
volúpia dos violões, vozes veladas,
Vagam nos velhos vórtices velozes
Dos ventos, vivas, vãs, vulcanizadas.
É comumente empregado para buscar palavras que podem conter erros de
acentuação (p.ex.: a expressão regular n.o casa com as palavras “não” e “nao”).
Expressões regulares para programação de scripts10
Outro metacaractere representante é a lista [...], que limita a busca, pois
só casa com os caracteres nela contidos. Por exemplo, a expressão [aeiou]
limita o casamento com letras vogais. No exemplo anterior do ponto, sobre
acentuação, a expressão regular n.o aceita qualquer caractere no lugar do
ponto; dessa forma, essa expressão pode casar com “n+o”, “nto”, “n9o” e
“n o”. Uma forma de limitar e evitar resultados indesejados se dá por meio
da lista. Por exemplo, a expressão regular n[aã]o casará somente com as
palavras não e não.
Para evitar que a lista fique muito extensa, é possível aplicar intervalos
a ela, representados por um traço (-). Dessa forma, quando se tem um traço
dentro de uma lista entre dois caracteres, ele indica que todos os caracteres
entre os dois caracteres serão aceitos. Por exemplo, a expressão regular [ab-
cdefghijklmnopqrstuvwxyz] é equivalente a [a-z].
O último metacaractere do grupo Representante é a lista negada [^...],
a qual, embora similar à lista, tem uma lógica inversa — ela casará com
qualquer caractere com exceção aos que estão nela. Observe que a diferença
em sua notação reside no fato de que o primeiro caractere da lista é um
circunflexo, que indica que se trata de uma lista negada. Então, se [a-z]
são letras minúsculas, [^a-z] será qualquer outro caractere exceto letras
minúsculas, podendo ser números, letras maiúsculas, espaço em branco, etc.
Grupo Quantificador
Os metacaracteres desse grupo servem para indicar o número de repetições
permitidas para um elemento imediatamente anterior, uma entidade pode
ser um caractere ou metacaractere. Em outras palavras, dizem a quantidade
de repetições que o átomo anterior pode ter, ou seja, quantas vezes ele pode
aparecer. A seguir, há uma breve descrição de cada metacaractere desse grupo.
O opcional ? é um metacaractere quantificador em que pode ter ou não a
ocorrência do caractere anterior, pois ele repete zero ou uma vez. Por exemplo,
a expressão regular a* significa zero ou uma ocorrência da letra a.
O metacaractere asterisco * é semelhante ao opcional, no entanto aceita
que o caractere anterior ocorra zero ou mais vezes. Por exemplo, a expressão
regular ba* indica que o “a” pode não aparecer (“b”), aparecer uma única
vez (“ba”) ou várias vezes (“baaaaaa”).
O mais + tem funcionamento idêntico ao do asterisco, com a ressalva de
que o mais não é opcional, ou seja, o caractere anterior deve casar pelo menos
uma vez, eventualmente havendo várias.
11Expressões regulares para programação de scripts
O metacaractere chaves {n,m} traz uma solução para uma quantificação
controlada, em que se pode especificar exatamente quantas repetições se deseja
do caractere anterior. A expressão {n,m} significa de n até m vezes; assim,
a expressão regular a{1,4} casa com “a”, “aa”, “aaa” e “aaaa”.
Grupo Âncora
Os metacaracteres desse grupo não casam com caracteres ou definem quan-
tidades, mas, em vez disso, marcam uma posição específica na linha. Assim,
não podem ser quantificados: o mais, o asterisco e as chaves não têm influência
sobre âncoras. A seguir, apresentamos uma breve descrição de cada metaca-
ractere do grupo Âncora.
O metacaractere circunflexo ^ marca o começo de uma linha, também
apenas dentro da lista (e no começo);fora dela, é a âncora que marca o começo
de uma linha: ̂ [0-9]. Isso quer dizer que, a partir do começo da linha, casa-se
com um número, ou seja, procuramos linhas que começam com números. O
contrário seria: ̂ [^0-9], ou seja, procuramos linhas que não começam com
números. O primeiro circunflexo é a âncora e o segundo, o “negador” da lista.
O metacaractere cifrão $ é similar e complementar ao circunflexo, mar-
cando o fim de uma linha e somente válido no final de uma expressão regular.
Como o exemplo anterior, [0-9]$ casa linhas que terminam com um número.
O metacaractere borda \b marca uma borda, mais especificamente o
delimitador de uma palavra. Marca os limites de uma palavra, ou seja, onde
ela começa e/ou termina. É muito útil para casar palavras exatas, e não partes
de palavras.
Grupo Outros
No grupo Outros, encontram-se os metacaracteres com funções específicas e
não relacionadas entre si; portanto, não podem ser agrupados em outra classe
fora a tradicional “Outros”. Dois dos principais metacaracteres desse grupo
são descritos a seguir.
Escapando, \'" é igual a [*] que é igual a um asterisco literal. Similar-
mente, é possível escapar todos os metacaracteres já vistos.
Por meio do metacaractere grupo (), é possível agrupar diversos ca-
racteres em um mesmo local. Dentro de um grupo, pode-se ter um ou mais
caracteres, metacaracteres e até mesmo outros grupos. Analogamente ao que
ocorre em uma expressão matemática, o conteúdo pode ser visto como um
bloco na expressão.
Expressões regulares para programação de scripts12
INSTITUTE OF ELECTRICAL AND ELECTRONICS ENGINEERS; THE OPEN GROUP. IEEE
1003.1-2017: IEEE Standard for Information Technology: Portable Operating System
Interface (POSIX®): Base Specifications, Issue 7. New York: IEEE; Berkshire: The Open
Group, 2018. 3951 p.
JARGAS, A. M. Expressões regulares: uma abordagem divertida. 4. ed. São Paulo: No-
vatec, 2012. 224 p.
LINGUAGEM de expressões regulares – referência rápida. Microsoft Docs, Redmond,
29 mar. 2017. Disponível em: https://docs.microsoft.com/pt-br/dotnet/standard/base-
-types/regular-expression-language-quick-reference. Acesso em: 8 out. 2019.
MENEZES, P. B. Linguagens formais e autômatos. Porto Alegre: Sagra-Dcluzzato, 1998.
165 p.
NEGUS, C.; BRESNAHAN, C. Linux, a bíblia: o mais abrangente e definitivo guia sobre
Linux. 8. ed. Rio de Janeiro: Alta Books, 2014. 856 p.
13Expressões regulares para programação de scripts
Dica do professor
Uma das diversas aplicações de expressões regulares é na validação de cadeias de caracteres. Por
exemplo, é possível usar expressões regulares para verificar entradas de usuários em
formulários como CPF, CEP e e-mail.
Nesta Dica do Professor, você verá como identificar um padrão de palavra, criar uma expressão
regular para verificar o padrão e inserir a expressão regular em um shell script.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://fast.player.liquidplatform.com/pApiv2/embed/cee29914fad5b594d8f5918df1e801fd/4a348651cb57b399b6f23b8186589ca7
Saiba +
Para ampliar o seu conhecimento a respeito desse assunto, veja abaixo as sugestões do professor:
Exemplos interativos de expressões regulares
Neste link, você acessará uma ferramenta capaz de interpretar expressões regulares em tempo real
e apresentar resultado, com vários exemplos já disponíveis para testar, fazer variações, mudar a
expressão e experimentar textos diferentes.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Engine on-line para expressões regulares
Neste link, você acessará uma engine on-line, em que é possível escrever e testar expressões
regulares. Além de executar a expressão, também apresenta explicações conforme você digita cada
comando.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Máquinas para implementar expressões regulares
Neste link, você acessará um artigo em que os autores revisitam a semântica de expressões
regulares com base em diversos trabalhos anteriores. Eles fazem uma investigação e propõem uma
nova classe de máquinas equivalentes a expressões regulares. Tais máquinas fornecem um método
consistente e conveniente de implementação de expressões regulares na prática.
https://www.piazinho.com.br/ed5/exemplos.html#1
https://www.regextester.com/
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Como extrair e formatar texto usando expressões regulares
Veja, neste vídeo, como usar expressões regulares para extrair informações de um texto.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://www.sciencedirect.com/science/article/pii/S0304397509001789/pdfft?isDTMRedir=true&download=true
https://www.youtube.com/watch?v=LZcTSKIwZqI
Linguagens de programação de
microcontroladores
Apresentação
Microcontroladores são dispositivos computacionais programáveis criados na década de 1970.
Nessa época, devido à restrição de memória, os microcontroladores eram programados com a
linguagem Assembly, que é classificada com uma linguagem de baixo nível. Essa denominação é
porque a linguagem Assembly contém instruções com uma correspondência muito forte com
códigos de máquina. A evolução da tecnologia de fabricação de hardware permitiu a produção de
microcontroladores com mais memória. Assim, foi possível o desenvolvimento de linguagens de
programação de alto nível para esses dispositivos como, por exemplo, a linguagem C. Desse modo,
o tempo de desenvolvimento de programas mais complexos diminuiu significativamente e
possibilitou a popularização dos microcontroladores.
Nesta Unidade de Aprendizagem, você vai compreender o significado das linguagens de baixo e
alto níveis. Vai compreender, também, as principais diferenças entre esses dois tipos de linguagem
de programação.
Bons estudos.
Ao final desta Unidade de Aprendizagem, você deve apresentar os seguintes aprendizados:
Caracterizar as linguagens de baixo nível.•
Descrever as linguagens de alto nível.•
Diferenciar as linguagens de baixo e alto nível.•
Infográfico
As linguagens de programação são métodos padronizados com um conjunto de instruções que é
utilizado para comandar um sistema computacional. Ao longo da história, ano a ano, diversas
linguagens de programação de baixo e de alto nível foram criadas, cada uma com suas vantagens e
desvantagens, voltadas para diversas aplicações, inclusive para a programação de
microcontroladores. A consolidação das linguagens de programação acorreu na década de 1980,
alinhada com a origem dos computadores e microprocessadores. Atualmente, muitas das
linguagens inventadas muito tempo atrás ainda estão sendo utilizadas juntamente com outras
novas linguagens criadas recentemente.
Neste Infográfico, você verá dois trechos de códigos com as mesmas operações, sendo um trecho
de código utilizando linguagem de alto nível e, no outro, uma linguagem de baixo nível.
Aponte a câmera para o
código e acesse o link do
conteúdo ou clique no
código para acessar.
https://statics-marketplace.plataforma.grupoa.education/sagah/8e5f6878-34c8-4135-8786-aacc897d8b0b/1deaecc9-c608-40a1-b8b1-f300b6da6762.png
Conteúdo do livro
A programação de microcontroladores pode ser realizada por meio de linguagens de baixo e alto
nível. As linguagens de baixo nível são aquelas que têm pouco ou nenhum nível de abstração das
suas instruções em relação ao código de máquina, enquanto as linguagens de alto nível têm
instruções mais complexas e próximas da linguagem humana. Desse modo, é importante conhecer
esses dois tipos de linguagem de programação.
No capítulo Programação de microcontroladores III, da obra Microprocessadores, você vai ver a
caracterização e definição das linguagens de programação de baixo e alto nível e vai saber como
diferenciar esses dois tipos de linguagens, além de compreender as vantagens e as desvantagensdessas duas linguagens.
Boa leitura.
MICROPROCESSADORES
Fernando Esquírio Torres
Programação de
microcontroladores III
Objetivos de aprendizagem
Ao final deste texto, você deve apresentar os seguintes aprendizados:
� Caracterizar as linguagens de baixo nível.
� Descrever as linguagens de alto nível.
� Diferenciar linguagens de baixo e de alto nível.
Introdução
Para se comandar um sistema computacional que executa determinada
tarefa ou aplicação, utiliza-se um programa em linguagem de máquina,
a qual é constituída de 0 (zeros) e 1 (uns). No entanto, os programadores,
ao desenvolver os programas para comandar esses sistemas, não utilizam
diretamente uma linguagem de máquina. A partir deste contexto surgiu
a necessidade de criar linguagens de programação para dispositivos
computacionais, classificadas em baixo e alto nível.
Os microcontroladores são dispositivos eletrônicos dotados de uma
inteligência programável e possuem processador, memória e perifé-
ricos acoplados em um único circuito integrado, denominado chip.
A inteligência programável é possível por meio de uma linguagem de
programação. Desde sua criação, os microcontroladores são programados
com linguagem de baixo nível, consideradas mais próximas ao hardware,
e devido à evolução da tecnologia de fabricação, estes passaram a ser
programados por linguagem de alto nível, consideradas mais próximas
da linguagem humana.
Neste capítulo, caracterizaremos as linguagens de baixo e alto nível,
a partir de exemplos de linguagens para cada uma destas classificações.
Abordaremos, também, as linguagens utilizadas em microcontroladores,
como Assembly (linguagem de baixo nível) e a linguagem C (linguagem
de alto nível). Em seguida, você aprenderá a diferenciar esses dois tipos
de linguagem.
Caracterizar as linguagens de baixo nível
Antes do surgimento das linguagens de programação, os dispositivos com-
putacionais (calculadoras, relógios digitais, computadores, microcontrola-
dores etc.) eram programados por sinais elétricos (códigos de máquina) que
comandavam o fluxo de dados na CPU. Esse tipo de programação restringia
bastante a complexidade dos programas desenvolvidos e fazia parte da primeira
geração de linguagem de programação. Portanto, havia uma necessidade de
que as linguagens de programação evoluíssem, possibilitando diversificar as
aplicações e melhorar a complexidade dos programas desenvolvidos.
Segundo Pereira (2010), os primeiros microcontroladores eram progra-
mados com linguagem de programação de baixo nível. Uma linguagem de
programação é conhecida como linguagem de baixo nível por possuir pouco
ou nenhum nível de abstração do conjunto de instruções de uma arquitetura de
computador. O conjunto de comandos e funções desta linguagem está próximo
às instruções do processador. Este tipo de linguagem pode ser convertido em
código de máquina, sem a necessidade de um compilador ou interpretador,
como acontece nas linguagens de programação de alto nível. A linguagem de
programação de baixo nível mais utilizada na família de microcontroladores
PIC da Microchip é Assembly (PEREIRA, 2010).
As linguagens de programação de baixo nível são geralmente simples e
possuem um conjunto de instruções com dezenas e/ou centenas de comandos
e funções. No entanto, o desenvolvimento de programas nessas linguagens
é considerado bastante complexo, devido a diversas técnicas com as quais
o programador deve ter familiaridade. A linguagem de baixo nível é muito
útil nos dispositivos de pouca memória, pois os seus programas, por estarem
mais próximos dos códigos de máquina, ocupam menos espaço na memória
de programa do microcontrolador (SOUZA, 2003).
Linguagem de máquina
Segundo Souza (2003), o código de máquina é uma linguagem de baixo nível
cujas instruções são compostas por números binários (0 e 1) e podem ser
executadas diretamente na unidade central de processamento do computador.
A linguagem de máquina é estritamente numérica, o que torna sua execução
mais rápida, porém dificulta a construção de programas nesta linguagem.
A arquitetura dos microprocessadores MIPS, por exemplo, utiliza uma
linguagem de máquina com instruções de 32 bits, dividida em campos que
representam operações como adição, subtração, operandos, ou a localização
Programação de microcontroladores III2
da próxima instrução (WEBER, 2012). A Figura 1 mostra um exemplo das
instruções LOAD e JUMP para essa arquitetura.
Figura 1. Instrução (a) LOAD e (b) JUMP para arquitetura MIPS.
Fonte: Adaptada de Weber (2012).
A Figura 1a mostra a instrução LOAD dividida nos campos op (operação,
6 bits); rs (operando registrador, 5 bits); rt (operando registrador, 5 bits) e
endereço ou valor imediato (16 bits). Essa instrução carrega (op) no registrador
8 (rt) o valor que está gravado 68 (endereço/valor imediato) posições de memó-
ria depois do endereço indicado pelo registrador 3 (rs). A Figura 1b mostra a
instrução JUMP dividida nos campos op (operação, 6 bits) e endereço-alvo (26
bits). Essa instrução salta para o endereço de memória 1024 (WEBER, 2012).
Assembly
Segundo Souza (2003), a linguagem Assembly faz parte da segunda geração
de linguagem de programação. Foi criada no final da década de 1940 e início
da década de 1950, possuindo forte relação entre seu conjunto de instruções
e os códigos de máquina de uma determinada arquitetura. Sendo assim, é
muito comum existirem pequenas diferenças entre a linguagem Assembly
de diferentes tipos de microcontroladores. Portanto, Assembly não é uma
linguagem de programação portátil.
Os nomes das instruções na linguagem Assembly são construídos por
mnemônicos, que são palavras (rótulos simbólicos) curtas(os) de fácil me-
morização e autoexplicativas na língua inglesa. Por exemplo, NOPE significa
sem operação (No OPEration), MOV significa mover (MOVe), ADD significa
somar (ADD), entre outras (PEREIRA, 2007). Antes de gravar na memória do
microcontrolador, esses códigos mnemônicos são convertidos em linguagem
de máquina por um programa utilitário denominado Assembler (montador) e
o código convertido executa diretamente no processador, como podemos ver
na Figura 2. A execução de um programa escrito na linguagem Assembly no
3Programação de microcontroladores III
microcontrolador é geralmente rápida e ocupa menos espaço de memória, se
comparada com as linguagens de alto nível.
Figura 2. Processo de conversão e gravação de
um código em Assembly no microcontrolador.
Fonte: Adaptada de Souza (2003).
Código em
Assembly
Assembler
Código de
máquina
IDE de programação
Conversão
Gravação
Microcontrolador
Em muitos casos, o desenvolvimento de programas na linguagem Assembly
necessita de programadores experientes e consome, relativamente, mais tempo
para desenvolver programas mais complexos. Mesmo assim é importante
conhecer o conjunto de instruções do microcontrolador que você utilizará em
seus projetos, como os microcontroladores da família PIC18F. Dependendo
do nível de programação do desenvolvedor, será necessário mesclar uma
linguagem de alto nível com uma linguagem de baixo nível.
Segundo Pereira (2010), o microcontrolador PIC18 tem 75 instruções em
Assembly e possui arquitetura RISC (reduced instruction set computer, ou
computador com um conjunto reduzido de instruções). A arquitetura RISC
se diferencia da CISC (complex instruction set computer) na construção da
pilha de instruções. A RISC tem uma quantidade reduzida de instruções
e, em geral, os acessos à pilha de memória de instruções são atômicos.
A CISC permite um número maior de instruções mais complexas, mas precisa
Programação de microcontroladores III4
de mais acessos à pilha de memória de instruções. Desse modo, a execução
das instruções em um sistema computacional RISC é mais rápida e acontece
diretamente no hardware. Além disso, dispositivos RISCs são mais simples
e mais baratos (TOKHEIM, 2013).
As instruções em Assembly sãodestinadas à movimentação de dados entre
os registradores e a memória do microcontrolador, podendo ser aritméticas,
lógicas, de teste e desvio etc. O Quadro 1 mostra as principais instruções de
movimentação de dados na linguagem Assembly para microcontroladores da
família PIC18 da Microchip.
Instrução Operando Descrição Flags afetados
MOVLW k Carrega o registrador W
com o valor de k imediato.
nenhum
MOVWF f, a Carrega o conteúdo de W
no registrador f indicado.
nenhum
MOVF f, d, a Armazena o conteúdo do
registrador f no destino.
Z e N
MOVFF f
f
, f
d
Carrega o registrador f
d
com
o conteúdo do registrador f
f
.
nenhum
MOVLB k Carrega a constante k
imediata no registrador BSR.
nenhum
LFSR f, k Carrega a constante k
imediata no registrador
FSRx especificado por f.
nenhum
CLRF f, a Apaga (preenche com
zero) o registrador f
especificado ((f)=0).
Z
SETF f, a “Seta” (preenche com
0xFF) o registrador f
especificado ((f)=0xFF).
nenhum
BCF f, b, a Apaga o bit b do
registrador f.
nenhum
Quadro 1. Instruções para movimentação de dados da linguagem Assembly
(Continua)
5Programação de microcontroladores III
Fonte: Adaptado de Pereira (2010).
Quadro 1. Instruções para movimentação de dados da linguagem Assembly
Instrução Operando Descrição Flags afetados
BSF f, b, a “Seta” o bit b do
registrador f.
nenhum
BTG f, b, a Inverte o estado do bit
b do registrador f.
nenhum
SWAPF f, d, a Troca os nibbles do
registrador f e armazena
o resultado no destino
especificado por d.
nenhum
(Continuação)
Ao observarmos o Quadro 1, podemos notar que a maioria das instruções
em Assembly tem o operando a, que representa o banco de memória que
contém o registrador f. Por exemplo, a = 0 ou o símbolo ACCESS, indica para
se utilizar o banco de memória de acesso; e a = 1 ou o símbolo BANKED,
acessa o banco indicado pelo registrador BSR (Bank Select Register, seleção
do banco de registradores) do microcontrolador PIC18. Quando o operando
a não for indicado, o microcontrolador entende que deverá acessar o banco
de acesso (PEREIRA, 2010). A Figura 3 mostra um exemplo da linguagem
Assembly com instruções de movimentação de dados.
Figura 3. Exemplo de código com instruções de movimentação de dados em Assembly
no PIC18.
Fonte: Adaptada de Pereira (2010).
Programação de microcontroladores III6
Na Figura 3, a instrução MOVWF copia o conteúdo do registrador de tra-
balho W para o endereço (primeiro operando) do banco de memória indicado
no segundo operando da instrução. A instrução CLRF apaga o conteúdo do
endereço de memória indicado por VA. A instrução SETF apaga o conteúdo do
endereço de memória indicado por VB. Na linguagem Assembly, o caractere
ponto-e-vírgula (;) indica o início de um comentário de linha. Os comentários
são interpretados como espaço em branco pelo montador, ao converter o código
Assembly para o código de máquina.
As instruções aritméticas realizam operações na unidade lógica aritmé-
tica (ULA) (PEREIRA, 2010). O Quadro 2 mostra as principais instruções
aritméticas na linguagem Assembly para microcontroladores da família PIC18
da Microchip.
Instrução Operando Descrição Flags afetados
ADDLW k Adição de W com a
constante imediata (W=W+k).
C, DC, Z, OV, N
ADDWF f,d,a Adição de W com o conteúdo
do registrador f. O resultado
é armazenado no destino
indicado por d (d = W +(f)).
C, DC, Z, OV, N
INCF f,d,a Incrementa (adiciona 1) o
conteúdo do registrador f
especificado e armazena
o resultado no destino
indicado (W ou o
próprio registrador f).
C, DC, Z, OV, N
SUBLW k Subtração de W da constante
imediata k (W=k-W).
C, DC, Z, OV, N
SUBWF f,d,a Subtração de W do conteúdo
do registrador f indicado.
C, DC, Z, OV, N
DECF f,d,a Decrementa (subtrai 1)
o conteúdo.
C, DC, Z, OV, N
Quadro 2. Instruções aritméticas da linguagem Assembly
(Continua)
7Programação de microcontroladores III
Fonte: Adaptado de Pereira (2010).
Quadro 2. Instruções aritméticas da linguagem Assembly
Instrução Operando Descrição Flags afetados
MULLW k Multiplica o conteúdo
de W pela constante
imediata k e armazena o
resultado nos registradores
PRODH e PRODL.
nenhum
MULWF f,a Multiplica o conteúdo
de W pelo conteúdo do
registrador indicado por f.
O resultado é armazenado
nos registradores
PRODH e PRODL.
nenhum
NEGF f,a Negação aritmética do
conteúdo do registrador f.
C, DC, Z, OV, N
(Continuação)
A Figura 4 mostra um exemplo na linguagem Assembly com instruções
aritméticas.
Figura 4. Exemplo de código com instruções aritméticas em Assembly
no PIC18.
Fonte: Adaptada de Pereira (2010).
Na Figura 4, a instrução MOVLW copia o valor 0x0A para o registrador W;
a instrução ADDLW soma o valor do operando ao registrador W e o resultado
é armazenado em W; e a instrução SUBLW subtrai o conteúdo de W do valor
indicado pelo operando (PEREIRA, 2010).
Programação de microcontroladores III8
As instruções lógicas realizam operações lógicas booleanas (and, or, xor e
not) (PEREIRA, 2010). O Quadro 3 mostra as principais instruções lógicas na
linguagem Assembly para microcontroladores da família PIC18 da Microchip.
Instrução Operando Descrição Flags afetados
ANDLW k Operação lógica E entre o
conteúdo do registrador
W e a constante imediata
k (W = W E k).
Z e N
ANDWF f,d,a Operação lógica E entre o
conteúdo do registrador
W e o conteúdo do
registrador f. O resultado é
armazenado no registrador
de destino d (d = W E f).
Z e N
IORLW k Operação lógica OU
entre o conteúdo do
registrador W e a constante
imediata k (W = W E k).
Z e N
IORWF f,d,a Operação lógica OU entre
o conteúdo do registrador
W e o conteúdo do
registrador f. O resultado é
armazenado no registrador
de destino d (d = W OU f).
Z e N
XORLW k Operação lógica OU exclusivo
entre o conteúdo do
registrador W e a constante
imediata k (W = W XOR k).
Z e N
XORWF f,d,a Operação lógica OU exclusivo
entre o conteúdo do
registrador W e o conteúdo
do registrador f. O resultado
é armazenado no registrador
de destino d (d = W XOR f).
Z e N
Quadro 3. Instruções lógicas da linguagem Assembly
(Continua)
9Programação de microcontroladores III
Fonte: Adaptado de Pereira (2010).
Quadro 3. Instruções lógicas da linguagem Assembly
Instrução Operando Descrição Flags afetados
COMF f,d,a Operação lógica NÃO
com o conteúdo do
registrador f. O resultado é
armazenado no registrador
de destino d (d = NÃO f).
Z e N
RLCF f,d,a Desloca o conteúdo do
registrador f um bit para a
esquerda (pela flag carry). O
resultado é armazenado no
registrador de destino d.
Z e N
RRCF f,d,a Desloca o conteúdo do
registrador f um bit para a
direita (pela flag carry). O
resultado é armazenado no
registrador de destino d.
Z e N
(Continuação)
A Figura 5 mostra um exemplo de sequência de instruções lógicas na
linguagem Assembly. A instrução ANDLW 0x1C realiza a operação lógica
booleana E entre o registrador W e a máscara 0x1C, e o resultado é arma-
zenado no registrador W. A instrução ANDLW PORTB realiza a operação
lógica booleana E entre o registrador W e o registrador PORTB, e o resultado
é armazenado no registrador W (SOUZA, 2003).
Figura 5. Exemplo de código com instruções lógicas em Assembly no PIC18.
Fonte: Adaptada de Pereira (2010).
Programação de microcontroladores III10
As instruções de teste e desvio realizam desvio incondicionais, condi-
cionais, com endereçamento absoluto e com endereçamento relativo. Essas
instruções permitem fazer desvios, comparação, teste de bit, incremento e
desvio, decremento e desvio, chamada e retorno de sub-rotina, entre outras
(PEREIRA, 2010). O Quadro 4 mostra as principais instruções de teste e
desvio na linguagem Assembly para microcontroladores da família PIC18 da
Microchip.
Instrução Operando Descrição Flags afetados
GOTO end Desvio absoluto incondicional
para o endereço indicado
pelo operando end.
nenhum
BRA end Desvio relativo incondicional
para o endereço indicado
pelo operando end.nenhum
BZ end Desvia para o endereço
especificado indicado pelo
operando end, se o flag
Z do registrador STATUS
estiver “setado” (Z=1).
nenhum
BNZ end Desvia para o endereço
especificado indicado por
pelo operando end, se o
flag Z do registrador STATUS
estiver zerado (Z=0).
nenhum
BC end Desvia para o endereço
indicado pelo operando end,
se o flag C do registrador
STATUS estiver “setado” (C=0).
nenhum
BNC end Desvia para o endereço
indicado pelo operando end,
se o flag C do registrador
STATUS estiver zerado (C=1).
nenhum
Quadro 4. Instruções de teste e desvio da linguagem Assembly
(Continua)
11Programação de microcontroladores III
Quadro 4. Instruções de teste e desvio da linguagem Assembly
Instrução Operando Descrição Flags afetados
BN end Desvia para o endereço
indicado pelo operando end,
se o flag N do registrador
STATUS estiver “setado” (N=1).
nenhum
BNN end Desvia para o endereço
indicado pelo operando end,
se o flag N do registrador
STATUS estiver zerado (N=0).
nenhum
BOV end Desvia para o endereço
indicado pelo operando end,
se o flag OV do registrador
STATUS estiver “setado” (OV=1).
nenhum
BNOV end Desvia para o endereço
indicado pelo operando end,
se o flag OV do registrador
STATUS estiver zerado (OV=0).
nenhum
CPFSEQ f,a Compara o registrador
W com o conteúdo do
registrador f e salta a
próxima instrução, se f=W.
nenhum
CPFSGT f,a Compara o registrador
W com o conteúdo do
registrador f e salta a próxima
instrução, se f > W.
nenhum
CPFSLT f,a Compara o registrador
W com o conteúdo do
registrador f e salta a próxima
instrução, se f < W.
nenhum
TSTFSZ f,a Testa o registrado f e salta
a próxima instrução, se
seu conteúdo for zero.
nenhum
DECFSZ f,a Decrementa o conteúdo
do registrador f e salta
a próxima instrução, se
o conteúdo for zero.
nenhum
(Continua)
(Continuação)
Programação de microcontroladores III12
Quadro 4. Instruções de teste e desvio da linguagem Assembly
Instrução Operando Descrição Flags afetados
DCFSNZ f,a Decrementa o conteúdo do
registrador f e salta a próxima
instrução, se o conteúdo
for diferente de zero.
nenhum
INCFSZ f,a Incrementa o conteúdo
do registrador f e salta
a próxima instrução se
o conteúdo for zero.
nenhum
INFSNZ f,a Incrementa o conteúdo do
registrador f e salta a próxima
instrução, se o conteúdo
for diferente de zero.
nenhum
BTFSC f,b,a Testa o bit indicado pelo
operando b e salta a próxima
instrução, se ele estiver zerado.
nenhum
BTFSS f,b,a Testa o bit indicado
pelo operando b e salta
a próxima instrução, se
ele estiver “setado”.
nenhum
CALL end,s Chamada de sub-rotina no
endereço indicado pelo
operando end. Opcionalmente
(se s=1) os registradores W,
STATUS e BSR são salvos em
registradores especiais.
nenhum
RCALL end Chamada de sub-rotina
no endereço indicado
pelo operando end.
nenhum
RETLW k Retorno de sub-rotina e a
constante k é armazenada
no registrador W.
nenhum
(Continua)
(Continuação)
13Programação de microcontroladores III
Fonte: Adaptado de Pereira (2010).
Quadro 4. Instruções de teste e desvio da linguagem Assembly
Instrução Operando Descrição Flags afetados
RETURN s Retorno de sub-rotina.
Opcionalmente (se s=1) os
registradores W, STATUS
e BSR são restaurados
com o valor salvo em
registradores especiais.
nenhum
RETFIE s Retorno de interrupção (o
flag GIE/GIEH/GIEL deve
estar “setado”, habilitando as
interrupções). Opcionalmente
(se s=1) os registradores W,
STATUS e BSR são salvos em
registradores “sombra”.
nenhum
POP - O conteúdo do apontador
do topo da pilha (STKPTR)
é decrementado em um,
descartando o último
endereço no topo da pilha.
nenhum
PUSH - Endereço da próxima
instrução (PC+2) é salvo
na pilha e o apontador do
topo da pilha (STKPTR) é
incrementado em um.
nenhum
(Continuação)
A Figura 6 mostra um exemplo de sequência de instruções de teste e
desvio na linguagem Assembly na construção de laços de repetição e desvio
condicionais (PEREIRA, 2010).
Programação de microcontroladores III14
Figura 6. Exemplo de código com instruções de teste e desvio em Assembly no PIC18.
Fonte: Adaptada de Pereira (2010).
Os exemplos da Figura 6 mostram como fazer laços de repetição e testes
lógicos condicionais. O primeiro laço com o rótulo repete, na linha 1,
executa a instrução de teste lógico condicional incfsz REG,f várias
vezes até que conteúdo do registrado f seja igual a zero. O segundo laço com
o rótulo repete2, na linha 6, é uma outra maneira de fazer o mesmo laço
de repetição, porém com a instrução do teste lógico condicional diferente.
Descrever as linguagens de alto nível
Devido à evolução dos processos de fabricação de dispositivos microcon-
trolados e a redução do custo de manufatura e de componentes eletrônicos,
tornou-se possível produzir microcontroladores com maior quantidade de
memória, reduzindo, assim, a limitação de hardware físico. Portanto, os
programas passaram a poder ocupar mais espaço de memória. Isso possibi-
litou que os microcontroladores pudessem ser programados com linguagens
de alto nível, como as linguagens C, C++, Java, Python, PHP, entre outras.
Como o foco deste capítulo é a programação de microcontroladores, será
detalhada apenas a linguagem C, que é a linguagem de alto nível utilizada
para programar microcontroladores (PEREIRA, 2007). As outras linguagens
citadas são utilizadas para o desenvolvimento de programas para desktops,
computadores pessoais etc.
Além disso, devido ao desenvolvimento de linguagem de programação de
alto nível com a eficiência das de baixo nível e a melhoria dos compiladores
de linguagem de alto nível, foi possível otimizar o desenvolvimento da lógica
de programação para microcontroladores e o processo de tradução do código
em alto nível para o código de máquina.
15Programação de microcontroladores III
Segundo Pinheiro (2012), a linguagem de alto nível possui um grande nível
de abstração do conjunto de instruções de uma arquitetura de computador e
está muito próxima da linguagem humana. Ela usa elementos de linguagem
natural e, desse modo, torna-se mais familiar para o programador. A primeira
linguagem de programação de alto nível desenvolvida para computadores foi a
Plankalkül, mas esta não foi utilizada em microcontroladores. Nos dispositivos
microcontrolados, atualmente, a linguagem de programação de alto nível
mais popular é a linguagem C, que está entre as cinco maiores linguagens de
programação do mundo, de acordo com o Spectrum Ranking do IEEE.
As linguagens de programação de alto nível têm uma etapa a mais no pro-
cesso de conversão de um código programado em alto nível para o código de
máquina, como vemos na Figura 7. Na primeira etapa, o código desenvolvido
por um programador em linguagem de alto nível é traduzido por um compilador
ou interpretador para uma linguagem de baixo nível intermediária, como a
linguagem Assembly. Em seguida, o código na linguagem Assembly é con-
vertido em linguagem de máquina, gravado na memória do microcontrolador
e executa diretamente no processador (WEBER, 2012).
Figura 7. Processo de tradução e gravação de um código em
linguagem de alto nível no microcontrolador.
Fonte: Adaptada de Pereira (2010).
Código em linguagem
de alto nível
Assembler
Código de
máquina
IDE de programação
Tradução
Gravação
Microcontrolador
Compilador ou
interpretador
Conversão
Programação de microcontroladores III16
Compiladores e interpretadores são programas auxiliares que verificam a
sintaxe e a semântica do código programado. A diferença principal entre eles,
em computadores pessoais e notebooks, é que o compilador traduz o código
completo para então executá-lo, enquanto o interpretador traduz o código
em tempo de execução linha por linha, conforme o código roda (PINHEIRO,
2012). Em microcontroladores, os ambientes de programação (IDE, integra-
ted development environment), em sua maioria, utilizam compiladores para
traduzir o códigoem linguagem de alto nível para instruções em Assembler.
Linguagem de programação C e C++
A linguagem C, apesar de ser uma das mais antigas, é considerada uma lingua-
gem de alto nível robusta e eficiente. Além disso, a linguagem C é, atualmente,
a linguagem de programação de alto nível mais utilizada no desenvolvimento de
códigos para microcontroladores e, mesmo não sendo uma linguagem próxima
das instruções de uma arquitetura computacional, permite acessar e configurar
facilmente o hardware desses dispositivos microcontrolados programáveis.
A popularização da linguagem C na programação dos microcontroladores
permitiu diversificar o desenvolvimento de aplicações, diminuir o tempo
gasto na implementação de programas mais complexos, facilitou a leitura e o
entendimento do código programado, entre outras vantagens. Por outro lado,
um código em linguagem C ocupa mais espaço de memória e, no processo de
tradução e conversão, podem não ser tão otimizados, gerando códigos mais
lentos de serem executados.
Segundo Pereira (2007), a tendência entre programadores de escolher a
linguagem C para o desenvolvimento de seus códigos é natural, visto que na
linguagem C eles se preocupam mais com a programação da aplicação desejada
do que com as tarefas, como o controle e a localização das variáveis, opera-
ções matemáticas e lógicas, a verificação com bancos de memória e outras,
como acontece na linguagem Assembly. Isso se dá pelo fato de as instruções
da linguagem C serem baseada na língua inglesa e possuírem comandos
e/ou funções como if (se), for (para), while (enquanto), void (vazio),
int (inteiro), switch-case (troca-caso), entre outras.
O C++ é uma evolução da linguagem C que possibilita utilizar conceitos
de programação orientada a objetos como herança múltipla, classes abstratas,
objetos estáticos, métodos constantes, entre outros. É uma linguagem utili-
zada principalmente no desenvolvimento de soluções computacionais para
desktops e computadores pessoais, não sendo utilizada para a programação
de microcontroladores (PINHEIRO, 2012).
17Programação de microcontroladores III
Os microcontroladores da família PIC possuem diversos compiladores que
permitem programa-los utilizando a linguagem C, como, por exemplo, o XC
da Microchip, o CCS da Custom Computer Services, o mikroC da MikroE-
lektronika, entre outros. Uma dica muito útil para quem está iniciando em
programação de microcontroladores utilizando a linguagem C é escolher o
compilador mais familiar e com suporte técnico mais acessível, assim como
documentação com exemplos práticos. Neste capítulo, recomendamos utilizar
o compilador oficial do fabricante Microchip, o XC, pois a empresa tem uma
vasta documentação e application notes com diversos assuntos teóricos e
práticos de seus produtos. Além disso, a Microchip administra um fórum para
tirar dúvidas dos usuários de seus produtos oficiais (Microcontroladores PIC,
IDE MPLAB, compiladores XC, etc.).
A Figura 8 mostra um código na linguagem C para receber um número
digitado no teclado pelo usuário e exibir o valor digitado na tela novamente.
Figura 8. (a) Exemplo de um código em C e (b) saída produzida na execução do código.
Fonte: Adaptada de Pereira (2010).
A linha 1 do código mostrado na Figura 8a possui o comando #include
<stdio.h>, que adiciona os códigos da biblioteca padrão stdio.h ao seu
programa. Esta biblioteca é necessária para utilizar os comandos scanf e
printf. A função de entrada de dados scanf("%d", &x), na linha 6
da Figura 4a, lê um dado inteiro (indicado pelo comando de formatação %d),
digitado no teclado e armazenado na variável inteira x. A função de saída de
dados printf imprime na tela do computador a mensagem desejada. Na
linha 5 da Figura 8a, o comando printf("Digite um número: ")
imprime a mensagem de interação com o usuário e solicita que ele digite um
número inteiro (Figura 8b). O comando printf("O número digitado
Programação de microcontroladores III18
é: %d\n", x), na linha 7 da Figura 8a, imprime a mensagem final com
o valor digitado (Figura 8b). O código de formatação \n indica a quebra de
linha e posiciona o cursor no início dessa nova linha (PINHEIRO, 2012).
O código mostrado na Figura 8a foi desenvolvido para ser executado em
computadores pessoais. Nos microcontroladores, esses comandos de entrada
e saída de dados não são muito utilizados, pois a maioria dos projetos micro-
controlados não utilizam teclado e tela.
Diferenciar linguagens de baixo e de alto nível
As linguagens de baixo e alto nível são importantes dentro do universo de
programação de microcontroladores. Cada uma possui vantagens e desvan-
tagens para os programadores no desenvolvimento de seus programas. Nesta
seção, você verá como pode diferenciar uma linguagem de alto nível de uma
linguagem de baixo nível, apontando as vantagens e desvantagens dessas
linguagens.
A principal característica para se diferenciar uma linguagem de baixo nível
de uma linguagem de alto nível é o fato de que as instruções da primeira são
formadas por mnemônicos curtos (ADD, SUB, MOV, CLR etc.), que repre-
sentam a ação e/ou comando a ser executado; enquanto, as instruções de uma
linguagem de alto nível possuem palavras semelhantes ou iguais à linguagem
humana, como a linguagem C, que como já vimos, é baseada na língua inglesa
e possui diversos comandos e funções (if, else, for, while, entre outros)
que representam palavras dessa língua (PEREIRA, 2010).
Entre as vantagens e as desvantagens destes tipos de linguagem de progra-
mação, pode-se citar a otimização e a velocidade de execução dos códigos e o
espaço ocupado na memória por eles. As linguagens de baixo nível permitem
que o programador desenvolva códigos mais otimizados (enxutos), porque suas
instruções têm pouca ou nenhuma abstração e, assim, estão mais próximas
da linguagem de máquina. Além disso, códigos mais otimizados ocupam
menos espaço de memória e são executados mais rapidamente pela CPU do
microcontrolador. Em contrapartida, a otimização das linguagens de alto nível
depende da qualidade e da eficiência do compilador. Desse modo, a tradução
do código em alto nível para a linguagem de baixo nível pode não ser bem
otimizada e, então, o código convertido para a linguagem de máquina pode
ocupar mais espaço de memória e ser executado de forma mais lenta pela CPU
do microcontrolador (PEREIRA, 2007).
19Programação de microcontroladores III
Um segundo ponto a ser destacado é a possibilidade de controle do har-
dware programado. As linguagens de programação de baixo nível viabilizam
o controle de grande parte do hardware do microcontrolador, sendo possível
acessar e configurar a grande maioria dos registradores de função especial
do dispositivo, enquanto na linguagem de programação de alto nível existe
restrição de acesso e configuração de um conjunto de registradores de função
especial.
A linguagem de alto nível é mais amigável aos programadores e permite o
desenvolvimento mais rápido de programas mais complexos do que a linguagem
de baixo nível. Além disso, a linguagem de alto nível facilita a manutenção
de um código já implementado.
Por fim, a linguagem de alto nível C tem uma última vantagem em relação
à linguagem de baixo nível Assembly: a linguagem C é muito mais difundida
do que a Assembly, devido a sua grande popularidade entre programadores.
Sendo assim, torna-se mais fácil encontrar soluções e programas com exemplos
na linguagem C do que em Assembly.
Importância da linguagem de baixo nível no
remapeamento de periféricos nos
microcontroladores PIC
Apesar de os programadores atuais escolherem a linguagem de programação
C para desenvolver seus códigos e quase nunca precisarem trabalhar com
linguagens de baixo nível, não se deve descartar totalmente o aprendizado
da linguagem Assembly. Em programas mais complexos, que necessitam de
acesso ao hardware durante a execução do programa, muitas vezes é necessário
combinar parte do código em linguagemC com Assembly.
Alguns microcontroladores PIC possuem a funcionalidade particular que
possibilita o remapeamento de periféricos, permitindo a liberdade de asso-
ciar pinos de entrada e saída a múltiplos periféricos, flexibilizando, assim, a
construção do hardware. Desse modo, periféricos internos como UART, I2C,
SPI, interrupções externas, entre outros, podem ser associados (remapeados)
a qualquer pino do microcontrolador (PEREIRA, 2010). O remapeamento
pode ser feito de duas maneiras: uma única vez, no início do seu código, ou
diversas vezes, durante a execução do código. No primeiro caso, o remape-
amento pode ser feito utilizando apenas a linguagem de alto nível C. Já no
segundo caso, de remapeamentos múltiplos durante a execução do programa,
você precisará mesclar códigos em linguagem de baixo nível para permitir um
novo remapeamento dos periféricos com códigos em linguagem de alto nível.
Programação de microcontroladores III20
PEREIRA, F. Microcontrolador PIC 18 detalhado: hardware e software. São Paulo: Érica,
2010. 304 p.
PEREIRA, F. Microcontroladores PIC: técnicas avançadas. 6. ed. São Paulo: Érica, 2007. 368 p.
PINHEIRO, F. A. C. Elementos de programação em C: em conformidade com o padrão
ISO/IEC 9899. Porto Alegre: Bookman, 2012. 548 p.
SOUZA, D. J. Desbravando o PIC: ampliado e atualizado para PIC16F628A. 6. ed. São
Paulo: Érica, 2003. 268 p.
TOKHEIM, R. Fundamentos de eletrônica digital: sistemas sequenciais. 7. ed. Porto Alegre:
AMGH; Bookman, 2013. v. 2. 274 p. (Série Tekne).
WEBER, R. F. Fundamentos de arquitetura de computadores. 4. ed. Porto Alegre: Bookman,
2012. 424 p. (Série Livros Didáticos Informática UFRGS).
Leituras recomendadas
GONÇALVES, L. S. Utilização de coordenadas georreferenciadas aplicada a máquinas agrí-
colas. Orientador: André Sanches Fonseca Sobrinho. 2017. 46 f. Trabalho de Conclusão
de Curso (Bacharelado em Engenharia de Controle e Automação) — Universidade
Tecnológica Federal do Paraná, Cornélio Procópio, 2017. Disponível em: http://reposi-
torio.roca.utfpr.edu.br/jspui/handle/1/11310. Acesso em: 20 jul. 2019.
PEREIRA, F. Instruções. In: PEREIRA, F. Microcontroladores PIC: técnicas avançadas. 6. ed.
São Paulo: Érica, 2007. cap. 4.
PEREIRA, F. Instruções Assembly. In: PEREIRA, F. Microcontrolador PIC 18 detalhado:
hardware e software. São Paulo: Érica, 2010. cap. 2. seção 2.1.6.
SCUDERO, E. Linguagens de Alto Nível vs. Baixo Nível: qual é melhor? BeCode, Porto
Alegre, 18 abr. 2017. Disponível em: https://becode.com.br/linguagens-alto-nivel-x-
-baixo-nivel/. Acesso em: 20 jul. 2019.
SOUZA, D. J. Conhecendo um pouco o set de instruções. In: SOUZA, D. J. Desbravando
o PIC: ampliado e atualizado para PIC16F628A. 6. ed. São Paulo: Érica, 2003. cap 7.
21Programação de microcontroladores III
Dica do professor
A maioria dos programadores, atualmente, escolhe a linguagem de programação C para
desenvolver os seus códigos e quase nunca precisa trabalhar com linguagens de baixo nível, como o
Assembly. Isso se deve porque o entendimento da linguagem C é mais simples e ela não exige
tantas técnicas e regras de programação para desenvolver códigos. Mesmo assim, a linguagem
Assembly é importante quando em situações críticas de acesso ao hardware ou de temporização
rigorosa entre comandos. Desse modo, ela não deve ser descartada totalmente.
Nesta Dica do Professor, você verá a importância de utilizar a linguagem Assembly em algumas
situações para a programação de hardwares, como os microcontroladores.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://fast.player.liquidplatform.com/pApiv2/embed/cee29914fad5b594d8f5918df1e801fd/e7720cacf1b912fd249d9a0a8067cb9b
Saiba +
Para ampliar o seu conhecimento a respeito desse assunto, veja abaixo as sugestões do professor:
Primeiro projeto com PIC e PICGenios - Série Primeiros Passos
#002
Assista ao vídeo da Microgênios e aprenda como programar um microcontrolador PIC utilizando a
linguagem de programação C de uma maneira prática e simples.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Um relato de experiência: ensinando robótica por meio de
microcontroladores em uma escola profissional de Ensino
Médio
Este artigo que visa a inserir alunos do ensino médio à área da robótica, por meio de um curso de
microcontroladores e de programação em linguagem C.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Vale a pena aprender o bom e velho Assembly?
Este artigo mostra que embora haja limitações em relação ao uso prático e profissional da
linguagem Assembly, certamente é um conhecimento que agrega valor à formação.
https://www.youtube.com/embed/cm6WVT-0bFs
https://sol.sbc.org.br/index.php/wei/article/view/3509
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Introdução aos sistemas embarcados e microcontroladores
Este artigo apresenta uma breve introdução aos sistemas embarcados, direcionando o assunto para
sistemas microcontrolados.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://www.profissionaisti.com.br/vale-a-pena-aprender-o-bom-e-velho-assembly/#:~:text=Benef%C3%ADcios%20em%20se%20aprender%20o%20bom%20e%20velho%20Assembly&text=A%20linguagem%20ensina%20o%20que,para%20as%20quais%20est%C3%A3o%20programadas.
https://www.embarcados.com.br/sistemas-embarcados-e-microcontroladores/
Introdução à linguagem Java
Apresentação
O mundo está se transformando rapidamente e acompanhar a evolução tecnológica tem sido um
desafio não trivial para muitas pessoas.
O mercado de trabalho está em busca de profissionais cada vez mais qualificados.
Quando se fala sobre o mercado de trabalho na área
de tecnologia, de forma geral, e em programação de computadores,
de forma mais específica, a situação é boa e ruim ao mesmo tempo.
Por um lado, são necessários profissionais altamente qualificados, porém a demanda é gigantesca e
a tendência é de crescimento.
Nesta Unidade de Aprendizagem, você começará sua jornada por
uma das linguagens mais populares do mercado: Java. Primeiramente, você verá um pouco da
história e da filosofia dessa linguagem e, depois, poderá ver um programa simples em Java sendo
executado, o qual será explicado em detalhes. Por último, você estudará sobre os fundamentos
básicos da linguagem Java e suas principais características.
Bons estudos.
Ao final desta Unidade de Aprendizagem, você deve apresentar os seguintes aprendizados:
Descrever a história, a filosofia e a terminologia da linguagem Java.•
Desenvolver um programa simples em Java. •
Explicar a sintaxe da linguagem Java. •
Infográfico
A linguagem Java foi pioneira em estabelecer uma linguagem híbrida (compilada e interpretada),
conseguindo, assim, ser multiplataforma. Depois de ter compreendido isso, você deve voltar sua
atenção para
a estrutura de classes do Java, sendo que cada componente tem
um significado.
Neste Infográfico, você verá como é uma classe Java em detalhes,
seu processo de compilação e interpretação até o código ser executado.
Aponte a câmera para o
código e acesse o link do
conteúdo ou clique no
código para acessar.
https://statics-marketplace.plataforma.grupoa.education/sagah/1371a156-0220-42c8-8d9a-4be5d65a65ee/99919668-e181-4055-960e-d656542b034f.jpg
Conteúdo do livro
A história do Java começou em meados dos anos 1990 e trouxe
uma nova maneira de programar para a Web. Sendo multiplataforma, gratuita e com a sintaxe
similar a linguagens já consagradas como C e C++, ela logo ganhou adeptos no mundo inteiro. Sua
estrutura orientada a objetos e a simplicidade na comunicação entre eles foram aspectos que a
tornaram popular. Ainda hoje, Java é uma das linguagens mais utilizadas no mercado e a demanda
por profissionais qualificados
só cresce.
No capítulo Introdução à linguagem Java, base teórica desta Unidade de Aprendizagem,você
aprenderá um pouco da história da linguagem Java. É necessário conhecer a sua história para
compreender suas origens, suas comunidades e seus objetivos. Logo após, você verá os elementos
básicos dela, os conceitos iniciais e alguns exemplos que servirão
de guia para que você, futuramente, escreva seus próprios códigos.
Boa leitura.
ESTRUTURA DE
DADOS EM JAVA
OBJETIVOS DE APRENDIZAGEM
> Descrever a história, a filosofia e a terminologia da linguagem Java.
> Desenvolver um programa simples em Java.
> Explicar a sintaxe da linguagem Java.
Introdução
Você sabia que a linguagem Java é uma das linguagens mais populares do mercado?
Isso ocorre porque, em primeiro lugar, é uma linguagem simples, fácil de aprender,
de forma que sua curva de aprendizado, em relação a outras linguagens, é bem
menor. Em segundo lugar, a linguagem Java possui uma grande comunidade de
colaboradores: ou seja, você terá o apoio de milhões de usuários e inúmeras
linhas de código que poderão facilitar seu aprendizado. Além disso, a linguagem
Java possui ótimas ferramentas de desenvolvimento (Eclipse, NetBeans, etc.), que
ajudam você a codificar e tornar seu código mais limpo, legível, organizado e, por
consequência, fácil de ser mantido, bem como uma grande coleção de bibliotecas
e de frameworks prontas para uso, como Maven, Struts, etc.
Neste capítulo, você vai aprender um pouco sobre a história do Java e como ela
se tornou, rapidamente, uma das linguagens de programação mais importantes da
atualidade. Em seguida, vamos desenvolver um programa simples em Java, mas
o suficiente para que você possa reconhecer o formato básico de um programa
em Java. Por fim, você vai conhecer a sintaxe básica dessa linguagem, bem como
alguns conceitos iniciais importantes.
Introdução à
linguagem Java
Pedro Kislansky
História, filosofia e terminologia
da linguagem Java
Em 1991, a Sun Microsystems financiou uma pesquisa que levaria ao de-
senvolvimento da linguagem Java, uma linguagem baseada em C e C++. A
principal motivação foi a necessidade de uma linguagem independente de
plataforma que pudesse ser usada na criação de software embutido em
vários dispositivos eletrônicos domésticos, como torradeiras, fornos de
micro-ondas e controles remotos. O projeto foi liderado por James Gosling,
programador canadense nascido em 19 de maio de 1956, que trabalhou
na Sun Microsystems de 1984 até abril de 2010. A versão inicial do Java foi
chamada de “Oak” (carvalho, em inglês), pois havia um carvalho em frente à
janela onde a equipe do projeto trabalhava. Contudo, já havia uma linguagem
de programação com esse nome, então os envolvidos foram obrigados a
modificar para “Java”, uma referência à forma coloquial de chamar o café em
algumas partes dos Estados Unidos, para contornar o problema de patente
registrada (SCHILDT, 2015).
Mais ou menos na mesma época quando os detalhes de Java estavam
sendo esboçados, surgia a World Wide Web, um fator que desempenharia
papel crucial no futuro da linguagem. Se a web não estivesse se formando
quase ao mesmo tempo em que Java estava sendo implementada, talvez ela
continuasse sendo uma linguagem útil, mas obscura para a programação de
utensílios eletrônicos domésticos. No entanto, com o surgimento da web, Java
foi impulsionada para a dianteira do design das linguagens de computador,
porque a web também precisava de programas portáteis (SCHILDT, 2015).
Uma novidade que o Java trouxe foi o gerenciamento de memória por
“garbage collector”, coletor de lixo que se encarrega de se desfazer
de posições de memória que não estão sendo utilizadas. Até aquele momento,
o programador era responsável por esse gerenciamento, o que induzia a vários
erros lógicos dentro do programa (FINEGAN; LIGUORI, 2018).
A principal filosofia que Gosling queria implementar na linguagem Java
era o fato de ela poder ser compilada uma vez e executada em qualquer
ambiente. Daí saiu o famoso slogan da linguagem: “write once, run anywhere”.
O modelo desenvolvido sugere que a linguagem Java, quando compilada, é
transformada em um código intermediário, chamado de bytecode. Depois,
o bytecode pode ser interpretado por qualquer máquina que tenha uma JVM
(máquina virtual Java) específica. Logo, se estiver usando o Linux, você precisa
Introdução à linguagem Java2
de uma JVM para Linux; se estiver usando o Windows, precisará de uma JVM
para Windows e assim sucessivamente.
De fato, converter um programa Java em bytecode facilita muito sua exe-
cução em uma grande variedade de ambientes, porque só a JVM tem que
ser implementada para cada plataforma. Uma vez que o pacote de tempo
de execução estiver presente em determinado sistema, qualquer programa
Java poderá ser executado nele. Lembre-se: embora os detalhes da JVM sejam
diferentes de uma plataforma para outra, todas entendem o mesmo bytecode
Java. Além disso, o fato de um programa Java ser executado pela JVM também
ajuda a torná-lo seguro. Como a JVM está no controle, ela pode reter o pro-
grama e impedi-lo de gerar efeitos colaterais fora do sistema (SCHILDT, 2015).
Quando você estiver aprendendo Java, verá que existe um mar de abre-
viações com que terá que se acostumar: JDK, JRE, JVM, JSE, JEE, JSP e muitas
outras. Mas não se apavore! Vamos explicar algumas delas no decorrer deste
capítulo e, na dúvida, uma simples busca na internet resolve o problema.
Antes de mais nada, para que você possa iniciar seu caminho no aprendi-
zado da linguagem, você precisa de duas coisas: JDK e JRE. JDK (Java develop-
ment kit), ou kit de desenvolvimento do Java, é um conjunto de utilitários que
permitem criar sistemas de software para a plataforma Java. É composto pelo
compilador e por bibliotecas. Por sua vez, o JRE (Java runtime environment),
ou ambiente de execução do Java, é o ambiente utilizado para executar as
aplicações da plataforma Java. É composto por bibliotecas (APIs, do inglês
application programming interfaces) e pela JVM (HORSTMANN, 2009).
Para codificar programas em Java, pode-se usar qualquer editor de textos;
porém, a melhor opção é utilizar um IDE (integrated development environ-
ment), ou ambiente de desenvolvimento integrado. Trata-se um software que
possui um editor de texto e várias outras ferramentas, como automação de
compilação local, debugger e análise de código em tempo real, que ajudam o
programador em suas tarefas e agilizam o processo, possibilitando trabalho
colaborativo, integração com outras ferramentas, etc.
Os dois IDEs mais populares são o Eclipse (ECLIPSE FOUNDATION, c2020)
e o Netbeans (NETBEANS, c2020). O projeto Eclipse foi criado, originalmente,
pela IBM em 2001, mas, em 2004, foi criada a fundação Eclipse, independente
e sem fins lucrativos. Hoje, o Eclipse é utilizado por milhões de pessoas e
possui uma comunidade bastante ativa. Por sua vez, o NetBeans começou
como um projeto de estudantes da República Tcheca em 1996. O objetivo
era escrever um IDE similar ao Delphi no Java, e, assim com o Eclipse, ele
também é gratuito. Com a aquisição da Sun Microsystems pela Oracle em
2010, o NetBeans se tornou parte da Oracle também.
Introdução à linguagem Java 3
Não existe um IDE melhor que outro, assim como não existe uma lin-
guagem melhor que outra. O que vai determinar o IDE mais adequado
para o projeto é sua afinidade com ele, e a linguagem geralmente é definida
pela natureza do problema ou pela expertise da equipe de trabalho.
Segundo o ranking da RedMonk (RENATO, 2020), hoje a linguagem Java é
a terceira linguagem de programação mais popular do planeta, perdendo
somente para C e Python. Desde que foi lançada, foi rapidamente adotada
por uma legião de fãs. Sua gratuidade e portabilidade fizeram com que fosse
adotada pela maioria das instituições públicas. Hoje, ela está presente em
notebooks, tablets, celulares, mainframes, sistemas de automação e muito
mais. De fato, a comunidade Java é uma das comunidades mais ativas entre
as linguagens de programação (GUJ, c2020;JAVA, c2020; SANTANA, 2020).
Como desenvolver um programa simples
em Java?
Nesta seção, vamos desenvolver um programa simples em Java. Primeiramente,
descreveremos um pequeno problema e, depois, veremos sua solução em
forma de programa codificado na linguagem Java. Por fim, analisaremos cada
linha do programa. Não se assuste caso não compreenda todos os detalhes:
o importante, por enquanto, é entender os conceitos de forma geral.
Problema
Digamos que uma pessoa trabalhe com importação e exportação. Certo dia,
seu chefe pede que ela faça um programa que converta valores em dólar
para real, uma vez que consiste em uma demanda diária do trabalho, pois
ele precisa saber quanto ganha em real nas exportações.
Solução
1 package Testes;
2 import java.util.Scanner;
3 public class Main {
4 public static void main(String[] args) {
Introdução à linguagem Java4
5 final double CAMBIO _ ATUAL = 5.4;
6 Scanner s = new Scanner(System.in);
7 System.out.println("Qual e o valor em dolar?");
8 double valorEmDolar = s.nextDouble();
9 double valorEmReal = valorEmDolar*CAMBIO _ ATUAL;
10 System.out.println("Valor em real: R$ "+valorEmReal);
11 }
12 }
A estrutura de um projeto em Java segue certa hierarquia. Primeiramente,
temos, é claro, o projeto. Dentro do projeto, temos pacotes (packages, em
inglês). Entenda pacote como se fosse uma pasta. Na pasta, podemos ter
subpastas ou arquivos de diferentes formatos. Um desses arquivo é chamado
de “classe”. Classe é uma abstração de algo que existe no mundo real, então
uma classe pode ser uma pessoa, um objeto ou parte de um objeto.
No código acima, a linha 1 identifica o pacote em que essa classe se
encontra. Na linha 3 está a declaração da
classe e seu nome, Main (o nome da classe tem que ser o mesmo nome do
arquivo). A classe sempre começará com letra maiúscula. Por quê? Convenção.
Na linha 4, temos um método (também chamado de função), muito especial
em Java. Um projeto Java pode ter dezenas, centenas, milhares de classes, mas
pelo uma delas deve conter esse método. Quando você executa um projeto
em Java, o que será executado é esse método.
Na linha 5, é declarada uma constante (variável que não se pode modi-
ficar seu valor depois de ele ter sido estabelecido) do tipo “double” (ponto
flutuante). Na linha 6, criamos um objeto de nome “s”, que tem a capacidade
de gerar “input” do usuário no sistema. Com ele, é possível receber valores
de usuários externos ao sistema.
Na linha 7, é impresso, na tela, “Qual é o valor em dólar?”, e, na linha 8,
recebemos, do usuário, um valor em ponto flutuante (valor decimal) e
colocamos em uma variável chamada de valorEmDolar. Nas linhas 13 e 14,
respectivamente, é feito o cálculo de conversão e ele é impresso na tela.
Note que toda linha de código termina em ponto e vírgula e que, nas
linhas 3 e 12, temos { abrindo o escopo da classe e } fechando esse escopo.
Assim como nas linhas 4 e 11, esses estão abrindo e fechando o escopo do
método Main.
Introdução à linguagem Java 5
Sintaxe da linguagem Java
Java é uma linguagem case sensitive, o que quer dizer que ela diferencia
caracteres maiúsculos de minúsculos. Logo, o nome Pedro é diferente de
PeDro em Java. Em todas as linguagens de programação, existem certas
convenções quanto à escrita do código, e elas devem ser seguidas. Ao longo
desta seção, explicaremos algumas delas. A seguir, você verá os elementos
básicos da linguagem Java.
Estrutura da linguagem Java
Existem elementos básicos na estrutura de um programa em Java: pacotes,
classes e importações. Os pacotes servem para você organizar suas classes,
e geralmente o nome dos pacotes tende a fazer referência a suas funcionali-
dades, como o pacote “persistência” pode se referir a um pacote com classes
que manipulam base de dados.
As classes são as unidades mais importantes. Cada classe deve realizar
tarefas especificas a seu propósito. Logo, se tenho uma classe chamada de
ContaBancaria, ela é uma abstração de uma conta bancária, então ela terá
saldo, número da conta, titular e tudo mais que faça sentido para ela. As impor-
tações são a maneira como temos de importar código de bibliotecas externas.
No código da seção anterior, por exemplo, importamos a classe Scanner do
pacote java.util, e essa classe nos permite receber entradas de usuários externos.
A classe tem um escopo que é delimitado por {}. As classes possuem
três coisas:
1. nome;
2. atributos;
3. métodos.
O nome da classe sempre começará com letra maiúscula (convenção),
como já comentamos. Os atributos, assim como o próprio nome sugere, são
os atributos daquela abstração que chamamos de classe. Então, se você tem
uma classe ContaBancaria, os atributos seriam: saldo, número da conta,
titular, tipo da conta (poupança, corrente), status (ativa, desativada), limite e
assim por diante.
Os métodos são as ações que a classe pode realizar. Em nossa classe
ContaBancaria, poderiam ser métodos dela: depositar, retirar,
transferir, visualizarSaldo, etc. Veja que métodos em Java começam
sempre com letras minúsculas, como já foi dito anteriormente.
Introdução à linguagem Java6
Comentários
Você pode inserir comentários em seu código. Comentários são muito bem-
-vindos, pois esclarecem o código para pessoas que o veem pela primeira
vez ou que realizarão sua manutenção. Os comentários em Java podem ser
feitos de duas maneiras: em uma linha ou em duas linhas. Veja:
// Isso é um comentário de apenas uma linha
Caso você queira comentar mais de uma linha, deverá usar assim:
/*
Várias linhas de comentário
são possíveis de fazer aqui
*/
É importante ressaltar que o comentário não deve ser feito de maneira
trivial: ele só deve ser inserido no código se consideramos que o código em
si não seja autoexplicativo. Mas lembre-se: o que é claro para você, talvez
não seja para outra pessoa.
Variáveis
Variáveis são endereços de memória onde você pode armazenar informações.
É claro que não vamos manipular endereços de memória, o que seria muito
trabalhoso. As linguagens de programação fornecem uma abstração para isso.
Há a possibilidade de dar um nome a esse endereço e atribuir a ele um tipo.
Logo, se declaro int numero=10;, isso quer dizer que estou declarando
uma variável chamada de numero do tipo inteiro e que está sendo atribuído
a ela o valor 10. Agora, quando quiser imprimir a variável numero, o Java vai
imprimir 10 (FINEGAN; LIGUORI, 2018).
Na seção anterior, vimos um código que possui uma variável especial,
chamada de constante. Esse tipo de variável não pode ser modificado
durante o programa. Nenhuma variável em Java pode começar com
número ou caracteres especiais, exceto underline. Variáveis em Java
começam sempre com letra minúscula, e caso haja um nome composto
por dois ou mais nomes, todos os outros nome, com exceção do primeiro,
virão com letra maiúscula (esse padrão é chamado de camelCase). Esse
padrão pode ser percebido na variável valorEmDolar, no código da
seção anterior.
Introdução à linguagem Java 7
Com relação a acentos, o Java aceita se você declarar uma variável
como você, por exemplo. Contudo, não é uma boa prática e deve
ser evitada.
Como pode ser percebido, as variáveis possuem um tipo. O tipo serve
para dizer ao computador qual é o domínio daquela variável, ou seja,
quais valores aquela variável pode assumir. O tipo também determina
qual faixa de valores a variável pode ter. No Quadro 1, você pode observar
os principais tipos primitivos da linguagem Java, sua faixa de valores e
seu tamanho.
Quadro 1. Tipos primitivos em Java
Tipo Descrição
Faixa
Menor Maior Tamanho
Int Valores
inteiros
–2.147.483648 2.147.483647 32 bits
Float Valores
com casas
decimais
–1.402E-37 3.40282347E+38 32 bits
Double Valores
com casas
decimais
–4.94E-307 1.79769313486231570E+308 64 bits
Char Um
caractere
0 65535 16 bits
Boolean Boleano False True 1 bit
Fonte: Adaptado de Caelum (c2020).
Observe que, se atribuirmos um valor a umavariável e esse valor estiver
fora da faixa, ocasionará um erro de compilação:
int numero = 21855002252;
Esse código não funcionará.
Introdução à linguagem Java8
Operadores aritméticos
Os operadores aritméticos em Java são + (adição), – (subtração), * (multiplica-
ção), / (divisão) e % (resto da divisão). Com relação a operações aritméticas,
é importante lembrar duas coisas. Vejamos.
1. Seus cálculos estão sob jurisdição das leis que regem a matemática e
a precedência das operações.
2. É importante verificar a compatibilidade de tipos antes de realizar
cálculos. Por exemplo: você não pode realizar uma conta de dividir
e colocar o resultado em uma variável inteira, pois, se houver casas
decimais, elas se perderão.
Caso você precise fazer uma conta do tipo int resultado = numero
/ outroNumero, onde numero é inteiro e outroNumero é double, você
pode fazer um “cast”. Casting é uma maneira de dizer ao compilador que
você sabe o que você está fazendo e que você só quer a parte inteira do
cálculo. Então como você faria? Simples: int resultado = (int) (nu-
mero / outroNumero). O que você está dizendo é: faça o cálculo e depois
me retorne somente a parte inteira da divisão. Assim, se o resultado do
cálculo é 13,254, a variável resultado só receberá 13 (HORSTMANN, 2009;
SCHILDT, 2015).
O operador + tem outra funcionalidade: concatenar um texto com
uma variável. Por exemplo: System.out.print(meu saldo é:
+saldo). Esse fenômeno é chamado de sobrecarga de operadores.
Palavras reservadas
No Quadro 2, você pode observar um conjunto de palavras que são reservadas
pela linguagem Java. Essas palavras, e ainda true, false e null, são
palavras que não podem ser usadas como nome de pacote, de classe, de
métodos ou de variáveis.
Introdução à linguagem Java 9
Quadro 2. Palavras reservadas na linguagem Java
abstract do import short volatile
assert double instanceof static while
boolean else int strictfp
break enum interface super
byte extends long switch
case final native synchronized
catch finally new this
char float package throw
class para private throws
const goto protected transient
continue if public try
default implements return void
Fonte: Adaptado de Perry (2010).
String
Como vimos anteriormente, temos vários tipos primitivos. Perceba que todos
eles começam com letra minúscula. “String” também é um tipo, só que não
primitivo: veja que ele começa com letra maiúscula e, em Java, isso quer dizer
que se trata de uma classe (HORSTMANN, 2009).
O tipo String é usado para estabelecer uma cadeia de caracteres (texto, se
preferir). Você a declara como uma variável qualquer (veja no exemplo abaixo).
Contudo, você não deve confundir a String “a” do char ‘a’. No primeiro, você
tem uma cadeia de caracteres com um caractere; no segundo, você tem um
caractere do tipo “char”.
Declarando uma String:
String texto = “eu gosto muito de programar”;
Por ser uma classe, String possui métodos, ou seja, ações que podem
ser realizadas porseu objeto. Existem diversos métodos úteis na classe
String. No Quadro 3, você pode ver alguns desses métodos. Na primeira
coluna, temos o nome do método; na segunda, um exemplo e, na terceira,
o que será impresso, com uma curta explicação entre parênteses. Você
Introdução à linguagem Java10
pode ver todos os métodos dessa classe na documentação oficial da
Oracle (ORACLE, c2020).
Quadro 3. Alguns métodos da classe String
Método Exemplo Saída
length() String texto="eu amo
java";
System.
out.println(texto.
length());
11 (tamanho da String;
inclui os espaços em
branco)
endsWith() String texto="eu amo
java"; System.
out.println(texto.
endsWith("java"));
System.out.
println(texto.
endsWith("jAva"));
true
false
(retorna true se a String
termina com o texto
mencionado. Perceba
que “java” é diferente de
“jAva”)
substring() String texto="eu amo
java";
System.out.
println(texto.
substring(0,6));
eu amo
(retorna uma parte da
String; nesse caso, da
posição zero [primeira
posição] até 6, inclui
espaços em branco)
toLower-
Case()
toUpper-
Case()
String texto="eu AMO
java";
System.out.
println(texto.toLower-
Case()); Sys-
tem.out.println(texto.
toUpperCase());
eu amo java
EU AMO JAVA
(a primeira retorna a
String em letras minúscu-
las, e a segunda retorna
em maiúsculas)
Neste capítulo, estudamos um pouco sobre a linguagem Java, sua estrutura,
seus elementos mais básicos, etc. Vimos os principais tipos primitivos da lingua-
gem e descobrimos que “String” não é um tipo primitivo, mas uma classe. Ainda,
aprendemos que devemos obedecer a certas convenções, porque isso leva a um
código limpo e fácil de manter. Estudamos, ainda, um pouco sobre a origem do
Java, sua história e seu caminho desde sua concepção até os dias de hoje.
A linguagem Java é muito rica em recursos e possui uma grande e ativa comuni-
dade. Participe de fóruns e de debates on-line sobre a linguagem e lembre-se: para
saber programar, é necessário praticar o máximo possível. Desenhe um projeto
e comece a desenvolver em Java, procurando os recursos de que você necessita.
Perseverança, curiosidade e foco são os três pilares de um bom programador.
Introdução à linguagem Java 11
Referências
CAELUM. Variáveis primitivas e controle de fluxo. c2020. Disponível em: https://www.
caelum.com.br/apostila-java-orientacao-objetos/variaveis-primitivas-e-controle-de-
-fluxo#casting-e-promocao. Acesso em: 4 jan. 2021.
ECLIPSE FOUNDATION. Eclipse IDE for Java developers. 2018. Disponível em: https://www.
eclipse.org/downloads/packages/release/oxygen/3a/eclipse-ide-java-developers.
Acesso em: 3 jan. 2021.
FINEGAN, E.; LIGUORI, R. OCA Java SE 8: guia de estudos para o exame 1Z0-808. Porto
Alegre: Bookman, 2018.
GUJ. Categorias. c2020. Disponível em: https://www.guj.com.br/. Acesso em: 3 jan. 2021.
HORSTMANN, C. Conceitos de computação com Java: compatível com Java 5 & 6. 5. ed.
Porto Alegre: Bookman, 2009.
JAVA. Por que aprender Java? c2020. Disponível em: https://www.javafree.org/. Acesso
em: 3 jan. 2021.
NETBEANS. Apache NetBeans. c2020. Disponível em: https://netbeans.org/. Acesso
em: 3 jan. 2021.
ORACLE. Java™ platform, standard edition 7: API specification. c2020. Disponível em:
https://docs.oracle.com/javase/7/docs/api/java/lang/String.html. Acesso em: 3 jan. 2021.
PERRY, J. S. Fundamentos da linguagem Java. 2010. Disponível em: https://developer.
ibm.com/br/tutorials/j-introtojava1/. Acesso em: 4 jan. 2021.
RENATO, S. Confira as 20 linguagens de programação mais populares do momento. 2020.
Disponível em: https://olhardigital.com.br/2020/03/03/pro/confira-as-20-linguagens-
-de-programacao-mais-populares-do-momento/. Acesso em: 3 jan. 2021.
SANTANA, P. SouJava, comunidades Java e o que você tem a ver com isso? 2020. Disponível
em: https://soujava.org.br/. Acesso em: 3 jan. 2021.
SCHILDT, H. Java para iniciantes: crie, compile e execute programas Java rapidamente.
6. ed. Porto Alegre: Bookman, 2015.
Leitura recomendada
GOODRICH, M. T.; TAMASSIA, R. Estrutura de dados e algoritmos com Java. 5. ed. Porto
Alegre: Bookman, 2013.
Os links para sites da web fornecidos neste capítulo foram todos
testados, e seu funcionamento foi comprovado no momento da
publicação do material. No entanto, a rede é extremamente dinâmica; suas
páginas estão constantemente mudando de local e conteúdo. Assim, os editores
declaram não ter qualquer responsabilidade sobre qualidade, precisão ou
integralidade das informações referidas em tais links.
Introdução à linguagem Java12
Dica do professor
Java é uma linguagem com uma comunidade muito ativa. Isso possibilita que você tenha acesso a
fóruns, repositório de códigos, eventos, e muito mais. Aprender uma linguagem de programação
envolve mergulhar em seu ecossistema.
Nesta Dica do Professor, você vai conhecer as comunidades Java formadas ao longo do tempo e
que oferecem muitos recursos e formas de se manter atualizado nos estudos da linguagem.
Aponte a câmera parao código e acesse o link do conteúdo ou clique no código para acessar.
https://fast.player.liquidplatform.com/pApiv2/embed/cee29914fad5b594d8f5918df1e801fd/def351b3511dc9ea46cd82eaa0d89ce0
Saiba +
Para ampliar o seu conhecimento a respeito desse assunto, veja abaixo as sugestões do professor:
Classes e objetos
Assista neste vídeo os conceitos básicos de classes e objetos, além dos pilares da Programação
Orientada a Objetos.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Seja reconhecido como um líder do setor
Neste site, você poderá obter todas as informações necessárias caso deseje fazer um certificado
Java. Certificações são importantes para o mercado de trabalho. Elas atestam que você domina
aquela tecnologia.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Java para iniciantes - Crie, compile e execute programas Java
rapidamente
Esta obra, de Herbert Schildt, é um excelente ponto de partida para quem está começando sua
jornada em programação Java. O livro começa do zero e avança de forma didática e legível.
Conteúdo interativo disponível na plataforma de ensino!
https://www.youtube.com/embed/GHLFEhdk7Ys
https://www.oracle.com/br/corporate/features/oracle-certification.html
Modularização em Java
Apresentação
A estruturação de um código-fonte com a possibilidade de reutilização de blocos de comandos em
diferentes pontos é uma estratégia amplamente usada no desenvolvimento de sistemas Java. O
conceito que dá suporte a esse tipo de estratégia é o de modularização. À medida que um software
vai crescendo em tamanho e incorporando um número cada vez maior de funcionalidades, essa
abordagem de construção baseada em módulos se torna ainda mais essencial.
Nesta Unidade de Aprendizagem, você vai aprender como o conceito de modularização pode ser
implementado por meio da definição de métodos em classes Java. Vai conhecer como é possível
efetuar a troca de dados entre objetos em diferentes trechos de código. Além disso, vários
exemplos serão demonstrados para dar uma visão mais prática desses conceitos.
Bons estudos.
Ao final desta Unidade de Aprendizagem, você deve apresentar os seguintes aprendizados:
Conceituar modularização em Java.•
Explicar a estrutura de código dos métodos em Java. •
Aplicar métodos em Java na modularização de programas. •
Infográfico
A utilização correta de métodos em Java depende de um entendimento sólido sobre como o fluxo
de execução acontece entre uma chamada de método e o fim de suas operações. Além disso,
compreender como parâmetros são processados e como novos valores computados são devolvidos
é parte essencial da construção de um código preciso.
Neste Infográfico, você terá uma visão detalhada de como um programa Java realiza chamadas a
métodos e como se dá essa interação entre os diferentes pontos de um código-fonte.
Aponte a câmera para o
código e acesse o link do
conteúdo ou clique no
código para acessar.
https://statics-marketplace.plataforma.grupoa.education/sagah/1d57ae31-b14a-4f9c-8ff8-1f7a48a725a9/e717aeda-d7c8-4185-9a53-0093b5e59a36.png
Conteúdo do livro
Organizar um código-fonte de maneira a viabilizar o seu reúso é relevante para a qualidade de
qualquer sistema. À medida que um software vai agregando mais funcionalidades e contemplando
mais requisitos de um domínio de problema, o conceito de modularização se mostra ainda mais
crítico.
No capítulo Modularização em Java, base teórica desta Unidade de Aprendizagem, você vai
conhecer como a noção de módulos pode ser implementada pela definição de métodos. A interação
entre diferentes trechos de código será detalhada por meio dos mecanismos de passagem de
parâmetros, retorno de valores e escopo de variáveis. Finalmente, vários exemplos práticos serão
apresentados para dar uma visão ainda mais programática de como todos esses conceitos podem
ser implementados em Java.
Boa leitura.
ESTRUTURA DE
DADOS EM JAVA
OBJETIVOS DE APRENDIZAGEM
> Conceituar modularização em Java.
> Explicar a estrutura de código dos métodos em Java.
> Aplicar métodos em Java na modularização de programas.
Introdução
A organização de um código-fonte em blocos que possam ser reaproveitados e
melhor testados pode ser relevante para a garantia da qualidade de um software.
Como diferentes níveis de agrupamentos podem ser feitos em Java, ter domínio
dos conceitos relacionados à modularização de código é essencial para explorar
as potencialidades da linguagem nesse aspecto.
Neste capítulo, você aprenderá como implementar métodos em Java e como
esses métodos podem ser empregados na modularização de código. Também
conhecerá o funcionamento dos mecanismos de passagens de parâmetros, retorno
de dados e escopo de variáveis, que são essenciais para um uso preciso desses
blocos de código. Além disso, serão apresentados exemplos práticos de como
todos esses conceitos podem ser usados em conjunto na linguagem Java.
O que é modularização em Java?
A construção de estruturas de dados e algoritmos requer que instruções
detalhadas sejam comunicadas ao computador. Uma maneira precisa de
Modularização
em Java
Thiago Nascimento Rodrigues
efetuar esse tipo de comunicação é por meio do uso de uma linguagem de
programação de alto nível, como Java. Em Java, os atores primários de qual-
quer operação são chamados de objetos. Todo objeto corresponde a uma
instância de uma classe, a qual serve como tipo para um objeto e funciona
como modelo ou projeto de objetos. Na prática, classes correspondem à
estrutura mais fundamental de qualquer programa Java. Em uma classe,
são definidos os tipos de dados que serão armazenados em um objeto, bem
como os métodos para acessar e modificar esses dados. Sob a perspectiva do
conceito de modularização, classes e métodos correspondem à maneira mais
básica de se dividir um programa Java em componentes ou subprogramas.
Os principais membros ou componentes de uma classe Java são (GOODRICH;
TAMASSIA; GOLDWASSER, 2014, tradução nossa):
Variáveis de instância (atributos) — Também chamadas de campos, elas
representam os dados associados a um objeto de uma classe. Variáveis de
instância precisam ter um tipo, o qual pode ser primitivo, como int, float
ou double, ou pode ser de um tipo definido por uma classe.
Métodos (operações) — São blocos de código que podem ser invocados para a
execução das operações neles definidas. Um método pode aceitar parâmetros
como argumentos, e seu comportamento pode depender tanto do objeto a
partir do qual ele é chamado como dos valores dos parâmetros passados
para ele.
Em Java, um novo objeto é criado através do comando new seguido da
chamada do método construtor da classe desejada. O operador new retorna
uma referência para a nova instância criada, e esta é atribuída, em geral, a uma
variável para uso posterior. Os construtores são métodos usados para iniciar
objetos durante sua instanciação. O código a seguir apresenta, primeiramente,
a definição de uma classe Contador e seu respectivo método construtor. Em
seguida, há um exemplo de definição de uma variável contador e a criação
de um objeto do tipo Contador através do comando new. Observa-se que
a declaração da variável cont como do tipo Contador não cria, de modo
automático, uma instância de Contador. Isso porque classes são conheci-
das também como referências em Java, e uma variável desse tipo (como a
variável cont no código a seguir) é conhecida como variável de referência.
Uma variável de referência é capaz de armazenar a localização (endereço na
memória) de um objeto da classe declarada. Nesse caso, é possível atribuir
à variável uma referência a uma instância já existente ou a uma instância
recém construída. Uma variável de referência pode também armazenar um
valor especial, null, que representa a ausência de um objeto. A Figura 1
Modularização em Java2
ilustra o relacionamento entre objetos e variáveis de referência. A atribuição
deuma referência a um objeto, ou seja, de seu endereço na memória a uma
variável, pode ser comparada ao armazenamento de um controle remoto do
objeto à variável.
public class Contador {
public Contador() {
}
}
Contador cont;
cont = new Contador();
Figura 1. Relação entre objetos e variáveis de referência a objetos.
Fonte: Adaptada de Goodrich, Tamassia e Goldwasser (2014, tradução nossa).
Além de construtores, uma classe pode receber a definição de quantos
métodos forem necessários. Para fins de exemplificação, será considerada a
mesma classe Contador apresentada anteriormente, porém acrescida de dois
Modularização em Java 3
novos métodos. O método incrementar faz com que a variável de instância
valor tenha seu valor incrementado de 1 (um). Já o método reiniciar retorna
o valor da variável para zero.
public class Contador {
private int valor;
public Contador() {
}
public void incrementar {
valor++;
}
public void reiniciar() {
valor = 0;
}
}
Um dos usos primários de uma variável que detém a referência a um
objeto é ter acesso às variáveis de instância e aos métodos daquele
objeto. Esse acesso é realizado por meio do operador ponto (“.”). A chamada a um
método associado a um objeto é feita usando o nome da variável de referência
seguido pelo do operador ponto e pelo nome do método e seus parâmetros
(se houver). Por exemplo, no código da classe TesteContador, o método
reiniciar foi invocado na linha sete com a chamada cont.reiniciar().
Para descrever como a classe Contador e seus respectivos métodos podem
ser invocados, será definida outra classe — TesteContador —, onde todas
essas operações serão realizadas. Para isso, a classe deve conter um método
especial em Java chamado main, o qual funciona como ponto de entrada para o
Modularização em Java4
programa. A partir desse método é que o interpretador Java começa a executar.
No primeiro comando, uma variável cont do tipo Contador é declarada. Em
seguida, uma instância da classe Contador é criada, e sua referência é atribuída
à variável cont. Os dois próximos comandos realizam a chamada do método
incrementar. Como a variável de instância valor do objeto Contador tem
valor inicial zero, após as duas invocações do método incrementar, seu novo
valor será de 2 (dois). O último comando faz a chamada ao método reiniciar,
que retorna a variável valor para o seu estado inicial com valor zero.
1. public class TesteContador {
2. public static void main(String[] args) {
3. Contador cont;
4. cont = new Contador();
5. cont.incrementar();
6. cont.incrementar();
7. cont.reiniciar();
8. }
9. }
Outro nível de modularização em Java está relacionado ao conceito
de pacotes. Um pacote é uma coleção de classes, interfaces e outras
estruturas Java. Um pacote serve para agrupar classes relacionadas e define um
espaço de nomes para as classes que ele contém. A nomeação de pacotes em
Java segue a convenção de serem escritos em letras minúsculas. Outra conven-
ção é o uso invertido do domínio de internet de uma organização para iniciar
os nomes de pacotes Java (THE JAVATM..., 2020, tradução nossa). Por exemplo,
br.com.sagah poderia ser usado para nomear pacotes Java da empresa Sagah.
Métodos em Java
Nos exemplos vistos até o momento, a definição do corpo de um método (o
que o método faz) ficou evidenciada por chaves — “{“ inicia o corpo do método
e “}” fecha o corpo. Contudo, além do corpo, outro componente que integra
Modularização em Java 5
a especificação de um método é a sua assinatura. Os elementos que podem
compor a assinatura de um método são listados a seguir (EVANS; FLANAGAN,
2014, tradução nossa).
� O nome do método (obrigatório).
� Uma lista, entre parênteses, de nomes e respectivos tipos de parâmetros
usados pelo método. Cada parâmetro composto pelo par tipo-nome deve
aparecer separado por vírgulas. No caso de não serem esperados parâme-
tros, o nome do método deve ser seguido de um par de parênteses vazio “()”.
� O tipo do valor retornado pelo método. No caso de nenhum valor ser
retornado, o tipo void deve ser informado. Uma exceção são os métodos
construtores que constituem o único tipo de método sem retorno explícito.
� As exceções que podem ser lançadas pelo método.
� Os modificadores de método que podem prover informação adicional
a respeito dele.
Diferentemente de outras linguagens, Java não dá suporte à definição
de métodos anônimos. Em vez disso, na versão 8 da linguagem, foram
introduzidas as expressões lambda, que funcionam de maneira análoga a
métodos anônimos. Entretanto, em tempo de execução, o Java converte automa-
ticamente expressões lambda para um método com algum nome conveniente.
Com o uso desses elementos, a especificação da assinatura de um método
Java tem a seguinte estrutura:
modificadores tipo nome (lista de parâmetros) [throws
exceptions]
Os modificadores de um método consistem em palavras-chave que agre-
gam mais informações acerca do funcionamento do método. Os modificadores
de controle de acesso são um tipo de modificador responsável por delimitar
a visibilidade de um método para componentes externos à classe que ele
pertence. Existem três modificadores desse tipo:
� public: permite que o método possa ser chamado por qualquer classe;
� private: restringe a invocação do método ao interior da própria classe
onde está definido;
� protected: permite que o método possa ser chamado tanto por sub-
classes da classe em que está definido como por classes que pertencem
ao mesmo pacote.
Modularização em Java6
Quando nenhum modificador de controle de acesso é explicitado
na assinatura de um método, um modificador implícito conhecido
como padrão é assumido pela máquina virtual Java. Esse modificador limita
a invocação de um método apenas às classes que estão definidas no mesmo
pacote da classe que ele pertence. Diferentemente do modificador protected,
subclasses não têm acesso ao método.
Outros dois tipos de modificadores podem ser encontrados na assina-
tura de um método. O modificador abstract indica que o método não tem
implementação, ou seja, o método é desprovido de corpo. Uma classe que
contém, pelo menos, um método desprovido de implementação também deve
receber o modificador abstract. Um terceiro tipo de modificador é o final.
Ele é essencialmente empregado em conformidade com os princípios da pro-
gramação orientada a objetos. Seu uso impossibilita, em uma classe, que ela
seja estendida e, em um método, que ele seja sobrescrito. Outro modificador
comumente encontrado é o static. Ele indica que o método está associado
diretamente à classe onde está definido, e não a uma instância (objeto) da
classe (SEDGEWICK; WAYNE, 2011, tradução nossa). Um tradicional método
definido com o modificador static é o método main, como apresentado
previamente na classe TesteContador.
Quando um método é chamado, podem ser passados para ele valores
chamados de argumentos. Os métodos executam alguma computação e,
opcionalmente, também podem devolver algum valor. Todos os parâmetros
em Java são passados por valor, ou seja, sempre que um parâmetro é passado
para um método, uma cópia do parâmetro é feita para uso no corpo do método.
Por exemplo, se um valor do tipo int for informado como parâmetro, o valor
da variável inteira é copiado e passado ao método. Nesse caso, o método é
capaz de alterar o valor copiado e não o valor original. O mesmo acontece
se o tipo do parâmetro passado for uma referência a um objeto. Será criada
uma cópia da referência original, e a cópia será informada ao método.
Considerando a classe Contador já apresentada, os dois métodos a seguir
ilustram o funcionamento do mecanismo de passagem de parâmetros em Java.
O método reiniciarSemEfeito recebe um parâmetro do tipo Contador,
o qual armazena uma referência a uma instância de Contador. Contudo, no
corpo do método, um novo valor (referência) é atribuído à variável cont. Como
se trata de uma nova instância, e