• Nenhum resultado encontrado

Capítulo 1 CONCEITOS BÁSICOS DA CIÊNCIA DA COMPUTAÇÃO 1. INTRODUÇÃO

N/A
N/A
Protected

Academic year: 2021

Share "Capítulo 1 CONCEITOS BÁSICOS DA CIÊNCIA DA COMPUTAÇÃO 1. INTRODUÇÃO"

Copied!
14
0
0

Texto

(1)

Capítulo 1

CONCEITOS BÁSICOS DA CIÊNCIA DA COMPUTAÇÃO

1. INTRODUÇÃO

A Ciência da Computação engloba toda atividade relacionada ao desenvolvimento

e uso dos computadores que permitam aprimorar e automatizar tarefas em qualquer área de atuação da sociedade.

O profissional de Ciência da Computação vai atuar basicamente no desenvolvimento do que se pode chamar de um Sistema Computacional, o qual abrangem a combinação de hardware (circuitos), software (programas) e outros elementos essenciais.

A crescente evolução na área de Computação, particularmente no que diz respeito ao desenvolvimento de equipamentos de informática (processadores cada vez mais velozes, o surgimento de novas tecnologias de armazenamento de dados e novos periféricos), aliada às constantes quedas nos preços do hardware, possibilitou um avanço das atividades relacionadas à Ciência da Computação na quase totalidade das atividades humanas, iniciando pelas Engenharias e atingindo as mais diversas áreas como a Medicina, as Artes, o Entretenimento, a Economia, etc.

Como conseqüência disto, é real a necessidade de que em cada área, os profissionais desenvolvam um conhecimento da tecnologia de Informática que seja útil na solução dos problemas relacionados com o seu eixo profissional.

Neste capítulo inicial, serão apresentados os conceitos básicos da Ciência da Computação, partindo dos principais conceitos relacionados às arquiteturas de computadores até introduzir os primeiros aspectos relativos à programação e das linguagens utilizadas na programação de computadores.

2. AS ARQUITETURAS DE COMPUTADORES

Como foi mencionado na introdução deste capítulo, tem-se observado, uma atuação cada vez maior dos computadores nas diversas atividades do nosso dia a dia.

As operações bancárias, as telecomunicações e o manuseio de muitos aparelhos eletrodomésticos são exemplos claros das facilidades trazidas pela utilização dos computadores, isto sem falar em aplicações mais clássicas, como os sistemas de reservas de passagens aéreas e a previsão meteorológica.

A evolução da informática foi caracterizada pelo desenvolvimento de computadores com características as mais diversas, traduzidas pelos diferentes parâmetros, cada vez mais conhecidos da maioria de usuários de computador: a CPU adotada, a capacidade de memória, a capacidade do disco rígido, a existência de memória cache e outros menos votados.

(2)

2.1. Evolução histórica das arquiteturas de computador

Os primórdios da computação

A história dos computadores começou no momento em que o homem sentiu a necessidade de efetuar cálculos complexos de maneira automática. Os primeiros computadores, ou de geração zero, apareceram no século XVII e eram compostos exclusivamente por elementos mecânicos. Além disso, caracterizavam-se por uma grande rigidez no que diz respeito aos programas a executar, a grande parte delas sendo o que se chama hoje de máquinas dedicadas.

Dos trabalhos conhecidos deste período, destaca-se o trabalho de Blaise Pascal, que em 1642 desenvolveu uma máquina de calcular totalmente mecânica. A máquina era baseada na existência de um disco para cada potência de 10, cada disco sendo dotado de 10 dígitos (de 0 a 9). Embora fosse capaz de realizar apenas adições e subtrações, outras operações, como multiplicações e divisões podiam ser realizadas através da combinação das primeiras.

Já no final do século XVIII, Charles Babbage, um matemático e engenheiro britânico, construiu uma máquina — a máquina de diferenças — capaz de calcular tabelas matemáticas. Do mesmo modo que a “calculadora” de Pascal, ela era baseada na existência de discos mecânicos e acionada através de uma manivela. Muitos dos projetos deste engenheiro acabaram não saindo do papel ou não foram terminados, as principais razões para isto tendo sido a falta de financiamento e a ineficiência da indústria da época, incapaz de produzir as peças mecânicas com a precisão necessária ao funcionamento daquelas máquinas.

Em 1880, surge um outro personagem importante na história das arquiteturas de computadores. Foi Herman Hollerith, que concebeu a idéia de processar dados a partir de cartões perfurados (o problema a resolver era a computação de dados do censo dos Estados Unidos). Com esta solução, Hollerith conseguiu que o tempo de processamento dos dados do censo baixasse de 8 para 3 anos. A tecnologia de cartões perfurados foi adotada rapidamente por diversos países da Europa, difundindo a utilização das máquinas Hollerith a nível mundial e por bastante tempo. Dez anos mais tarde, Hollerith fundou uma companhia, a Tabulating Machine Company que passaria a fazer parte da IBM e deixou seu marco na história tendo seu nome associado à tecnologia de cartões perfurados até os dias de hoje.

As máquinas de primeira geração (1930-1950)

Já no século XX, um grande número de projetos foram implementados, baseados na utilização de relés e válvulas eletrônicas para a realização de cálculos automaticamente — eram os computadores de primeira geração.

Destacam-se, deste período, os computadores construídos pela Bell Telephone Laboratories — os computadores Bell a relé. Uma das grandes vantagens das máquinas a relé sobre as máquinas de calcular mecânicas era, sem dúvida, a maior velocidade de processamento. Ainda, um outro aspecto positivo era a possibilidade de funcionamento contínuo, apresentando poucos erros de cálculo e pequeno tempo de manutenção.

Outro resultado conhecido é o Mark I, máquina construída durante a II Guerra Mundial, baseada em relés, capaz de executar um conjunto de operações aritméticas sob o controle de uma seqüência codificada de instruções. Com o apoio da IBM e da Marinha dos Estados Unidos, Howard Aiken, o pesquisador que desenvolveu Mark I, construiu outras versões deste computador (Mark II a Mark IV).

(3)

potência de 150 Kwatts, ocupando uma área de 1400 m2 e pesando 30 toneladas. A entrada de dados no ENIAC era baseada na tecnologia de cartões perfurados e os programas eram modificados através de reconfigurações no circuito. Apesar das dúvidas com relação à sua confiabilidade, o ENIAC permaneceu operacional por mais de 10 anos.

Outra contribuição importante desta época foi o conceito de programa armazenado, introduzida por John Von Neuman. Von Neuman tinha sido consultor no projeto ENIAC e conhecia os problemas da programação destas máquinas. Os programas para os computadores da época eram feitos através de modificações nos circuitos, o correspondia a um trabalho de dias para um programa relativamente simples. A proposta de Von Neuman foi inspirada na tecnologia de entrada de dados utilizada na época, fazendo com que os programas fossem introduzidos através de cartões perfurados como se fazia com os dados. Este conceito, que é adotado nos computadores atuais, revolucionou o conceito de programação de computadores da época, tornando muito mais flexíveis e versáteis.

O novo conceito de programação introduzido por Von Neuman deu origem a muitos outros projetos nos quais ele próprio esteve envolvido, como por exemplo o EDVAC (Electronic Discrete Variable Automatic Computer) e o UNIVAC (Universal Automatic Computer), que foi o primeiro computador a ser fabricado em linha. Juntamente com o ENIAC, ocorreu também o desenvolvimento na área de periféricos de computador com o aparecimento de equipamentos tais como as unidades de fita magnética, impressoras, etc...

Computadores de segunda geração (1955-1965) — o transistor

Com a invenção do transistor em 1948, o mundo dos computadores é tomado de assalto por uma onda de novos projetos que dá origem, na década de 60 a empresas hoje mundialmente conhecidas no que diz respeito à fabricação destas máquinas — DEC e IBM

Um dos computadores mais comercializados nesta época foi o IBM 7090, que eram comercializados a um custo de três milhões de dólares. Já no início dos anos 60, a IBM passou a produzir os computadores da linha IBM 7040, que eram menos poderosos que seus predecessores, mas de custo bastante inferior.

Computadores de terceira geração (1965-1980) — os circuitos integrados

A tecnologia dos circuitos integrados, que permitiu a substituição de dezenas de transistores numa única peça de silício, permitiu o surgimento de computadores de menores dimensões, mais rápidos e menos caros. Uma máquina típica desta época é o IBM-360, do qual era equipado há alguns anos atrás o Núcleo de Processamento de Dados da UFSC. Um aspecto interessante desta linha de computadores era a sua modularidade, uma vez que sua configuração podia ir sendo modificada em função das necessidades e possibilidades de investimento. Esta estratégia permitiu que a IBM se posicionasse, já neste período, como líder do mercado de computadores. Outra novidade introduzida por esta classe de computadores foi o conceito de multiprogramação, na qual diversos programas poderiam estar residentes na memória da máquina. No caso em que um programa entrasse em espera para uma operação de entrada/saída de dados, a unidade central passava a executar a parte de um outro programa. Um outro computador desta geração que conheceu grande sucesso, particularmente nas universidades e centros de pesquisa foram os minicomputadores da série PDP-11 (DEC).

Computadores de quarta geração (1980 - ...) — integração em larga escala (VLSI)

Os anos 80, com o grande desenvolvimento da tecnologia de circuitos integrados, o número de transistores podendo ser integrados numa pastilha de silício atingiu a faixa dos milhares e, logo em seguida, dos milhões. Foi assim que surgiram os novos computadores, ainda menores, mais velozes e mais poderosos que aqueles da geração anterior.

(4)

era da informática pessoal. Os computadores pessoais passaram então a ser utilizados de uma maneira relativamente distinta dos grandes computadores de então.

Eles são utilizados para tratamento de texto, cálculos auxiliados por planilhas eletrônicas e outras atividades altamente interativas para as quais os grandes computadores não eram bem adaptados.

Atualmente, as famílias de computadores podem ser classificadas em 5 grupos distintos: os computadores pessoais (PCs), os minicomputadores, os superminicomputadores, os computadores de grande porte (mainframes) e os supercomputadores. A tabela a seguir dá um exemplo das máquinas comerciais que se enquadram nestes grupos e as suas aplicações típicas.

GRUPO MIPS MB MÁQUINA APLICAÇÃO

Computador pessoal 2 8 IBM Pentium Tratamento de texto

Minicomputador 4 32 PDP-11/84 Tempo real

Supermini 20 64 Sun SPARC Pesquisa, serv. arquivos Mainframes 60 512 IBM 3090/300 Banco, Universidade

Supercomputador 125 2048 Cray-2 Cálculo

2.2. Componentes básicos de um computador

Apesar da existência de uma grande diversidade em termos de arquiteturas de computador, como os exemplos mostrados na tabela acima, pode-se enumerar, num ponto de vista mais genérico os componentes básicos desta classe de equipamentos.

A figura 1.1 apresenta um esquema de um computador, destacando os elementos que o compõem. Apesar da grande evolução ocorrida na área de informática desde o aparecimento dos primeiros computador, o esquema apresentado na figura pode ser utilizado tanto para descrever um sistema computacional atual como os computadores da década de 40, projetados por engenheiros como John Von Neuman.

Os parágrafos que seguem apresentam os componentes principais de um computador genérico.

A Unidade Lógica e Aritmética

O primeiro componente essencial num computador (ou sistema computacional) é a

Unidade Lógica e Aritmética (ALU), a qual, como o próprio nome indica, assume todas as

tarefas relacionadas às operações lógicas (ou, e, negação, etc.) e aritméticas (adições, subtrações, etc...) a serem realizadas no contexto de uma tarefa realizada através dos computadores.

Neste contexto, é importante observar a evolução que este elemento sofreu ao longo dos anos e quais são os parâmetros a ele associados que influenciam no desempenho global de um sistema computacional.

Um parâmetro importante é o tamanho da palavra processada pela unidade lógica e aritmética, lembrando que o sistema de numeração adotado nas arquiteturas de computadores é o binário, o qual tem como unidade básica de informação o bit, que pode assumir os valores 0 ou 1. Quanto maior o tamanho da palavra manipulada pelo microprocessador, maior é o seu potencial de cálculo e maior a precisão das operações realizadas.

As primeiras CPUs integradas num único chip, como por exemplo, o 4004 fabricado pela Intel em 1968 manipulava palavras (dados e instruções) expressas por 4 dígitos binários. Os microprocessadores mais recentes são capazes de manipular palavras entre 32 bits (caso dos 486) e 64 bits (Pentium e Power PC).

(5)

A velocidade de cálculo está diretamente relacionada com a freqüência do relógio que pilota o circuito da CPU como um todo. Nos últimos 15 anos, a velocidade de cálculo dos processadores aumentou em aproximadamente 20 vezes, o que é uma evolução considerável.

Ainda relacionada com a ALU, é possível destacar a quantidade de operações que ela suporta. Os primeiros processadores suportavam um conjunto relativamente modesto de operações lógicas e aritméticas. Em particular, no que diz respeito às operações aritméticas, os primeiros processadores suportavam apenas operações de adição e subtração, sendo que as demais operações tinham de ser implementadas através de seqüências destas operações básicas. Os processadores suportando um conjunto mais complexo de instruções surgiu de 15 anos para cá, graças à adoção da tecnologia CISC (Complex Instruction Set Computer).

A Memória

Todo computador é dotado de uma quantidade (que pode variar de máquina para máquina) de memória a qual se constitui de um conjunto de circuitos capazes de armazenar (temporariamente ou por longos períodos de tempo) as unidades de dados e os programas a serem executados pela máquina. Nos computadores de uso geral, é possível encontrar diferentes denominações para as diferentes categorias de memória que neles são encontradas:

• a memória principal, ou memória de trabalho, onde normalmente devem estar armazenados os programas e dados a serem manipulados pelo processador; • a memória secundária que permitem armazenar uma maior quantidade de dados

e instruções por um período de tempo mais longo; os discos rígidos são exemplo mais evidentes de memória secundária de um computador, mas podem ser citados outros dispositivos menos recentes como as unidades de fita magnética e os cartões perfurados introduzidos por Hollerith;

• a memória cache, conceito introduzido mais recentemente e que se constitui de uma pequena porção de memória com curto tempo de resposta, normalmente integrada aos processadores e que permite incrementar o desempenho durante a realização de um programa.

Os circuitos de memória são normalmente subdivididos em pequenas unidades de armazenamento denominadas palavras.

Memória Unidade de Controle Unidade Lógica e Aritmética Entrada Saída

(6)

Cada palavra é identificada no circuito por um endereço único, o qual vai ser referenciado pelo processador no momento de consultar ou alterar o seu conteúdo. Historicamente, cada palavra de memória permitia armazenar 8 dígitos binários (ou bits), o que introduziu o conceito de byte como sendo uma palavra de 8 bits, unidade até hoje utilizada para medir a capacidade de armazenamento das memórias e o tamanho dos programas.

As quantidades de memória hoje são definidas em termos de Kbytes (quilobytes) que correspondem a 1024 bytes ou (210 bytes) e Mbytes (megabytes), que correspondem a 1024 Kbytes ou (220 bytes).

Dispositivos de entrada/saída

Conhecidos também como I/O (de Input/Output), são os elementos que possibilitam a troca de dados entre o computador e o seu ambiente (usuário, periféricos, outros equipamentos). Os periféricos mais utilizados nos computadores de uso geral são o teclado, o mouse, as impressoras, o monitor de vídeo, etc... Os circuitos que possibilitam a troca de dados com o ambiente externo ao computador são conhecidas sob o nome de portas de E/S, as quais podem implementar a transmissão das palavras de dados segundo duas diferentes políticas:

• a comunicação paralela, onde cada dígito (ou bit) da palavra de dados é conduzido por um fio dedicado, o que significa que os cabos utilizados para a comunicação paralela são dotados de uma grande quantidade de fios (ou vias); o exemplo mais clássico de dispositivos que utilizam a comunicação paralela são as impressoras;

• a comunicação serial, onde os bits de cada palavra são transmitidos um a um, de forma seqüencial, através de uma única via, o que explica o fato dos cabos que implementam este tipo de comunicação serem constituídos por uma pequena quantidade de fios; os exemplos mais conhecidos de dispositivos que fazem uso desta política de comunicação são o mouse e os modems.

Unidade de Controle

Este último componente de um sistema computacional tem, sem dúvida alguma, a maior importância na operação de um computador, uma vez que é esta unidade quem assume toda a tarefa de controle das ações a serem realizadas pelo computador, comandando todos os demais componentes de sua arquitetura. É este elemento quem deve garantir a correta execução dos programas e a utilização dos dados corretos nas operações que as manipulam. É a unidade de controle quem gerencia todos os eventos associados à operação do computador, particularmente as chamadas interrupções, tão utilizadas nos sistemas há muito tempo.

Apesar de descritas separadamente, é impossível isolar a unidade de controle da unidade lógica e aritmética, uma vez que elas são implementadas num circuito único conhecido sob a sigla de CPU (Central Processing Unit) ou por Unidade Central de Processamento, Microprocessador ou, simplesmente, Processador.

3. A PROGRAMAÇÃO DE COMPUTADORES

(7)

Como foi apresentado na introdução deste capítulo, um Sistema Computacional pode ser visto como uma associação entre dois conceitos cada vez mais utilizados na terminologia de informática:

• o hardware, que está associado à parte física do sistema (os circuitos e dispositivos) que suporta o processamento da informação;

• o software, que corresponde ao conjunto de programas responsáveis pela pilotagem do sistema para a execução das tarefas consideradas.

No que diz respeito a esta segunda classe de componentes, pode-se estabelecer uma classificação segundo o tipo de serviço por ele realizado. Assim, tem-se as seguintes definições:

• o software de sistema (ou sistema operacional) capaz de oferecer ao usuário facilidades de acesso aos recursos do computador, seja através de comandos, seja através de serviços especiais ativados a nível de um programa;

• o software utilitário, que podem ser programas desenvolvidos por especialistas ou mesmo por usuários experimentados que tem por objetivo facilitar a realização de determinadas atividades correntes no uso dos computadores (detecção e eliminação de vírus, programas de comunicação em redes de computadores, compressão de arquivos, etc...);

• o software aplicativo, que são os programas desenvolvidos ou adquiridos pelos usuários para algum fim específico, seja ele de natureza profissional, educacional ou mesmo de lazer (games).

Independente da classe em que está definido, um programa consiste de uma organização de operações a serem realizadas pelo Sistema Computacional para a realização de uma dada atividade. As operações a serem realizadas no contexto do programa são expressas a partir de um conjunto limitado de comandos, eventualmente acompanhados de referências a dados, aos quais definiremos como sendo as instruções.

3.1. Linguagens de Programação

Informalmente, uma linguagem de programação pode ser definida como sendo um conjunto limitado de instruções, associado a um conjunto de regras que define como as instruções podem ser associadas, ou seja, como se pode compor os programas para a resolução de um determinado problema. Ao longo dos anos, foram desenvolvidas (e continuam sendo) uma grande quantidade de linguagens de programação, algumas de uso mais geral e outras concebidas para áreas de aplicação específicas. Os parágrafos que seguem discutirão os principais aspectos de algumas destas linguagens.

Linguagens de Máquina e Assembly

(8)

Por uma questão de custo a nível do hardware, as operações representadas pelas instruções de linguagem de máquina são bastante elementares, como por exemplo, a transferência de dados entre memória e registro da CPU, a adição de dois valores, o teste de igualdade entre dois valores, etc...

Embora seja a linguagem diretamente executável pelos processadores, a programação de aplicações diretamente em linguagem de máquina é impraticável. Por esta razão, a linguagem de máquina de cada processador é acompanhada de uma versão “legível” da linguagem de máquina que é a chamada linguagem Assembly.

As instruções de Assembly fazem uso de palavras abreviadas (denominadas mnemônicos) que indicam a operação realizada por uma dada instrução. Alguns exemplos são mostrados na tabela a seguir:

INSTRUÇÃO SIGNIFICADO MOV R1,R2 Copia (move) o conteúdo de R2 para R1

ADD R1,R2 Adiciona (add) os conteúdos de R1 e R2 JMP 01 Salta (jump) para a posição 01 do programa CMP 00 Testa (compare) se um valor é igual a zero

Apesar de oferecer uma representação mais próxima do que o programador está acostumado a manipular, a linguagem Assembly apresenta certas dificuldades para a realização dos programas, tais como a necessidade de definição de um conjunto relativamente grande de instruções para a realização de tarefas que seriam relativamente simples (se representadas através de outras linguagens) e a exigência do conhecimento de detalhes do hardware do sistema (arquitetura interna do processador, endereços e modos de operação de dispositivos de hardware, etc...).

Por outro lado, a utilização da linguagem Assembly proporciona um maior controle sobre os recursos do computador, permitindo também obter-se bons resultados em termos de otimização de código

Linguagens de alto nível

As linguagens de alto nível são assim denominadas por apresentarem uma sintaxe mais próxima da linguagem natural, fazendo uso de palavras reservadas extraídas do vocabulário corrente (como READ, WRITE, TYPE, etc...) e permitirem a manipulação dos dados nas mais diversas formas (números inteiros, reais, vetores, listas, etc...).

As linguagens de alto nível ou de segunda geração surgiram entre o final da década de 50 e início dos anos 60. Linguagens como Fortran, Cobol, Algol e Basic, com todas as deficiências que se pode apontar atualmente, foram linguagens que marcaram presença no desenvolvimento de programas, sendo que algumas delas têm resistido ao tempo e às críticas, como por exemplo Fortran que ainda é visto como uma linguagem de implementação para muitas aplicações de engenharia. Cobol é um outro exemplo de linguagem bastante utilizada no desenvolvimento de aplicações comerciais.

Linguagens estruturadas

Nesta classe, encaixam-se as chamadas linguagens de programação, surgidas em meados dos anos 60. As linguagens concebidas neste período foram resultado da necessidade da produção de código de programa de forma clara, aparecendo o conceito de estruturação do código (indentação, utilização de letras maiúsculas e minúsculas nos identificadores, eliminação de instruções “problemáticas” como o “go to”, etc...).

(9)

• as linguagens de uso geral, as quais podem ser utilizadas para implementação de programas com as mais diversas características e independente da área de aplicação considerada; encaixam-se nesta categoria linguagens como Pascal, Modula-2 e C;

• as linguagens especializadas, as quais são orientadas ao desenvolvimento de aplicações específicas; algumas das linguagens que ilustram esta categoria são Prolog, Lisp e Forth;

• as linguagens orientadas a objeto, que oferecem mecanismos sintáticos e semânticos de suporte aos conceitos da programação orientada a objetos; alguns exemplos destas linguagens são Smalltalk, Eiffel, C++ e Delphi.

3.2. As etapas de desenvolvimento de um software

O estabelecimento de etapas de desenvolvimento de um produto de software nada mais é do que a formalização de passos ou atividades que são intuitivamente realizadas por qualquer programador.

Vamos tentar ilustrar isto através do exemplo de um desenvolvimento do programa, supondo que o problema a resolver por este seja a verificação da correção do valor de prestações de um dado financiamento (por exemplo, no caso do financiamento de um automóvel). A primeira preocupação do programador será o correto entendimento do problema a ser resolvido, ou seja, que informações ele deverá manipular (no caso, os valores do montante financiado, o prazo de financiamento e a taxa de juros aplicada) e a que resultado chegar (a verificação de que a prestação a pagar é correta). Em seguida, ele deverá preocupar-se em planejar a solução do sistema e fazer as escolhas relativas a ela. É imperativo que as decisões no tocante à solução devam ser tomadas antes que a codificação do programa seja iniciada. Por exemplo, a solução a ser encaminhada passa pelo cálculo das prestações (tendo como entradas o montante a financiar, a duração e a taxa de juros) seguida da comparação com o valor das prestações proposta pela financeira? Ou melhor seria, a partir do valor das prestações fornecidas calcular a taxa de juros que está sendo aplicada? Tomadas as decisões, o programador vai, então, passar à etapa de programação propriamente dita, seguida finalmente dos testes do programa.

Deste exemplo, pode-se verificar que, de fato, o desenvolvimento de um programa vai envolver 4 etapas, a saber: o entendimento do problema, a definição da solução, a codificação do programa e os testes.

No caso do desenvolvimento de programas de pequeno porte (como o exemplo apresentado), estas etapas não são normalmente explicitadas, sendo executadas seqüencialmente e intuitivamente pelo programador. Também, a definição das fronteiras entre uma etapa e outra não é uma grande preocupação neste caso. Ainda, nenhum traço (ou documento) é de fato registrado sobre o desenvolvimento destas etapas, a única documentação sendo, na maior parte dos casos, a listagem do código do programa na linguagem considerada.

Por outro lado, para sistemas de grande porte (a classe de sistemas alvo da Engenharia de Software), a formalização das etapas de desenvolvimento assume uma considerável importância. Cada uma destas etapas pode assumir um grau de complexidade distinto (normalmente alto), o que significa que metodologias e ferramentas são necessárias para que elas sejam executadas de forma correta e eficiente. Além disso, pode existir a necessidade de que uma dada etapa seja subdividida em etapas menores, em função das dificuldades encontradas.

(10)

De um ponto de vista mais genérico, é possível enumerar as etapas de desenvolvimento de um produto de software como sendo: Análise de Requisitos, Projeto

do Software, a Codificação e o Teste.

É possível, ainda, destacar algumas atividades importantes posteriormente ao desenvolvimento do sistema. É o caso da Instalação (ou Implementação) que consiste em colocar em funcionamento o sistema desenvolvido no equipamento do cliente e testar a sua execução. A Manutenção é outra atividade a ser levada em conta, uma vez que é através dela que eventuais erros são eliminados ou novas funções são adicionadas ao sistema.

As seções a seguir vão apresentar os principais aspectos relacionados a cada uma das fases mencionadas.

A Análise de Requisitos

A Análise de Requisitos é a etapa na qual é encaminhado o completo entendimento do problema a ser resolvido. Por exemplo, na área de automação, o problema é automatizar um dado processo existente ou gerar um novo processo totalmente automatizado?

No caso de sistemas de grande porte, onde existe grande quantidade de tarefas a executar, o entendimento dos requisitos do sistema é uma tarefa de suma importância. É a etapa onde é definido o que é necessário para o sistema a ser desenvolvido. É uma tarefa relativamente complicada, por envolver pelo menos duas partes interessadas no desenvolvimento do sistema — o cliente e o programador.

A preocupação do programador é desenvolver o sistema de modo a satisfazer as necessidades do cliente. Em princípio, o programador não conhece o domínio de aplicação do cliente; por outro lado, o cliente não conhece os problemas envolvidos no desenvolvimento de um sistema de software. Isto pode causar um grave problema de comunicação, o que deve ser resolvido de forma eficiente para a garantia do sucesso desta etapa.

Esta etapa resulta, normalmente, na redação de um documento descrevendo os requisitos do sistema, o qual é definido como a especificação de requisitos do sistema.

Nesta etapa, duas atividades são efetivamente realizadas. A primeira atividade consiste do entendimento do problema, sendo que o programador deve fazer o possível para tomar perfeito conhecimento do problema e do contexto no qual este se insere.

Informações que devem ser dominadas neste momento são: • as características do sistema existente;

• os dados a serem manipulados;

• os pontos do sistema onde ações devem ser aplicadas; • o objetivo das ações a aplicar;

• as entradas e saídas do sistema;

• as propriedades desejáveis para o sistema (desempenho, interfaces, etc...). A definição destes pontos só é possível através de um conjunto de reuniões com o cliente e/ou usuários finais, bem como através do estudo de documentos (manuais) e procedimentos existentes.

A segunda atividade desenvolvida nesta etapa é a especificação dos requisitos, onde será gerado um documento contendo informações do que efetivamente deverá ser provido pelo sistema. Para facilitar a especificação, o documento a ser escrito poderá utilizar-se de diferentes linguagens, podendo ser a linguagem natural, tabelas, gráficos ou até ilustrações. O documento deve conter a especificação de todos os requisitos funcionais e de desempenho, os formatos dos dados de entrada e saída, padrões necessários, restrições (por exemplo, restrições ambientais), etc... Resumindo, além das funções a serem executadas, devem ser expressos também todos os fatores que poderão influenciar nas escolhas de projeto.

(11)

cliente e para verificar se todos os requisitos estão efetivamente expressos. Esta validação é normalmente realizada na forma de uma revisão de requisitos, no qual uma equipe de pessoas, composta inclusive de representantes do cliente, examina o documento de especificação dos requisitos.

O Projeto do Software

O objetivo do Projeto do Software é o planejamento da solução ao problema especificado pelo documento obtido na etapa de Análise de Requisitos. Nesta etapa, o ponto de partida é o que deve ser feito e o ponto de chegada vai ser a definição de como satisfazer aos requisitos especificados. O resultado desta etapa é um segundo documento, denominado documento de projeto, o qual define, num primeiro tempo a solução encontrada para o problema imposto.

O Projeto é, normalmente, subdividido em duas fases distintas — o projeto do

sistema e o projeto detalhado. O projeto do sistema, também conhecido por projeto de alto nível, é caracterizado pela definição dos componentes (ou módulos) que vão constituir

o sistema, a especificação destes módulos e a forma como estes vão interagir no sistema. Nesta fase, as principais estruturas de dados, os formatos de arquivos, os formatos das saídas, enfim, os principais objetos do sistema serão identificados.

O objetivo do projeto detalhado é a obtenção de um primeiro nível de especificação

relativo ao comportamento interno de cada módulo do sistema. Nesta fase, são definidos em mais detalhes as estruturas de dados, os algoritmos que vão caracterizar cada módulo, sendo que o comportamento dos módulos é especificado utilizando uma linguagem de especificação de alto nível, totalmente independente da linguagem de programação a ser utilizada na etapa de Codificação. Nesta etapa, a linguagem de programação a adotar pode ser, inclusive, ainda desconhecida.

Uma metodologia de projeto é a sistemática que vai permitir executar o projeto,

pela aplicação de um conjunto de técnicas e regras orientadas a este fim. A maior parte das metodologias de projeto são baseadas, principalmente em dois conceitos: o particionamento

do problema e a abstração.

O princípio de particionamento do problema é baseado na constatação de que um

grande sistema não pode ser manipulado como um todo, mas sim como um conjunto de pequenas porções, cujas dimensões sejam favoráveis a um projeto individual (o princípio do

"dividir para conquistar").

Abstração é um conceito relacionado ao princípio do particionamento do problema.

A abstração implica na representação, a um dado nível de particionamento, do comportamento global do sistema ou de parte dele sem entrar nos detalhes internos dos níveis posteriores. Ao refletir sobre o projeto de um dado componente, o programador abstrai-se dos detalhes de projeto dos demais componentes do sistema, atendo-se apenas ao conhecimento de como os demais componentes vão interagir.

De modo similar à etapa de Análise de Requisitos, o final desta etapa é caracterizado por uma verificação do projeto, a qual pode ser conduzida automaticamente (se o projeto foi efetuado numa linguagem executável ou utilizando uma metodologia de projeto suportada por um conjunto de ferramentas de validação) ou pela simples análise do documento de projeto e o eventual confronto com o documento de análise de requisitos. Neste último caso, são realizadas duas revisões — uma sobre o projeto do sistema e outra sobre o projeto detalhado.

A Codificação e Geração de Código Executável

Concluído o Projeto do Software, os documentos obtidos naquela etapa vão ser a base da etapa de Codificação, cujo objetivo é a representação, na forma de uma linguagem de programação do que foi estabelecido nos documentos.

(12)

testes e manutenção. Para isto os programas devem ser escritos sob uma ótica de facilidade de entendimento e de introdução de modificações.

Um conceito que aportou uma grande contribuição neste sentido foi o da

programação estruturada, o qual impunha uma linearização do código do programa pela

definição de seqüências de procedimentos e funções. Mais recentemente, o conceito de

programação orientada a objetos veio como uma nova forma de gerar programas de forma

rápida e eficiente.

Os resultados da etapa de codificação são, além do código em linguagem de programação dos componentes do sistema, o código que vai ser executado pelo sistema computacional.

O Teste

A função básica da etapa de Teste é o controle da qualidade do sistema, através da detecção de erros de concepção e programação. Isto porque, a detecção de erros de concepção nas etapas anteriores não é evidente, uma vez que, na maior parte dos casos, o resultado das etapas de Análise de Requisitos e Projeto do Software não são escritos na forma de uma linguagem executável. Isto ocorre somente na etapa de Codificação, o que torna a etapa de Teste de vital importância para a garantia de um bom grau de qualidade do sistema.

Para que esta etapa seja realizada de forma eficiente, são efetuados diferentes tipos ou níveis de teste. Inicialmente, são realizados os testes de unidade, onde cada componente do sistema é testado individualmente com o objetivo de verificar o seu comportamento no sentido de detectar erros de codificação (algoritmos implementados, estruturas de dados, etc...). Em seguida, estes módulos vão sendo gradualmente integrados para compor partes maiores do sistema (ou subsistemas), isto podendo ser realizado em vários níveis, para finalmente compor o sistema final. Nesta oportunidade, são realizados os

testes de integração, cujo objetivo é detectar eventuais erros de projeto, pela verificação

da definição das interfaces entre os diferentes módulos. Uma vez composto todo o sistema, é efetuado o teste do sistema, onde será observado o correto atendimento aos requisitos definidos na primeira etapa do seu desenvolvimento. Finalmente, a última etapa é o teste de

aceitação, onde o sistema, na forma de um produto é colocado à disposição do cliente ou

do usuário final para que este(s) possa(m) dar o seu parecer sobre o sistema desenvolvido. Uma dificuldade encontrada nesta etapa é o fato de que ela pode constituir-se numa atividade longa e custosa, requerendo o desenvolvimento prévio de um plano de teste, o qual vai permitir identificar todas as atividades relacionadas ao teste, os recursos necessários e as diretivas a serem seguidas. O plano vai definir as condições nas quais os módulos serão testados, que módulos deverão ser testados e ainda a forma como estes deverão ser integrados para a obtenção do sistema final.

Os resultados obtidos desta etapa são, geralmente, um relatório de teste, que aponta para todos módulos testados e a forma como cada um deles foi testado. Ainda, é gerado nesta etapa um relatório de erros, que descreve, obviamente, os erros encontrados e as correções introduzidas.

A Manutenção

Como foi dito anteriormente, a Manutenção é uma etapa posterior ao desenvolvimento do software, que se constitui de uma importante atividade para a vida do produto. A Manutenção consiste de todas as atividades realizadas após a instalação do software para mantê-lo em funcionamento.

(13)

outro lado, não é incomum acontecer de aparecerem requisitos a serem satisfeitos apenas após o sistema estar instalado (requisitos que não tenham sido contemplados na etapa de Análise de Requisitos). O atendimento a estes novos requisitos vai envolver, naturalmente, modificações no software as quais são classificadas como manutenção adaptativa.

A manutenção do software envolve, normalmente, etapas de análise do sistema existente (entendimento do código e dos documentos associados), teste das mudanças, teste das partes já existentes, o que a torna uma etapa complexa e de alto custo.

3.3. As ferramentas de desenvolvimento de programas

No que diz respeito à etapa de codificação, o uso de linguagens de programação é associado ao uso de ferramentas ou ambientes de desenvolvimento que acompanham o programado desde a etapa de codificação propriamente dita até a geração e teste do código executável. Serão apresentados, seguindo uma seqüência de utilização as principais funcionalidades encontradas isoladamente ou integradas num mesmo ambiente de desenvolvimento de programas:

Editores

Os editores são a primeira ferramenta à qual o programador recorre na etapa de codificação, pois é através dela que será gerado o arquivo (ou o conjunto de arquivos) que vai conter o código-fonte do programa a ser desenvolvido. Apesar de que é possível utilizar qualquer editor de linha (como por exemplo o EDIT do DOS) para gerar o arquivo de programa, alguns ambientes oferecem ferramentas de edição mais poderosas (orientadas à sintaxe ou de coloração de sintaxe). Alguns ambientes mais recentes oferecem a possibilidade de projeto de interfaces gráficas e gerenciadores de eventos, com geração automatizada do código-fonte.

Tradutores de Código

Independente da linguagem utilizada e da arquitetura do sistema computacional, o código-fonte não é executável diretamente pelo processador. Para que se possa obter o programa executável, é necessário que o código-fonte seja traduzido para o código de máquina do processador que compõe a arquitetura do sistema. Felizmente, isto é realizado de forma automática graças à existência de ferramentas como os Montadores (ou Assemblers que, como o nome indica, são orientados para traduzir programas escritos na linguagem Assembly) e os Compiladores, construídos para gerar o código de programas originalmente escritos em linguagens de alto nível como Pascal, C, Fortran e outras. O código gerado por estas ferramentas é representado segundo o sistema de numeração binária e é denominado código-objeto.

Editores de ligação

(14)

Depuradores ou debuggers

Os debuggers são assim chamados devido à sua função essencial que é de auxiliar o programador a eliminar (ou reduzir) a quantidade de “bugs” (erros) de execução no seu programa. Eles executam o programa gerado através de uma interface apropriada que possibilita uma análise efetiva do código do programa graças à:

• execução passo-a-passo (ou instrução por instrução) de partes do programa; • visualização do “estado” do programa através das variáveis e eventualmente dos

conteúdos dos registros internos do processador;

• alteração em tempo de execução de conteúdos de memória ou de variáveis ou de instruções do programa;

Referências

Documentos relacionados

Esta degradação, é de difícil avaliação, por isso para cada caverna realiza-se uma análise da capacidade de carga, ou seja, o quanto uma área pode agüentar as

Os candidatos reclassificados deverão cumprir os mesmos procedimentos estabelecidos nos subitens 5.1.1, 5.1.1.1, e 5.1.2 deste Edital, no período de 15 e 16 de junho de 2021,

Para disciplinar o processo de desenvolvimento, a Engenharia de Usabilidade, também conceituada e descrita neste capítulo, descreve os métodos estruturados, a

Faial, que parecia mesmo um lobo, abriu e fechou a boca várias vezes, mas não uivou (19).. No entanto, era evidente (20) que os cães também se

Para que o estudo seja possível, houve um levantamento bibliográfico sobre o cenário do sistema produtivo da saúde no Brasil, tendo em vista a proteção

Quando os dados são analisados categorizando as respostas por tempo de trabalho no SERPRO, é possível observar que os respondentes com menor tempo de trabalho concordam menos que

c.4) Não ocorrerá o cancelamento do contrato de seguro cujo prêmio tenha sido pago a vista, mediante financiamento obtido junto a instituições financeiras, no

[r]