Curso de C
Includes
Você está em: MarMSX >> Cursos >> C
Biblioteca GLIB exclusiva do MSX.
Módulos
Quando o programa que criamos é muito grande, torna-se difícil de compreender todo o código armazenado em um mesmo arquivo. Dessa forma, é desejável que separemos as funcionalidades por temas (ou módulos), colocados em arquivos separados.
Uma vez feito isso, podemos utilizar as funções de cada módulo em outros programas, apenas indicando o nome do módulo mais a função a ser utilizada.
As principais vantagens da modularização de programas são:
- Reuso - o mesmo módulo pode ser utilizado em diversas aplicações.
- Ganho de tempo - certas rotinas já estão prontas e funcionando.
- Foco em cada módulo - erros são locais e de mais fácil tratamento.
- Confiabilidade - o módulo quando maduro, é bem confiável.
- Transparência - o programador não necessita saber como o módulo resolve os problemas , mas somente como utilizar as funções disponíveis.
O C fornece a opção de incluir novos módulos ao programa corrente, através da diretiva include.
Podemos incluir vários módulos em um programa, até mesmo em cascata, ou seja, chamar um módulo que também chama outros módulos.
O exemplo "modulo.c" a seguir, cria um módulo com uma rotina para calcular o produto de dois números.
double calculaProduto(double a, double b)
{
return a*b;
}
O programa "teste.c" a seguir irá incluir o módulo "modulo.c" e fará uso de sua função.
#include <stdio.h>
#include "modulo.c"
main()
{
printf("O produto de 5x4 é: %.2f\n", calculaProduto(5,4));
}
Saída:
O produto de 5x4 é: 20.00
Observe que no arquivo teste.c não há qualquer código que trate do produto entre dois números. Isto é responsabilidade do módulo "modulo.c".
Observação importante:
No Hi-Tech C, quando são utilizados pontos flutuantes (double, float), é obrigatória a indicação da biblioteca "libf" na compilação. No caso do exemplo acima, deve-se compilar assim:
A> c -lf teste
Caso não seja usada a opção "-lf", um erro em tempo de link acontece:
undefined symbol:
flmul
Bibliotecas
Quando criamos módulos que serão utilizados por diversos outros programas, conforme visto na seção anterior, eles terão sempre que passar pelo processo de compilação juntamente com os programas. Para evitar o disperdício de tempo de ter sempre que compilar esses módulos, a linguagem C permite que utilizemos uma versão já compilada deles. Dessa forma, quando desenvolvemos programas que utilizam tais módulos, somente é necessário compilar a parte do programa que criamos.
Para entender melhor como o C utiliza os arquivos já compilados, vejamos como é o processo de compilação:
Arquivo ------------> Arquivo --------> Arquivo
Fonte Compilador Objeto Linker Executável
O compilador recebe o arquivo fonte contendo o código em C e o converte em arquivo objeto (extensão ".o" ou ".obj"). O arquivo objeto contém o programa convertido para linguagem de máquina, mais algumas informações. O linker é responsável por juntar os arquivos objetos gerados em um único arquivo executável (".com").
Uma biblioteca reune um ou mais arquivos objetos em um único arquivo (".lib"), que serão utilizados no final do processo de compilação.
Arquivo ------------> Arquivo ---+-------> Arquivo
Fonte Compilador Objeto | Linker Executável
|
Biblioteca -+
Cada biblioteca possui vinvulada a ela um ou mais arquivos de cabeçalho (header, com extensão ".h"), que irão conter a declaração de todas as funções existentes nessa biblioteca. São eles que serão referenciados pelos arquivos fontes, através da diretiva "include".
Na linguagem C, temos as bibliotecas padrão e as bibliotecas do usuário.
Bibliotecas Padrão
O C é uma linguagem que não realiza por si só operações básicas como entrada e saída, cálculos matemáticos, acesso ao sistema etc. Para atingir tais fins, são utilizadas bibliotecas específicas, que acompanham o pacote da linguagem.
As bibliotecas padrão são aquelas presente na maioria dos compiladores C, independente da plataforma. Dessa forma, um programa que utilize tais bibliotecas pode ser compilado tanto no MSX, como no PC utilizando Windows ou Linux.
As principais bibliotecas são:
- stdio.h - biblioteca padão de entrada e saída de dados.
- stdlib.h - biblioteca de recursos de memória.
- math.h - biblioteca de operações matemáticas.
- string.h - biblioteca com diversas operações sobre strings.
- time.h - biblioteca de acesso a recursos de relógio.
Exemplo 1:
#include <stdio.h>
main()
{
printf("Olá, mundo.\n");
}
Saída:
Olá, mundo.
Neste exemplo, há a chamada a uma função de entrada e saida "printf", que é responsável por imprimir na tela do computador.
Exemplo 2:
#include <stdio.h>
#include <stdlib.h>
main()
{
char *p = (char *) malloc(6 * sizeof(char));
p[0] = 'M';
p[1] = 'a';
p[2] = 'r';
p[3] = 'M';
p[4] = 'S';
p[5] = 'X';
printf("%s\n", p);
}
Saída:
MarMSX.
Obs: é possível chamar as bibliotecas padrão utilizando-se aspas em vez dos sinais de maior e menor. Ex:
#include "stdio.h"
Entretanto, é uma convenção o uso dos sinais de de maior e menor para as bibliotecas padrão e aspas para as bibliotecas do usuário.
Bibliotecas do Usuário
Quando certas funcionalidades não estão presentes nas bibliotecas padrão do C, o usuário então cria suas próprias bibliotecas. Elas podem servir para resolver problemas específicos desse usuário, ou até mesmo de uma comunidade inteira, como, por exemplo, a biblioteca gráfica "GLIB" para MSX.
O arquivo da biblioteca possui extensão ".lib", no qual incluem módulos já compilados no formato objeto ou ".obj".
Principais passos para criar uma biblioteca:
1o. passo: criar o arquivo fonte.
Vamos criar o arquivo "modulo.c".
double calculaProduto(double a, double b)
{
return a*b;
}
2o. passo: criar o arquivo header ".h".
Vamos criar o arquivo "modulo.h".
double calculaProduto(double a, double b);
3o. passo: compilar e gerar um arquivo objeto.
No prompt do MSX-DOS, e com o compilador Hi-Tech C:
A> c -c modulo
Resulta no arquivo objeto "modulo.o". Caso deseje, mude a extensão de ".o" para ".obj".
4o. passo: criar a bilioteca.
No prompt do MSX-DOS, e com o compilador Hi-Tech C:
A> libr r libteste.lib modulo.obj
Resulta no arquivo "libteste.lib".
Obs: opções para o comando "libr":
- r - adiciona ou substitui módulos à biblioteca.
- d - apaga módulos da biblioteca.
- x - extrai módulos da biblioteca para o disquete, sem apagar o original.
- m - lista os módulos da biblioteca.
- s - lista os módulos da biblioteca, com os símbolos.
5o. passo: testar a biblioteca criada.
O programa "teste.c" a seguir irá incluir o módulo "modulo.h" da biblioteca "libteste.lib".
#include <stdio.h>
#include "modulo.h"
main()
{
printf("O produto de 5x4 é: %.2f\n", calculaProduto(5,4));
}
Caso o programa "teste.c" seja compilado sem informar a biblioteca "libteste.lib", um erro acontece.
A> c teste
...
undefined symbol:
_calculaProduto
Corrigindo:
A> c -lf -lteste teste
Biblioteca Gráfica "GLIB" - Pierre Gielen
O pacote do Hi-Tech C da Funet (www.msxarchive.nl) acompanha uma biblioteca gráfica criada por Pierre Gielen, que permite acessar os recursos gráficos do MSX como desenhos, sprites, modos de tela etc.
O arquivo hitech-4.pma contém o pacote LIBG1193.PMA, no qual contém três arquivos necessários: libg.lib, glib.h e msxbios.h. Os arquivos restantes são os códigos-fonte dessa biblioteca em Assembly.
Assim, deve-se copiar os três arquivos para o disquete do Hi-Tech C.
Para utilizar a bilioteca, adicione a seguinte linha ao seu programa:
#include <glib.h>
As funções dessa biblioteca podem ser vistas aqui.
O exemplo 1 irá desenhar figuras geométicas na screen 5.
#include <stdio.h>
#include <conio.h>
#include <glib.h>
char c;
main()
{
screen(5);
/* Desenha circulo */
circle(128,95,50,13,0,32752,32768);
paint(128,95,2,13);
/* Desenha linha */
line(10,10,80,80,15,PSET);
/* Desenha caixa vazia */
boxline(10,150,80,180,15,PSET);
/* Espera pelo enter ser pressionado */
c = getch();
totext();
}
Compile assim:
A> c -lg exemplo1
Saída:
O exemplo 2 irá escrever um texto na tela do MSX.
#include <stdio.h>
#include <conio.h>
#include <glib.h>
main()
{
static int i;
static char c;
static char msg[] = "Texto na screen 5";
screen(5);
color(15,1,1);
/* Escreve na tela */
glocate(10,10);
for (i=0; i<strlen(msg); i++)
grpprt(msg[i], PSET);
/* Espera pelo enter ser pressionado */
c = getch();
totext();
}