Ponteiros

  1. $ \bigstar\bigstar$ Escrever um programa para imprimir as matrizes declaradas abaixo utilizando ponteiros.

    int vetor [5] = 0, 1, 2, 3, 4;

    int matriz [4][4] = 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4;

    char string [10] = "BICAMPEAO";

  2. $ \bigstar\bigstar$ Escreva um programa para:

    a) declarar variáveis a, b, c, d do tipo int.

    b) declarar variáveis e, f, g, h do tipo float.

    c) declarar vetor v de 10 elementos do tipo char.

    d) declarar variável x do tipo int.

    e) criar um ponteiro apontando para o endereço de a.

    f) incrementar o ponteiro, mostrando o conteúdo do endereço apontado (em forma de número). Caso o endereço coincida com o endereço de alguma outra variável, informar o fato.

  3. $ \bigstar\bigstar$ Se i e j são variáveis inteiras e p e q ponteiros para int, quais das seguintes expressões de atribuição são inválidas? Justifique a sua resposta.

    a) p = &i;

    b) *q = &j;

    c) p = &*&i;

    d) i = (*&)j;

    e) i = *&j;

    f) i = *&*&j;

    g) q = *p;

    h) i = (*p)++ + *q

  4. $ \bigstar$ Verifique o programa abaixo. Encontre o seu erro e corrija-o para que escreva o número 10 na tela.

    #include <stdio.h> 
    int main() 
    { 
        int x, *p, **q; 
        p = &x; 
        q = &p; 
        x = 10; 
        printf("\n%d\n", &q); 
        return(0);
    }
    

  5. $ \bigstar\bigstar$ Escreva um programa que a partir da leitura de duas strings quaisquer, informe o número de caracteres resultante da concatenação das duas strings.

  6. $ \bigstar$ Qual será a saída deste programa supondo que i ocupa o endereço 2000 na memória?

    # include <stdio.h>
    int main(void)
    {
       int i=5, *p;
       p= &i;
       printf("%u %d %d %d %d \n", p, *p+2, **&p, 3**p, **&p+4);
       return 0;
    }
    

  7. $ \bigstar$ Considere o seguinte trecho de programa:

    int i=3, j=5;
    int *p, *q;
    p= &i;
    q= &j;
    

    Qual é o valor das expressões?

    a) p==&i

    b) *p-*q

    c) **&p

    d) 3*-*p/(*q)+7

  8. $ \bigstar\bigstar$ Assumindo que pulo[] é uma matriz de uma dimensão do tipo int, quais das seguintes expressões referenciam o valor do terceiro elemento da matriz?

    a) *(pulo + 3)

    b) *(pulo + 2)

    c) *(pulo + 4)

    d) pulo + 3

    e) pulo + 2

  9. $ \bigstar\bigstar$ O que faz o programa seguinte quando executado?

    #include <stdio.h>
    int main(void)
    {
       static int mat[]={4, 5, 6};
       int i;
       for (i=0; i<3; i++)
          printf("%d ", *(mat + i));
       return 0;
    }
    

  10. $ \bigstar\bigstar$ O que faz o programa seguinte quando executado?

    #include <stdio.h>
    int main(void)
    {
        static int mat[]={4, 5, 6};
        int i, *ptr;
        ptr = mat;
        for (i=0; i<3; i++)
           printf("%d ", *ptr++);
        return 0;
    }
    

  11. $ \bigstar\bigstar$ Qual o valor de y no final do programa? Tente primeiro descobrir e depois verifique no computador o resultado. A seguir, escreva um /* comentário */ em cada comando de atribuição explicando o que ele faz e o valor da variável à esquerda do '=' após sua execução.

    int main() 
    { 
        int y, *p, x; 
        y = 0; 
        p = &y; 
        x = *p; 
        x = 4; 
        (*p)++; 
        x--; 
        (*p) += x; 
        printf ("y = %d\n", y); 
        return(0);
    }
    

  12. $ \bigstar\bigstar$ Verifique o programa abaixo. Encontre o seu erro e corrija-o para que escreva o número 10 na tela.

    #include <stdio.h>
    int main()
    {
          int x, *p, **q;
          p = &x;
          q = &p;
          x = 10;
          printf("\n%d\n", &q);
          return(0);
    }
    

  13. $ \bigstar\bigstar$ Reescreva o programa abaixo utilizando ponteiros:

    int main ()
    {
          float matrx [50][50];
          int i,j;
          for (i=0;i<50;i++)
                for (j=0;j<50;j++)
                       matrx[i][j]=0.0;
          return(0);
    }
    

  14. $ \bigstar\bigstar$ Diga quais expressões abaixo são válidas ou não, considerando as declarações abaixo. Justifique as suas respostas.

    int vetor[10];
    int *ponteiro;
    

    a) vetor = vetor + 2;

    b) vetor++;

    c) vetor = ponteiro;

    d) ponteiro = vetor;

    e) ponteiro = vetor+2;

  15. $ \bigstar\bigstar$ Faça um programa usando ponteiros, para ordenar 5 números e mostrá-los ordenados na tela.

  16. $ \bigstar\bigstar$ Suponha as seguintes declarações em C:

    int i; int v[10]; int* p;

    Quais dos seguintes comandos estão corretos, quais dão erros de compilação, e quais dão erros de execução? Suponha que os comandos são executados na ordem dada, e que os comandos que dão erro não afetam os demais comandos.

    1. p = v;
    2. i = *v;
    3. p += 3;
    4. v = p - 2;
    5. *i = v[0];
    6. v[2] = p[1];
    7. p[7] = i;
    8. *(v + 1) = i;
    9. i = p + 2;

  17. $ \bigstar$ O que quer dizer *(p+10);?

  18. $ \bigstar$ Se p é int*, qual é o tipo de *p?

  19. $ \bigstar$ (Prova EST/2010-1) Um ponteiro pode ser iniciado com quais valores?

  20. $ \bigstar\bigstar$ (Prova EST/2010-1) Considere o programa abaixo e informe o que será impresso. Observe a ordem do que será impresso na sua resposta.

    #include <stdio.h>
    
    int main() 
    { 
    	int y, *p, x; 
    	y = 0; 
    	p = &y; 
    	x = *p; 
    	x = 10; 
    	(*p)++; 
    	x--; 
    	printf("%d\n", *p);
    	(*p) += x; 
    	printf ("%d\n", y); 
    	printf("%d\n", &x==p);
    	return(0);
    }
    

  21. O que será impresso na execução do programa abaixo?

    #include<stdio.h>
    
    int main(){
       int x = 320;
       char *ptr;
       ptr = (char *) &x;
       printf("%d ",*ptr);
       return 0;
    }
    

    a) 2.

    b) 320.

    c) 64.

    d) Erro na compilação.

    e) NDA (nenhuma das alternativas).

    Solução: para resolver essa questão, deve-se lembrar que o tipo int é representado por dois bytes, enquanto o tipo char é representado por apenas um byte.

    O valor binário de 320 é 00000001 01000000 (lembrando que seria usado 16 bits). Porém, o ponteiro ptr está apontando para os primeiros 8 bits da variável x, ou seja, o valor 01000000. Isso acontece porque o ponteiro ptr é do tipo char. Esse valor corresponde ao valor 64 em decimal.

    Para confirmar essa equivalência de valores em sistemas numéricos diferentes, basta utilizar uma calculadora científica do seu sistema operacional. Ou, se achar melhor, construir um programa em C para constatar essa equivalência.

  22. O que será impresso na execução do programa abaixo?

    #include <stdio.h>
    
    int main(){
       int i = 3;
       int *j;
       int **k;
       j=&i;
       k=&j; 
       printf("%u %u %d ", k, *k, **k);
       return 0;
    }
    

    a) endereço, endereço, 3.

    b) endereço, 3, 3.

    c) 3, 3, 3.

    d) Erro na compilação.

    e) NDA (nenhuma das anteriores).

  23. Que tipo de problema ocorreria na execução do trecho de programa abaixo?

    int *p;
    p = rand();
    

  24. O que será impresso na execução do programa abaixo? O objetivo da questão é entender as regras de precedência entre operadores (* e ++) e também sobre atribuição de ponteiros.

    #include <stdio.h>
    
    int main (void) {
    	int *p, A[] = {10, 20, 30};
    	p = A;
    	printf("%p\n", A);
    	printf("%d - %p\n", *p+1, p);
    	printf("%d - %p\n", *p++, p);
    	printf("%d - %p\n", *(p++), p);
    	printf("%d - %p\n", (*p)++, p);
    	return 0;
    }
    

  25. O que é um ponteiro genérico em C? Qual é a sua finalidade? Dê um exemplo.

  26. Considere o programa abaixo, de nome teste.c, e responda ao que se pede.

    #include <stdio.h>
    #include <stdlib.h>
    
    int main() { 
    	int valor = 10, *ponteiro;
    	void *ptr;
    	ptr = &valor;
    	ponteiro = ptr;
    	printf("%d", *ponteiro); 		
    //	printf("%d", *ptr);
    	return 0;
    }
    

    Se o código for compilado e executado, irá aparecer na tela o valor 10. Porém, se a linha printf("%d", *ptr); for descomentada, irá aparecer a mensagem de erro abaixo. Explique o que estaria errado neste programa (na hipótese de tirar o comentário).

    gcc -lm -Wall -o "teste1" "teste1.c" (no diretório: /home/tiago)

    Compilação falhou.

    teste.c: In function ‘main’:

    teste.c:10: warning: dereferencing ‘void *’ pointer

    teste.c:10: error: invalid use of void expression

    Resposta: o erro irá aparecer na linha 10, que é exatamente a linha que antes estava comentada (e por isso mesmo é que funcionava). O erro acontece porque o ponteiro ptr é genérico e pode apontar para endereços de qualquer tipo. Por isso que a atribuição ptr = &valor está correta. Porém, este ponteiro (ptr) precisa ser convertido para um tipo específico no momento de ser desreferenciado. O desreferenciamento acontece quando se pega o valor (conteúdo) do ponteiro a partir do endereço para o qual está apontando.

  27. Considere o código abaixo e responda ao que se pede:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main() { 
    	int a = 10;
    	float b = 2.3;
    	void *ptr; 
    
    	ptr = &a; 
    	printf("%d\n", *(int *)ptr);
    
    	ptr = &b; 
    	printf("%.1f\n", *(float *)ptr);
    		
    	return 0;
    }
    

    Há necessidade de se fazer a conversão explícita (cast) do ponteiro ptr ou seria possível imprimir diretamente através dos comandos abaixo?

    printf("%d", *ptr);

    printf("%.1f", *ptr);

  28. (Prova EST/2011-3) Escreva um programa na Linguagem C que leia um vetor com N elementos do tipo inteiro, onde N é lido a partir do teclado. O vetor deverá ser alocado dinamicamente e devem ser tomadas as medidas necessárias para garantir a correta alocação do vetor. Depois de preenchido este vetor, deve ser criado um segundo vetor, também dinamicamente, e então, este segundo vetor será preenchido inicialmente com os valores pares do primeiro vetor, seguidos dos valores ímpares também do primeiro vetor. Escreva os dois vetores.

    SOLUçãO: VMSEPARAPARESIMPARES.C

  29. $ \bigstar\bigstar\bigstar$ Considere o código abaixo e assuma que queremos ler o valor de x através do ponteiro px. Observe que o endereço de x foi atribuído a px. O programa abaixo funciona? Justifique a sua resposta. Caso o programa não funcione, o que seria necessário para corrigi-lo?

    #include <stdio.h>
    
    int main() {
    	int x, *px;
    	px = &x;
    	scanf("%d", *px);
    	printf("%d", x);
    	return 0;
    }
    

  30. $ \bigstar\bigstar$ (Prova EST/2014-1) Considere o trecho de código abaixo e explique o que seria necessário para que ele funcionasse corretamente?

    #include <stdio.h>
    
    int main () {
      int i, *pi;
      *pi = 10;
      return 0;
    }
    

  31. $ \bigstar\bigstar$ (Prova EST/2013-2) Para responder a questão abaix, considere o número de sua matrícula, desprezando os dois primeiros dígitos (Exemplo: 1397012188 considerar apenas 97012188).

    Dado o seguinte trecho de programa escrito na Linguagem C.

    int x, y, *p, **p;
    
    x = 20;
    
    y = 15;
    
    p = &x;
    
    pp = &p;
    
    *p = 30;
    
    **pp = 40;
    

    Considerando que x foi alocado num endereço composto pelos 3 primeiros dígitos de sua matrícula (já com os dois primeiros dígitos desprezados), e que y foi alocado nos próximos três, responda o que será impresso em cada alternativa, após a execução do trecho de programa acima:

    a) *p

    b) **pp

    c) p

    d) pp

    e) &x

    f) &y

  32. $ \bigstar$ Crie um ponteiro e uma variável de qualquer valor, usando o ponteiro imprima o valor da variável e sua localização, depois libere o ponteiro.

  33. $ \bigstar\bigstar$ Temos uma variável c de valor 10 e endereço 967, e um ponteiro p, explique qual o valor em cada coluna.
    *p = $ &c$ p *p p = p + 10 *p = *p + 10
             

  34. $ \bigstar\bigstar$ Usando o comando sizeof, descubra quantos bit são necessários para alocar um caractere, um inteiro, um booleano e um void.

Tiago Eugenio de Melo 2014-03-31