#include <stdio_ext.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100
/*
* Área de definição das estruturas
**/
struct aluno
{
int matricula;
char nome[80];
char endereco[120];
char telefone[20];
};
// Criando o tipo Aluno que representa a estrutura aluno
typedef struct aluno Aluno;
/*
* Área dos protótipos da função
**/
int show_menu ();
void initializer (Aluno*);
void select_action (int, int*, Aluno*);
void insert_register (int*, Aluno*);
void remove_register (int, Aluno*, int*);
void change_register (int, Aluno*, int*);
void sort_registers (Aluno*, int*);
void show_registers (Aluno*, int*);
void show_register (int, Aluno*, int*);
/*
* Método principal, start do programa.
**/
int
main (void)
{
Aluno alunos[MAX];
int index = 0; // Essa variável é responsável por controlar os índices do vetor que mantem os alunos
initializer (alunos);
while (1)
select_action (show_menu(), &index, alunos);
sort_registers (alunos, &index);
show_registers (alunos, &index);
return 0;
}
/*
* Exibe o menu de funcionalidades
**/
int
show_menu (void)
{
int option;
printf ("\n1 -\tInserir novo aluno");
printf ("\n2 -\tApagar registro de aluno");
printf ("\n3 -\tModfificar registro");
printf ("\n4 -\tListar registros");
printf ("\n5 -\tBuscar registro por matricula");
printf ("\n0 -\tExit \n.: ");
scanf("%d", &option);
return option;
}
/*
* Inicializa todas as matriculas com o número 9999
**/
void
initializer (Aluno *a)
{
int i;
for (i = 0; i < MAX; i++)
a[i].matricula = 9999;
}
/*
* Esse método dita o comportamento do programa. É ele quem chama as funções que são exibidas pelo programa no menu.
* Ele é a chave central, todas as chamadas principais, passam por ele.
**/
void
select_action (int option, int *index, Aluno *a)
{
int number; /* Variável number armazena o número de matricula do aluno que o usuário deseja excluir/alterar/buscar */
int dialog_option; /* Variável dialog_option tem a função de armazenar a escolha do usuário quando o mesmo entra na tela de encerramento do programa, caso o valor armazenado pela variável seja 1 o encerramento do programa deve ser feito, caso seja 0 o encerramento do programa é abortado */
int list_option = 0; /* Variável list_option tem a função de selecionar qual a ordem da exibição, caso seja 0 (default) os registros serão dispostos em ordem crescente. Caso contrário os registros serão dispostos em ordem decrescente */
switch (option)
{
case 1:
insert_register (index, a);
break;
case 2:
printf ("\nInforme o número de matricula do aluno que deseja excluir.: ");
scanf ("%d", &number);
remove_register (number, a, index);
break;
case 3:
printf ("\nInforme o número de matricula do aluno que deseja alterar.: ");
scanf ("%d", &number);
change_register (number, a, index);
break;
case 4:
show_registers (a, index);
break;
case 5:
printf ("\nInforme o número do registro que deseja buscar.: ");
scanf ("%d", &number);
show_register (number, a, index);
break;
case 0:
system ("clear");
printf ("\nDeseja encerrar o programa? \n[1]Sim \n[0]Não \n");
scanf ("%d", &dialog_option);
if (dialog_option == 1)
exit (0);
break;
}
}
/*
* Esse método é responsável pela inserção de registros existentes na persistencia.
**/
void
insert_register (int *index, Aluno *a)
{
int avaliable = 1;
/* Essa variavel irá responder se o nro de matricula solicitado para novo registro já se encontra cadastrado na persistência de dados.
Caso o valor de avaliable seja igual a 0 corresponde que o número solicitado já se encontra na persistência de dados, caso seja 1 corresponde que o número está disponível para identificar um novo registro.
*/
int number; /* variável armazana o número da matricula do aluno depois que ela foi validada */
do
{
int i;
system("clear");
printf ("\nInforme o número de matricula.: ");
scanf ("%d", &number);
for (i = 0; i < MAX; i++)
{
if (number < 0 || number == 9999)
{
printf ("\nEsse número não é válido!");
avaliable = 0;
break;
}
else if (number == a[i].matricula)
{
printf("\nEsse número já está cadastrado, informe um número válido!");
avaliable = 0;
break;
}
else
avaliable = 1;
}
}
while (avaliable == 0);
a[*index].matricula = number;
__fpurge (stdin);
printf ("\nInforme o nome.: ");
gets (a[*index].nome);
__fpurge (stdin);
printf ("\nInforme o endereço: ");
gets (a[*index].endereco);
__fpurge (stdin);
printf ("\nInforme o telefone: ");
gets (a[*index].telefone);
// Incrementando a variável responsável pelo controle do vetor dos alunos
*index = *index + 1;
// Reordenando os registros que se encontram na persistencia, já que um novo aluno foi inserido
sort_registers (a, index);
printf ("\n\n \t\t -- Registro inserido com sucesso! -- \n");
}
/*
* Esse método é responsável pela exclusão de registros existentes na persistencia.
**/
void
remove_register (int number, Aluno *a, int *index)
{
system ("clear");
int i;
int status = 0; /* Variável armazena se foi possível realizar a exclusão, se 0 não se 1 sim */
for (i=0; i < *index; i++)
{
if (a[i].matricula == number)
{
/* Exibindo o registro de aluno que foi encontrado, e perguntando ao usuário se realmente deseja efetuar a exclusão */
int dialog_option = 0; // Se o valor for 0 o registro não será removido, se o valor for igual a 1 o registro será removido
show_register (number, a, index);
printf ("\n Deseja realmente excluir o registro? [1] Sim [0] Não.: ");
scanf ("%d", &dialog_option);
// Sinalizando que foi encontrado registro com codigo de matricula equivalente
status = 1;
if (dialog_option == 1)
{
a[i].matricula = 9999;
strcpy (a[i].nome, "");
strcpy (a[i].endereco, "");
strcpy (a[i].telefone, "");
// Decrementando a variável responsável pelo controle do vetor dos alunos
*index = *index - 1;
// Reordenando os registros que se encontram na persistencia, já que um registro de aluno fio removido
sort_registers (a, index);
system ("clear");
printf ("\n\t\t --Registro removido com sucesso!--\n");
break;
}
}
}
if (status == 0)
printf ("\n\t\t -- Nenhum registro foi encontrado!--\n");
}
/*
* Esse método é responsável pela alteração de registros existentes na persistencia.
**/
void
change_register (int number, Aluno *a, int *index)
{
system ("clear");
int i;
int status = 0; /* Variável armazena se foi possível realizar a alteração, se 0 não se 1 sim */
Aluno aux;
for (i=0; i < *index; i++)
{
if (a[i].matricula == number)
{
__fpurge (stdin);
printf ("\nNovo nome.: ");
gets (aux.nome);
printf ("\nNovo endereço.: ");
gets (aux.endereco);
printf ("\nNovo telefone.: ");
gets (aux.telefone);
strcpy (a[i].nome, aux.nome);
strcpy (a[i].endereco, aux.endereco);
strcpy (a[i].telefone, aux.telefone);
// Modificando o valor de status, sinalizando que o registro foi localizado e removido com sucesso!
status = 1;
printf ("\n\t\t --Registro alterado com sucesso!--\n");
break;
}
}
if (status == 0)
printf ("\n\t\t -- Nenhum registro foi encontrado!--\n");
}
/*
* Esse método reorganiza a persistencia de dados (vetores) toda vez que o mesmo tem uma alteração, seja uma adição ou subtração de registros.
**/
void
sort_registers (Aluno *a, int *index)
{
int i, j;
Aluno aux;
for (i = 0; i < *index; i++)
{
for (j = 0; j < *index; j++)
{
if (a[i].matricula < a[j].matricula)
{
aux.matricula = a[i].matricula;
strcpy (aux.nome, a[i].nome);
strcpy (aux.endereco, a[i].endereco);
strcpy (aux.telefone, a[i].telefone);
a[i].matricula = a[j].matricula;
strcpy (a[i].nome, a[j].nome);
strcpy (a[i].endereco, a[j].endereco);
strcpy (a[i].telefone, a[j].telefone);
a[j].matricula = aux.matricula;
strcpy (a[j].nome, aux.nome);
strcpy (a[j].endereco, aux.endereco);
strcpy (a[j].telefone, aux.telefone);
}
}
}
}
/*
* Esse método exibe todos os registros cadastrados na persistencia (vetores)
**/
void
show_registers (Aluno *a, int *index)
{
system ("clear");
int i = 0;
for (i = 0; i < *index; i++)
{
if (a[i].matricula != 9999)
{
printf ("\n \t\t -- Registro número %d --", a[i].matricula);
printf ("\n Nome.: %s", a[i].nome);
printf ("\n Endereço.: %s", a[i].endereco);
printf ("\n Telefone.: %s", a[i].telefone);
puts("");
}
}
if (*index == 0)
printf ("\n\t\t -- Nenhum registro cadastrado -- \n");
}
/*
* O método show_register tem um funcionamento parecido com o método show_registers.
* A diferença é que esse método busca um único registro e caso encontre o exibe.
**/
void
show_register (int number, Aluno *a, int *index)
{
system ("clear");
int i;
int status = 0;
for (i = 0; i < *index; i++)
{
if (a[i].matricula == number)
{
status = 1;
break;
}
}
if (status == 1)
{
printf ("\n \t\t -- Registro número %d", a[i].matricula);
printf ("\n Nome.: %s", a[i].nome);
printf ("\n Endereço.: %s", a[i].endereco);
printf ("\n Telefone.: %s", a[i].telefone);
puts("");
}
else
printf ("\n\t\t -- Nenhum registro foi encontrado!--\n");
}
sexta-feira, 16 de novembro de 2012
Exercício de C - Estrutura de dados - Lista 5
sexta-feira, 19 de outubro de 2012
Resolução do exercício do curso de Python - Urna
Exercício
Desenvolva uma urna eletrônica utilizando a linguagem de programação Python. O programa deve possuir tupla, dicionário de dados, comandos condicionais e de iteração. O sistema deve computar os votos de todos os candidatos assim como os votos em branco e nulos.Ao final programa deve informar qual candidato venceu as eleições e mostrar um gráfico semelhante a esse:
Candidato x: ||||||||||||||||||||||||||
Candidato y: |||||||||||||||||||||||||||||||||||||||
Candidato c: |||||||||||||||||||
Candidato b: ||||||||||||||||||||||||||||||||||
Candidato a: ||||
O numero de barras na frente dos nomes são definidas peçla quantidade de votos que o candidato obteve. Considere que a cidade tenha 200 eleitores.
# -*- coding: utf-8 -*-
t = ('Marcelo ', 'Marcia ', 'Vermelho', 'Valter ', 'Branco ', 'Nulo ')
d = {t[0]: 0, t[1]: 0, t[2]: 0, t[3]: 0, t[4]: 0, t[5]: 0}
print """
\nMarcelo 15
\nMarcia 13
\nValter 55
\nVermelho 21
\nBranco 00
\nNulo 99
\n
"""
for i in range(50):
voto = int(raw_input('Informe o número do seu candidato: '))
if voto == 15: d[t[0]] += 1
elif voto == 13: d[t[1]] += 1
elif voto == 21: d[t[2]] += 1
elif voto == 55: d[t[3]] += 1
elif voto == 0: d[t[4]] += 1
else: d[t[5]] += 1
maior = -1
prefeito = ''
for candidato in d.keys():
grafico = ''
for i in range(d[candidato]):
grafico += '|'
if d[candidato] > maior:
maior = d[candidato]
prefeito = candidato
print candidato, ':', grafico
print 'O candidato ', prefeito, ' é o novo prefeito de Araraquara!'
sábado, 29 de setembro de 2012
2ª lista de recursividade
Exercício 1:
Exercício 2:
#include <stdio.h>
float calc_tarifa(int, int, int, int, int *);
int main(void)
{
int h1,h2,m1,m2, tempo;
printf("\nInforme a hr de entrada: ");
scanf("%d", &h1);
printf("\nInforme a min de entrada: ");
scanf("%d", &m1);
printf("\nInforme a hr de saída: ");
scanf("%d", &h2);
printf("\nInforme a min de saída: ");
scanf("%d", &m2);
printf("Valor a ser pago = R$ %2.2f", calc_tarifa(h1, m1, h2, m2, &tempo));
return 0;
}
float calc_tarifa(int h1, int m1, int h2, int m2, int *tempo)
{
int i;
float total;
if(m1 > 0) h1++;//se minutos forem maior que 0, serão arredondados
if(m2 > 0) h2++;
*tempo = h2-h1;
for(i=1; i<=*tempo; i++)
{
switch(i)
{
case 1:
total = 8.00;
break;
case 2:
total += 6.00;
break;
case 3:
total += 3.5;
break;
case 4:
total += 3.0;
break;
case 5:
total += 3.0;
break;
default:
total += 2.0;
break;
}
}
printf("\nVocê permaneceu %d hrs no estacionamento! \n", *tempo);
return total;
}
Exercício 2:
#include <stdio.h>//biblioteca para entrada/saída
#include <string.h>//biblioteca para manipulação de cadeia de caracteres
#include <stdlib.h>//biblioteca para funções acessar algumas funções do sistema, neste seu uso é para alocação dinâmica de memória
#define MAX 100//constante define o tamanho máximo de caracteres que podem ser inseridos no vetor
char * mesclar(char *, char *);
int main(void)
{
char original[MAX];//vetor original, ele quem armazena a palavra completa fornecida pelo usuário
int i, v1=0, v2=0;//variaveis de controle
char * pCp1, * pCp2;//ponteiros para a posição de memória dos vetores cp1, cp2[]
pCp1=malloc(MAX*sizeof(char));//alocando MAX memória para garantir que todas as letras serão armazenadas com sucesso
pCp2=malloc(MAX*sizeof(char));//alocando MAX memória para garantir que todas as letras serão armazenadas com sucesso
if(!pCp1 || !pCp2) printf("\n** ERRO : MEMÓRIA INSUFFICIENTE **");//verifica se não houve erro ao alocar a memória por falta de espaço
//exibindo msg na tela e capurando a entrada do usuário
printf("\nEntre com a palavra : ");
gets(original);//função própia para ler cadeia de caracters... gets armazena inclusive espaços em branco
/*
comando irá percorrer até o tamanho da palavra digitada (strlen), afim de dividir o vetor em outros
dois vetores. O vetor pCp1 armazena todas as letras que se encontram em indices pares. Já o vetor
pCp2 armazena todas as letras que se encontram em indices ímpares.
*/
for(i=0; i<strlen(original); i++)
{
if(i%2==0)
{
pCp1[v1] = original[i];
v1++;
}
else
{
pCp2[v2] = original[i];
v2++;
}
}
pCp1 = realloc(pCp1,v1*sizeof(char));//realocando a memória a fim de economizá-la
pCp2 = realloc(pCp2,v2*sizeof(char));//realocando a memória a fim de economizá-la
printf("%s", mesclar(pCp1, pCp2));//chamada da função para refazer as palavras
return 0;
}
char * mesclar(char * cp1, char * cp2)
{
int i, size, v1=0, v2=0;/* A variavel i, v1, v2 são controladoras... já a variavel size é responsável por indicar a soma
entre os tamanhos das cadeias de caracteres passadas por parametro.
*/
char * final;//Essa será a cadeia de caracteres final, ou seja, a mesma cadeia que foi digitada no inicia do programa
size = strlen(cp1)+strlen(cp2);//somando os tamanhos das cadeias distintas
final=malloc(size*sizeof(char));//alocando o espaço de memoria de acordo com o tamanho que a palavra possui
if(!final)
{
printf("\n** ERRO : MEMÓRIA INSUFFICIENTE **");//verifica se não houve erro ao alocar a memória por falta de espaço
return NULL;
}
else
{
for(i=0; i<size; i++)
{
if(i%2==0)
{
final[i] = cp1[v1];
v1++;
}
else
{
final[i] = cp2[v2];
v2++;
}
}
return final;
}
}
quinta-feira, 27 de setembro de 2012
Recursividade - entendendo o conceito recursivo
Olá pessoal, hoje vamos entender e aprender a montar funções recursivas, como estou trabalhando em um novo projeto de python onde vou montar um curso do básico ao avançado, todos os exemplos de hoje serão escritos na linguagem python.
O que é recursividade?
Recursividade pode ser definida como a capacidade que uma função ou subrotina tem de invocar a si mesma, ou seja, definimos uma função como recursiva se esta faz uma chamada a si mesmo.
Recursividade x Iteração
Quando falamos de recursividade algumas duvidas surgem, como: "Porque não usar iteração ao invés de recursividade?"... bom é um estilo de programação e algumas vezes determinadas soluções não serão possíveis de ser realizadas apenas com iterações (loops). Abaixo os prós e contras da recursividade:
Prós:
- Código elegante;
- Código mais legivel;
- Necessidade de mais memória;
- Consome mais processamento;
- Recursividade só pode ser usanda com linguagem C/C++?
- Porque quando falamos de recursividade o pessoal só mostra exemplos aplicados em funções que calculam fatorial de um número ou série fibonnacci?
Vamos aos ... Exemplos!
Vamos exemplificar o conceito programando alguns problemas utilizando-se da recursividade para solucioná-los.Abaixo temos o famoso exemplo fatorial utilizando recursividade:
def fatorial (valor):
if valor == 1 or valor == 0:
return 1
else:
return valor * fatorial(valor-1)
#vamos pedir um valor para o usuario
a = input('Informe um numero: ')
#chamando a funcao e imprimindo o valor que ela retorna
print fatorial(a) Uma função só é liberada da memória quando ela chega ao seu final. No caso da função fatorial() enquanto o parâmetro valor não for igual a 1, ela não vai ser encerrada (não vai chegar ao seu final) com isso ela persiste com uma referencia ativa na memória e se reexecuta. Com isso uma pilha de valores vai sendo criada na memória e enquanto a função não terminar esse processor vai ser repetido até que haja um estouro de memória ou que a função seja encerrada.
Vamos fazer um exemplo mais tranquilo agora pequeno gafanhoto, vamos fazer um programa que irá imprimir a soma de todos os numeros presentes no intervalo de 1 até X:
# -*- coding: UTF-8 -*-
def soma (n):
if n == 1:
return 1
else:
return n + soma( n - 1)
n = input("Informe um número: ")
print soma(n)
Importante: Deve-se definir uma solução que implica em uma condição de terminação (solução trivial). Outro fator importante é provar que a função decresce a cada passo de repetição.
Dúvidas, sujestões comentem...
domingo, 23 de setembro de 2012
Programando em Java - parte 11
Encapsulamento
Encapsulamento é uma técnica usada no paradigma Orientado a Objetos afim de centralizar e facilitar a busca de eventuais erros contidos no código.
Exemplo:
public class Gato {
String raca;
}
No exemplo acima, o atributo raça pode ser acessado e modificado em qualquer classe que esteja no projeto em que a classe Gato foi criada. Quando isso ocorre dizemos que o controle é descentralizado.
Para identificarmos e corrigirmos possíveis erros relacionados a raça do gato teremos que analisar todo o projeto já que a raça é visível ao projeto todo.
Vamos nos deparar muito com essa palavra "visibilidade", isso quer dizer "quem tem permissão para realizar a manipulação daquele atributo".
Para resolvermos este problema e criarmos o chamado controle centralizado devemos tornar o atributo raca privado e implementar métodos publicos que implementem toda a lógica de manipulação necessária desse atributo.
Os atributos devem ser privados porque todo atributo privado só pode ser acessado ou alterado pela classe que ele está contido, ou seja, o atributo raca só pode ser alterado por código que esteja contido na classe Gato. E o contrário nunca poderá ser feito, se alguma outra classe que não seja a Gato tentar acessar o atributo raca, um erro de compilação será gerado.
Os métodos devem ser publicos para que as demais classes consigam acessá-los. Definir todos os atributos como privado e métodos publicos que implementem a lógica de manipulação dos atributos, é praticamente uma regra em Orientação a Objetos. Isso é feito para que o controle seja centralizado, facilitando a manutenção e detecção de erros.
Gato.java
Para identificarmos e corrigirmos possíveis erros relacionados a raça do gato teremos que analisar todo o projeto já que a raça é visível ao projeto todo.
Vamos nos deparar muito com essa palavra "visibilidade", isso quer dizer "quem tem permissão para realizar a manipulação daquele atributo".
Para resolvermos este problema e criarmos o chamado controle centralizado devemos tornar o atributo raca privado e implementar métodos publicos que implementem toda a lógica de manipulação necessária desse atributo.
Os atributos devem ser privados porque todo atributo privado só pode ser acessado ou alterado pela classe que ele está contido, ou seja, o atributo raca só pode ser alterado por código que esteja contido na classe Gato. E o contrário nunca poderá ser feito, se alguma outra classe que não seja a Gato tentar acessar o atributo raca, um erro de compilação será gerado.
Os métodos devem ser publicos para que as demais classes consigam acessá-los. Definir todos os atributos como privado e métodos publicos que implementem a lógica de manipulação dos atributos, é praticamente uma regra em Orientação a Objetos. Isso é feito para que o controle seja centralizado, facilitando a manutenção e detecção de erros.
Gato.java
public class Gato {
private raca;
public void mudarRaca(String raca) {
this.raca = raca;
}
}Métodos Privados
Nem sempre os métodos deveram ser visíveis a todas as classes do seu projeto, às vezes o método tem papel de auxiliar outros métodos que estejam na mesma classe. Nesse caso seria um erro chamar este método fora da classe em que ele foi escrito.No exemplo abaixo o método atribuiIp() é um método auxiliar de entrarRede(), sairRede(). Sendo assim ele não deve ser chamado diretamente, pois a atribuição de ip só deve ocorrer quando ele entrar na rede.
Rede.java
public class Rede {
void connectar() {
//lógica para criar conexão
}
void desconectar() {
//lógica para desconectar da rede
}
String atribuirIp() {
//lógica para retornar um número IP válido na rede
}
}
Para garantir que não será possível a chamada do método atribuirIP() fora da classe Rede, devemos adicionar o modificador private.
public class Rede {
void connectar() {
//lógica para criar conexão
}
void desconectar() {
//lógica para desconectar da rede
}
private String atribuirIp() {
//lógica para retornar um número IP válido na rede
}
}
Agora qualquer chamada ao método atribuirIP() que não seja feita pela classe Rede, acarretará um erro de compilação garantindo assim que nosso método só será chamado dentro da classe Rede.
Métodos Públicos
Todos os métodos que devem ser acessados fora da classe de origem devem conter o modificador de acesso public. O public diz ao compilador que o método pode ser acessado por qualquer objeto que esteja no projeto em que o método chamado se encontra.
public class Rede {
public void connectar() {
//lógica para criar conexão
}
public void desconectar() {
//lógica para desconectar da rede
}
private String atribuirIp() {
//lógica para retornar um número IP válido na rede
}
}
Porque encapsular?
Encapsular é uma das principais funcionalidades da programação orientada a objetos. Encapsular seria esconder o código de implementação e apenas mostrar a interface de uso do método.O encapsulamento de dados nos ajuda na manutenção e no desenvolvimento do sistema, uma vez que com ele as tarefas ficam melhores divididas entre as classes e quando devemos modificar o comportamento dos objetos basta alterar a classe do objeto.
Para que você entenda melhor vamos fazer uma simples analogia ao mundo real utilizando o conceito de POO.
Imagine o controle remoto de sua televisão, a interface de uso seria os botões de: aumentar volume, abaixar volume, trocar de canal .. etc. Quando você usa o controle podemos dizer que você está usando a interface, porém, você não sabe como o serviço é feito. Você simplesmente aperta o botão e algo acontece, pois a implementação do serviço não é interessante, não é necessária conhecermos apenas queremos executar o serviço. Trazendo para a programação agora, o botão seria a assinatura do método = public void aumentarVolume(), e o serviço é o corpo do método, ou seja, o código que está escrito dentro dele. O código não deve ser visível ao objetos que vão acessar o método mais a assinatura do método deve ser visível aos demais objetos. Entendeu?
Getters e Setters
Aplicando a ideia do encapsulamento os atributos deveriam ser todos privados, com isso não seriam acessiveis por código que estivesse fora da classe em que foram definidos.Mas na maioria dos sistemas as informações contidas nos atributos precisam ser acessadas e modificadas em qualquer parte do sistema. Nesse caso, podemos disponibilizar métodos para consulta e alteração de valores dos atributos.
Na linguagem Java, há uma convenção de nomenclatura para os métodos que tem como finalidade acessar ou alterar as propriedades de um objeto. Os métodos que tem como finalidade consultar as propiedades do objeto devem possuir o prefixo get, já os métodos que permitem a alteração das propriedades do objeto devem possuir o prefixo set.
Lembre-se bons programadores Java seguem a convenção.
public class Aluno {
private String nome;
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
}
É isso ai pessoal! Dúvidas, sugestões, comentem ai...
sábado, 22 de setembro de 2012
Programando em Java - parte 10
Atributos e Métodos de Classe
Em um sistema muitas vezes é necessário que uma váriavel seja compartilhada por todos os objetos que venham a ser criados. Em Java temos os atributos e métodos de classe. Para criarmos métodos e atributos de classe utilizamos a palavra reservada static. Um atributo de classe por definição é publico então é redundante colocar o modificador de acesso public, já que por definição static é public também.Vejamos um problema em que poderiamos aplicar uma solução utilizando atributo de classe:
Problema:
Imagine que uma montadora de veículos precise armazenar o número de carros fabricados por dia. A cada novo carro criado o sistema deve contabilizar o carro para que no final do dia possa exibir a quantidade de veículos criados.
Solução:
Montadora.java
import java.util.Date;
import java.text.SimpleDateFormat;
import javax.swing.JOptionPane;
public class Montadora {
public static void main(String[] args) {
Carro.numCarros = 0;//inicializando o valor da variável
for(int i=0; i<10;i++)
new Carro();
JOptionPane.showMessageDialog(null, "Foram fabricados " + Carro.numCarros + " carros.");
JOptionPane.showMessageDialog(null, "Data: " + new SimpleDateFormat("dd/MM/yyyy").format(new Date()));
}
}
Carro.java
public class Carro {
static int numCarros;
public Carro() {
numCarros++;
}
}
Para acessar variáveis de classe utilizamso o nome da classe, em seguida o operador ponto final (.) e o nome da variável que queremos acessar.
O correto para manipular atributos de classe é criarmos métodos de classe com a finalidade de controlar os valores contidos nesses atributos. Como a variável é publica e visível por todas as classes do nosso projeto não é explicitamente obrigatória a criação dos métodos de classe para fazer o controle dos mesmos, porém, fazer o manusei dos atributos de classe sem o uso de métodos é uma má prática de programação e consiste em um erro conceitual.
Problema 2:
Os funcionários da empresa GTi sistemas recebem vale refeição, todos os meses o valor do vale pode ser reajustado.
Solução:
Funcionario.java
public class Funcionario {
private String nome;
static float valeRefeicao;
public Funcionario(String nome) {
this.nome = nome;
}
static void reajusteValeRefeicao(float valor) {
valeRefeicao = valor;
}
}
EmpresaGTi.java
public class EmpresaGTi {
public static void main(String[] args) {
Funcionario programador = new Funcionario("Guilherme");
Funcionario rh = new Funcionario("Débora");
Funcionario analista = new Funcionario("Luiz");
Funcionario.reajusteValeRefeicao(20);//todas as instancias de funcionário compartilham da mesma variável valeRefeicao
//ERRO...
programador.valeRefeicao = 20;//é possivel, porém, é erro conceitual
}
}Dúvidas , sugestões comentem...
Programando em Java - parte 9
Arrays
Quando desejamos armazenar uma grande quantidade de valores de um determinado tipo, podemos utilizar arrays. Um array é um objeto que pode armazenar muitos valores de um determinado tipo.Podemos imaginar um array como sendo um armário com um determinado número de gavetas. E cada gaveta possui um rótulo com um número de identificação.
Criando um Array
Em Java, os arrays são criados através do comando new.int numeros = new int[100];
int numeros[]; //aqui declaro meu array, porém, não instancie. Se eu tentar usá-lo irá acontecer um erro
int numeros[] = new int[] {1,23,54,19};/*Esse tipo de declaração instancia meu array e já adiciona os valores que são passados entre as chaves. Esse tipo de declaração é usado quando o programador já sabe quais valores devem sem iniciados junto com o array*/
Utilizando as Classes Arrays e Collections
Uma das vantagens de se usar a linguagem Java é que já existem muitas coisas prontas, basta o programador pesquisar a API e conhece-lá conforme suas necessidades. Quando trabalhamos com arrays podemos contar com as Classes Arrays e Collections do pacote java.util. Essas classes possuem os seguintes métodos já definidos:- Método de pesquisa de elemento;
- Método de ordenação;
- Método de exibição de todos elementos;
- Método de inversão de ordem dos elementos contidos no array;
import java.util.Arrays;
import java.util.Collections;
import javax.swing.JOptionPane;
public class ArraysExemplo {
public static void main(String[] args) {
String profInf[] = new String[] {"Renata", "Luiz", "Edilson", "Ednilson", "Janaina", "Gislaine", "Fábio", "Eduardo", "Francisco", "José Arnaldo"};
//método bynarySearch retorna um int que condiz com a posição do elemento buscado no array
//método sort organiza o array em de forma crescente
//método toString imprime o array converte o array em String e exibe o completo na tela
//método reverse inverte a ordem do array
JOptionPane.showMessageDialog(null,"Posição: " + Arrays.binarySearch(profInf, "Janaina"));
Arrays.sort(profInf);
JOptionPane.showMessageDialog(null, "Array de forma organizada crescente : " + Arrays.toString(profInf));
Collections.reverse(Arrays.asList(profInf));
JOptionPane.showMessageDialog(null, "Array de forma organizada invertida : " + Arrays.toString(profInf));
}
}
PS = Todo bom programador deve conhecer os recursos que sua linguagem já oferece pronta, para que ele não fique "reinventando a roda". A API do completa e atualizado Java pode ser encontrada no site da Oracle.
Comparando a utilização de array em um programa Java
Abaixo temos 3 versões de um mesmo programa Java. A função desse programa é ler três valores informados pelo usuário referentes a peso. Ao termino da entrada de dados o programa deve exibir qual o maior, menor e a lista de todos os pesos lidos.Programadores que não sabem utilizar array, ou acha que é perda de tempo escreve códigos Java assim:
import javax.swing.JOptionPane;
public class ArraysExemplo1 {
public static void main(String[] args) {
float peso, x, y;
/*
* a variável peso irá armazenar o peso fornecedo pelo usuário durante a execução do programa
* a variável x irá armazenar a pessoa mais pesada
* a variável y irá armazenar a pessoa mais leve
*/
//inicializando x e y com valores impossíveis... Lembrando que essa é uma técnica não aconselhável
x = -1000;
y = 10000;
for(int i=0; i<3; i++) {
//diferentemente de C, o comando for em Java pode conter a declaração e inicialização de variáveis em sua primeira parte
peso = Float.parseFloat(JOptionPane.showInputDialog("Informe o peso"));
if(peso > x)
x = peso;
if(peso < y)
y = peso;
}
JOptionPane.showMessageDialog(null, "Mais pesado = " + x + "kg");
JOptionPane.showMessageDialog(null, "Mais leve = " + y + "kg");
//não tem como mostrar todos os pesos lidos :(
}
}Programadores que sabem utilizar array, porém, não conhecem os recursos que a API os oferecem. Irá desenvolver um código Java semelhante a este:
import javax.swing.JOptionPane;
public class ArraysExemplo2 {
public static void main(String[] args) {
float peso[] = new float[3];
float x, y;
/*
* a variável peso irá armazenar o peso fornecedo pelo usuário durante a execução do programa
* a variável x irá armazenar a pessoa mais pesada
* a variável y irá armazenar a pessoa mais leve
*/
for(int i=0; i<3; i++) {
peso[i] = Float.parseFloat(JOptionPane.showInputDialog("Informe o peso"));
}
//inicializando os valores de x e y, com o primeiro valor lido
x = peso[0];
y = x;
for(int i=1; i<3; i++) {
//diferentemente de C, o comando for em Java pode conter a declaração e inicialização de variáveis em sua primeira parte
if(peso[i] > x)
x = peso[i];
if(peso[i] < y)
y = peso[i];
}
JOptionPane.showMessageDialog(null, "Mais pesado = " + x + "kg");
JOptionPane.showMessageDialog(null, "Mais leve = " + y + "kg");
JOptionPane.showMessageDialog(null, "Todos os pesos lidos = " + peso[0] + ", " + peso[1] + ", " + peso[2]);
}
}Bons programadores, escrevem códigos assim:
import javax.swing.JOptionPane;
import java.util.Arrays;
public class ArraysExemplo3 {
public static void main(String[] args) {
float peso[] = new float[3];
for(int i=0; i<3; i++) {
try {
peso[i] = Float.parseFloat(JOptionPane.showInputDialog("Informe o peso"));
} catch(NumberFormatException e) {
JOptionPane.showMessageDialog(null, "Erro ao coverter o valor digitado!", "Erro", JOptionPane.ERROR_MESSAGE);
}
}
Arrays.sort(peso);//ordena os valores digitados
JOptionPane.showMessageDialog(null, "Mais pesado = " + peso[2] + "kg");
JOptionPane.showMessageDialog(null, "Mais leve = " + peso[0] + "kg");
JOptionPane.showMessageDialog(null, "Todos os pesos informados = " + Arrays.toString(peso));
}
}Bom pessoal, duvidas e sugestões comentem...
sexta-feira, 21 de setembro de 2012
1ª lista de exercícios EDA
Fala galera, acho que vcs já estavam com saudades ... ou não, mas enfim vamos ao que interessa, coma a volta das aulas na faculdade voltaram também as listas de exercicíos, e como muitos adoram verificar e corrigir exercicíos alheios deixo para vcs a resolução dos 29 exercicíos da lista de ETA.
#include <stdio.h>
int main() {
printf("\nÉ preciso fazer todos os algoritmos para aprender!");
return 0;
}
#include <stdio.h>
int main() {
printf("\nGuilherme Carvalho!");
return 0;
} #include <stdio.h>
int main() {
printf("%d", 28*43);
return 0;
}
#include <stdio.h> <stdio.h>
int main() {
printf("%d", (9+8+7)/3);
return 0;
} #include <stdio.h>
int main() {
int i;
printf("\nInforme um numero inteiro: ");
scanf("%d", &i);
printf("%d", i);
return 0;
}
#include <stdio.h>
int main() {
int i, ii;
printf("\nInforme dois numeros inteiro: ");
scanf("%d%d", &i, &ii);
printf("%d \n%d", i,ii);
return 0;
} #include <stdio.h>
int main() {
int i, s, a;
printf("\nInforme um numero: ");
scanf("%d", &i);
s = i + 1;
a = i - 1;
printf("Sucessor: %d \nAntecessor: %d", s, a);
return 0;
} #include <stdio.h>
int main() {
char nome[80];
char endereco[80];
char telefone[20];
printf("\nInforme o nome: ");
gets(nome);
printf("\nInforme o endereço: ");
gets(endereco);
printf("\nInforme o telefone: ");
gets(telefone);
printf("\nNome: %s \nEndereço: %s \nTelefone: %s", nome, endereco, telefone);
return 0;
} #include <stdio.h>
int main() {
int x, y;
printf("\nInforme 2 numeros inteiros: ");
scanf("%d%d", &x, &y);
printf("Soma = %d", x+y);
return 0;
} #include <stdio.h>
int main() {
int x, y;
printf("\nInforme 2 numeros inteiros: ");
scanf("%d%d", &x, &y);
printf("Produto = %d", x*y);
return 0;
} #include <stdio.h> <stdio.h>
int main() {
int x;
printf("\nInforme um numero: ");
scanf("%d", &x);
printf("Terça parte de %d = %d", x, x/3);
return 0;
} #include <stdio.h>
int main() {
int x, y;
printf("\nInforme 2 numeros inteiros: ");
scanf("%d%d", &x, &y);
printf("Media = %d", (x+y)/2);
return 0;
} #include <stdio.h>
int main() {
float v;
printf("\nInforme valor: ");
scanf("%f", &v);
v *= 1.01;
printf("\n%f", v);
return 0;
} #include <stdio.h>
int main() {
int a, h;
printf("\nárea: ");
scanf("%d", &a);
printf("\nbase: ");
scanf("%d", &h);
printf("\narea=%d \nperimetro=%d", h*a, (h*2)+(a*2));
return 0;
} #include <stdio.h>
#define PI 3.1415
int main() {
int r;
printf("\nRaio: ");
scanf("%d", &r);
printf("\nPerimetro = %f, Area = %f", 2*PI*r, PI*r*r);
return 0;
} #include <stdio.h>
int main() {
int a, h;
printf("\nlado: ");
scanf("%d", &a);
printf("\narea=%d \nperimetro=%d", a*a, (a*2)+(a*2));
return 0;
} #include <stdio.h>
int main() {
int b, a;
printf("\naltura: ");
scanf("%d", &a);
printf("\nbase: ");
scanf("%d", &b);
printf("\narea=%d ", (b*a)/2);
return 0;
} #include <stdio.h>
int main() {
float x;
printf("\nvalor: ");
scanf("%f", &x);
printf("\nnovo valor = %f", x*0.91);
return 0;
} #include <stdio.h>
int main() {
int x;
printf("\nnumero: ");
scanf("%d", &x);
if(x >= 20 && x <= 90) {
printf("\nNro está compreendido entre o intervalo!");
} else {
printf("\nNro não está compreendido entre o intervalo!");
}
return 0;
} #include <stdio.h>
int main() {
char nome[100];
int idade;
char sexo;
printf("\nInforme o nome: ");
gets(nome);
printf("\nInforme a idade: ");
scanf("%d", &idade);
__fpurge(stdin);
printf("\nInforme sexo [M/F]: ");
scanf("%c", &sexo);
sexo = toupper(sexo);
if(sexo == 'F' && idade < 25) {
printf("\nNome: %s \nAceito (a)", nome);
} else {
printf("\nNome: %s \nNão aceito (a)", nome);
}
return 0;
} #include <stdio.h>
int main() {
int x, y, z;
printf("\nInforme 3 valores: ");
scanf("%d%d%d", &x, &y, &z);
if((x + y > z) && (x + z > y) && (y + z > x)) {
printf ("É triangulo");
} else {
printf("\nNão é triangulo");
}
return 0;
} #include <stdio.h>
int main() {
int x, y, z;
printf("\nInforme 3 valores: ");
scanf("%d%d%d", &x, &y, &z);
if((x + y > z) && (x + z > y) && (y + z > x)) {
printf("\nTriângulo ");
if((x == y) && (z == x) && (y == z))
printf("Equilátero");
else if((x != y) && (z != x) && (y != z))
printf("Escaleno");
else
printf("Isóceles");
} else {
printf("\nNão é triangulo");
}
return 0;
} #include <stdio.h>
int main() {
int x;
printf("\nInforme um numero: ");
scanf("%d", &x);
if(x % 4 == 0) {
printf("\nMultiplo de 4!");
} else if(x % 7 == 0) {
printf("\nMultiplo de 7!");
} else {
printf("\nNão é multiplo de 4 nem de 7!");
}
return 0;
} #include <stdio.h>
int main() {
int x;
printf("\nInforme um numero: ");
scanf("%d", &x);
if(x <= 1) {
x = 1;
} else if(x > 1 && x <= 2) {
x = 2;
} else if(x > 2 && x <= 3) {
x = x*x;
} else {
x = x*x*x;
}
printf("\nValor de x = %d", x);
return 0;
} #include <stdio.h>
int main() {
int i;
for(i = 1; i <= 600; i++) {
if(i % 2 == 0) {
printf("%d\t", i);
}
}
return 0;
} #include <stdio.h>
int verificaPrimo(int n) {
int i;
for(i = 2; i < n; i++) {
if(n % i == 0) {
return 1;//não é primo
break;
}
}
return 0;//primo
}
int main() {
int i;
for(i = 1; i < 2001; i++) {
if(!verificaPrimo(i))//nega condição
printf("%d\t", i);
}
return 0;
} #include <stdio.h>
int main() {
float v;
printf("\nInforme o valor do produto: ");
scanf("%f", &v);
if(v < 20)
v *= 1.45;
else
v *= 1.3;
printf("\nValor de venda: %5.2f", v);
return 0;
} #include <stdio.h>
int main() {
int nBg, nBm;//número do boi gordo e boi magro respectivamente
float pBg, pBm;//peso do boi gordo e boi magro respectivamente
int i = 1;
int n;
float p;
printf("\nInforme o numero do %dº boi: ", i);
scanf("%d", &nBg);
printf("\nInforme o peso do %dº boi: ", i);
scanf("%f", &pBg);
nBm = nBg;
pBm = pBg;
for(i = 2; i <= 90; i++) {
printf("\nInforme o numero do %dº boi: ", i);
scanf("%d", &n);
printf("\nInforme o peso do %dº boi: ", i);
scanf("%f", &p);
if(p > pBg) {
pBg = p;
nBg = n;
} else {
pBm = p;
nBm = n;
}
}
printf("\nBoi + gordo = %dº %3.2f \nBoi + magro = %dº %3.2f", nBg, pBg, nBm, pBm);
return 0;
} #include <stdio.h>
#include <stdio.h> <stdio.h>
int main() {
char sexo;
char olhos[9];
char cabelos[9];
float porcentagem = 0;
int idade, i, mIdade = -1;
for(i = 1; i <= 200; i++) {
__fpurge(stdin);
printf("\nSexo [M/F]: ");
scanf("%c", &sexo);
sexo = toupper(sexo);
__fpurge(stdin);
printf("\nOlhos: ");
gets(olhos);
__fpurge(stdin);
printf("\nCabelos: ");
gets(cabelos);
printf("\nIdade: ");
scanf("%d", &idade);
if(idade > mIdade)
mIdade = idade;
if(sexo == 'F') {
if(idade > 17 && idade < 36) {
if(strcasecmp("castanho", olhos) == 0 && strcasecmp("preto", cabelos) == 0)
porcentagem++;
}
}
}
printf("\nMaior idade = %d", mIdade);
printf("\nPorcentagem = %3.2f", porcentagem/2);
return 0;} terça-feira, 31 de julho de 2012
Estrutura de dados - Vetor
Em C existem vetores unidimensionais e bidimensionais, ambos são estruturas homogenias ordenadas e que podem assumir um número de elementos finitos.
Para declarar um vetor, usa-se o a seguinte notação:
tipo nome_vetor [intervalo]
O menor elemento do vetor é chamado limite mínimo e, em C, é sempre 0, e o maior elemento é chamado limite máximo. O número de elementos no vetor é chamado de faixa, a faixa pode ser obtida com limite máximo - limite mínimo - 1 = faixa.
Em C os limites não podem serem alterados durante a execução do programa, o limite mínimo é sempre fixado em 0, o limite máximo é fixado quando é escrito. Uma técnica que muitos programadores utilizam para simplificar a manutenção do código, é o emprego de um identificador de constante.
Para declarar um vetor, usa-se o a seguinte notação:
tipo nome_vetor [intervalo]
O menor elemento do vetor é chamado limite mínimo e, em C, é sempre 0, e o maior elemento é chamado limite máximo. O número de elementos no vetor é chamado de faixa, a faixa pode ser obtida com limite máximo - limite mínimo - 1 = faixa.
Em C os limites não podem serem alterados durante a execução do programa, o limite mínimo é sempre fixado em 0, o limite máximo é fixado quando é escrito. Uma técnica que muitos programadores utilizam para simplificar a manutenção do código, é o emprego de um identificador de constante.
//sem idenficador
int main() {
int vetor[100];
return 0;
}#define LIM 100
int main() {
int vetor[LIM];
return 0;
}Vetores como parâmetros
Como uma variável vetor em C é um ponteiro, os parâmetros vetores são passados por referência em vez de por valor. O conteúdo de um vetor não é copiado quando passado como um parâmetro, em vez disso é passado o seu endereço de memória.
A passagem por referência é muito mais eficiente, já que ela poupa espaço e tempo. Espaço porque não há necessidade de uma segunda cópia do vetor, já que este será modificado diretamente, com isso há um ganho de tempo.
Uma string tem limite minimo igual a 0 e seu limite máximo é o número de caracteres na string. Exemplo:
"Guilherme" é um vetor de 10 elementos (a tecla de escape é contada).
Isso define um novo vetor contendo três elementos. Cada um desses elementos é em si mesmo um vetor contendo cinco inteiros. Um elemento desse vetor é acessado especificando-se dois índices: um número de linha e um número de coluna.
A passagem por referência é muito mais eficiente, já que ela poupa espaço e tempo. Espaço porque não há necessidade de uma segunda cópia do vetor, já que este será modificado diretamente, com isso há um ganho de tempo.
#include <stdio.h>
#define SIZE 10
//PERCEBA QUE NÃO É NECESSÁRIO A PASSAGEM DO TAMANHO DE MEU VETOR
void _preencheVetor(int []);
void _preencheVetor(int v[]) {
int i;
for(i = 0; i < SIZE; i++) {v[i] = 1;}
}
void _exibeVetor(int v[]) {
int i;
for(i = 0; i < SIZE; i++) {printf("%d\t", v[i]);}
}
int main() {
int v[SIZE];
_preencheVetor(v);
_exibeVetor(v);
return 0;
}Cadeia de caracteres (String) em C
Em C uma string é definida como um vetor de caracteres. O carácter NULL é responsável por encerrar uma string, esse caractere é inserido automaticamente ao final de toda string. O caractere NULL é representado pela sequencia de escape \0.Uma string tem limite minimo igual a 0 e seu limite máximo é o número de caracteres na string. Exemplo:
"Guilherme" é um vetor de 10 elementos (a tecla de escape é contada).
Operações com Strings
Agora vamos implementar algumas operações para manipular Strings.- Encontrar o tamanho da string (strlen);
- Concatenar strings (strcat).
int strlen(char []);
int strlen(char array[]) {
int i;
for(i = 0; array[i] != '\0'; i++)
return i;
}
int main() {
char array[100];
printf("\nNúmero de elementos = %d", strlen("GUILHERME"));
return 0;
}
#include <stdlib.h>
char *concat(char *s1, const char *s2)
{
char *ps1 = s1;
while(*ps1)
ps1++;
while(*ps1++ = *s2++);
return s1;
}
int main(int argc, char *argv[])
{
char nome[10] = "Guilherme";
char sobrenome[10] = " Carvalho";
char *resultado = concat(nome, sobrenome);
printf("%s\n\n", resultado);
return 0;
}
Vetores bidimensionais
O tipo dos componentes de um vetor pode ser outro vetor. Por exemplo, podemos definir:
int m[3][5];
Isso define um novo vetor contendo três elementos. Cada um desses elementos é em si mesmo um vetor contendo cinco inteiros. Um elemento desse vetor é acessado especificando-se dois índices: um número de linha e um número de coluna.
Próximo assunto -> Lista
domingo, 22 de julho de 2012
Estrutura de dados - Ponteiros
O ponteiro nada mais é do que uma variável que guarda o endereço de memória, ou seja, ela aponta para um determinado espaço que foi alocado na memória. A declaração de ponteiros é feita das três seguintes formas:
- permitem a modificação de argumentos de funções: Permite que as funções altere valores de variáveis não globais e não locais e ela através da referência ao endereço de memória da variável passada como parâmetro para a função;
#include <stdio.h>
void _f_modifica(int *); ///assinatura da função
void _f_modifica(int *p) {
*p = 5;
}
int main() {
int i;
i = 10;
printf("\nValor de i = %d", i);
_f_modifica(&i); //passando o endereço de meḿória da variável i
printf("\nValor de i = %d", i);
return 0;
} - Permitem o uso de rotinas de alocação dinâmica de memória: alocação e desalocação de memória em tempo de execução conforme a necessidade do programa;
char *ptr;
ptr = malloc (1); - Aumento de eficiência em determinadas rotinas. A forma de declaração de uma variável ponteiro é:
tipo *nome_variável
Onde tipo é o tipo de variável apontada pela variável ponteiro.
Próximo assunto -> Vetor
Tipo de dado abstrato TDA
TDA ou tipo de dado abstrato significa um conjunto de valores e uma sequencia de operações sobre estes valores. Isto é um modelo matemático pelo par (V, O), onde V é um conjunto de valores e O é um conjunto de operações sobre estes valores.
Exemplo:
Dicionário Inglês-Português
Exemplo:
Dicionário Inglês-Português
- V: conjunto de pares de palavras;
- O: inserção de um novo par, remoção de um par, consulta palavra, alteração de palavra.
Um TDA permite definir, além dos dados que serão manipulados por uma estrutura de dado, as operações a executar nos dados representados. Diferentes operações podem ser executadas, tais como operações para criar e eliminar estruturas de dados, operações para inserir, alterar e eliminar elementos das estruturas de dados, e operações para acessar elementos na estrutura de dados.
Não é necessário conhecer ou depender da implementação de um TDA para utilizá-lo, mas, apenas sua interface (conjunto de operações válidas). O TDA é uma técnica muito útil para os programadores que queiram usar certas propriedades matemáticas que não existam na linguagem que eles usam ou usar um tipo de dado de maneira correta.
Próximo assunto -> Ponteiro
Assinar:
Postagens (Atom)
Novidade!!! Agora vamos ter canal no Youtube =D
Fala pessoal tudo beleza, estou sumido a correria está forte por aqui. Estou querendo dar um start em um projeto antigo que vem desde o temp...
-
Olá pessoal, hoje vamos entender para que servem as bibliotecas que importamos para o programa C. Com certeza a primeira coisa que você...
-
Olá pessoal, vamos atualizar nosso blog? :-) Depois de um longo período sem postagens novas resolvi liberar 2 novos assuntos para o pessoa...
