Mostrando postagens com marcador Programação. Mostrar todas as postagens
Mostrando postagens com marcador Programação. Mostrar todas as postagens

Estruturas em C

14 janeiro 2012
1 comentários

Depois de cerca de 1 ou 2 seculos sem postar aqui no blog(o motivo seria este?), aproveito para me desculpar perante o fundador e os outros colaboradores do BlogIG, venho agora postar um artigo mais ou menos explicativo sobre as estruturas em C, que são umas das coisas mais importantes e decisivos que o C apresenta a quem esta interessado em utiliza-lo!
Primeiro claro vamos a uma breve aula sobre a basicidade do C: A linguagem C ao contrario daquilo que a maioria das pessoas pensa, e uma linguagem de programação bastante direta, não é complicada(ela é complexa) e não complica a vida complicada do programador! O que existe é o que chamo de ignorância acusativa , quando as pessoas acusam algo sem mesmo conhece-las !
Comecemos, o C tem quatro tipo básico de dados: int(variável para guardar valores inteiros positivos ou negativos), float(variável para guardar valores decimais) , char(para guardar caracteres,apenas caracteres) e o double(o double é uma mistura do float e do int), você precisa saber disso porque no C você quando  cria uma variável você tem de especificar o seu tipo.No C não existe o tipo string de forma implicita, o que você tem de fazer é criar um array de caracteres que vão albergar uma string(ideia simplesmente genial) e já agora quando você cria uma array você tem de especificar o seu tamanho resultando em erro no caso negativo.As regras de nomenclatura das variáveis são muito simples, o C difere A de a, ou seja, ele e case-sensitive tanto nas funções como nas variáveis, e as variáveis não podem conter caracteres especiais nem espacos,o underscore( _ ) e o "tracinho"(-) sao exceções a regra.
O que as pessoas precisam entender é que o C e uma linguagem que trabalha na camada mais perto do computador possivel, um programa bem feitinho no C corre 1000 vezes mais rápido do que outro tambem bem feitinho no Python,Ruby,Visual Basic,PHP ou no Java (1000 talvez seja exagero mas...) porquê? Muito simples, o C trabalha com a memoria,o cpu enfim "quase" directamente com o computador, também entenda que isso pode ser perigoso se o seu programa faz coisas "indevidas" ou se ele não se controla e sai por ai disparando ciclos infinitos ou ponteiros que estão apontando para o nada(fica a dica), essa linguagem maravilhosa faz as coisas como você quiser, o C não sabe se voce vai usa-lo no terminal,ou numa interface gráfica ou em qualquer outra coisa por isso ele deixa que você o informe qual vai ser a sua saida,por isso quando você quer imprimir um trivial "Hello World" no terminal (por favor faça esse hello world , assim você chamará os deuses da programação para te acompanharem  e assim as dificuldades não serão nulas mas poucas e solucionáveis a tempo) você deve incluir uma ou duas bibliotecas(stdio e stdlib) para lhe fornecerem funções para poder trabalhar com o terminal( o printf, ou o scanf são grandes exemplos disso), através de chamados preprocessadores (#include <biblioteca.extensao> ou #include "biblioteca. extensão" ).Como funcionam as funções no C,quando você quer criar uma função voce deve pensar e decidir se ele vai retornar algo ou não,porque nessa linguagem as funções estão divididas em 2 ramos: as que não retornam nada(apelidadas de void) e as que retornam alguma coisa(aqui voce vai especificar se a função vai retornar um numero,um caractere ou uma string) isso é uma das engenharias mais bem planeadas que já vi.Bom paremos por aqui,tenho de lhe remeter a ideia de que este artigo nao lhe ensina a programar em C, mas se voce quiser ler algo sobre o C ( LEIA ISTO ,as melhores documentações estão em português brasileiro, por isso,o meu português é uma mistura da portuguesa e da brasileira ).
As estruturas em C impressionaram-me de tal forma que a minha ideia de construir uma linguagem de programação para mim(projecto pessoal, não é nada de reinventar a roda como alguns podem pensar) tomou outra frente, mas porquê, muito simples, o C permite que você crie os seus próprios tipos de dados usando os já existentes(int,float,char e double) isso não é maravilhoso ? Eu não conheço muitas linguagens de programação mas esta capacidade original e esmagadora não abunda por ai fora, se você misturar esse conceito com os ponteiros(um tipo de variável que guarda o endereço de memória de outra variável) você vai conseguir criar algo esmagador(smashing turbo) e que vai impressionar qualquer um.
Uma estrutrura serve simplesmente para guardar tipos de variáveis dentro de si(apenas tipos,ela não guarda nenhuma variavel dentro dela) que possuem algo em comum.Não confunda, quando você cria uma estrutura você cria apenas um conceito de dado, nunca uma variável, pensar que uma estrutura é uma variável e como pensar que o int ou que o char sao variáveis, quando elas são apenas tipos de dados, pense da seguinte forma se o int e o float são tipos de dados, criar uma ]] estrutura e como criar o seu proprio int ou o seu proprio char,so que a estrutura vai ser muito mais rica e forte do que um simples int ou um simples char   porque ela vai ser uma mistura dessas variáveis e ela vai conter um conceito lógico rico e diversificado. Resumindo uma estrutura é um tipo de dado criado por si mesmo,em que o tipo de dados que a constroem possuem uma relação entre si.Bom vamos deixar de ler e falar,escrever e pensar e passar para a prática.
Imagine que você quer criar uma programa para guardar os seus contatos, ele funcionaria como sendo uma agenda, só que ela não precisaria ir na sua bolsa/mochila, ela ficava no seu laptop.Nesse caso precisaríamos de criar um tipo que é o contacto, o contacto seria uma estrutura contendo nela 4 tipos de dados (Nome,Celular,Morada,Email),se você notou precisaremos de 3 strings(ou array de caracteres) para guardar Nome,Email e Morada e um inteiro para guardar o número de celular. Uma pergunta bem lógica seria: Se a estrutura vai conter vários e diferentes tipos de dados como vou acessar cada um? ou no contexto no nosso programa como vou introduzir o nome,o celular,a morada e o email da pessoa se eles estao todos encapsulados(guardados,inseridos,protegidos) dentro da estrutura? É muito simples, para aceder um campo ou elemento de uma estrutura(um tipo de dado que faz parte de uma estrutura) você terá de usar o operador ponto ( . ), ou seja a sintaxe seria: nomeDaVariavel.campo.
Vamos aos códigos que nos interessam.

#include <stdio.h>//biblioteca de entrada e saida padrao(standard input output) 
#include <stdlib.h>//incluir a biblioteca padrao(standard library) 
typedef struct __contacto{
   char nome[20];//string para guardar o nome
   char morada[40];//string para guardar a morada
   char email[20];//string parar guardar o email
   int numeroCelular;//inteiro para guardar o numero de celular
}contacto;
main(){
}

No código acima demos ao luxo de apenas criar a nossa estrutura, ali não existe variável nenhuma, então analisando a nossa estrutura vemos que ela possui quatro campos,um nome temporário ( __contacto ), o seu nome real (contacto),quando você cria uma estrutura você se reserva no direito de omitir o nome temporário, mas sempre deve atribuir um nome a essa estrutura senão não terá como utiliza-la.
Agora voltemos ao nosso código e agora vamos criar as variáveis que guardarão os contactos.


#include <stdio.h>//biblioteca de entrada e saida padrao(standard input output) 
#include <stdlib.h>//incluir a biblioteca padrao(standard library) 
typedef struct __contacto{

   char nome[20];//string para guardar o nome
   char morada[40];//string para guardar a morada
   char email[20];//string parar guardar o email
   int numeroCelular;//inteiro para guardar o numero de celular
}contacto;
main(){
   contacto novoContacto;//criamos uma variavel do tipo contacto
   strcpy(novoContacto.nome,"Lily Duarte");//copiamos Lily Duarte para o campo nome da variavel novoContacto
   strcpy(novoContacto.morada,"C.Praia");//copiamos C.Praia para o campo morada da variavel novoContacto
   strcpy(novoContacto.email,"lily12345_beutll@email.com");//copiamos lily12345_beutll@email.com para o campo email da variavel novoContacto
   novoContacto.numeroCelular = 12389088;
}


Agora sim começamos a criar a nossa agenda em si, e até inserimos algumas entradas nela,mais concretamente o contacto de Lily.Na linguagem C quando você quer popular uma string com algo você tem de usar a função strcpy(string1,string2), aonde ele vai passar a string2 para string1! Repare que a variável novoContacto não possui absolutamente nada e por isso voce nunca vai utiliza-la, o que voce vai utilizar sao os campos do novoContacto mais concretamente(nome,email,morada e celular). Se voce fizer algo como:

novoContacto = "Lily Duarte";


ou algo como:

novoContacto = 12389088;


voce ira receber um verdadeiro pontapé do compilador (e meu se eu estivesse ali) simplesmente porque ele não vai saber aonde guardar esse valor (e eu também não), e também porque sendo novoContacto uma variável estrutura (do tipo estrutura criado por voce) ela seria uma variável composta,ou seja, uma variavel constituida por outras variaveis o que leva voce a ser especifico que subvariavel da estrutura voce esta acessando.
Para que podermos guardar varios contactos na nossa agenda, voce já viu logo que teriamos que criar varias variáveis do tipo contacto, ou seja algo como:



#include <stdio.h>
//biblioteca de entrada e saida padrao(standard input output)
 
#include <stdlib.h>//incluir a biblioteca padrao(standard library) 
typedef struct __contacto{

   char nome[20];//string para guardar o nome
   char morada[40];//string para guardar a morada
   char email[20];//string parar guardar o email
   int numeroCelular;//inteiro para guardar o numero de celular
}contacto;
main(){
   contacto novoContacto;//criamos uma variavel do tipo contacto
   contacto novoContacto1;//criamos uma variavel do tipo contacto
   contacto novoContacto2;//criamos uma variavel do tipo contacto
   contacto novoContacto3;//criamos uma variavel do tipo contacto
}

E  viu que se quiséssemos guardar 100 contactos teriamos que multiplicar a linha acima por 25 e  teríamos um programa totalmente desgraçado,mas voce so faria isso se quisesse ganhar o campeonato de programas instáveis e difíceis de debuggar além de fazer figura de parvo perante aquela garota mais linda da sala e/ou da faculdade (a Lily por exemplo),é aqui que entra o array, porque se  pensar bem, escrevendo 100 linhas em que cada uma cria uma variavel do tipo contacto diferente é o mesmo que criar um array do tipo contacto com 100 posições só que a segunda opção é bem melhor n vezes,então vamos racionalizar e optimizar o nosso programa de agenda:

#include <stdio.h>//biblioteca de entrada e saida padrao(standard input output) 
#include <stdlib.h>//incluir a biblioteca padrao(standard library) 
typedef struct __contacto{

   char nome[20];//string para guardar o nome
   char morada[40];//string para guardar a morada
   char email[20];//string parar guardar o email
   int numeroCelular;//inteiro para guardar o numero de celular
}contacto;
main(){
   contacto novoContacto[100];//criamos 100 variaveis do tipo contacto   
   novoContacto[0].numeroCelular = 12389088;//inserimos o numero de celular do contacto numero 1
   strcpy(novoContacto[80].nome,"Lily Duarte");//inserimos o nome Lily Duarte no contacto numero 81
}

Quando cria um array de um tipo de dado qualquer você está criando n numeros dessa variável que uma forma bem racional e eficaz, e lembre que na linguagem C  o array começa no zero, ou seja, a posição zero(0) guarda a primeira posição, a posicao um(1) a segunda e a posição 99 a centésima posição, porque (0+90 = 100,isso e falando em termos de array e nunca de qualquer outra coisa, numéricamente falar que algo somado a zero da diferente desse algo é um autêntico disparate). Bom se algo esta relacionado com arrays ele vai se dar muito bem com os ciclos(for,while,do-while, entre outros que não conheço) porque os ciclos fazem coisas repetitivas e você vai querer percorrer todo esse array desde a posicao 0 ate chegar a posicao n-1(ou seja um array de 100 posicoes vai de 0 ate chegar 99 porque em termos de array 0+90 = 100,EM TERMOS DE ARRAY)  para fazer qualquer coisa.Então vamos aperfeiçoar o nosso programa e fazer com que ele me pergunte quandos contactos eu quero adicionar e ele vai me dar a oportunidade de guardar todos esse contactos. 

#include <stdio.h>//biblioteca de entrada e saida padrao(standard input output) 
#include <stdlib.h>//incluir a biblioteca padrao(standard library) 
typedef struct __contacto{
   char nome[20];//string para guardar o nome
   char morada[40];//string para guardar a morada
   char email[20];//string parar guardar o email
   int numeroCelular;//inteiro para guardar o numero de celular
}contacto;

main(){

   contacto novoContacto[100];//criamos 100 variaveis do tipo contacto

   int numContactos = 0;
   printf(" ========= Agenda de Ayrton Gomes - Powered By BlogIg.corp ========= \n");
   printf("Quantos contactos quer adicionar? ");
   scanf("%d",&numContactos);
   if(numContactos > 100){
       printf("Agenda so pode guardar 100 contactos.");
   }else{
       int i;
   for(i=0;i<numContactos;i++){
       printf("Insira o nome do contacto %d: ",i+1);
       scanf("%s", novoContacto [i].nome);
       printf("Insira a morada(sem espacos): ");
       scanf("%s", novoContacto [i].morada);
       printf("Insira o email: ");
       scanf("%s",novoContacto[i].email);
       printf("Insira o numero de celular(sem espacos): ");
       scanf("%d",&novoContacto[i].celular);
    }
}


Coisas ditas sem sentido,erros ortográficos, erros de natureza geral, confusão em relação a alguma coisa,alguma coisa dita e que não corresponde a verdade? Qualquer coisa por favor comente. Se copiar o artigo por favor cite a fonte! Que Deus vos abençoe ! Ayrton Gomesz 2012
Continuar lendo >>

SSH Para iniciantes

25 agosto 2011
0 comentários


Pode parecer fácil para muitos, e uma dor de cabeça para outros, fato é que ninguém nasce sabendo SSH então hoje o post vai pra você que vai ter que se virar pra aprender isso!


Com o tempo a linguagem do SSH se torna pratica a fácil desde que sempre praticada, usuários de linux com experiencia com o terminal tem mais facilidade para aprender CLARO, mas a diferença nem chega a ser tanta, então chega de bla bla bla e vamos aos comandos básicos.


Primeiro Passo
Você tem o ssh na máquina?
Abra o terminal e digite o seguinte comando:

Terminal
elian@Saruman:~$   ssh

Se o resultado for algo como abaixo você tem o SSH já instalado na sua máquina.


EXEMPLO:
Terminal
elian@Saruman:~$ ssh
usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]
           [-D [bind_address:]port] [-e escape_char] [-F configfile]
           [-I pkcs11] [-i identity_file]
           [-L [bind_address:]port:host:hostport]
           [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
           [-R [bind_address:]port:host:hostport] [-S ctl_path]
           [-W host:port] [-w local_tun[:remote_tun]]
           [user@]hostname [command]

Caso você não tenha use o comando



Terminal
elian@Saruman:~$   sudo apt-get install openssh-client



esse comando irá instalar o SSH Cliente em sua máquina, para que seja possível acessar outra, caso queira liberar o acesso da sua máquina use openssh-server ao invés de openssh-client.


Comandos Básicos
Logar via SSH
Para logar via SSH abra o terminal e digite o seguinte comando:


Terminal
elian@Saruman:~$   ssh usuario@ip_da_maquina

Onde USUARIO é o nome do usuário da maquina que está tentando logar e IP_DA_MAQUINA é? o ip do servidor propriamente dito, logo em seguida aperte <ENTER> e o terminal vai pedir a senha da máquina na qual você está tentando se conectar.


EXEMPLO:
Terminal
elian@Saruman:~$   ssh gandalf@10.42.43.1
gandalf@10.42.43.1's password:



E então o servidor te dará uma mensagem de boas vindas.
Você também pode logar por SSH com o modo gráfico ativo, assim você poderá executar comandos para abrir ambientes gráficos da máquina que está logado desde que os mesmos estejam instalados, por exemplo o comando firefox, desde que o mesmo esteja instalado no servidor ao passar o comando você vai visualizar o firefox de dentro da outra máquina, legal não? pará isso você deve logar usando o parâmetro -X  logo depois de ssh da seguinte forma:

Terminal
elian@Saruman:~$   ssh -X usuario@ip_da_maquina

Uma vez logado estaremos passando os comando direto a máquina na qual entramos, vamos aos comandos mais usados.


Para copiar arquivos de uma pasta para outra:
Terminal
gandalf@Sauron:~$   cp arquivo novo_arquivo



Para copiar uma pasta e seus arquivos de modo recursivo use
Terminal
gandalf@Sauron:~$   cp -r pasta pasta_destino

Para mover arquivo
Terminal
gandalf@Sauron:~$   mv arquivo arquivo_destino

Para apagar um arquivo use
Terminal
gandalf@Sauron:~$   rm nome_do_arquivo


Para renomear um arquivo use o mesmo comando de mover


Para logar como root
Terminal
gandalf@Sauron:~$   sudo su
Para executar comandos como root use sudo antes do comando.



Para sair

Terminal
gandalf@Sauron:~$   exit






Para copiar arquivos da sua maquina para a outra maquina use:
Terminal
elian@Saruman:~$   scp -r pasta usuario@ip_da_maquina:/destino
Esse comando é pouco mais difícil  note que para enviar arquivos da sua máquina para outra você não pode estar logado na outra maquina via SSH, pois se estivesse logado estaria executando o comando na outra máquina e não na sua.


EXEMPLO:
Terminal
elian@Saruman:~$   scp -r blog gandalf@10.42.43.1:/home/gandalf
Nesse caso eu estaria copiando a pasta BLOG da minha máquina para a pasta do usuário na outra máquina.
Para copiar da outra máquina para a minha o comando é o mesmo, basta inverter a ordem.





Espero ter ajudado alguém com essas dicas, e até a próxima.
Continuar lendo >>

Torne-se um Programador em 5 segundos!

10 maio 2011
4 comentários

Digite seu código na caixa-preta-mágica-dos-programadores: Espere carregar...



Via: Jiboiando.
Continuar lendo >>

Linguagem de máquina – Como o computador entende a nossa língua

20 março 2011
12 comentários
Para os humanos a interação não seria completamente nada sem o alfabeto e os números não é mesmo? Mas com os computadores isso é um pouco diferente. Chamada de "linguagem binaria", os famosos 1 e 0 é o que dão origem a essa linguagem. Entenda um pouco sobre como ela funciona.

Para entender melhor como funciona essa TRADUÇÃO da linguagem humana para a linguagem de máquina, como assim é chamada, é preciso saber o alfabeto binário (não necessariamente decorá-lo).

Cada algarismo 1 ou 0, é chamado de bit (binary digit) e para que se forme um dígito são necessários oito bits e cada conjunto de oito bits é chamado de byte, normalmente. Veja o alfabeto binário:

A 01000001 B 01000010 C 01000011 D 01000100 E 01000101 F 01000110
G 01000111 H 01001000 I 01001001 J 01001010 K 01001011 L 01001100
M 01001101 N 01001110 O 01001111 P 01010000 Q 01010001 R 01010010
S 01010011 T 01010100 U 01010101 V 01010110 W 01010111 X 01011000 Y 01011001 Z 01011010

Essa é a codificação ASCII (American Standard Code for Information Interchange ou Código Padrão Americano para Intercâmbio de Informações) e é a mais usada.

Se você pedir um comando para que, por exemplo, seja encontrado todos os números primos até um inteiro n, nossa estratégia tem de seguir uma lógica como se fosse usada na aula de matemática, no caso. Aí ficará da seguinte forma:

1. Obter números do intervalo [2, n];
2. Apagar os números maiores que e divisíveis por 2;
3. Obter próximo primo p;
4. Se p for menor que a raiz quadrada de n, então:
4.1. Apagar os números maiores que e divisíveis por p;
4.2. Ir ao passo 3;
5. Senão:
5.1. Ir ao passo 6;
6. Fim.

Este modelo numérico antes de cada comando é o chamado algoritmo usado em várias linguagens de programação.

Obviamente, um algoritmo deve ser executado por algum ser. Este ser pode ser uma pessoa munida de certos equipamentos e utensílios ou por máquinas projetadas para executar automaticamente algumas instruções básicas. Mas preciso saber se esse ser, ou agente, é capaz de interpretar as instruções. Pegando o exemplo acima, se a pessoa souber o que é um número primo, raiz quadrada e os números divisíveis por 2 e p, ele é capaz. Não sabendo de ao menos um desses itens ele se torna incapaz. Então há essa necessidade de saber a capacidade do agente que no computador é conhecido com Processador ou CPU.

Você deve estar se perguntando: "Cada letra desse comando acima eu vou ter que passar par a linguagem dos "0" e "1"?" Não se assuste. Hoje existem vários tradutores encarregados de fazer essa tradução da linguagem humana para a linguagem de máquina e vice-versa.

Bom, isso é o básico do básico. Se você pretende ser um programador de renome, vale a pena estudar bastante (que nem eu) e a internet contém vários meios ao qual já o faz ficar por dentro do mundo dos programadores.
Pesquise. Você só tem a ganhar!

Continuar lendo >>

PHP e MYSQL! Quem são esses caras?

26 fevereiro 2011
3 comentários

              Bom, perguntar quem são não seria a pergunta mais indicada, visto que PHP e MYSQL não são pessoas, mas sim aplicativos, programas, etc, mas o que interessa é satisfazer a curiosidade do internauta enquanto ser enduvidado. Antes de mais saiba que esses dois programas são actualmente os mais populares quando o assunto é desenvolvimento web e não só, também o facto de serem softwares livres (gratuitos e podem ser modificados) ajuda na sua ampla expansão e fama.
                Mas afinal o que são ? Vamos analisar primeiramente o que é PHP depois Mysql  e depois veremos os dois em conjunto, porque é sendo dois softwares totalmente diferentes são vistos sempre juntos ou mesmo como irmãos.
               Antes de iniciarmos ao estudo, devo alertá-lo que não iremos abordar definições  nem conceitos aborrecidos, enfim aqui veremos o que é directamente e para que serve, acredito que assim será mais fácil entendermos (eu e você) em que consiste PHP e MYSQL, sendo assim a minha filosofia.

O que é PHP ?
Quando cria-se websites, usamos tecnologias como XHTML,CSS e XML para desenhar o website e decidir aonde aninhar os conteúdos,pode ler alguma coisa sobre HTML em dois posts que o Guilherme fez acerca ,clique aqui para o primeiro capitulo  e aqui para o segundo, até aqui tudo bem, só que essas tecnologias servem "apenas" para conceber o design e o visual do site, e a parte dinâmica ? Como adicionar conteúdos de forma dinâmica através de sistemas bem fáceis, ou seja, como publicar os posts através de caixas, como estou fazendo neste momento, digitando este post ? Essas tecnologias não tem o suporte ou não foram concebidas para elaborar esses sistemas, então é aqui que entra PHP.
Logo do PHP

 Iremos usar esse aplicativo muito rico e de uma sintaxe de programação muito fácil para elaborar esses tais sistemas, PHP é o aplicativo mais utilizado mundialmente para este tipo de tarefa, simplesmente porque é muito acessível de estudar, é gratuito e é muito, muito  rico mesmo,futuramente explicarei porquê :D .Esta famosa linguagem de programação (programa que serve para criar aplicações ou programas) desde a sua criação , a internet nunca foi a mesma, simplesmente porque ajudou e muito no desenvolvimento de websites, comércios eletrónicos , portais entre outros.

Depois de analisarmos o que é PHP veremos agora o que é MYSQL, depois disso veremos em que contexto podemos associar os dois aplicativos.

O que é MYSQL ?
Falámos que para criar websites usamos tecnologias como (X)HTML,CSS e XML para desenhar e conceber a organização dos elementos que vai conter as informações, falamos do PHP como tecnologia necessária para elaborar sistemas dinâmicos para gerir o website, mas não falámos daquilo que nos leva a construir o website, que é o conteúdo, sem ele não vale a pena elaborar nada, tudo é feito pelo conteúdo e pelo conteúdo....
Logo do MYSQL

Então é na parte de suportar e dar aguarita ao conteúdo, ou seja, alojar o conteúdo é que  entra o MYSQL, pois ele é uma base de dados e a sua função é armazenar dados e disponibilizá-los quando são solicitados, mas porque MYSQL é tão interessante se existem milhares de base de dados por aí ?
MYSQL à semelhança do PHP é um software livre, gratuito e muito rico e veloz, MYSQL se destaca dos outros bases de dados porque é rápido, escalável,estável e muito muito bom, além de ter uma sintaxe muito fácil de ser utilizada.

Como é que PHP e MYSQL se implicam ?
PHP e MYSQL se implicam porque os dois são gratuitos, rápidos, são desenvolvidos por milhares de desenvolvedores à volta do mundo.
Imaginemos que vou desenvolver um website, vou fazer da seguinte forma:

  1. (X)HTML,CSS e XML para desenhar o website
  2. PHP e MYSQL para desenvolver o sistema que vai gerenciar o website, ou seja, criar um sistema dinâmico para gerir o conteúdo e armazená-lo.
Todas as tecnologias que usei para desenvolver o website são 100% livres e de grande qualidade, sobretudo os dois últimos.
Resumindo: PHP é um software desenvolvido para conceber aplicativos web e MYSQL é uma poderosa base de dados, cuja a função, como o próprio nome diz, é armazenar conteúdo e disponibilizar esse conteúdo quando lhe é solicitado.
Exemplos de grande sucessos construidos apartir de PHP e MYSQL:
  1. A rede social Facebook;
  2. O Software Wordpress;
  3. O Website  Wikipédia;
Entre outros exemplos.Mas o que importa é que vemos que esses dois aplicativos são muito famosos e a sua qualidade é inegável.:D
Bom, é tudo e espero que tenha gostado, qualquer coisa é só comentar.
Continuar lendo >>

Tabela Hash: A tabela de Espalhamento ou Dispersão.

12 dezembro 2010
2 comentários



Hoje eu vou falar um pouco sobre Tabela Hash.  Bem, esta tabela é uma Estrutura de Dados bem como as Árvores.  Então, vamos entender o que seria esta tabela.

A tabela Hash é uma estrutura de dados que implementa o espalhamento, ou seja que associa chaves de pesquisa a valores. Ela também é conhecida por tabela de espalhamento ou dispersão. Seu objetivo é, a partir de uma chave simples, fazer uma busca rápida e obter o valor desejado. É algumas vezes traduzida como tabela de escrutínio.

Ela pode ser representada por um vetor onde cada posição deste é chamada de encaixe e armazena uma uma classe de partição.

Complexidade e usos comuns
Tabelas hash são tipicamente utilizadas para implementar vetores associativos, sets e caches. São tipicamente usadas para indexação de grandes volumes de informação (como bases de dados). A implementação típica busca uma função hash que seja de complexidade O(1), não importando o número de registros na tabela (desconsiderando colisões). O ganho com relação a outras estruturas associativas (como um vetor simples) passa a ser maior conforme a quantidade de dados aumenta.
Outros exemplos de uso das tabelas hash são as tabelas de transposição em jogos de xadrez para computador até mesmo em serviços de DHCP.

A função hash
Tabela hash com vetor simples e com vetor de listas.
A função hash é a responsável por gerar um índice a partir de determinada chave. Caso a função seja mal escolhida, toda a tabela terá um mau desempenho.
O ideal para a função hash é que sejam sempre fornecidos índices únicos para as chaves de entrada. A função perfeita seria a que, para quaisquer entradas A e B, sendo A diferente de B, fornecesse saídas diferentes. Quando as entradas A e B são diferentes e, passando pela função hash, geram a mesma saída, acontece o que chamamos de colisão.
Na prática, funções hash perfeitas ou quase perfeitas são encontradas apenas onde a colisão é intolerável (por exemplo, nas funções hash da criptografia, ou quando conhecemos previamente o conteúdo da tabela armazenada.
Nas tabelas hash comuns a colisão é apenas indesejável, diminuindo o desempenho do sistema. Muitos programas funcionam sem que seu responsável suspeite que a função hash seja ruim e esteja atrapalhando o desempenho.
Por causa das colisões, muitas tabelas hash são aliadas com alguma outra estrutura de dados, tal como uma lista encadeada ou até mesmo com árvores balanceadas. Em outras oportunidades a colisão é solucionada dentro da própria tabela.

Exemplo de função hash e colisão.
Imagine que seja necessário utilizar uma Tabela Hash para otimizarmos uma busca de nomes de uma lista telefônica (dado o nome, temos que obter o endereço e o telefone). Nesse caso, poderíamos armazenar toda a lista telefônica em um vetor e criar uma função hash que funcionasse de acordo com o seguinte critério:
        Para cada nome começado com a letra A, retornar 0
        Para cada nome começado com a letra B, retornar 1
        ...
        Para cada nome começado com a letra Z, retornar 25

O exemplo anterior poderia ser implementado, em C, da seguinte forma:
        int hashExemplo(char * chave)
        {
                return (chave[0]-65);
        }
Agora inserimos alguns nomes à lista telefônica:
José da Silva; Rua das Almas, 35; Telefone (11) 888-9999
Ricardo Souza; Rua dos Coqueiros, 54; Telefone (11) 222-4444
Orlando Nogueira; Rua das Oliveiras, 125; Telefone (11) 444-5555
A função distribuiria os nomes assim:


Agora inserimos mais um nome:
Renato Porto; Rua dos Elefantes, 687; Telefone (11) 333-5555
E temos uma colisão:


Como se pode notar, a função de exemplo causaria muitas colisões. Se inserirmos um outro nome começado com a letra R, teremos uma outra colisão na letra R. Se inserirmos "João Siqueira", a entrada estaria em conflito com o "José da Silva".

Resolvendo colisões.
Um bom método de resolução de colisões é essencial, não importando a qualidade da função hash. Considere um exemplo derivado do paradoxo do aniversário: mesmo que considerarmos que a função irá selecionar índices aleatórios uniformemente em um vetor de um milhão de posições, há uma chance de 95% de haver uma colisão antes de inserirmos 2500 registros.
Há diversos algoritmos de resolução de colisão, mas os mais conhecidos são Encadeamento Separado e Endereçamento Aberto.

Encadeamento Separado.
É a solução mais simples, em que normalmente um registro aponta para uma lista encadeada em que são armazenados os registros em conflito. A inserção na tabela requer uma busca e inserção dentro da lista encadeada; uma remoção requer atualizar os índices dentro da lista, como se faria normalmente.
Estruturas de dados alternativas podem ser utilizadas no lugar das listas encadeadas. Por exemplo, se utilizarmos uma árvore balanceada, podemos melhorar o tempo médio de acesso da tabela hash para O(log n) ao invés de O(n). Mas como as listas de colisão são projetadas para serem curtas, o overhead causado pela manutenção das árvores pode fazer o desempenho cair.
Apesar disso, as árvores podem ser utilizadas como proteção contra ataques que buscam criar overhead propositalmente - descobrindo uma forma da função gerar repetidamente o mesmo índice - e derrubar o sistema (ataques DOS). Nesse caso, uma árvore balanceada ajudaria o sistema a se manter estável, por ser uma estrutura com grande capacidade de crescimento.

Endereçamento Aberto.
No método de Endereçamento Aberto os registros em conflito são armazenados dentro da própria tabela. A resolução das colisões é realizadas através de buscas padronizadas dentro da própria tabela.
A forma mais simples de fazer a busca é procurar linearmente na tabela até encontrar um registro vazio ou o registro buscado. Outras formas utilizadas incrementam o índice exponencialmente: caso o registro não seja encontrado na posição 10, será buscado na posição 100, depois na posição 1000. A inserção tem que seguir o mesmo critério da busca.
Outra forma mais complexa de implementar o Endereçamento Aberto é criar uma nova função hash que resolva o novo conflito (também chamado de double hashing ou rehash 1). Na prática, o que acontece nesse caso é que o vetor da tabela é formado por uma seqüência de funções hash auxiliares, onde a chave de entrada será o valor gerado pela função anterior. Esse tipo de implementação pode ser útil em casos muito específicos, com enormes quantidades de dados, mas normalmente o overhead não justifica a experiência.
Indexação Perfeita
Se tivermos uma relação fixa de registros, podemos obter uma função que indexe os itens sem que ocorra nenhuma colisão, chamada função hash perfeita. Podemos até mesmo buscar uma função hash perfeita mínima, que, além de não causar colisões, preenche todas as posições da tabela. As funções hash perfeitas fazem o acesso aos dados ser O(1) no pior caso.
Existem métodos que atualizam a função hash de acordo com a entrada, de forma que nunca ocorra colisão. O inconveniente dessa técnica é que a própria atualização da função hash causa overhead do sistema.

Problemas e comparações com outras estruturas.
Apesar das tabelas hash terem em média tempo constante de busca, o tempo gasto no desenvolvimento é significativo. Avaliar uma boa função hash é um trabalho duro e profundamente relacionado à estatística. Na maioria dos casos soluções mais simples como uma lista encadeada devem ser levados em consideração.
Os dados na memória ficam aleatoriamente distribuídos, o que também causa overhead no sistema. Além disso, e mais importante, o tempo gasto na depuração e remoção de erros é maior do que nas árvores balanceadas, que também podem ser levadas em conta para solução do mesmo tipo de problema.

1 -  Double hashing ou rehash

Existem duas funções de Hash: Uma para usar normalmente  e outra para usar quando há colisões.

h1( i )=( i mod m ) = C1
h2 = ( i mod m-1 )+1 = C2  ---} usada quando há colisões

Para calcular o primeiro índice usa-se C1;
Para calcular o segundo índice ( se existir colisões) usa-se C1+C2;
Para calcular o terceiro índice ( se também existir colisões ) usa-se C1+2C2, depois C1+3C2, etc. 
Devemos normalizar  h1( i ) e h2 ( i ) para que o tamanho da tabela seja igual.

Nota: ( m ) e ( m-1 ) são primos entre si, para que o resto entre os 2 seja diferente de 0.

Exemplo:
 
h1( i ) = i mod 7 = C1
h2( i ) = ( i mod 6 ) +1 =C2
5     h1 ( 5 ) = 5  ----} 5 está vazio;
10   h1 ( 10 ) = 3 ----} 3 está vazio;
12   h1 ( 12 ) = 5 ----} 5 está ocupado, logo faz-se h2;
h2 ( 12 ) =1;

C1+C2 = 5 + 1 = 6  ----} soma-se o C1 com C2 logo 6 está vazio;
19  h1 ( 19 ) = 5 ----} 5 está ocupado logo fazemos o h2;
h2 ( 19 ) =2 = C1+C2= 5+2=7  ----} como o rehash é circular vai-se inserir no 0;


Nota: Se a posição  0  também estivesse ocupado recorreríamos a C1+2C2 
(iria inserir-se no 5+2(2)=9 ---}corresponde ao lugar 2)



Tipos:

Método da divisão (método da congruência linear)

h(k) = k(mod m)

Potências de dois devem ser evitadas para valores de m.
m deve ser um número primo distante de pequenas potências de dois (m grande).
Exemplo:
k = 10028;m = 5013;h(10028) = 10028mod5013;h(10028) = 2
(m é o tamanho da tabela)

Método da multiplicação (método da congruência linear multiplicativo)

h(k) = (m * (kA(mod 1)))

m normalmente é uma potência de dois.
A é uma constante, tal que 0 < A < 1.
Extrair a parte fracionária de kA, ou seja, kA(mod 1).
Utilizar o piso do resultado


Escrevi com base no trabalho dos alunos em Tecnologia em Sistemas de Informação: Claudio Cesconeto e Alex Sandro Oliveira. No mais, dei uma lida em Wiki e outros sites. Caso algo não condiz com o certo, corrija-me por comentário. 
                                                                  
Continuar lendo >>

Conceito de árvores em Estrutura de Dados

11 dezembro 2010
7 comentários



Bom, não vou falar sobre árvores daquelas que se plantam e elas crescem e aproveitando esse tempo de fim-de-ano, não vou falar sobre pinheirinhos de Natal. Estou escrevendo este Post porque preciso estudar para minha prova de exame na Faculdade, (pois é, eu fiquei em exame L). O título ficou meio tosco também, comentem o que acharam... (Mudado o título que era antes "Conceito de Árvores"). Bom então sobre o que eu vou falar? Sobre árvores em Estrutura de Dados.
Então vamos entender um pouco sobre essas árvores. Basicamente, esse nome “árvores” teve origem por causa da estrutura física de um objeto que se assemelha muito com uma árvore, em que suas ramificações tende a se convergir a uma raiz. Espero que eu consiga explicar sobre este assunto.


Nós ou Nodos: São os itens guardados na árvore.
Raiz: É o primeiro nó e o nó principal da árvore. Há somente um nó em cada árvore, conforme mostra a figura abaixo:

Pais: São nós que vem antes de outros nós;
Filhos: São os nós que vem depois dos nós pais. Um filho precisa de um pai para ser filho, entendeu ? =P
Folhas: São nós que não tem filhos. Eles são os últimos das árvores. Ex.: Um caminho como C:\XXX\YYY\ZZZ.doc, corresponde ao caminho da raiz ao nó folha ZZZ.doc.
Um exemplo está na árvore abaixo:

Grau de um nó: Números de filhos de cada nó;
Nível de um nó: Por definição, é zero para a raiz, e, para os demais nós, é o número de “linhas” que ligam o nó à raiz;
Altura de árvore: É o nível mais alto da árvore;
Floresta: Conjunto de árvores disjuntas;
Galhos: Quaisquer nodos que não são raiz e nem folhas de árvore;
Aresta: É a linha que liga dois nodos da árvore;
Caminho: Diz-se que existe um caminho entre dois nodos A e B de uma árvore, se a partir do nodo A pode-se chegar ao nodo B percorrendo-se as arestas que ligam os nodos intermediários entre A e B.


Abaixo vou falar sobre os tipos de árvores:
Árvores Binárias e de Busca:
Essa árvore se caracteriza por não ter elemento nenhum ou tem um elemento distinto denominado raiz com dois ponteiros  para uma sub-árvore a direita e outra para a esquerda. Sua definição é que seus graus estão entre 0, 1 e 2. Cada nó só pode ter dois filhos



 As três maneiras mais usuais para percorrer os nós são:

Caminhamento Pré-fixado
Visita a raiz
Percorre a sub-árvore da esquerda
Percorre a sub-árvore da direita

Caminhamento In-fixado
Percorre a sub-árvore da esquerda
Visita a raiz
Percorre a sub-árvore da direita

Caminhamento Pós-fixado
Percorre a sub-árvore da esquerda
Percorre a sub-árvore da direita
Visita à raiz

Arvores AVL:
São árvores balanceadas pela altura. É uma árvore binária auto-balanceada. Uma árvore AVL é dita balanceada quando, para cada nó da árvore, a diferença entre as alturas das suas sub-árvores (direita e esquerda) não é maior do que um. Caso a árvore não esteja balanceada é necessário seu balanceamento através da rotação simples ou rotação dupla. O balanceamento é requerido para as operações de inserção e remoção de elementos. Para definir o balanceamento é utilizado um fator específico para nós.
O fator de balanceamento de um nó é dado pelo seu peso em relação a sua sub-árvore. Um nó com fator balanceado pode conter 1, 0, ou -1 em seu fator. Um nó com fator de balanceamento diferente dos citados é considerado uma árvore não-AVL e requer um balanceamento por rotação ou dupla-rotação.



Arvores B e B+
Uma árvore B de ordem "m" (máximo de filhos para cada nó) é uma árvore que atende as seguintes propriedades:
  1. Cada nó tem no máximo "m" filhos
  2. Cada nó (exceto a raíz e as folhas) tem pelo menos "m/2" filhos
  3. A raiz tem pelo menos dois filhos se a mesma não for uma folha
  4. Todas as folhas aparecem no mesmo nível e carregam informação
  5. Um nó não-folha com "k" filhos deve ter k-1 chaves
Uma árvore B+ é uma variação da árvore B. Numa árvore-B+, contrastando com uma árvore-B, todos os dados são gravados nas folhas. Os nodos internos contêm apenas chaves e apontadores da árvore. Todas as folhas estão no mesmo nível mais baixo. Os nodos das folhas também estão ligados entre si como uma lista de ligações para efectuar consultas facilmente.


Arvores Red-Black.
Características
As árvores Red-Black foram inventadas em 1972, por Bayer sob o nome B-árvores binárias simétricas. As árvores red-black são também árvores binárias de busca balanceadas que tem algoritmos de inserção e remoção de complexidade logarítmica no número de nós. Porém, elas são geralmente mais usadas, pois tem implementações mais eficientes.

Em uma árvore red-black o equilíbrio é conseguido durante a inserção. Quando um item está sendo inserido a rotina de inserção verifica que certas características da árvore não sejam violadas. Se forem, ela toma a atitude de correção e reestruturando da árvore, conforme o necessário. Mantendo estas características, a árvore fica equilibrada.
A principal característica das árvores red-black é que seus nós são coloridos (negros ou vermelhos) e durante os processo de inserção e inclusão as regras são seguidas para que se preserve o ajuste destas cores.


Propriedades
1. Cada nó tem uma cor que é vermelha ou negro. Por convenção, uma árvore não vazia (ou sub-árvore) tem a cor de sua raiz e uma árvore vazia é negra.
2. A raiz é negra.
3. Qualquer caminho da raiz até uma sub-árvore vazia tem um número igual de nós negros.
4. As sub-árvores de um nó vermelho são negros.

Uma propriedade óbvia resultando da quarta condição é que num caminho da raiz até uma sub-árvore vazia não pode haver dois nós vermelhos consecutivos.



Por enquanto é isso. Isto foi um conceito básico de árvores. Comente, se estiver errado alguma coisa aqui encima, corrija-me por favor... E desculpe meus erros gramaticais! Gostou? Comente também!!! =D
Continuar lendo >>