SlideShare uma empresa Scribd logo
1 de 35
Baixar para ler offline
Curso Superior de Tecnologia em Telemática
                               Programação e Estruturas de Dados

Linguagem C, Apontadores e Revisão Prática
                                                    Copyright©2010
                                                    Prof. César Rocha
                                             cesarocha@ifpb.edu.br 1
Objetivos

§ Explorar os conceitos fundamentais acerca do uso
  de apontadores (ponteiros)na linguagem C
   § sintaxe, principais operadores, erros comuns, aritmética
     de ponteiros, cadeias de caracteres, ponteiros em
     vetores, vetores de apontadores, acessando vetores com
     apontadores, indexação, diretrizes básicas para utilizá-
     los com segurança, etc.
§ Mostrar vários exemplos de códigos que você deve
  testar e solidificar seus conhecimentos
§ Este módulo é breve e aborda alguns assuntos já
  vistos em disciplinas anteriores
                                                                2
Conceitos

§ Em poucas palavras, um apontador é uma variável
  que guarda o endereço de uma área de memória
  § Em programação, uma variável é uma área da memória
    que “sabe como” guardar um valor específico
  § Tal endereço armazenado pelo ponteiro, geralmente, é a
    posição em memória de uma outra variável
§ A memória possui endereços para que possamos
  referenciá-la adequadamente
  § Assim, toda variável declarada possui um endereço
    relacionado a esta, o qual indica a posição de memória
    onde se inicia o armazenamento dos bytes relativos ao
    valor (dados) desta variável                             3
Graficamente...
                        Memória RAM       Endereços      Variáveis


                                            0x22f5    Ponteiro
§ Cada variável possui seu                            Ponteiro

próprio endereço de onde foi
                                                        0xff97
alocada na memória ( inclusive o
apontador! )                                0x8322    Variável 1
                                                      Variável 1
§ O apontador, por sua vez,
                                                          56
ainda guarda o endereço da
Variável 2                                  0xff97    Variável 2
                                                      Variável 2
§ O apontador não guarda o
              não guarda o
                                                        128,78
conteúdo da variável 2 (128,78)!
conteúdo da            (128,78)!


§ O ponteiro contém o endereço de uma
                                 de uma
variável que possui um valor armazenado                              4
Motivação

§ A linguagem C faz uso maciço de apontadores:
  § pode-se gerar códigos mais compactos e eficientes
  § em alguns casos, é a única maneira de se realizar uma
    determinada operação computacional
  § utilizado para que funções modifiquem os valores de seus
    argumentos
  § bastante usados em trabalhos que exijam alocação
    dinâmica de memória (veremos mais adiante)
  § você já deve saber que boa parte da biblioteca de C
    possui dezenas de funções manipulam apontadores (
    passando e/ou retornando-os)
                                                               5
Porém...

§ Programar em C usando apontadores requer um
  pouco mais de disciplina e de cuidados
§ É fácil criar apontadores que enderecem posições de
  memória indevidas, como as áreas de dados da
  aplicação ou até mesmo outros programas
§ Em alguns casos mais críticos, a utilização de forma
  incorreta pode provocar uma parada total do
  aplicativo ou até mesmo do sistema operacional
§ Somente a prática garante a experiência e o domínio
  total deste recurso
                                                       6
Sintaxe utilizada em C

§ Se uma variável irá conter um ponteiro, ela deve ser
  declarada como tal
§ Uma vez que o apontador tenha sido declarado e
  inicializado com um endereço válido de um
  elemento, este último poderá ser acessado
  indiretamente através do apontador
§ A forma geral para se declarar uma variável
  ponteiro é a seguinte:

         <tipo> * <nome_da_variável> ;
                                                         7
Sintaxe utilizada em C

          int main (void) {
               int *pntInt;
               float *pntFloat, salarioMensal;
               double *d = NULL; /* constante simbólica */
               char *str = “Apontadores em C”;
           }

§ O tipo base do ponteiro define o tipo base de variáveis
  para o qual o ponteiro pode apontar
§ Sempre procure, após declarar o ponteiro, inicializá-lo.
   § Isso é muito importante para evitar resultados
     indesejados!!!                                           8
Operadores & e *

§ Conforme já foi dito, uma variável pode ser acessada
  indiretamente através de um ponteiro
   § Para tanto, há 2 operadores unários fundamentais
     utilizados na manipulação de apontadores: * e &.
§ O operador unário * acessa o conteúdo de uma
  dada posição de memória cujo endereço está
  armazenado em um apontador
§ O operador unário & devolve o endereço de
  memória inicial de uma variável
   § Dica: o operador & pode ser aplicado apenas à variáveis
                                                               9
Operadores & e *

§ & (lê-se: o endereço de memória de...) como em:
  int x = 10;
  int *px; // apontador para um inteiro
  px = &x; // coloca em px o endereço de memória da variável x

§ Não são permitidas construções do tipo:
  int x = 10;
  int x = 10;
  int *px; // apontador para um inteiro
  int *px; // apontador para um inteiro
  px = & (x + 5); // expressões
  px = & (x + 5); // expressões
  px = &10; // não é possível obter endereços de constantes
  px = &10; // não é possível obter endereços de constantes
                                                                 10
Operadores & e *

§ * (lê-se: o conteúdo de...) como em:
     int y = 10, z;
     int *py; /* apontador para a variavel y */
     py = &y; /* coloca em py o endereço y */
     z = *py; /* Atribui a z o valor (conteúdo) da variável y */



     float f = 10.5;
     float *pf; /* apontador para a variavel f */
     pf = &f; /* coloca em py o endereço f */
     *pf = 300; /* O que esta instrução faz? */
     pf = 300; /* E esta instrução? Está errada?*/
                                                                   11
Evite erros!

§ Observe, no slide anterior, que é muito fácil apontar
  para áreas de memória indevidas!
§ Por isso, lembre-se: quando você declara um
                    se
  ponteiro no seu código, ele não aponta para lugar
  nenhum! Você deve “direcionar” o ponteiro para
  um endereço válido. Ainda que para NULL
     int *pntInt;
     int i = 100;
     ptnInt = NULL; /* está correto */
     ptnInt = &i; /* está correto */
                                                      12
Qual a saída do programa abaixo?
#include <stdio.h>
void main(void) {
    int x = 50, *p1, *p2;
    p1 = &x; // p1 recebe o endereço de x ou aponta para x
    p2 = p1; // p2 recebe endereço de p1 ou &x
    printf( "%pn", p2); // &x
                    p2);
    printf( "%pn", p1); // &x
                    p1);
    printf( "%pn", &x); // &x
                    &x);
    printf( "%pn", x); // errado, pois %p
                    x);
    printf( "%dn", p2); // errado pois %d
                    p2);
    printf( "%dn", *p2); // imprime 50
                    *p2);
    printf( "%pn", &p2); // endereço onde p2 foi alocado
                    &p2);
    printf( "%d", x);
                  x);    //imprime 50
}                                                            13
Como cavar a própria cova!
                                    cova!
int *p1;
 int *p1;
                         O ponteiro não foi
                          O ponteiro não foi
p1 = 5000;
 p1 = 5000;        inicializado! E se o endereço
                    inicializado! E se o endereço
                   5000 estiver alocado ao SO?
                    5000 estiver alocado ao SO?
int *p2;
 int *p2;
*p2 = 5000;
 *p2 = 5000;
                Erro gravíssimo! Reze para

int *p3;
 int *p3;
                Erro gravíssimo! Reze para
                 não travar a máquina…
                  não travar a máquina…             N
float a;
 float a;                 Incompatibilidade de tipos
                           Incompatibilidade de tipos
p3 = &a;
 p3 = &a;                 (talvez apenas um WARN)
                           (talvez apenas um WARN)

int *p4;
 int *p4;              Apenas 2 bytes são
                       Apenas 2 bytes são
float b, c;
 float b, c;     transferidos para c, e não os
                  transferidos para c, e não os
                   4 bytes do tipo float em b!
                   4 bytes do tipo float em b!
p4 = &b;
 p4 = &b;
c = *p4;
 c = *p4;                                               14
Aritmética de ponteiros

§ Podemos realizar duas operações aritméticas
  básicas com ponteiros: adição e subtração
§ Existem algumas regras que governam isso:
  § R1: se um ponteiro aponta para um objeto, a aritmética
    será feita levando-se em conta o tamanho do objeto
  § R2: cada vez que um ponteiro é incrementado (ou
    decrementado) o “salto” será feito de acordo com o tipo
    base do ponteiro
  § R3: não se pode adicionar ou subtrair constantes float
    ou double a ponteiros
  § R4: é claro, não se pode dividir ou multiplicar ponteiros
                                                                15
Aritmética de ponteiros

§ Exemplo:               Memória RAM   Endereços     Variáveis

   § Se um ponteiro p1 aponta            1998          p1
                                                       p1
     para um inteiro localizado
                                                      2000
     no endereço 2000                                 2002
     (assuma inteiro ocupando
                                         2000      Um int
     2 bytes). Qual o resultado                    Um int

     final após a expressão:                           78
     p1++; ?
   § Conclusão: Na figura ao             2002      Outro int
                                                   Outro int

     lado, quando p1 foi                               12
     incrementado, ele
     “saltou” 2 bytes para o
     próximo inteiro
                                                                 16
Aritmética de ponteiros

§ Você não está limitado apenas a operações de
  incremento e decremento
§ O comando p1 += 8 é válido. O ponteiro irá saltar
  para o oitavo elemento a partir do elemento em que
  ele estiver, atualmente, apontando.
§ Mas, p1+= 5.86; não o é. Isso por causa da regra
  R3 vista anteriormente.
§ Dica: utilize parênteses para evitar enganos:
  § *pt + 3 == 10; é bem diferente de…
  § *(pt + 3) == 10;
                                                   17
Apontadores e cadeias de caracteres

§ Você já deve saber que constantes do tipo cadeia
  são dados na forma:
   § “Eu sou uma cadeia de caracteres”
   § Esta cadeia de caracteres é, na verdade, um vetor de
     caracteres. O tamanho armazenado na memória é o
     tamanho da cadeia + 1, para conter o ‘0’ no final.
§ Poderemos ter num programa a seguinte construção
   char *mensagem = “O livro é um alimento”;
   mensagem = “vetor anterior foi perdido!”;
   § Um ponteiro para caracteres, por definição, aponta
     sempre para o primeiro caractere da cadeia!
   § Na linguagem C não existem operadores para manipular
     cadeia de caracteres, isto é feito através de funções.
                                                              18
Apontadores e cadeias de caracteres

§ Cuidado:
     char *nome = “José”;
     char *nome
     char *nomeCompleto = null;
     char *nomeCompleto
     if (*nome == “José”){
     if (*nome == “José”){
       *nomeCompleto = *nome + “da Silva”;
       *nomeCompleto = *nome + “da Silva”;
     } Código errado!
     } Código errado!        char *nome = "José";
                             char *nomeCompleto = NULL;
Consulte a API C sobre as
 Consulte a API C sobre as
funções strcmp e strcat.
 funções strcmp e strcat.    if (strcmp( nome, "José") == 0 ){
Existem ainda outras
 Existem ainda outras          nomeCompleto =
funções: strcpy, strlen…
 funções: strcpy, strlen…
                                     strcat( nome, "da Silva" );
                                     strcat(                  );
                             } Correto!
                             } Correto!
                                                                   19
Apontadores e vetores

§ Em C, qualquer operação que possa ser realizada
  com índices de um vetor também pode ser realizada
  com apontadores. Veja o código abaixo:
    #include <stdio.h>
    #include <stdio.h>
    void main(void) {
    void main(void) {
        char str[] = “Cesar”; // char str[] = {'C', 'e', 's', 'a', 'r', '0' };
        char str[] = “Cesar”; // char str[] = {'C', 'e', 's', 'a', 'r', '0' };
        char *pt;
        char *pt;
        pt = str; // pt irá apontar para &str[0]
        pt = str; // pt irá apontar para &str[0]
        str[2] = ‘A’; /* Atribui A ao terceiro elemento de str */
        str[2] = ‘A’; /* Atribui A ao terceiro elemento de str */
        putchar( *(pt + 2) ); /* ou pt[2] */
        putchar( *(pt + 2) ); /* ou pt[2] */
    }
    }
                                                                                  20
Apontadores e vetores

§ Muitas vezes, um ponteiro e um vetor se confundem
  no código devido a uma regra básica:
   § O nome de um vetor é sempre interpretado como o
     endereço do primeiro elemento deste.
§ Por exemplo:
    int a [3] = {1,2,3};
    int *p, *q;
    p = a; // a mesma coisa que &a[0];
    q = p;
§ Após este código, a, p e q referem-se todos ao
  mesmo endereço
                                                       21
Apontadores e vetores

§ Assim, de forma semelhante, ponteiros também
  podem ser indexados como arrays:
  a [1] = 7 ou p [1] = 7 ou até *(p+1) = 7
§ Mas lembre-se: arrays e ponteiros não são a
  mesma coisa!
  § Um ponteiro ocupa uma palavra de memória enquanto
    que, normalmente, um array ocupa várias posições
  § Um vetor não pode mudar de endereço!
  § Qual o significado de a = &salario; ?


                                                        22
Apontadores e vetores

                  *ptInt               ==     p[0]      ==       vetorInt[0]
                  *(ptInt + 1)         ==     p[1]      ==       vetorInt[1]
Portanto:         *(ptInt + 2)         ==     p[2]      ==       vetorInt[2]
                  *(ptInt + n)         ==     p[n]      ==       vetorInt[n]

  #include <stdio.h>
  #include <stdio.h>
  void main(void) {
  void main(void) {
  char vetor[] = “Cesar”; // char vetor[] = {'C', 'e', 's', 'a', 'r', '0' };
  char vetor[] = “Cesar”; // char vetor[] = {'C', 'e', 's', 'a', 'r', '0' };
       char *pv = vetor; // ou char *pv = &vetor[0];
       char *pv = vetor; // ou char *pv = &vetor[0];
       pv[ 2 ] = 'Z'; // ou *( pv+2 )) = 'Z'; ou vetor[2] = 'Z’;
       pv[ 2 ] = 'Z'; // ou *( pv+2 = 'Z'; ou vetor[2] = 'Z’;
       *( pv+1 )) = 'R'; // ou p[ 1 ] = 'R'; ou vetor[1] = ‘R’;
       *( pv+1 = 'R'; // ou p[ 1 ] = 'R'; ou vetor[1] = ‘R’;
       printf("%c", *( pv -- 2 )) );
       printf("%c", *( pv 2 );
       printf("%c", pv[ 1 ] );
       printf("%c", pv[ 1 ] );
  }
  }                                                                             23
Varrendo vetores com ponteiros

§ Pode-se varrer os elementos de um vetor via
  apontadores e também via indexação
    char v1[] = "Maria";
    char
    char v2[] = "Zezinho"; // char v2[] = {‘Z', 'e', ..., '0' };
    char v2[] = "Zezinho"; // char v2[] = {‘Z', 'e', ..., '0' };
    char *p;
    char *p;
    p = v1; // ou p = &v1[ 0 ];
    p = v1; // ou p = &v1[ 0 ];
    while ( *p )
    while ( *p )
        putchar( *p++ );
        putchar( *p++ );
    p = v2; // ou p = &v2[ 0 ];
    p = v2; // ou p = &v2[ 0 ];
    for ( register ii = 0; v2[ ii ] ;; ++i )
    for ( register = 0; v2[ ] ++i )
        putchar( *( p + ii ) ); // ou p[i] ou v2[i] ou *(vetor + i)
        putchar( *( p + ) ); // ou p[i] ou v2[i] ou *(vetor + i)

                                                                      24
Apontadores vs. Indexação

§ E então, devo apontar ou indexar?
  § A literatura diz que o uso de apontadores é mais
    adequado quando o vetor é acessado contiguamente, em
    ordem ascendente ou descendente
     § a codificação escrita com apontadores é mais rápida, uma
       vez que não se faz necessário o cálculo da posição de
       memória a partir do índice normal
     § Porém, o programador deve lembrar-se de reinicializar o
       ponteiro, após utilizá-lo
     § No geral, se você se sente confiante em utilizar ponteiros,
       faça-o.
  § O uso de índices é, geralmente, mais fácil de ser
    compreendido por programadores iniciantes                    25
Vetores de apontadores

§ Ponteiros podem ser organizados em arrays como
  qualquer outro tipo de dado:
§ Por exemplo:
      int *inteiros[10];
      int i = 20, j = 40;
      inteiros[0] = &i;
      inteiros[1] = &j;
      printf("i = %d j= %d", *inteiros[0], *inteiros[1]);

§ Lembre-se que *inteiros[] não é um ponteiro para
  inteiros, e sim um array de ponteiros para inteiros
                                                            26
Vetores de apontadores

§ Vetores de ponteiros são, geralmente, usados em
  ponteiros para cadeias de caracteres
   § Um exemplo bastante interessante e útil em
     programação consiste em construir uma função capaz de
     retornar mensagens a partir de um código:
          void erros( int cod ) {
          void erros( int cod ) {
              char *mensagemErro[] = {
              char *mensagemErro[] = {
                       “Impressora desconectadan”,
                       “Impressora desconectadan”,
                       “Rede fora do arn”,
                       “Rede fora do arn”,
                       “Arquivo não encontradon”
                       “Arquivo não encontradon”
              } ;;
              }
              printf( “%s”, mensagemErro[ cod ] );
              printf( “%s”, mensagemErro[ cod ] );
          }
          }
                                                         27
Passagem de parâmetros para funções

§ Em C, as funções são blocos de construção
  essenciais no desenvolvimento de um sistema
  § Consiste no local onde as atividades do programa são
    codificadas e executadas
  § C é uma linguagem imperativa e não é preciso dizer que
    a programação imperativa dá ênfase às funções (ou
    verbos) na hora de modelar um problema do mundo real
§ Podemos passar parâmetros para as funções de duas
  formas:
  § Passagem por valor: este método cria uma cópia do valor
    de um argumento e o passa como parâmetro da função
  § Passagem por referência: este método não passa uma
    cópia, e sim o endereço do argumento para o parâmetro 28
Passagem de parâmetros para funções

§ Na passagem de parâmetros por valor, modificações
  feitas nos parâmetros dentro da função não serão
  refletidas fora desta
  § Quando a função termina, a cópia também desaparece.
    int x = 5, int y = 2; // declaração de
     int x = 5, int y = 2; // declaração de          Pilha
                           variáveis
                            variáveis          Y     25




                                                             parâmetros
    trocar( x, y ); // chamada de função
     trocar( x, y ); // chamada de função
                                               X     52
    void trocar( int x, int y ) {
     void trocar( int x, int y ) {                   52
                                              temp
        int temp = x;
         int temp = x;                                 5
        x = y;
        x = y;                                 Y      2




                                                             globais
        y = temp;
        y = temp;                              X      5
    }
    }
                                                                          29
Passagem de parâmetros para funções

§ Na passagem de parâmetros por referência, (usando
  ponteiros) faz com que o endereço do argumento
  seja passado como parâmetro
  § Alterações serão refletidas fora da função
    int x = 5, int y = 2; // declaração de
     int x = 5, int y = 2; // declaração de              Pilha
                           variáveis
                           variáveis            *Y       ff97
                                                         ff97




                                                                 parâmetros
    trocar( &x, &y ); // chamada função
     trocar( &x, &y ); // chamada função
                                                *X       32f5
    void trocar( int *x, int *y ) {
     void trocar( int *x, int *y ) {
                                               temp
        int temp = *x;
         int temp = *x;                                   5
        *x = *y;
        *x = *y;                              Y: ff97    25




                                                                 globais
        *y = temp;
        *y = temp;                            X : 32f5   52
    }
    }
                                                                              30
Exercícios

§ Qual(is) o(s) erro(s)?
     char *cliente; char endereco[40];
     char *cliente;
     int idade = 50, *p1, *p2;
     int idade = 50, *p1, *p2;

     *cliente = “Lojas Americanas";
     *cliente = “Lojas Americanas";
     endereco = “Av. Sol, 555";
     endereco = “Av. Sol, 555";
     *p1 = 50;
     *p1 = 50;
     p2 = idade;
     p2 = idade;
     if ( p1 < p2 )
     if ( p1 < p2 )
         printf( “p1 em área de memória baixa. n” ) ;;
         printf( “p1 em área de memória            )
     exit(0);
     exit(0);
                                                              31
1) Ponteiro não inicializado!
                                 1) Ponteiro não inicializado!
                                                        Exercícios
                                2) Inicialização array errada!
                                 2) Inicialização array errada!
                                3) Área de memória desconhecida irá
                                 3) Área de memória desconhecida irá
                                    receber 50 em p1
                                     receber 50 em p1
§   Qual(is) o(s) erro(s)? 4) Endereço 50 em p2 pode estar
                                 4) Endereço 50 em p2 pode estar
                                    alocado a outro programa ou dados
                                     alocado a outro programa ou dados
      char *cliente;                ou SO. Código perigoso!
      char *cliente; char endereco[40]; Código perigoso!
                                     ou SO.
Π    int idade = 50, *p1, *p2; 5) O SO decide onde colocar ser
      int idade = 50, *p1, *p2; 5) O SO decide onde colocar ser
                                                                as
                                                                as
                                    variáveis. Printf pode não
                                     variáveis. Printf pode não
                                    executado amanhã!
                                     executado amanhã!
        *cliente = “Lojas Americanas";
        *cliente = “Lojas Americanas";
•
        endereco = “Av. Sol, 555";
        endereco = “Av. Sol, 555";
        *p1 = 50;
        *p1 = 50;         Ž
•       p2 = idade;
        p2 = idade;
        if ( p1 < p2 )
        if ( p1 < p2 )
            printf( “p1 em área de memória baixa. n” ) ;;
            printf( “p1 em área de memória            )
•       exit(0);
        exit(0);
                                Preste atenção nos pontos críticos! 32
                                                   pontos críticos!
Exercícios

§ Qual(is) o(s) erro(s)? (Versão 2)
     char *p1, s[81];
     char *p1,
     p1 = s;
     p1 = s;
     do {
     do {
         scanf( " %80[^n]", s ); //não captura brancos no início,
         scanf(                   //não captura brancos no início,
     limite de 80, permitindo brancos no meio da cadeia e todos
     limite de 80, permitindo brancos no meio da cadeia e todos
     caracteres menos enter
     caracteres menos enter
         while ( *p1 ) printf ( “%c”, *p1++ ) ;
                                              ;
     } while ( strcmp( s, “fim” ) );
     exit(0);



                                                                     33
1) Na primeira iteração do laço, p1
                                    1) Na primeira iteração do laço, p1
                                                             Exercícios
                                       aponta para S. O while imprime a
                                        aponta para S. O while imprime a
                                       string corretamente, mas…
                                        string corretamente, mas…

§ Qual(is) o(s) erro(s)? 2)Versão 2) impressão e início da
                         ( e no final da impressão e início da
                         2) e no final da
                                        segunda interação, pra onde p1
                                         segunda interação, pra onde p1
                                        está apontando? Por onde a
                                         está apontando? Por onde a
      char *p1, s[81];                  impressão vai começar neste
                                         impressão vai começar neste
                                        momento?
                                         momento?
  Πp1 = s;
      do {
           scanf( " %80[^n]", s ); //não captura brancos no inicio, ll
                                    //não captura brancos no inicio,
                             limite de 80 ate que o usuário tecle enter
                             limite de 80 ate que o usuário tecle enter
     p1?
           // imprime cada caractere
           // imprime cada caractere
           while ( *p1 ) printf ( “%c”, *p1++ ) ;
                                                ;
      } while ( strcmp( s, “fim” ) );
      exit(0);
                 O que deve ser feito para corrigir o programa?
                 O                                  o programa?

                                                                          34
Para um bom aproveitamento:

§ Instale a IDE de sua preferência e configure logo seu
  ambiente de trabalho
§ Codifique os exemplos mostrados nestes slides e
  verifique pontos de dúvidas
§ Resolva os exercícios da lista de apontadores
§ Procure o professor ou monitor da disciplina e
  questione conceitos, listas, etc.
§ Não deixe para codificar tudo e acumular assunto
  para a primeira avaliação.
   § Este é apenas um dos assuntos abordados na prova!
                                                         35

Mais conteúdo relacionado

Mais procurados (20)

Cet P Sistemas Linguagem C Introducao
Cet P Sistemas Linguagem C IntroducaoCet P Sistemas Linguagem C Introducao
Cet P Sistemas Linguagem C Introducao
 
Curso de Linguagem C
Curso de Linguagem CCurso de Linguagem C
Curso de Linguagem C
 
Apresentação Linguagem C
Apresentação Linguagem CApresentação Linguagem C
Apresentação Linguagem C
 
Compiladores 3
Compiladores 3Compiladores 3
Compiladores 3
 
Aula6 - Linguagem C
Aula6 - Linguagem CAula6 - Linguagem C
Aula6 - Linguagem C
 
Algoritmos - capítulo 6
Algoritmos - capítulo 6Algoritmos - capítulo 6
Algoritmos - capítulo 6
 
Introduçãso a linguagem c
Introduçãso a linguagem cIntroduçãso a linguagem c
Introduçãso a linguagem c
 
Aula09 traducaosin110
Aula09 traducaosin110Aula09 traducaosin110
Aula09 traducaosin110
 
Aula 6 pc - slides
Aula 6   pc - slidesAula 6   pc - slides
Aula 6 pc - slides
 
Apostila c++
Apostila c++Apostila c++
Apostila c++
 
Revisão sobre ponteiros em C
Revisão sobre ponteiros em CRevisão sobre ponteiros em C
Revisão sobre ponteiros em C
 
Linguagem c parte 2
Linguagem c parte 2Linguagem c parte 2
Linguagem c parte 2
 
Linguagem C clecioamerico
Linguagem C clecioamericoLinguagem C clecioamerico
Linguagem C clecioamerico
 
Linguagem c
Linguagem cLinguagem c
Linguagem c
 
Apostila da linguagem c
Apostila da linguagem cApostila da linguagem c
Apostila da linguagem c
 
Linguagem C - Controle de Programa
Linguagem C - Controle de ProgramaLinguagem C - Controle de Programa
Linguagem C - Controle de Programa
 
C++
C++C++
C++
 
Linguagem C - Funções e ponteiros
Linguagem C - Funções e ponteiros Linguagem C - Funções e ponteiros
Linguagem C - Funções e ponteiros
 
Linguagem C - Strings
Linguagem C - StringsLinguagem C - Strings
Linguagem C - Strings
 
Apostila C++ Básico - UNIVERSIDADE ESTADUAL PAULISTA “JÚLIO DE MESQUITA FILHO”
Apostila C++ Básico - UNIVERSIDADE ESTADUAL PAULISTA “JÚLIO DE MESQUITA FILHO”Apostila C++ Básico - UNIVERSIDADE ESTADUAL PAULISTA “JÚLIO DE MESQUITA FILHO”
Apostila C++ Básico - UNIVERSIDADE ESTADUAL PAULISTA “JÚLIO DE MESQUITA FILHO”
 

Semelhante a Pged 01

Aula c++ estruturas de dados
Aula c++   estruturas de dadosAula c++   estruturas de dados
Aula c++ estruturas de dadosJean Martina
 
document.onl_manual-psi-m5.pdf
document.onl_manual-psi-m5.pdfdocument.onl_manual-psi-m5.pdf
document.onl_manual-psi-m5.pdfAnaAlmeida462833
 
Programação Estruturada 2 - Aula 05
Programação Estruturada 2 - Aula 05Programação Estruturada 2 - Aula 05
Programação Estruturada 2 - Aula 05thomasdacosta
 
Apostila de-introdução-à-linguagem-c
Apostila de-introdução-à-linguagem-cApostila de-introdução-à-linguagem-c
Apostila de-introdução-à-linguagem-cMaicon Rodrigues
 
8 ponteiros, ponteiros e vetores e alocacao dinamica de memoria
8   ponteiros,  ponteiros e vetores e alocacao dinamica de memoria8   ponteiros,  ponteiros e vetores e alocacao dinamica de memoria
8 ponteiros, ponteiros e vetores e alocacao dinamica de memoriaRicardo Bolanho
 
Comandos de Controle de Programa em C
Comandos de Controle de Programa em CComandos de Controle de Programa em C
Comandos de Controle de Programa em CElaine Cecília Gatto
 
Laboratório de Programação II: Uso do ponteiro void *
Laboratório de Programação II: Uso do ponteiro void *Laboratório de Programação II: Uso do ponteiro void *
Laboratório de Programação II: Uso do ponteiro void *Alex Camargo
 
Algoritmos C/C++ - Aula 01
Algoritmos C/C++ - Aula 01Algoritmos C/C++ - Aula 01
Algoritmos C/C++ - Aula 01Leandro Rezende
 
Aula 03 - Introducao ao PHP (1).pdf
Aula 03 - Introducao ao PHP (1).pdfAula 03 - Introducao ao PHP (1).pdf
Aula 03 - Introducao ao PHP (1).pdfJOSESOUZA55923
 
Curso Completo de Linguagem de Programação C
Curso Completo de Linguagem de Programação CCurso Completo de Linguagem de Programação C
Curso Completo de Linguagem de Programação CJoberthSilva
 
Introdução à Linguagem de Programação C
Introdução à Linguagem de Programação CIntrodução à Linguagem de Programação C
Introdução à Linguagem de Programação CJose Augusto Cintra
 
Apostila linguagem c
Apostila linguagem cApostila linguagem c
Apostila linguagem cvingue
 

Semelhante a Pged 01 (20)

Linguagem C - Ponteiros
Linguagem C - PonteirosLinguagem C - Ponteiros
Linguagem C - Ponteiros
 
Unidade04
Unidade04Unidade04
Unidade04
 
Aula c++ estruturas de dados
Aula c++   estruturas de dadosAula c++   estruturas de dados
Aula c++ estruturas de dados
 
Introdução à Linguagem C
Introdução à Linguagem CIntrodução à Linguagem C
Introdução à Linguagem C
 
document.onl_manual-psi-m5.pdf
document.onl_manual-psi-m5.pdfdocument.onl_manual-psi-m5.pdf
document.onl_manual-psi-m5.pdf
 
Programação Estruturada 2 - Aula 05
Programação Estruturada 2 - Aula 05Programação Estruturada 2 - Aula 05
Programação Estruturada 2 - Aula 05
 
Apostila de-introdução-à-linguagem-c
Apostila de-introdução-à-linguagem-cApostila de-introdução-à-linguagem-c
Apostila de-introdução-à-linguagem-c
 
8 ponteiros, ponteiros e vetores e alocacao dinamica de memoria
8   ponteiros,  ponteiros e vetores e alocacao dinamica de memoria8   ponteiros,  ponteiros e vetores e alocacao dinamica de memoria
8 ponteiros, ponteiros e vetores e alocacao dinamica de memoria
 
Linguagem_C.pdf
Linguagem_C.pdfLinguagem_C.pdf
Linguagem_C.pdf
 
Aula de C e C++
Aula de C e C++Aula de C e C++
Aula de C e C++
 
Comandos de Controle de Programa em C
Comandos de Controle de Programa em CComandos de Controle de Programa em C
Comandos de Controle de Programa em C
 
Laboratório de Programação II: Uso do ponteiro void *
Laboratório de Programação II: Uso do ponteiro void *Laboratório de Programação II: Uso do ponteiro void *
Laboratório de Programação II: Uso do ponteiro void *
 
Algoritmos C/C++ - Aula 01
Algoritmos C/C++ - Aula 01Algoritmos C/C++ - Aula 01
Algoritmos C/C++ - Aula 01
 
Aula 03 - Introducao ao PHP (1).pdf
Aula 03 - Introducao ao PHP (1).pdfAula 03 - Introducao ao PHP (1).pdf
Aula 03 - Introducao ao PHP (1).pdf
 
Curso Completo de Linguagem de Programação C
Curso Completo de Linguagem de Programação CCurso Completo de Linguagem de Programação C
Curso Completo de Linguagem de Programação C
 
Ed1
Ed1Ed1
Ed1
 
Introdução à Linguagem de Programação C
Introdução à Linguagem de Programação CIntrodução à Linguagem de Programação C
Introdução à Linguagem de Programação C
 
Apostila linguagem c
Apostila linguagem cApostila linguagem c
Apostila linguagem c
 
Apostila linguagem c
Apostila linguagem cApostila linguagem c
Apostila linguagem c
 
Apostila linguagem c
Apostila linguagem cApostila linguagem c
Apostila linguagem c
 

Mais de samuelthiago

Interface grafica em_java_parte_v
Interface grafica em_java_parte_vInterface grafica em_java_parte_v
Interface grafica em_java_parte_vsamuelthiago
 
Interface grafica em_java_parte_iv
Interface grafica em_java_parte_ivInterface grafica em_java_parte_iv
Interface grafica em_java_parte_ivsamuelthiago
 
Interface grafica em_java_parte_iii
Interface grafica em_java_parte_iiiInterface grafica em_java_parte_iii
Interface grafica em_java_parte_iiisamuelthiago
 
Interface grafica em_java_parte_ii
Interface grafica em_java_parte_iiInterface grafica em_java_parte_ii
Interface grafica em_java_parte_iisamuelthiago
 
Interface grafica em_java_parte_i
Interface grafica em_java_parte_iInterface grafica em_java_parte_i
Interface grafica em_java_parte_isamuelthiago
 
Poo interacao entre_objetos_blue_j_ii
Poo interacao entre_objetos_blue_j_iiPoo interacao entre_objetos_blue_j_ii
Poo interacao entre_objetos_blue_j_iisamuelthiago
 
Introducao a poo_com_blue_j
Introducao a poo_com_blue_jIntroducao a poo_com_blue_j
Introducao a poo_com_blue_jsamuelthiago
 
Projeto calculadora em_java
Projeto calculadora em_javaProjeto calculadora em_java
Projeto calculadora em_javasamuelthiago
 
Introducao a poo_com_blue_j
Introducao a poo_com_blue_jIntroducao a poo_com_blue_j
Introducao a poo_com_blue_jsamuelthiago
 
01 02 introdução aos bancos de dados (slides)
01 02 introdução aos bancos de dados (slides)01 02 introdução aos bancos de dados (slides)
01 02 introdução aos bancos de dados (slides)samuelthiago
 

Mais de samuelthiago (20)

Eclipse i (1)
Eclipse i (1)Eclipse i (1)
Eclipse i (1)
 
Html básico
Html básicoHtml básico
Html básico
 
Interface grafica em_java_parte_v
Interface grafica em_java_parte_vInterface grafica em_java_parte_v
Interface grafica em_java_parte_v
 
Interface grafica em_java_parte_iv
Interface grafica em_java_parte_ivInterface grafica em_java_parte_iv
Interface grafica em_java_parte_iv
 
Interface grafica em_java_parte_iii
Interface grafica em_java_parte_iiiInterface grafica em_java_parte_iii
Interface grafica em_java_parte_iii
 
Interface grafica em_java_parte_ii
Interface grafica em_java_parte_iiInterface grafica em_java_parte_ii
Interface grafica em_java_parte_ii
 
Interface grafica em_java_parte_i
Interface grafica em_java_parte_iInterface grafica em_java_parte_i
Interface grafica em_java_parte_i
 
Poo interacao entre_objetos_blue_j_ii
Poo interacao entre_objetos_blue_j_iiPoo interacao entre_objetos_blue_j_ii
Poo interacao entre_objetos_blue_j_ii
 
Introducao a poo_com_blue_j
Introducao a poo_com_blue_jIntroducao a poo_com_blue_j
Introducao a poo_com_blue_j
 
Projeto calculadora em_java
Projeto calculadora em_javaProjeto calculadora em_java
Projeto calculadora em_java
 
Introducao a poo_com_blue_j
Introducao a poo_com_blue_jIntroducao a poo_com_blue_j
Introducao a poo_com_blue_j
 
01 02 introdução aos bancos de dados (slides)
01 02 introdução aos bancos de dados (slides)01 02 introdução aos bancos de dados (slides)
01 02 introdução aos bancos de dados (slides)
 
Java 08
Java 08Java 08
Java 08
 
Java 07
Java 07Java 07
Java 07
 
Java 06
Java 06Java 06
Java 06
 
Java 05
Java 05Java 05
Java 05
 
Java 04
Java 04Java 04
Java 04
 
Java 03
Java 03Java 03
Java 03
 
Java 02
Java 02Java 02
Java 02
 
Java 01
Java 01Java 01
Java 01
 

Pged 01

  • 1. Curso Superior de Tecnologia em Telemática Programação e Estruturas de Dados Linguagem C, Apontadores e Revisão Prática Copyright©2010 Prof. César Rocha cesarocha@ifpb.edu.br 1
  • 2. Objetivos § Explorar os conceitos fundamentais acerca do uso de apontadores (ponteiros)na linguagem C § sintaxe, principais operadores, erros comuns, aritmética de ponteiros, cadeias de caracteres, ponteiros em vetores, vetores de apontadores, acessando vetores com apontadores, indexação, diretrizes básicas para utilizá- los com segurança, etc. § Mostrar vários exemplos de códigos que você deve testar e solidificar seus conhecimentos § Este módulo é breve e aborda alguns assuntos já vistos em disciplinas anteriores 2
  • 3. Conceitos § Em poucas palavras, um apontador é uma variável que guarda o endereço de uma área de memória § Em programação, uma variável é uma área da memória que “sabe como” guardar um valor específico § Tal endereço armazenado pelo ponteiro, geralmente, é a posição em memória de uma outra variável § A memória possui endereços para que possamos referenciá-la adequadamente § Assim, toda variável declarada possui um endereço relacionado a esta, o qual indica a posição de memória onde se inicia o armazenamento dos bytes relativos ao valor (dados) desta variável 3
  • 4. Graficamente... Memória RAM Endereços Variáveis 0x22f5 Ponteiro § Cada variável possui seu Ponteiro próprio endereço de onde foi 0xff97 alocada na memória ( inclusive o apontador! ) 0x8322 Variável 1 Variável 1 § O apontador, por sua vez, 56 ainda guarda o endereço da Variável 2 0xff97 Variável 2 Variável 2 § O apontador não guarda o não guarda o 128,78 conteúdo da variável 2 (128,78)! conteúdo da (128,78)! § O ponteiro contém o endereço de uma de uma variável que possui um valor armazenado 4
  • 5. Motivação § A linguagem C faz uso maciço de apontadores: § pode-se gerar códigos mais compactos e eficientes § em alguns casos, é a única maneira de se realizar uma determinada operação computacional § utilizado para que funções modifiquem os valores de seus argumentos § bastante usados em trabalhos que exijam alocação dinâmica de memória (veremos mais adiante) § você já deve saber que boa parte da biblioteca de C possui dezenas de funções manipulam apontadores ( passando e/ou retornando-os) 5
  • 6. Porém... § Programar em C usando apontadores requer um pouco mais de disciplina e de cuidados § É fácil criar apontadores que enderecem posições de memória indevidas, como as áreas de dados da aplicação ou até mesmo outros programas § Em alguns casos mais críticos, a utilização de forma incorreta pode provocar uma parada total do aplicativo ou até mesmo do sistema operacional § Somente a prática garante a experiência e o domínio total deste recurso 6
  • 7. Sintaxe utilizada em C § Se uma variável irá conter um ponteiro, ela deve ser declarada como tal § Uma vez que o apontador tenha sido declarado e inicializado com um endereço válido de um elemento, este último poderá ser acessado indiretamente através do apontador § A forma geral para se declarar uma variável ponteiro é a seguinte: <tipo> * <nome_da_variável> ; 7
  • 8. Sintaxe utilizada em C int main (void) { int *pntInt; float *pntFloat, salarioMensal; double *d = NULL; /* constante simbólica */ char *str = “Apontadores em C”; } § O tipo base do ponteiro define o tipo base de variáveis para o qual o ponteiro pode apontar § Sempre procure, após declarar o ponteiro, inicializá-lo. § Isso é muito importante para evitar resultados indesejados!!! 8
  • 9. Operadores & e * § Conforme já foi dito, uma variável pode ser acessada indiretamente através de um ponteiro § Para tanto, há 2 operadores unários fundamentais utilizados na manipulação de apontadores: * e &. § O operador unário * acessa o conteúdo de uma dada posição de memória cujo endereço está armazenado em um apontador § O operador unário & devolve o endereço de memória inicial de uma variável § Dica: o operador & pode ser aplicado apenas à variáveis 9
  • 10. Operadores & e * § & (lê-se: o endereço de memória de...) como em: int x = 10; int *px; // apontador para um inteiro px = &x; // coloca em px o endereço de memória da variável x § Não são permitidas construções do tipo: int x = 10; int x = 10; int *px; // apontador para um inteiro int *px; // apontador para um inteiro px = & (x + 5); // expressões px = & (x + 5); // expressões px = &10; // não é possível obter endereços de constantes px = &10; // não é possível obter endereços de constantes 10
  • 11. Operadores & e * § * (lê-se: o conteúdo de...) como em: int y = 10, z; int *py; /* apontador para a variavel y */ py = &y; /* coloca em py o endereço y */ z = *py; /* Atribui a z o valor (conteúdo) da variável y */ float f = 10.5; float *pf; /* apontador para a variavel f */ pf = &f; /* coloca em py o endereço f */ *pf = 300; /* O que esta instrução faz? */ pf = 300; /* E esta instrução? Está errada?*/ 11
  • 12. Evite erros! § Observe, no slide anterior, que é muito fácil apontar para áreas de memória indevidas! § Por isso, lembre-se: quando você declara um se ponteiro no seu código, ele não aponta para lugar nenhum! Você deve “direcionar” o ponteiro para um endereço válido. Ainda que para NULL int *pntInt; int i = 100; ptnInt = NULL; /* está correto */ ptnInt = &i; /* está correto */ 12
  • 13. Qual a saída do programa abaixo? #include <stdio.h> void main(void) { int x = 50, *p1, *p2; p1 = &x; // p1 recebe o endereço de x ou aponta para x p2 = p1; // p2 recebe endereço de p1 ou &x printf( "%pn", p2); // &x p2); printf( "%pn", p1); // &x p1); printf( "%pn", &x); // &x &x); printf( "%pn", x); // errado, pois %p x); printf( "%dn", p2); // errado pois %d p2); printf( "%dn", *p2); // imprime 50 *p2); printf( "%pn", &p2); // endereço onde p2 foi alocado &p2); printf( "%d", x); x); //imprime 50 } 13
  • 14. Como cavar a própria cova! cova! int *p1; int *p1; O ponteiro não foi O ponteiro não foi p1 = 5000; p1 = 5000; inicializado! E se o endereço inicializado! E se o endereço 5000 estiver alocado ao SO? 5000 estiver alocado ao SO? int *p2; int *p2; *p2 = 5000; *p2 = 5000; Erro gravíssimo! Reze para int *p3; int *p3; Erro gravíssimo! Reze para não travar a máquina… não travar a máquina… N float a; float a; Incompatibilidade de tipos Incompatibilidade de tipos p3 = &a; p3 = &a; (talvez apenas um WARN) (talvez apenas um WARN) int *p4; int *p4; Apenas 2 bytes são Apenas 2 bytes são float b, c; float b, c; transferidos para c, e não os transferidos para c, e não os 4 bytes do tipo float em b! 4 bytes do tipo float em b! p4 = &b; p4 = &b; c = *p4; c = *p4; 14
  • 15. Aritmética de ponteiros § Podemos realizar duas operações aritméticas básicas com ponteiros: adição e subtração § Existem algumas regras que governam isso: § R1: se um ponteiro aponta para um objeto, a aritmética será feita levando-se em conta o tamanho do objeto § R2: cada vez que um ponteiro é incrementado (ou decrementado) o “salto” será feito de acordo com o tipo base do ponteiro § R3: não se pode adicionar ou subtrair constantes float ou double a ponteiros § R4: é claro, não se pode dividir ou multiplicar ponteiros 15
  • 16. Aritmética de ponteiros § Exemplo: Memória RAM Endereços Variáveis § Se um ponteiro p1 aponta 1998 p1 p1 para um inteiro localizado 2000 no endereço 2000 2002 (assuma inteiro ocupando 2000 Um int 2 bytes). Qual o resultado Um int final após a expressão: 78 p1++; ? § Conclusão: Na figura ao 2002 Outro int Outro int lado, quando p1 foi 12 incrementado, ele “saltou” 2 bytes para o próximo inteiro 16
  • 17. Aritmética de ponteiros § Você não está limitado apenas a operações de incremento e decremento § O comando p1 += 8 é válido. O ponteiro irá saltar para o oitavo elemento a partir do elemento em que ele estiver, atualmente, apontando. § Mas, p1+= 5.86; não o é. Isso por causa da regra R3 vista anteriormente. § Dica: utilize parênteses para evitar enganos: § *pt + 3 == 10; é bem diferente de… § *(pt + 3) == 10; 17
  • 18. Apontadores e cadeias de caracteres § Você já deve saber que constantes do tipo cadeia são dados na forma: § “Eu sou uma cadeia de caracteres” § Esta cadeia de caracteres é, na verdade, um vetor de caracteres. O tamanho armazenado na memória é o tamanho da cadeia + 1, para conter o ‘0’ no final. § Poderemos ter num programa a seguinte construção char *mensagem = “O livro é um alimento”; mensagem = “vetor anterior foi perdido!”; § Um ponteiro para caracteres, por definição, aponta sempre para o primeiro caractere da cadeia! § Na linguagem C não existem operadores para manipular cadeia de caracteres, isto é feito através de funções. 18
  • 19. Apontadores e cadeias de caracteres § Cuidado: char *nome = “José”; char *nome char *nomeCompleto = null; char *nomeCompleto if (*nome == “José”){ if (*nome == “José”){ *nomeCompleto = *nome + “da Silva”; *nomeCompleto = *nome + “da Silva”; } Código errado! } Código errado! char *nome = "José"; char *nomeCompleto = NULL; Consulte a API C sobre as Consulte a API C sobre as funções strcmp e strcat. funções strcmp e strcat. if (strcmp( nome, "José") == 0 ){ Existem ainda outras Existem ainda outras nomeCompleto = funções: strcpy, strlen… funções: strcpy, strlen… strcat( nome, "da Silva" ); strcat( ); } Correto! } Correto! 19
  • 20. Apontadores e vetores § Em C, qualquer operação que possa ser realizada com índices de um vetor também pode ser realizada com apontadores. Veja o código abaixo: #include <stdio.h> #include <stdio.h> void main(void) { void main(void) { char str[] = “Cesar”; // char str[] = {'C', 'e', 's', 'a', 'r', '0' }; char str[] = “Cesar”; // char str[] = {'C', 'e', 's', 'a', 'r', '0' }; char *pt; char *pt; pt = str; // pt irá apontar para &str[0] pt = str; // pt irá apontar para &str[0] str[2] = ‘A’; /* Atribui A ao terceiro elemento de str */ str[2] = ‘A’; /* Atribui A ao terceiro elemento de str */ putchar( *(pt + 2) ); /* ou pt[2] */ putchar( *(pt + 2) ); /* ou pt[2] */ } } 20
  • 21. Apontadores e vetores § Muitas vezes, um ponteiro e um vetor se confundem no código devido a uma regra básica: § O nome de um vetor é sempre interpretado como o endereço do primeiro elemento deste. § Por exemplo: int a [3] = {1,2,3}; int *p, *q; p = a; // a mesma coisa que &a[0]; q = p; § Após este código, a, p e q referem-se todos ao mesmo endereço 21
  • 22. Apontadores e vetores § Assim, de forma semelhante, ponteiros também podem ser indexados como arrays: a [1] = 7 ou p [1] = 7 ou até *(p+1) = 7 § Mas lembre-se: arrays e ponteiros não são a mesma coisa! § Um ponteiro ocupa uma palavra de memória enquanto que, normalmente, um array ocupa várias posições § Um vetor não pode mudar de endereço! § Qual o significado de a = &salario; ? 22
  • 23. Apontadores e vetores *ptInt == p[0] == vetorInt[0] *(ptInt + 1) == p[1] == vetorInt[1] Portanto: *(ptInt + 2) == p[2] == vetorInt[2] *(ptInt + n) == p[n] == vetorInt[n] #include <stdio.h> #include <stdio.h> void main(void) { void main(void) { char vetor[] = “Cesar”; // char vetor[] = {'C', 'e', 's', 'a', 'r', '0' }; char vetor[] = “Cesar”; // char vetor[] = {'C', 'e', 's', 'a', 'r', '0' }; char *pv = vetor; // ou char *pv = &vetor[0]; char *pv = vetor; // ou char *pv = &vetor[0]; pv[ 2 ] = 'Z'; // ou *( pv+2 )) = 'Z'; ou vetor[2] = 'Z’; pv[ 2 ] = 'Z'; // ou *( pv+2 = 'Z'; ou vetor[2] = 'Z’; *( pv+1 )) = 'R'; // ou p[ 1 ] = 'R'; ou vetor[1] = ‘R’; *( pv+1 = 'R'; // ou p[ 1 ] = 'R'; ou vetor[1] = ‘R’; printf("%c", *( pv -- 2 )) ); printf("%c", *( pv 2 ); printf("%c", pv[ 1 ] ); printf("%c", pv[ 1 ] ); } } 23
  • 24. Varrendo vetores com ponteiros § Pode-se varrer os elementos de um vetor via apontadores e também via indexação char v1[] = "Maria"; char char v2[] = "Zezinho"; // char v2[] = {‘Z', 'e', ..., '0' }; char v2[] = "Zezinho"; // char v2[] = {‘Z', 'e', ..., '0' }; char *p; char *p; p = v1; // ou p = &v1[ 0 ]; p = v1; // ou p = &v1[ 0 ]; while ( *p ) while ( *p ) putchar( *p++ ); putchar( *p++ ); p = v2; // ou p = &v2[ 0 ]; p = v2; // ou p = &v2[ 0 ]; for ( register ii = 0; v2[ ii ] ;; ++i ) for ( register = 0; v2[ ] ++i ) putchar( *( p + ii ) ); // ou p[i] ou v2[i] ou *(vetor + i) putchar( *( p + ) ); // ou p[i] ou v2[i] ou *(vetor + i) 24
  • 25. Apontadores vs. Indexação § E então, devo apontar ou indexar? § A literatura diz que o uso de apontadores é mais adequado quando o vetor é acessado contiguamente, em ordem ascendente ou descendente § a codificação escrita com apontadores é mais rápida, uma vez que não se faz necessário o cálculo da posição de memória a partir do índice normal § Porém, o programador deve lembrar-se de reinicializar o ponteiro, após utilizá-lo § No geral, se você se sente confiante em utilizar ponteiros, faça-o. § O uso de índices é, geralmente, mais fácil de ser compreendido por programadores iniciantes 25
  • 26. Vetores de apontadores § Ponteiros podem ser organizados em arrays como qualquer outro tipo de dado: § Por exemplo: int *inteiros[10]; int i = 20, j = 40; inteiros[0] = &i; inteiros[1] = &j; printf("i = %d j= %d", *inteiros[0], *inteiros[1]); § Lembre-se que *inteiros[] não é um ponteiro para inteiros, e sim um array de ponteiros para inteiros 26
  • 27. Vetores de apontadores § Vetores de ponteiros são, geralmente, usados em ponteiros para cadeias de caracteres § Um exemplo bastante interessante e útil em programação consiste em construir uma função capaz de retornar mensagens a partir de um código: void erros( int cod ) { void erros( int cod ) { char *mensagemErro[] = { char *mensagemErro[] = { “Impressora desconectadan”, “Impressora desconectadan”, “Rede fora do arn”, “Rede fora do arn”, “Arquivo não encontradon” “Arquivo não encontradon” } ;; } printf( “%s”, mensagemErro[ cod ] ); printf( “%s”, mensagemErro[ cod ] ); } } 27
  • 28. Passagem de parâmetros para funções § Em C, as funções são blocos de construção essenciais no desenvolvimento de um sistema § Consiste no local onde as atividades do programa são codificadas e executadas § C é uma linguagem imperativa e não é preciso dizer que a programação imperativa dá ênfase às funções (ou verbos) na hora de modelar um problema do mundo real § Podemos passar parâmetros para as funções de duas formas: § Passagem por valor: este método cria uma cópia do valor de um argumento e o passa como parâmetro da função § Passagem por referência: este método não passa uma cópia, e sim o endereço do argumento para o parâmetro 28
  • 29. Passagem de parâmetros para funções § Na passagem de parâmetros por valor, modificações feitas nos parâmetros dentro da função não serão refletidas fora desta § Quando a função termina, a cópia também desaparece. int x = 5, int y = 2; // declaração de int x = 5, int y = 2; // declaração de Pilha variáveis variáveis Y 25 parâmetros trocar( x, y ); // chamada de função trocar( x, y ); // chamada de função X 52 void trocar( int x, int y ) { void trocar( int x, int y ) { 52 temp int temp = x; int temp = x; 5 x = y; x = y; Y 2 globais y = temp; y = temp; X 5 } } 29
  • 30. Passagem de parâmetros para funções § Na passagem de parâmetros por referência, (usando ponteiros) faz com que o endereço do argumento seja passado como parâmetro § Alterações serão refletidas fora da função int x = 5, int y = 2; // declaração de int x = 5, int y = 2; // declaração de Pilha variáveis variáveis *Y ff97 ff97 parâmetros trocar( &x, &y ); // chamada função trocar( &x, &y ); // chamada função *X 32f5 void trocar( int *x, int *y ) { void trocar( int *x, int *y ) { temp int temp = *x; int temp = *x; 5 *x = *y; *x = *y; Y: ff97 25 globais *y = temp; *y = temp; X : 32f5 52 } } 30
  • 31. Exercícios § Qual(is) o(s) erro(s)? char *cliente; char endereco[40]; char *cliente; int idade = 50, *p1, *p2; int idade = 50, *p1, *p2; *cliente = “Lojas Americanas"; *cliente = “Lojas Americanas"; endereco = “Av. Sol, 555"; endereco = “Av. Sol, 555"; *p1 = 50; *p1 = 50; p2 = idade; p2 = idade; if ( p1 < p2 ) if ( p1 < p2 ) printf( “p1 em área de memória baixa. n” ) ;; printf( “p1 em área de memória ) exit(0); exit(0); 31
  • 32. 1) Ponteiro não inicializado! 1) Ponteiro não inicializado! Exercícios 2) Inicialização array errada! 2) Inicialização array errada! 3) Área de memória desconhecida irá 3) Área de memória desconhecida irá receber 50 em p1 receber 50 em p1 § Qual(is) o(s) erro(s)? 4) Endereço 50 em p2 pode estar 4) Endereço 50 em p2 pode estar alocado a outro programa ou dados alocado a outro programa ou dados char *cliente; ou SO. Código perigoso! char *cliente; char endereco[40]; Código perigoso! ou SO. Œ int idade = 50, *p1, *p2; 5) O SO decide onde colocar ser int idade = 50, *p1, *p2; 5) O SO decide onde colocar ser as as variáveis. Printf pode não variáveis. Printf pode não executado amanhã! executado amanhã! *cliente = “Lojas Americanas"; *cliente = “Lojas Americanas"; • endereco = “Av. Sol, 555"; endereco = “Av. Sol, 555"; *p1 = 50; *p1 = 50; Ž • p2 = idade; p2 = idade; if ( p1 < p2 ) if ( p1 < p2 ) printf( “p1 em área de memória baixa. n” ) ;; printf( “p1 em área de memória ) • exit(0); exit(0); Preste atenção nos pontos críticos! 32 pontos críticos!
  • 33. Exercícios § Qual(is) o(s) erro(s)? (Versão 2) char *p1, s[81]; char *p1, p1 = s; p1 = s; do { do { scanf( " %80[^n]", s ); //não captura brancos no início, scanf( //não captura brancos no início, limite de 80, permitindo brancos no meio da cadeia e todos limite de 80, permitindo brancos no meio da cadeia e todos caracteres menos enter caracteres menos enter while ( *p1 ) printf ( “%c”, *p1++ ) ; ; } while ( strcmp( s, “fim” ) ); exit(0); 33
  • 34. 1) Na primeira iteração do laço, p1 1) Na primeira iteração do laço, p1 Exercícios aponta para S. O while imprime a aponta para S. O while imprime a string corretamente, mas… string corretamente, mas… § Qual(is) o(s) erro(s)? 2)Versão 2) impressão e início da ( e no final da impressão e início da 2) e no final da segunda interação, pra onde p1 segunda interação, pra onde p1 está apontando? Por onde a está apontando? Por onde a char *p1, s[81]; impressão vai começar neste impressão vai começar neste momento? momento? Œ p1 = s; do { scanf( " %80[^n]", s ); //não captura brancos no inicio, ll //não captura brancos no inicio, limite de 80 ate que o usuário tecle enter limite de 80 ate que o usuário tecle enter p1? // imprime cada caractere // imprime cada caractere while ( *p1 ) printf ( “%c”, *p1++ ) ; ; } while ( strcmp( s, “fim” ) ); exit(0); O que deve ser feito para corrigir o programa? O o programa? 34
  • 35. Para um bom aproveitamento: § Instale a IDE de sua preferência e configure logo seu ambiente de trabalho § Codifique os exemplos mostrados nestes slides e verifique pontos de dúvidas § Resolva os exercícios da lista de apontadores § Procure o professor ou monitor da disciplina e questione conceitos, listas, etc. § Não deixe para codificar tudo e acumular assunto para a primeira avaliação. § Este é apenas um dos assuntos abordados na prova! 35