Fundamentos da Programação 17 IV. L INGUAGEM DE P ROGRAMAÇ ÃO Uma linguagem de programação é uma lingua artificial utilizada para expressar instruções para uma máquina em geral, ou um computador em particular. A linguagem é composta de um vocabulário e de um conjunto de regras gramaticais que permitem que o programador especifique de maneira precisa como o computador organiza e manipula a informação colocada a seu dispor, isto é, quais ações são esperadas, como os dados são armazenados e transmitidos. As palavras definidas no vocabulário são denominadas palavras reservadas ou keywords. Um conjunto de palavras composto de acordo com as regras da linguagem constitue um programa fonte ou código fonte. Esse código fonte é traduzido para um programa executável ou código de máquina, que pode ser executado pelo processador. Um dos principais objetivos do uso de linguagens de programação é aumentar a produtividade ao permitir que programadores possam expressar as suas intenções de uma maneira mais próxima àquela encontrada no dia-a-dia, entre humanos. Além disso, linguagens de programação devem permitir que as idéias sejam colocadas de modo claro, organizado e estruturado, facilitando a leitura e manutenção. Linguagens de programação com alto nı́vel de abstração, isto é, que mais se aproximam de linguagens humanas são chamadas linguagens de alto nı́vel. Por outro lado, linguagens de baixo nı́vel são aquelas mais próximas ao código de máquina. Em geral linguagens de alto nı́vel são independentes dos ambientes computacionais onde são executadas (propriedade denominada portabilidade). Existem milhares de linguagens de programação definidas e novas são criadas todos os anos. A. Interpretação e Compilação Uma linguagem de programação pode ser convertida (traduzida) em código de máquina por compilação ou interpretação. Se o método utilizado traduz todo o texto do código fonte para somente depois executar, então diz-se que o programa foi compilado e a ferramente utilizada para isso é um compilador. A versão traduzida (compilada) do programa é tipicamente armazenada e pode ser executada um número indefinido de vezes sem que nova compilação seja necessária. Desse modo, mesmo que a compilação seja um processo demorado, a sua utilização pode ser eficiente porque ela é realizada poucas vezes. Linguagens como Fortran, Pascal e C são linguagens compiladas. Se o texto do programa é traduzido à medida em que ele é executado, num processo de tradução de trechos seguidos de sua execução, então diz-se que o programa é interpretado e a ferramenta utilizada para isso é um interpretador. Programas interpretados são geralmente mais lentos do que programas compilados. Linguagens como Javascript, Python e Perl são linguagens interpretadas. Existem também linguagens que são compiladas para um código de máquina de uma máquina virtual. Uma máquina virtual não existe fisicamente, mas tem o seu comportamento e especificação detalhados de maneira que qualquer máquina fı́sica com os recursos necessários pode comportar-se como uma máquina virtual. Java e o Parrot são linguagens desse tipo. A tradução consiste de várias fases: análise léxica, análise sintática ou parsing, geração de código e otimização. B. Linguagem de Baixo Nı́vel Linguagem de programação de baixo nı́vel significa aquela que assemelha-se mais ao código de máquina, isto é, está mais próxima da linguagem entendida pela CPU. Linguagens de baixo nı́vel ofecerem pouca ou nenhuma abstração do hardware. Isso significa que o conhecimento de detalhes do funcionamento e da arquitetura do hardware são em geral fundamentais para a utilização com sucesso desse tipo de linguagem. Além disso, alterações no hardware podem significar que um determinado programa deixe de executar corretamente. Por exemplo, uma linguagem de programação de baixo nı́vel conhecida como Assembly oferece apenas uma representação simbólica dos números utilizados no código de máquina e trabalha diretamente com os registradores da CPU. UEM/CTC/DIN/Elvio Fundamentos da Programação Figura 1. 18 Etapas para gerar o executável. C. Linguagem de Alto Nı́vel Linguagem de programação de alto nı́vel oferece um alto nı́vel de abstração do hardware do computador, isto é, conhecimento dos detalhes da máquina fı́sica onde o programa irá executar não são fundamentais para uma programação correta. Além disso, alterações no hardware têm um impacto limitado na funcionalidade do programa. Ou seja, linguagens de alto nı́vel oferecem uma maior portabilidade. Em outras palavras, linguagens de alto nı́vel estão mais próximas da linguagem natural humana e mais distantes da linguagem de máquina. Os termos “alto nı́vel” e “baixo nı́vel” são relativos. No passado, a linguagem assembly era considerada uma linguagem de baixo nı́vel enquanto a linguagem C era considerada de alto nı́vel pelo fato de permitir funções, variáveis e expressões mais complexas. Entretanto muitos programadores hoje referem-se a linguagem C como linguagem de baixo nı́vel pelo fato de ela permitir acesso direto a memória, de maneira similar àquele permitido pelo assembly. Resumidamente, denominamse linguagens de alto nı́vel aquelas que permitem a utilização de vetores e matrizes, que permitem operações de entrada e saı́da para arquivos, e que oferecem cálculo matemático e lógico complexo, entre outras caracterı́sticas. Acesso a registradores e à memória diretamente, e necessidade de gerenciar desvios na execução do programa (através da pilha) são caracterı́sticas de linguagens de baixo nı́vel. De modo geral, pode-se dizer que linguagens de alto nı́vel tornam simples a tarefa de implementar algoritmos (programas) complexos, enquanto linguagens de baixo nı́vel produzem um executável mais eficiente. Exemplos de linguagem de alto nı́vel: Fortran, ADA, C e Java. D. Linguagem de Muito Alto Nı́vel Linguagem de programação de muito alto nı́vel é uma linguagem que oferece um alto grau de abstração e é usualmente utilizada para aplicações especı́ficas e com o escopo limitado a um tipo de trabalho. Em geral são linguagens proprietárias. Exemplos de linguagem de alto nı́vel: Python, Ruby e Scheme. E. Gerando o Executável A geração e execução do código binário inclui os seguintes passos (veja Fig. 1): • compilação, quando o código fonte é convertido em código objeto relocável; • ligação (linking), quando os módulos de código objeto relocável e as bibliotecas (libraries) são montados em um único arquivo binário relocável; UEM/CTC/DIN/Elvio Fundamentos da Programação • • 19 carregamento (loading), quando o arquivo binário relocável é carregado em memória utilizando endereços absolutos; e execução, quando o controle é trasferido para a primeira instrução do programa. UEM/CTC/DIN/Elvio