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.

//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.


#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.
  1. Encontrar o tamanho da string (strlen);
  2. 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:

  1. 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;
    }

  2. 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);

  3. 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
  • 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

Estrutura de dados - Introdução

O que são Estrutura de dados?


Estruturas de dados são estruturas que tem o propósito de armazenar os dados de forma inteligente no computador, fazendo que tais estruturas sejam utilizadas eficientemente na resolução de um problema. Existem inúmeras estruturas que podem ser usadas, porém dependendo do problema a ser solucionado algumas estruturas serão mais indicadas do que outras.

Por que estudar Estruturas de dados?


Essa pergunta é feita com muita frequência já que hoje as linguagens de alto nível oferecem essas estruturas todas prontas, porém, se você é um desenvolvedor que se limita apenas a conhecer as estruturas presentes na API da linguagem que você trabalha infelizmente você estará amarrado a ela, pois você adquiriu conhecimento em uma linguagem e não nas estruturas que compõem a linguagem. Supomos que você tenha que mudar de linguagem de programação e essa nova linguagem não oferece nenhuma estrutura de dados pronta, e ai? E se você não conhece o funcionamento da estrutura como você estará apto a tomar a decisão de qual a melhor estrutura utilizar em um determinado problema? São nessas horas que o conhecimento se faz necessário!


Próximo assunto -> Tipo de dado abstrato (TDA).



Estrutura de dados - Apresentação

Olá pessoal, conheça a nova seção do blog programando onde iremos aprender sobre estrutura de dados. Será utilizada a linguagem C no decorrer deste mini-curso, podendo haver exemplos em Java e Python, porém, C é a linguagem que utilizaremos como padrão.

Abaixo está descrita a grade de nossa seção, aproveitem para se orientar em seus estudos e boa sorte.

  1. O QUE É ESTRUTURA DE DADOS
  2. TDA
  3. PONTEIRO
  4. VETOR
  5. LISTA
  6. PILHA
  7. FILA
  8. ÁRVORE
  9. ÁRVORES ORDENADAS
  10. ÁRVORES ORIENTADAS
  11. ÁRVORE LIVRE
  12. PROGRESSÃO DE ÁRVORES
  13. REPRESENTAÇÃO LIGADA DE ÁRVORES
  14. ÁRVORE BINÁRIA
  15. FUNÇÃO MALLOC
  16. FUNÇÃO CALLOC
  17. FUNÇÃO FREE
PS: Devido a falta de tempo o mini-curso de banco de dados foi adiado para o mês que vem, abraços.

quarta-feira, 18 de julho de 2012

Programando em Java - parte 8

Construtor

Um construtor permite que um determinado trecho de código seja executado toda vez que um objeto é criado, ou seja, toda vez que o operador new é chamado. Assim como os métodos, os construtores podem receber parâmetros. Contudo, diferentemente dos métodos, os construtores não devolvem resposta.
Em Java, um construtor deve ter o mesmo nome da classe na qual ele foi definido:
class CartaoDeCredito {
    int numero ;
    CartaoDeCredito ( int numero ) {
        this . numero = numero ;
    }
}


Na criação de um objeto com o comando new, os argumentos passados devem ser compatíveis com a lista de parâmetros de algum construtor definido na classe que está sendo instanciada. Caso contrário, um erro de compilação ocorrerá para avisar o desenvolvedor dos valores obrigatórios que devem ser passados para criar um objeto.

CartaoDeCredito c = new CartaoDeCredito(736723672);


Construtor Padrão

Toda vez que um objeto é criado, um construtor da classe correspondente deve ser chamado. Mesmo quando nenhum construtor for definido explicitamente, há um construtor padrão que será inserido pelo próprio compilador. O construtor padrão não recebe parâmetros e será inserido sempre que o desenvolvedor não definir pelo menos um construtor explicitamente.
Portanto, para instanciar uma classe que não possui construtores definidos no código fonte, devemos utilizar o construtor padrão, já que este é inserido automaticamente pelo compilador.

class Conta() {}

Lembrando que o construtor padrão só será inserido pelo compilador se nenhum construtor for definido no código fonte. Dessa forma, se você adicionar um construtor com parâmetros então não poderá  utilizar o comando new sem passar argumentos, pois um erro de compilação ocorrerá.

Sobrecarga de Construtores

O conceito de sobrecarga de métodos pode ser aplicado para construtores. Dessa forma, podemos definir diversos construtores na mesma classe.

class Pessoa {
    String rg ;
    int cpf ;
    Pessoa ( String rg ) {
        this . rg = rg ;
    }
    Pessoa ( int cpf ) {
        this . cpf = cpf ;
   }
}

Quando dois construtores são definidos, há duas opções no momento de utilizar o comando new.

// Chamando o primeiro construtor
Pessoa p1 = new Pessoa ( " 123456 X " ) ;
// Chamando o segundo construtor
Pessoa p2 = new Pessoa (123456789) ;


Construtores chamando construtores

Assim como podemos encadear métodos, também podemos encadear construtores.

class Conta {
    int numero ;
    double limite ;
    Conta ( int numero ) {
        this . numero = numero ;
    }
    Conta ( int numero , double limite ) {
        this ( numero ) ;
        this . limite = limite ;
    }
}


segunda-feira, 9 de julho de 2012

Programando em Java - parte 7

Sobrecarga (Overloading)

Java nos permite criar vários métodos com o mesmo nome desde que tenham parâmetros diferentes. Isso é o que chamamos de sobrecarga de métodos.

A sobrecarga de métodos consiste em criarmos o mesmo método com possibilidades de entradas diferentes. Essas entradas, caracterizadas como parâmetros, devem sempre ser de tipos diferentes, quantidades de parâmetros diferentes ou posições dos tipos diferentes.

Os clientes dos bancos costumam consultar periodicamente informações relativas às suas contas. Geralmente, essas informações são obtidas através de extratos. No sistema do banco, os extratos podem ser gerados por métodos da classe Conta.

class Conta {
    double saldo ;
    double limite ;
    void imprimeExtrato ( int dias ) {
        // extrato
    }
}


O método imprimeExtrato() recebe a quantidade de dias que deve ser considerada para gerar o extrato da conta. Por exemplo, se esse método receber o valor 30 então ele deve gerar um extrato com as movimentações dos últimos 30 dias.

Em geral, extratos dos últimos 15 dias atendem as necessidades dos clientes. Dessa forma, poderíamos acrescentar um método na classe Conta para gerar extratos com essa quantidade fixa de dias.

class Conta {
    double saldo ;
    double limite ;
    void imprimeExtrato () {
        // extrato dos últimos 15 dias
    }
    void imprimeExtrato ( int dias ) {
        // extrato
    }
}

O primeiro método não recebe parâmetros pois ele utilizará uma quantidade de dias padrão
definida pelo banco para gerar os extratos (15 dias).

O segundo recebe um valor inteiro como parâmetro e deve considerar essa quantidade de dias
para gerar os extratos.

Os dois métodos possuem o mesmo nome e lista de parâmetros diferentes. Quando dois ou mais
métodos são definidos na mesma classe com o mesmo nome, dizemos que houve uma sobrecarga
de métodos. Uma sobrecarga de métodos só é válida se as listas de parâmetros dos métodos são
diferentes entre si.

No caso dos dois métodos que geram extratos, poderíamos evitar repetição de código fazendo
um método chamar o outro.

class Conta {
    void imprimeExtrato () {
        this . imprimeExtrato (15) ;
    }
    void imprimeExtrato ( int dias ) {
        // extrato
    }
}


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...