Oi, tudo bem? Gostaria de uma a ajuda, na faculdade o professor pediu um exercício em C, que seria mais ou menos assim, teria no menu alguns algoritmos, exemplo bubble sort,insert sort e outros, quando fosse escolher o algoritmo no menu ira trazer um arquivo do professor com as informações para compilar nesse algoritmo.... conclusão eu sei que e isso arquivo, mas o que não entendo como isso vai compilar a informação dele???
Eu fiz simplesmente: gcc main.c funcoes.c -o programa.exe e deu certo também, é muito mais simples assim.
28 de abril de 2015 às 19:53
Anônimo disse...
o que acontece se em vez de um numero se puser uma letra? XD
14 de abril de 2018 às 11:04
Nesta aula de nossa apostila de C, vamos aprender como organizar melhor nossos códigos, através da divisão de nosso código em módulos, algo que irá nos auxiliar muito, principalmente na hora de criar projetos mais longos.
A organização na programação
Vamos fazer um programa de matemática. Bem simples, mas um pouco grande, no sentido de ter várias funções.
Vamos criar funções que somam, subtraem, multiplicam, dividem, calculam resto da divisão, checam se um número é par, se é primo, mostra seus divisores, se é múltiplo de outro, calculam o quadrado e o cubo de um número.
Ou seja: um programa de 11 funções.
(Se quiser, pode fazer mais. Que calcula porcentagem, tira raiz quadrada, tira a média etc etc etc).
Cabeçalhos no início, função main() sempre a mais limpa e clara possível, pois apenas chama o menu(), que irá exibir as opções para o usuário escolher, outra função que vai tratar os 'case' e fazer a operação que o usuário quer.
Simples não? Nada que já não tenhamos visto aqui, em nosso curso C Progressivo.
Pois bem, temos quase 300 linhas. Isso mesmo, uma calculadora simples, quase 300 linhas.
E nem está tão 'rigorosa' assim, não está robusta. Uma simples inserção de uma letra pode fazer falhar o sistema.
Com o tratamento de erros e possibilidades, com todas as funções comentadas como pede a norma, ficaria uma aplicação com milhares de linhas, fácil fácil.
Como o código ficou grande, não vamos mostrar ele diretamente.
Clique no botão abaixo, veja seu código, copie e cole no seu Code::Blocks e rode para vê-lo funcionando.
Código C:
#include <stdio.h>
#include <stdlib.h>
/*
* Apostila C Progressivo: www.cprogressivo.net
*
* Programa com funções matemáticas
*
*/
float soma(float x, float y);
float subtracao(float x, float y);
float produto(float x, float y);
float divisao(float x, float y);
float quadrado(float x);
float cubo(float x);
int restoDivisao(int x, int y);
int par(int x);
int multiplo(int x, int y);
int primo(int x);
int* divisores(int x);
void menu();
void executa(int opcap);
int main(void)
{
menu();
return 0;
}
float soma(float x, float y)
{
return x+y;
}
float subtracao(float x, float y)
{
return (x-y);
}
float produto(float x, float y)
{
return x*y;
}
float divisao(float x, float y)
{
return (x/y);
}
float quadrado(float x)
{
return (x*x);
}
float cubo(float x)
{
return (x*x*x);
}
int restoDivisao(int x, int y)
{
return (x % y);
}
int par(int x)
{
if(x%2 == 0)
return 1;
else
return 0;
}
int multiplo(int x, int y)
{
if(x%y == 0)
return 1;
else
return 0;
}
int primo(int x)
{
int count;
if(x==1)
return 1;
else
{
for(count=2 ; count <= x/2 ; count++)
if(x%count == 0) //x é múltiplo de 'count', então não é primo
return 0;
return 1;
}
}
int* divisores(int x)
{
int *divisores,
*temp,
count,
divisor=0;
// Não sabemos quantos divisores x tem, mas no máximo tem x (se for 2)
temp = (int *) malloc(x*sizeof(int));
//zerando todos os elementos de temp com 0
for(count=0 ; count < x ; count++)
temp[count]=0;
//Checando os divisores de 'x' e colocando no vetor temp
for(count=1 ; count <= x ; count++)
if(x % count == 0) //'count' é divisor
{
temp[divisor] = count;
divisor++;
}
// Agora vamos colocar os divisores do vetor 'temp' em 'divisores' e retorná-lo
divisores = (int*) malloc(divisor*(sizeof(int)));
for(count=0 ; count < divisor ; count++)
divisores[count] = temp[count];
free(temp);
return divisores;
}
void menu()
{
int opc;
printf("\n\n### Biblioteca Matematica do C Progressivo ### \n");
printf("Escolha sua opcao: \n");
printf("0. Sair\n");
printf("1. Somar dois numeros\n");
printf("2. Subtrair dois numeros\n");
printf("3. Multiplicar dois numeros\n");
printf("4. Dividir dois numeros\n");
printf("5. Resto da divisao de dois numeros\n");
printf("6. Quadrado de um numero\n");
printf("7. Cubo de um numero\n");
printf("8. Saber se um numero eh par\n");
printf("9. Saber se um numero eh multiplo de outro\n");
printf("10. Saber se numero eh primo\n");
printf("11. Divisores de um numero\n");
do
{
printf("\nEscolha sua opcao: ");
scanf("%d", &opc);
}while(opc<0 || opc > 11);
if(opc)
executa(opc);
else
printf("Saindo do programa...\n");
}
void executa(int opcao)
{
int continuar=1,
x,
y,
*div;
float num1,
num2;
switch( opcao )
{
case 1:
printf("\n\n###Soma de dois numeros\n");
printf("Numero 1: "); scanf("%f",&num1);
printf("Numero 2: "); scanf("%f",&num2);
printf("%.2f + %.2f = %.2f\n\n",num1, num2, soma(num1,num2) );
break;
case 2:
printf("\n\n### Subtracao de dois numeros\n");
printf("Numero 1: "); scanf("%f",&num1);
printf("Numero 2: "); scanf("%f",&num2);
printf("%.2f - %.2f = %.2f\n\n",num1, num2,subtracao(num1,num2) );
break;
case 3:
printf("\n\n### Produto de dois numeros\n");
printf("Numero 1: "); scanf("%f",&num1);
printf("Numero 2: "); scanf("%f",&num2);
printf("%.2f * %.2f = %.2f\n\n",num1, num2,produto(num1,num2) );
break;
case 4:
printf("\n\n### Divisao de dois numeros\n");
printf("Numero 1: "); scanf("%f",&num1);
printf("Numero 2: "); scanf("%f",&num2);
if(num2 == 0)
printf("Operacao invalida. Denominador nao pode ser 0\n\n");
else
printf("%.2f / %.2f = %.2f\n\n",num1, num2, divisao(num1,num2) );
break;
case 5:
printf("\n\n### Resto da divisao de dois numeros\n");
printf("Numero 1: "); scanf("%d",&x);
printf("Numero 2: "); scanf("%d",&y);
printf("%d %% %d == %d\n\n",x,y,restoDivisao(x,y) );
break;
case 6:
printf("\n\n### Quadrado de um numero\n");
printf("Numero: "); scanf("%f",&num1);
printf("%.2f * %.2f = %.2f\n\n",num1, num1, quadrado(num1) );
break;
case 7:
printf("\n\n### Cubo de um numero\n");
printf("Numero: "); scanf("%f",&num1);
printf("%.2f * %.2f * %.2f= %.2f\n\n",num1, num1, num1, cubo(num1) );
break;
case 8:
printf("\n\n### Paridade de um numero\n");
printf("Numero: "); scanf("%d",&x);
if(par(x))
printf("%d eh par\n\n", x);
else
printf("%d nao eh par\n\n", x);
break;
case 9:
printf("\n\n### Multiplicidade de numeros\n");
printf("Numero 1: "); scanf("%d",&x);
printf("Numero 2: "); scanf("%d",&y);
if(multiplo(x, y))
printf("%d eh multiplo de %d\n\n", x, y);
else
printf("%d nao eh multiplo de %d\n\n", x, y);
break;
case 10:
printf("\n\n### Saber se numero eh primo\n");
printf("Numero: "); scanf("%d",&x);
if(primo(x))
printf("%d eh primo\n\n", x);
else
printf("%d nao eh primo\n\n", x);
break;
case 11:
printf("\n\n### Divisores de um numero\n");
printf("Numero: "); scanf("%d",&x);
printf("Divisores de %d: ", x);
//Exibindo o vetore de numeros
div=divisores(x);
for(y=0 ; div[y-1] != x; y++)
printf("%3d ",div[y]);
printf("\n\n");
break;
default:
printf("Operacao nao identificada\n\n");
}
printf("Digite 0 para sair, ou outro numero para continuar: ");
scanf("%d", &continuar);
if(continuar)
menu();
else
printf("Saindo do programa...\n");
}
O ponto que queremos chegar é: não dá pra criar uma aplicação grande num único código fonte.
Precisamos nos organizar, facilitar as coisas. E iremos fazer isso através do uso de módulos, que são arquivos com código fonte da implementação.
Vamos mostrar como criar um módulo que tem somente as funções de um programa.
Criando um projeto no Code::Blocks
Uma maneira de nos organizarmos melhor, é dividir esse código todo em vários arquivos fontes, ou seja, em vários arquivos com extensão .c
Uma ótima maneira de dividirmos os arquivos é através da criação de um projeto no Code Blocks.
O nosso projeto será o mesmo, com exatamente o mesmo código e irá fazer exatamente a mesma coisa.
Na verdade, na hora que tudo virar binário (linguagem de máquina), vai ser a mesma coisa.
Essas alterações tem um único objetivo: facilitar a vida do programador.
Então vamos lá criar nosso projeto no Code Blocks.
Vá em File -> New -> Project
Como vamos criar um projeto para rodar no terminal, escolha "Console application".
[Image]
Em seguida, escolha a linguagem que irá usar, no caso, C:
[Image]
E por fim, dê um nome ao seu projeto.
Evite usar espaços em branco e acentos. Eu usei só "Calculadora". E escolha também um local para salvar seu projeto.
[Image]
Vá clicando em Next, até ter criado o projeto.
Agora vamos adicionar nosso código fonte.
Note que, ao lado, irá aparecer o nome do seu projeto, e dentro uma pasta chamada "Sources".
Se clicar nela, vai ver que foi gerado um arquivo de código fonte de nome "main":
[Image]
Nesse arquivo main.c é onde vamos deixar a função main(), e nela vamos colocar apenas os cabeçalhos das funções, e uma função interna, a menu(), que vai exibir o menu de nossa aplicação, onde essa função vai ser a responsável por trabalhar com as funções presente no módulo (que vamos criar a seguir) onde iremos, de fato, implementar as funções.
O código do arquivo main.c é (veja como ela está linda, limpa e radiante):
Código C:
#include <stdio.h>
#include <stdlib.h>
/*
* Apostila C Progressivo: www.cprogressivo.net
*
* Programa com funções matemáticas
*
*/
float soma(float x, float y);
float subtracao(float x, float y);
float produto(float x, float y);
float divisao(float x, float y);
float quadrado(float x);
float cubo(float x);
int restoDivisao(int x, int y);
int par(int x);
int multiplo(int x, int y);
int primo(int x);
int* divisores(int x);
void menu();
void executa(int opcap);
int main(void)
{
menu();
return 0;
}
Agora vamos criar o módulo, de nome 'funcoes.c', que apenas contém a implementação das funções.
Ou seja, ele não precisa de main().
Para isso, vá em File -> New -> Empty File
Nesse momento o C::B pergunta se você quer salvar esse arquivo dentro do projeto, diga que sim, e escolha um nome: funcoes.c
Note que este arquivo será adicionado ao seu projeto, no menu esquerdo.
Agora dentro deste novo arquivo, vamos salvar todas as implementações das funções que compõem nosso programa.
O nosso arquivo 'funcoes.c' vai ficar:
Código C:
#include <stdio.h>
#include <stdlib.h>
void menu();
float soma(float x, float y)
{
return x+y;
}
float subtracao(float x, float y)
{
return (x-y);
}
float produto(float x, float y)
{
return x*y;
}
float divisao(float x, float y)
{
return (x/y);
}
float quadrado(float x)
{
return (x*x);
}
float cubo(float x)
{
return (x*x*x);
}
int restoDivisao(int x, int y)
{
return (x % y);
}
int par(int x)
{
if(x%2 == 0)
return 1;
else
return 0;
}
int multiplo(int x, int y)
{
if(x%y == 0)
return 1;
else
return 0;
}
int primo(int x)
{
int count;
if(x==1)
return 1;
else
{
for(count=2 ; count <= x/2 ; count++)
if(x%count == 0) //x é múltiplo de 'count', então não é primo
return 0;
return 1;
}
}
int* divisores(int x)
{
int *divisores,
*temp,
count,
divisor=0;
// Não sabemos quantos divisores x tem, mas no máximo tem x (se for 2)
temp = (int *) malloc(x*sizeof(int));
//zerando todos os elementos de temp com 0
for(count=0 ; count < x ; count++)
temp[count]=0;
//Checando os divisores de 'x' e colocando no vetor temp
for(count=1 ; count <= x ; count++)
if(x % count == 0) //'count' é divisor
{
temp[divisor] = count;
divisor++;
}
// Agora vamos colocar os divisores do vetor 'temp' em 'divisores' e retorná-lo
divisores = (int*) malloc( divisor*(sizeof(int)));
for(count=0 ; count < divisor ; count++)
divisores[count] = temp[count];
free(temp);
return divisores;
}
void executa(int opcao)
{
int continuar=1,
x,
y,
*div;
float num1,
num2;
switch( opcao )
{
case 1:
printf("\n\n###Soma de dois numeros\n");
printf("Numero 1: "); scanf("%f",&num1);
printf("Numero 2: "); scanf("%f",&num2);
printf("%.2f + %.2f = %.2f\n\n",num1, num2, soma(num1,num2) );
break;
case 2:
printf("\n\n### Subtracao de dois numeros\n");
printf("Numero 1: "); scanf("%f",&num1);
printf("Numero 2: "); scanf("%f",&num2);
printf("%.2f - %.2f = %.2f\n\n",num1, num2,subtracao(num1,num2) );
break;
case 3:
printf("\n\n### Produto de dois numeros\n");
printf("Numero 1: "); scanf("%f",&num1);
printf("Numero 2: "); scanf("%f",&num2);
printf("%.2f * %.2f = %.2f\n\n",num1, num2,produto(num1,num2) );
break;
case 4:
printf("\n\n### Divisao de dois numeros\n");
printf("Numero 1: "); scanf("%f",&num1);
printf("Numero 2: "); scanf("%f",&num2);
if(num2 == 0)
printf("Operacao invalida. Denominador nao pode ser 0\n\n");
else
printf("%.2f / %.2f = %.2f\n\n",num1, num2, divisao(num1,num2) );
break;
case 5:
printf("\n\n### Resto da divisao de dois numeros\n");
printf("Numero 1: "); scanf("%d",&x);
printf("Numero 2: "); scanf("%d",&y);
printf("%d %% %d == %d\n\n",x,y,restoDivisao(x,y) );
break;
case 6:
printf("\n\n### Quadrado de um numero\n");
printf("Numero: "); scanf("%f",&num1);
printf("%.2f * %.2f = %.2f\n\n",num1, num1, quadrado(num1) );
break;
case 7:
printf("\n\n### Cubo de um numero\n");
printf("Numero: "); scanf("%f",&num1);
printf("%.2f * %.2f * %.2f= %.2f\n\n",num1, num1, num1, cubo(num1) );
break;
case 8:
printf("\n\n### Paridade de um numero\n");
printf("Numero: "); scanf("%d",&x);
if(par(x))
printf("%d eh par\n\n", x);
else
printf("%d nao eh par\n\n", x);
break;
case 9:
printf("\n\n### Multiplicidade de numeros\n");
printf("Numero 1: "); scanf("%d",&x);
printf("Numero 2: "); scanf("%d",&y);
if(multiplo(x, y))
printf("%d eh multiplo de %d\n\n", x, y);
else
printf("%d nao eh multiplo de %d\n\n", x, y);
break;
case 10:
printf("\n\n### Saber se numero eh primo\n");
printf("Numero: "); scanf("%d",&x);
if(primo(x))
printf("%d eh primo\n\n", x);
else
printf("%d nao eh primo\n\n", x);
break;
case 11:
printf("\n\n### Divisores de um numero\n");
printf("Numero: "); scanf("%d",&x);
printf("Divisores de %d: ", x);
//Exibindo o vetore de numeros
div=divisores(x);
for(y=0 ; div[y-1] != x; y++)
printf("%3d ",div[y]);
printf("\n\n");
break;
default:
printf("Operacao nao identificada\n\n");
}
printf("Digite 0 para sair, ou outro numero para continuar: ");
scanf("%d", &continuar);
if(continuar)
menu();
else
printf("Saindo do programa...\n");
}
void menu()
{
int opc;
printf("\n\n### Biblioteca Matematica do C Progressivo ### \n");
printf("Escolha sua opcap: \n");
printf("0. Sair\n");
printf("1. Somar dois numeros\n");
printf("2. Subtrair dois numeros\n");
printf("3. Multiplicar dois numeros\n");
printf("4. Dividir dois numeros\n");
printf("5. Resto da divisao de dois numeros\n");
printf("6. Quadrado de um numero\n");
printf("7. Cubo de um numero\n");
printf("8. Saber se um numero eh par\n");
printf("9. Saber se um numero eh multiplo de outro\n");
printf("10. Saber se numero eh primo\n");
printf("11. Divisores de um numero\n");
do
{
printf("\nEscolha sua opcao: ");
scanf("%d", &opc);
}while(opc<0 || opc > 11);
if(opc)
executa(opc);
else
printf("Saindo do programa...\n");
}
Agora basta compilar e rodar nosso projeto, normalmente.
O Code::Blocks vai buscar dentro desses arquivos (main.c e funcoes.c) aquele que possui a função 'main()', e iniciar a execução do código. Para ele, é como se fosse tudo a mesma coisa, um único amontoado de código.
Para nós, programadores, é que há diferença, pois agora nossos códigos estão mais organizados.
Imagine que você vai criar um programa complexo, como um jogo.
Em vez de misturar tudo num código fonte só, você poderá fazer: 'audio.c', 'graficos.c', 'cenario.c' e outros arquivos, onde cada um deles irá conter os códigos referentes ao áudio, gráficos, cenários e o que mais tiver em seu sistema.
Agora ele pode ter milhares de linhas, mas pelo menos dividimos o código em vários arquivos, e sabemos o que cada um deles contém.
Criando e Linkando (ligando) códigos/arquivos objeto via linha de comando
Quando criamos um projeto no Code Blocks, podemos dividir o código em vários módulos, e apenas rodamos tudo para ver o resultado final. Isso acontece porque o Code Blocks faz algumas coisas por debaixo dos panos.
Como nunca é bom, no estudo de uma linguagem de baixo nível, deixar que algumas coisas aconteçam 'secretamente', vamos ensinar agora como juntar esses módulos na mão, através da linha de comando, pois ao entender isso vamos entender o que é código-fonte, código-objeto e o binário.
Primeiro criamos o 'main.c' e o 'funcoes.c', separadamente. Pelo bloco de notas, ou outro editor de texto, por exemplo.
Agora precisamos compilar cada um deles, onde a compilação é um processo de checagem de seu código, onde será avaliado se seu código está ok, se declarou todas as variáveis, não digitou nada errado e detalhes específicos de cada linguagem.
Vamos, portanto, compilar nossos dois códigos fonte: 'main.c' e 'funcoes.c'
Isso é feito através dos comandos, no seu terminal de comando, dentro do diretório onde salvou os fontes:
gcc -c main.c
gcc -c funcoes.c
Ou diretamente: gcc -c main.c funcoes.c
Um fato interessante sobre o processo de compilação, é que ela é feita separadamente.
Fazemos a compilação de ambos os códigos fonte, mas esses arquivos simplesmente não sabem da existência um do outro.
Embora o arquivo 'main.c' tenha a chamada para a função 'menu()', que chama as funções que são implementadas no módulo 'funcoes.c', o compilador exige apenas que essas funções sejam declaradas no 'main.c', e não necessariamente implementada lá.
Ou seja, fizemos os cabeçalhos das funções no 'main.c' apenas para dizer ao compilador 'Hey, essas funções aqui existem. Elas recebem argumentos de tais tipos e retornam tais valores, ok? É apenas isso que você precisa saber'.
Se você notar na sua pasta onde estão os códigos fonte, vão ser criados alguns arquivos automaticamente: main.o e funcoes.o
Estes são os códigos objeto, que nada mais são que o resultado da compilação de um código-fonte.
É no código que existem as informações sobre os símbolos das variáveis, alocação de memória e outras informações e instruções especificas, que variam para cada linguagem. O que precisamos saber aqui é que o código-objeto é o resultado de uma compilação dos códigos fonte.
Agora sim, um arquivo tomará ciência da existência do outro, pois vamos usar o linker (ou ligador) para unir os dois códigos objetos em um arquivo só, e o transformar em arquivo executável.
E isso também é feito pelo maravilhoso e fantástico gcc (um viva para o gcc: VIVA!), através do comando (caso use Linux):
gcc -o programa main.o funcoes.o
Caso esteja no Windows, faça:
gcc -o programa.exe main.o funcoes.o
Em ambos casos, tanto 'programa' como 'programa.exe' são os arquivos executáveis, resultado da união dos arquivos-objeto.
Agora sim podemos executar nosso programa, que foi feito por mais de um código fonte.
No Windows, simplesmente digite o nome do arquivo no terminal do DOS (command) ou clique duas vezes no executável criado.
No Linux: ./programa
E voilá. Criamos nosso código, organizamos criando módulos, compilamos e linkamos os código-objeto para criar o executável.
7 Comentários
Fechar esta janela Ir para formulário de comentárioTenho uma duvisa dentro do pouco que sei.
Se usarmos na pagina main.c;
#include "funcoes.c"
este comando faria a ligação as duas páginas?
20 de setembro de 2013 às 11:02
Vamos ensinar, no próximo tutorial de nossa apostila, como fazer isso, de importar outros arquivos.
No caso, vamos mostrar como criar os headers (cabeçalhos, aqueles arquivos com extensão .h)
20 de setembro de 2013 às 12:17
Olá...
mais se eu criar um FILE *exemplo
dentro de um arquivo.c que não seja a main ele da erro
pode me ajudar?
10 de novembro de 2013 às 20:24
Olá Patrick,
Qual o erro que o compilador está mostrando?
Lembrando que pra usar o FILE* você deve ter incluído a biblioteca stdlib . h
11 de novembro de 2013 às 11:29
Oi, tudo bem? Gostaria de uma a ajuda, na faculdade o professor pediu um exercício em C, que seria mais ou menos assim, teria no menu alguns algoritmos, exemplo bubble sort,insert sort e outros, quando fosse escolher o algoritmo no menu ira trazer um arquivo do professor com as informações para compilar nesse algoritmo.... conclusão eu sei que e isso arquivo, mas o que não entendo como isso vai compilar a informação dele???
25 de janeiro de 2014 às 22:44
Eu fiz simplesmente:
gcc main.c funcoes.c -o programa.exe
e deu certo também, é muito mais simples assim.
28 de abril de 2015 às 19:53
o que acontece se em vez de um numero se puser uma letra? XD
14 de abril de 2018 às 11:04