Prévia do material em texto
1ºAula Modularização de Código Objetivos de aprendizagem Ao término desta aula, vocês serão capazes de: compreender o conceito de modularização de código; analisar o surgimento da técnica da modularização; entender a importância dela para a programação. Olá, Caros(as) alunos(as) Nesta aula, vamos estudar o conceito de modularização de código, destacando o surgimento dessa técnica após uma crise de software, e a sua importância para programação de computadores existentes hoje. Bons estudos! 131 Linguagem de programação II 6 1. Definição 2. Cabeçalhos ou Headers - Arquivo .h 3. Algumas funções da linguagem 4. Vantagens e Desvantagens A definição de modularizar, segundo o dicionário Aurélio, é “Dividir em partes menores.”, mas o que isso tem a ver com a linguagem de programação? Geralmente quando estamos programando um problema simples, nosso código fica fácil de entender, pois para problema simples utilizamos poucas estruturas condicionais e algumas estruturas de repetição. No entanto, para problemas mais complexos, muitas vezes, temos que utilizar várias validações, leituras e muitos outros comandos, o que torna o nosso código cada vez maior. Podemos fazer uma analogia ao conceito de variáveis e matrizes da disciplina passada. Vimos que quando temos muitas variáveis para realizar algo parecido, nosso código cresce e fica confuso, já quando passamos a utilizar matrizes ou vetores conseguimos melhorar nosso código (GCC, 2010). Da mesma forma, se conseguirmos modularizar nosso código, poderemos melhorar o funcionamento e a compreensão dele. Podemos dizer que a modularização na TI (Tecnologia da Informação) é um conceito onde um software ou sistema é dividido em partes. Com o intuito de tornar- se um programa mais legível, com uma facilidade maior de realizar manutenções e melhorar o desempenho por meio da programação estruturada. Podemos caracterizar da seguinte forma: elemento endereçável de forma separada no sistema, menor parte do sistema que realiza uma função independente das outras, conjunto de instruções de um programa que pode ser chamado por um nome, sendo ideal que para os outros módulos seja uma caixa preta (HARRY, 2008). 1.1 - Características A ideia de dividir os programas em módulos surgiu no final da década de 1960, quando os países desenvolvidos estavam passando por uma “crise de software”. Essa crise ocorreu por causa da rápida evolução e desenvolvimento de hardware. E em contrapartida, o desenvolvimento de software caminhava a passos lentos, devido às técnicas utilizadas no desenvolvimento de software. Ela se manifestou de várias formas (HARRY, 2008): Projetos estourando o orçamento. Projetos estourando o prazo. Software de baixa qualidade. Software muitas vezes não satisfaz os requisitos. Projetos ingerenciáveis e código difícil de manter. Nessa crise notaram que não havia uma metodologia no Seções de estudo 1 desenvolvimento de sistemas, o que geralmente resultava em softwares com vários erros e com alto custo de desenvolvimento e, consequentemente, acabavam exigindo um custo maior ainda na sua manutenção e correção. As soluções para a crise de software foram: A análise econômica de sistemas de informação (SI). O uso de melhores técnicas, métodos e ferramentas. O investimento do governo e empresas privadas em treinamentos e educação. A mudança de paradigma de desenvolvimento de software. Dentro das melhorias nas técnicas de programação surgiu também o conceito de modularização de programas. Visando, principalmente, os aspectos de confiabilidade, legibilidade, manutenção e flexibilidade (HARRY, 2008). Um módulo pode ser definido como um grupo de comandos, constituindo um trecho de algoritmo, com uma função bem definida e o mais independente possível em relação ao resto do algoritmo. A maneira mais intuitiva de proceder à modularização é definir um módulo principal de controle e um módulo específico para as funções do algoritmo. O ideal é que os módulos não sejam grandes demais, pois senão se tornam multifuncionais e de difícil compreensão, de modo que o módulo deve ser implementado apenas às estruturas de dados necessários para atingir ao objetivo do módulo (AGUILAR, 2008). 2 - Cabeçalhos ou Headers - Arquivo .h Vimos até agora, que todos os códigos que escrevemos iniciavam com as primeiras linhas desta forma . Por padrão, sempre utilizávamos as bibliotecas stdio ou iostream, no entanto, nunca nos perguntamos por que de sua utilização. A única certeza até então, era que, ao não adicionarmos uma delas, não conseguiríamos escrever ou ler uma variável no c/c++. Para entendermos melhor o porquê dessa utilização, vamos pegar uma das definições de header ou cabeçalhos na linguagem de programação. O arquivo cabeçalho ou arquivos de cabeçalho (em inglês: header file) permite que os programadores separem certos elementos de um código fonte de um programa em arquivos reutilizáveis. Arquivos de cabeçalho, normalmente, contêm declarações de envio de s, sub- rotinas, variáveis e outros identificadores (GCC, 2010). Nas linguagens C e C++, geralmente, se convenciona nomear esses arquivos com a extensão “.h”. Os arquivos cabeçalho são incluídos através da diretiva de pré- processamento #include seguido pelo nome do arquivo. Incluir uma biblioteca em um arquivo produz o mesmo resultado de copiar o conteúdo do arquivo incluído no arquivo onde é feita a inclusão. Um exemplo é o arquivo stdio.h que fornece a declaração para a função printf e scanf (GCC, 2010). Os compiladores da linguagem C++ incorporam muitos arquivos de cabeçalho, que suportam diferentes características. “Os arquivos de cabeçalho da linguagem C utilizam a extensão 132 7 “.h” com seu nome como, por exemplo, string.h. Inicialmente, o C++ tinha a mesma notação, no entanto, com a evolução das versões do compilador o .h foi retirado restando apenas o nome do arquivo como, por exemplo, . Dessa forma, é possível diferenciar bibliotecas escritas para linguagem C em relação às bibliotecas escritas para linguagem C++. Todas as bibliotecas em C agora iniciam com a letra c em seu nome, por exemplo, . A seguir veremos a tabela comparativa relacionada essa diferença (VICTORINE, 2005). Tipo de cabeçalho Extensão Exemplo Uso C antigo .h Math.h String.h Programas C e C++ C++ antigo .h Iostrean.h String.h Programas em C++ Novo padrão C++ nenhuma Iostream String Programas em C++ Bibliotecas C no novo C++ Nenhuma Cmath Cstring Programas em C++ Tabela 1 - Mudança nas declarações de header Fonte: O autor (2018). Dica: o uso das funções e padrões das bibliotecas nos ajudam a tornar os programas mais portáveis. Muitas vezes, não precisamos criar algo novo, podemos utilizar alguma das funções existentes em uma das várias bibliotecas das linguagens C/C++. Uma das principais características de programadores é a curiosidade. Então, para iniciarmos, pedimos que você abra alguns arquivos do tipo headers, ou seja, arquivos de cabeçalho, como o stdio ou iostream, arquivos esses que utilizamos por várias vezes no decorrer da disciplina passada. Ao abrir esses tipos de arquivos, observamos que eles contêm diversos protótipos de funções, muitos comentários entre outras coisas (AGUILAR, 2008). Vimos até agora o que são os arquivos de cabeçalhos, no entanto, quando criamos um arquivo C++, geralmente, utilizamos uma diretiva using namespace std. Apesar disso, nunca debatemos qual a finalidade dessa sentença. As linguagens C e C++ podem ser divididas em diferentes espaços de nomes (namespace). Um espaço de nomes é uma parte do programa na qual certos nomes são reconhecidos e fora desses espaços são desconhecidos. Portanto, quando utilizamos using namespace std, dizemos que todos componentes declarados dentro do espaço de nomes std estarão disponíveis dentro do nosso código (GCC, 2010). Dica: familiarize-se com a coleção de bibliotecas das linguagens C e C++. 3- Algumas funções da linguagem Ao analisarmos um arquivo de cabeçalho, observamos que existem inúmeras funções, ou seja, pequenos blocos ou módulos de códigos, ambos com finalidade específica. Portanto, podemos afirmar que o compilar incorpora muito esse conceito de modularização, o que facilita no nosso desenvolvimento. Imagina se na leitura de um nome tivéssemos a necessidade de manipular todas as entradas de I/O vindas do teclado para ler um texto digitado. Com certeza, seria algo muito trabalhoso, o que nos remete que o cin é um módulo ou função da linguagem C++. 3.1 - Exemplo de Blocos da linguagem 3.1.1 - Funções Matemáticas Existem inúmeras funções matemáticas na linguagem que facilitam nosso desenvolvimento. Essas funções estão disponíveis através da biblioteca math. Muitas das funções matemáticas nos permitem realizar vários cálculos matemáticos de forma simples e eficiente. Normalmente, as funções são usadas em um programa ao escrevermos seu nome seguido de um parêntese à esquerda (abre, seguido do argumento ou lista de argumentos, separados por vírgula, e por fim é adicionado o parêntese à direita, fecha). Por exemplo, caso um programador queira calcular a raiz quadrada de um número, como poderia escrever esse código? Primeiramente, iríamos parar para analisar como funciona a raiz quadrada, e pensar como elaborar um código para calcular essa função matemática. No entanto, é possível resolver esse problema de maneira mais fácil e simples utilizando uma função da biblioteca math. A função responsável por realizar o cálculo de raiz quadrada é a sqrt, a seguir é apresentado como podemos utilizá-la: Quando esse comando é executado, a função sqrt é chamada para calcular a raiz quadrada do número contido entre os parênteses. Ao executar esse comando escreveria em tela o valor 15. A função sqrt pede um argumento do tipo double, e retorna um resultado do tipo double. Todas as funções da biblioteca matemática retornam números de ponto flutuante double, no entanto, podemos utilizar variáveis do tipo float. Dica de prevenção a erros: escreva o include da biblioteca math antes de utilizar qualquer função matemática existente na biblioteca. Os argumentos das funções podem ser de vários tipos, como constantes, variáveis ou uma expressão. No exemplo a seguir será apresentada a utilização da função sqrt utilizando uma expressão. Para o exemplo, vamos considerar as variáveis com seus respectivos valores, c1 = 13, d=3 e f=4, então, a instrução. Ao executarmos o código apresentado, o compilador retornaria o cálculo da raiz quadrada do resultado da expressão 13+3*4. O resultado desta expressão seria igual 25, já que o compilar respeita as mesmas regras matemáticas. Por fim, o resultado apresentado seria o valor 5. Vejamos a seguir algumas das funções existentes na biblioteca math. Nome Descrição acos(x) arco-coseno Asin arco-seno Atan arco-tangente atan2 arco-tangente (círculo cheio) 133 Linguagem de programação II 8 Ceil Arredonda para cima Cos co-seno Cosh co-seno hiperbólico Exp Exponencial Fabs valor absoluto (módulo de) Floor Arredonda para baixo Fmod resto de uma divisão Frexp fracção norm./parte exp Ldexp Log logaritmo natural log10 logaritmo base 10 modf(x,p) retorna a parte fraccionária inteira para onde o pow(x,y) retorna o resultado Sin Seno Sinh seno hiperbólico Sqrt raiz quadrada Tan Tangente Tanh tangente hiperbólica Tabela 2 - Bibliotecas math da Linguagem C/C++ Fonte: Aguilar (2008). 3.1.2 - Outras Funções das linguagens Existem inúmeras outras funções da linguagem que nos auxiliam na programação de computadores. No subitem acima foram citadas, como exemplo, a biblioteca que é apenas uma das possíveis. Por exemplo, podemos citar a biblioteca , que nos auxilia na manipulação de cadeias de caracteres e oferece inúmeras funções que facilita nossa programação, através dela podemos comparar textos, e verificar tamanhos entre muitas outras opções. Outra biblioteca interessante é a , que oferece muitos recursos na manipulação de conteúdo, tanto string quanto valores. Uma outra que já utilizamos muito é a , que nos oferece recursos de entrada e saída. Se fôssemos citar todas as existentes teríamos que escrever quase um livro inteiro sobre elas, pois existem muitas bibliotecas onde cada uma contém inúmeras funções. No decorrer da disciplina, vamos conhecendo algumas dessas bibliotecas e suas funções. 4 - Vantagens e desvantagens Segundo Donald (1996), as vantagens da modularização são muitas. A modularização é um dos métodos usados em engenharia de software para desenvolvimento de programas em grande escala. Mas a modularização é útil mesmo para pequenos programas. 4.1 - Vantagens Programas feitos com funções são programados e testados de uma vez só, embora possam ser utilizados várias vezes dentro de um sistema. É possível ainda criar bibliotecas com as funções que podem ser usados em outros programas ou por outros programadores (CARVALHO, 2017). Com a modularização conseguimos preservar os refinamentos conseguidos em uma parte específica do código. Além de oferecer a economia de memória do computador, já que uma vez que o módulo é utilizado, ele é armazenado uma única vez, mesmo que utilizado em diferentes partes do programa. E o mais importante é que a modularização facilita a detecção de erros, pois no princípio é mais fácil identificar um erro em um pequeno bloco de código, ao invés de um ter que analisar todo código de um sistema. Portanto, podemos concluir que ao modularizar um programa é mais fácil testar os módulos individualmente do que o programa completo, e também é bem mais fácil fazer a manutenção (correção de erros, melhoramentos etc.). 4.2 - Desvantagem Como vimos, a modularização possui muitas vantagens, no entanto, podemos citar uma desvantagem nessa abordagem do desenvolvimento de software. Ao modularizarmos nosso código, ocorre um aumento no tempo de execução do programa, devido ao tratamento adicional de ativação dos módulos. No entanto, esse aumento não é muito significativo nos dias atuais, já o nosso hardware evoluiu muito, hoje, contamos com um alto poder de processamento e uma grande quantidade de memória (AGUILAR, 2008). 1 - Definição Na seção 1, vimos a definição de modulação na programação. No início da programação surgiram vários paradigmas de programação, mas, muitas vezes, não eram realizadas análises do sistema como um todo, ou seja, ao realizar a entrega de um software, constantemente ele apresentava erros, que eram muito difíceis de tratar pelo modelo de programação adotado. Vimos que foi necessária uma crise para que houvesse uma melhoria no processo de desenvolvimento de software, e com ela surgiram novos conceitos de engenharia de software. 2 - Cabeçalhos ou Headers - Arquivo .h Na seção 2, descrevemos o que é um arquivo de cabeçalho, qual a sua finalidade e como ele auxilia no desenvolvimento de programas nas linguagens C e C++. 3 - Algumas funções da linguagem Na seção 3, utilizamos a biblioteca matemática math para exemplificar uma das vantagens de utilização de cabeçalhos. Retomando a aula 134 9 4 - Vantagens e Desvantagens Na seção 4, apresentamos vantagens e desvantagens de se modularizar um software. Nesse novo conceito deixou- se de pensar apenas no produto final, e passou a se pensar na qualidade do produto desde sua confecção, entrega e manutenção. A modularização foi a base para todo esse modelo. Podemos notar a importância da modularização quando utilizamos recursos das bibliotecas, já que elas possuem muitos módulos que facilitam a vida de todo programador. ARLEI, Adriano et al.; A pré-história da computação; Departamento de Ciência da Computação Informática e Sociedade; 2006. Vale a pena ler Modularidade. Disponível em: . Acesso em: 22 de ago. 2018. Reference. Disponível em: .Acesso em: 20 de ago.2018. Vale a pena acessar Curso de Algoritmos- História da programação. Disponível em: . Acesso em: 20 de ago. 2018. História Da Programação. Disponível em: . Acesso em: 18 de ago.2018. COM210 - AULA 01 - Vídeo 01 - Software e Crise de Software. Disponível em: https://www.youtube.com/ watch?v=HbmkfCoGAEs >. Acesso em: 18 de ago.2018. Evolução dos softwares - 1950 a 1965. Disponível em: . Acesso em: 20 de ago. 2018. Vale a pena assistir Vale a pena Minhas anotações 135