Este é um tópico muito batido, tão velho quanto a linguagem C, mas que muita gente procura. Já que existem milhares de livros de c/c++ parecidos que podem fazer diferença para cada leitor, resolvi escrevi este artigo. Em resumo será mostrado como fazer um programa em c++ com funções e como fazê-lo da mesma forma com uma biblioteca.
Para criar nosso arquivo principal (claro ele será o nosso velho arquivo principal, afinal dissemos que gerar bibliotecas era dividir nosso programas), dentro da pasta /home/programas crie um outro arquivo texto e chame-o de de soma_principal.cpp. Cole o programa principal (abaixo) neste arquivo:
// aqui iniciamos o programa principal. Ele é que chamara funções
// quantas vezes pedirmos pra ele fazer isso
#include <iostream.h> // Este é um cabeçalho já embutido no compilador.
#include "soma_head.h" // Aqui você já usou protótipo de função, que avisa
// qual função deverá ser usada pelo
// compilador para criar o executável
// é o velho protótipo de função que tenhamos
int main ()
{
int soma1;
int soma2;
int a;
int b;
cout << "\ndigite o primeiro valor\t";
cin >> a;
cout << "\ndigite o segundo valor\t";
cin >> b;
soma1 = soma (a,b); // chamou a função "soma_fuction" acima e a atribuiu à
// suas entradas os valores "a" e "b" digitados na tela e
// soma1 recebe o valor de "r"
cout << "\nO resultado da soma1 vale\t" << soma1;
// Chamando novamente a função "soma_fuction".
cout << "\n\n\ndigite o primeiro valor\t";
cin >> a;
cout << "\ndigite o segundo valor\t";
cin >> b;
soma2 = soma (a,b); // chamou a função "soma_fuctions" de novo e a
// atribuiu à suas entradas os valores "a" e "b" digitados
// na tela e soma2 recebe o valor de "r".
cout << "\nO resultado da soma2 vale\t" << soma2;
}
Compilando o programa principal:
Antes de criarmos um executável devemos compilar o nosso arquivo arquivo principal "soma_principal.cpp", que se tornará "soma_principal.o". Para tanto devemos fazer a mesma coisa de antes: entrar na pasta onde está o soma_principal.cpp e digitar:
$ g++ -c soma_principal.cpp
Novamente usamos opção -c (compile only), que indica ao gcc só pra compilar o soma_principal.cpp e não gerar um executável a partir dele, mesmo porque ele é meio incompleto.
Agora temos tudo. Lembra-se do nosso velho "programão" completo "programa_com_função.cpp"? Ele tinha tudo num único código.
Agora o seu protótipo de função virou o arquivo header "soma_head.h". Sua função foi pro arquivo "soma_function.cpp" e depois de compilada entrou pra biblioteca "libsoma_function.a". O seu programa principal foi pro arquivo "soma_principal.cpp", que depois de compilado virou "soma_principal.o".
[1] Comentário enviado por linuxalexsandro em 03/06/2007 - 11:30h
Gostei muito do artigo. Ele é bastante útil para estudantes iniciantes das linguagens c/cpp que desejam conhecer mais sobre o compilador gcc. Parabéns FAB
[2] Comentário enviado por sombriks em 03/06/2007 - 17:00h
Olá,
sombriks@comander:~/variados$ g++ -Wall pograma.cc -o pograma
In file included from /usr/lib/gcc/i486-slackware-linux/4.1.2/../../../../include/c++/4.1.2/backward/iostream.h:31,
from pograma.cc:3:
/usr/lib/gcc/i486-slackware-linux/4.1.2/../../../../include/c++/4.1.2/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or <iostream> instead of the deprecated header <iostream.h>. To disable this warning use -Wno-deprecated.
sombriks@comander:~/variados$
todavia a execução é perfeita. Aparentemente no C++ o .h no final do arquivo foi depreciado.
Em C/C++ não basta apenas saber a linguagem; tem-se que aprender também os pormenores do compilador! Como estou estudando isso há umas 48 horas (direto, hahahaha) não resisti e decidi comentar.
Um Livro (pdf, mas deve existir como papel tb!) que eu recomendo se vc quiser uma rápida referência de C/C++ e um excelente tutorial de gcc é o do Brian Gough; dêem uma boa gloogada.
[4] Comentário enviado por feraf em 03/06/2007 - 19:48h
Para tornar o código portável, deve-se utilizar o iostream sem o .h. Isso se deve ao fato de que a iostream é uma namespace, ou seja, um aglomerado de classes. Na hora de invocar os métodos da iostream, deve-se chamá-los com std::cin e std::cout para entrada e saída padrão respectivamente. Opcionalmente pode-se importar o namespace std com 'using namespace std' e depois usar cin e cout diretamente.
[6] Comentário enviado por staltux em 23/04/2009 - 01:54h
cara legal...mas eu tenho uma pergunta...eu fiz isso que você mostrou e funcionou...
depois eu fiz novamente mas no code::blocks...sabe, criei um projeto e coloquei os arquivos nele...entao eu mandei compilar e executar e funcionou perfeitamente tambem...agora eu te pergunto:
Como o Code::Blocks sabe que o arquivo soma_function.cpp é a implementação do soma_header.h se em nenhum desses arquivos existe algo os relacionando...e eu tambem nao fiz nenhuma modificação nos scriptis de compilação do code...
é magica? magia negra? como ele adivinha isso?
[7] Comentário enviado por sombriks em 23/04/2009 - 09:18h
@alexfernandognr, essa é fácil.
ao compilar cada um dos N fontes individualmente o compilador vai apenas averiguar se todos os protótipos de função existem (i.e. não vai atrás da implementação ainda)
"g++ -c" não faz o executável, apenas o que é chamado de "código objeto".
No exemplo dado se vc der "g++ -c soma_function.cpp ; g++ -c g++ -c soma_principal.cpp" ambos vão gerar seus respectivos ".o" sem maiores dificuldades. Você somente teria problemas se os protótipos de função (declarados neste caso como manda a boa prática, no header) fossem usados de forma errada, o que implica em erro de compilação.
A mágica aqui é a etapa de linkagem ou linkedição.
"g++ soma_function.o soma_principal.o -o soma" faz a linkagem, é aqui o truque: o linker não precisa mais conhecer o código, apenas assegurar que cada chamada tem uma implementação em algum lugar no meio de todos os códigos objeto. dessa forma o problema é quebrado em pedaços menores e fica mais simples de resolver, ;)
em resumo, lembre-se que há duas etapas bem distintas: compilação e linkedição. A primeira cuida de achar os protótipos, mas é na segunda que juntamos as implementações.
[8] Comentário enviado por staltux em 23/04/2009 - 16:20h
entendido...
existe algum paramentro que possa ser colocado dentro do arquivo que implementa, para especificar de qual header se trata?
pois acho que teria problema se mais de um arquivo cpp implementa-se a mesma função...
tipo dois cpps implementando a mesma função com apenas um header...
[9] Comentário enviado por sombriks em 23/04/2009 - 19:55h
tem não, mas se você tiver no meio do seu mar de arquivos fontes dois que implementem o mesmo protótipo o linker irá falhar ao tentar juntar essas duas.