Ir ao conteúdo

Posts recomendados

Postado

"Faca um programa que atribua um vetor a um ponteiro de inteiro. Utilizando o ponteiro inverta o conteúdo do vetor." Estou em dúvida em como farei a inversão do conteúdo desse vetor.

 

Código anexado como exemplo da ideia inicial.

#include <stdio.h>
 
 int main ()
 {
    int i;
    int vetorTeste[3] = {4, 7, 1};
    int *ptr = vetorTeste;
 
    printf("%p\n", vetorTeste);
    printf("%p\n", ptr);
    printf("%p\n", &ptr);
 
    for (i = 0; i < 3; i++)
    {
       printf("O endereço do índice %d do vetor é %p\n", i, &ptr[i]);
       printf("O valor do índice %d do vetor é %d\n", i, ptr[i]);
    }
    return 0;

 

Postado

 

Inverta os elementos tal que os primeiros elementos [valores] trocaram de posições, respectivamente, com os últimos. Existem duas maneiras usuais de fazer esse procedimento; na primeira se inverte a partir do início até o centro do vetor, que é interpretado como o marco 0 [tamanho/2] na reta das posições. A segunda maneira não interessa o centro porque usar uma cópia inversa do vetor para sobrescrever os elementos do vetor original, mas essa maneira envolve alocação dinâmica de memória e “loops” excessivos, logo é desinteressante.

 

Escrever em C envolve recursos que você @paulo luz magalhaes em sua postagem apresentou conhecer bem. Lembre-se que o 'loop' tem o número [N] de ciclos, igual à metade [inteira] do vetor, como sabes a primeira metade troca de valor com a segunda, inversamente. Uma variável auxiliar simplifica a transição [troca] de valores entre as posições inversas.

 

Primeiro  troca com o Último

Segundo troca com o Antepenúltimo

...

Postado
6 horas atrás, paulo luz magalhaes disse:

ideia inicial.

 

Não entendi qual era  a "ideia inicial". Qual seria?
 

Se

 

    int vetorTeste[3] = {4, 7, 1};
    int *ptr = vetorTeste;
    printf("%p\n", vetorTeste);
    printf("%p\n", ptr);

 

Então

  • vetorTeste é int[3] e ptr é int* e depois da atribuição eles vão claro apontar para o mesmo endereço.  
     
        printf("%p\n", &ptr);
  • ptr é uma variável, declarada como int* e vai ter um endereço e ocupar o tamanho de um ponteiro, sizeof(int*) em sua máquina. Toda variável tem um endereço e mostrar o endereço dela quase nunca faz diferença para o programa.

De volta ao programa

 

  • não precisa declarar o tamanho do vetor em
     
        int vetorTeste[3] = {4, 7, 1};


    Se está inicializando o vetor inteiro. O compilador assume isso e faz as contas. Pode usar apenas
     

        int vetorTeste[] = {4, 7, 1};


    O compilador assume o tamanho do vetor a partir do maior índice inicializado. Se tivesse declarado assim
     

        int testev[] =
        {
            [0] = 4,
            [2] = 1,
            [1] = 7
        };

    Teria o mesmo resultado, porque declarou até o 2. Mas se tivesse escrito
 

    int testev[] =
    {
        [300] = 1,
        [0] = 4,
        [2] = 1,
        [1] = 7
    };

 

o compilador prontamente assumiria testev como int[301].

 

    for (i = 0; i < 3; i++)
    {
       printf("O endereço do índice %d do vetor é %p\n", i, &ptr[i]);
       printf("O valor do índice %d do vetor é %d\n", i, ptr[i]);
    }

 

Evite a todo custo esse tipo de construção. Há 40 anos isso foi corrigido e se pode declarar as variáveis no próprio loop em C. 

E nunca use uma variável global à função com um nome ingênuo como i ou aux ou cont com sempre se vê. Isso sempre cai na sua cabeça porque elas ficam vivas durante todo o programa e podem e VÃO acabar sendo usadas por engano e vai ser um inferno pra achar o erro. Logo seus programas não vão ter só 10 linhas e caber na mesma tela.

 

Mais ainda, não deixe o tamanho fixo se não precisa. Prefira sempre o genérico porque se mudar a p@rr@ do vetor no próximo teste grande chance de esquecer de alterar esse singelo 3.

 

Entenda:

  • qual o tamanho do vetor? sizeof(vetorTeste)
  • qual o tamanho de um int? sizeof(int)
  • quantos int tem no vetor então? 
     
        int tam = sizeof(vetor) / sizeof(int);

    Então escreva algo assim
     
        int tam = sizeof(vetor) / sizeof(int);
    
        printf("Vetor original:  [ ");
        for( int i=0; i<tam; i+= 1)
        printf( "%d ", *(ptr+i) );
        printf(" ]\n");

    E não precisará lembrar de mexer no loop se mudar o tamanho do vetor ;) e nem se preocupar com o valor de i porque a variável só vai existir dentro do for

Ainda sobre o programa

 

O objetivo desse tipo de programa é mostrar que p[34] é equivalente a *(p+34) se p for por exemplo int*. E essa noção é essencial em C e a linguagem foi escrita com o objetivo de facilitar essa notação porque é a que se usa em linguagem de máquina e C foi escrita para permitir trocar Assembler por uma linguagem de mais alto nível e acelerar o desenvolvimento de sistemas ( de um, no caso, o Unix).

 

Sobre essa linha
 

    int *ptr = vetorTeste;

 

Talvez não precise usar DEZ letras para o nome de uma variável que vai usar toda hora no programa :(

 

Como o compilador pode te dizer, está declarando nessa linha o nome ptr. E o que é ptr? É int*. 
Essa é a definição: uma declaração associa um nome, ptr, a um tipo, int* e talvez deva se acostumar a declarar 

 

    int*    ptr = vetor;

 

Em alguns casos essa noção vai fazer muita diferença. * é um operador em C, e é claro que se ptr é um ponteiro ^ptr vai te dar o conteúdo. Mas não se declara um conteúdo...

 

Invertendo um vetor usando os endereços e não os índices

 

Esse é o provável objetivo desse exercício e você deve considerar:

  • ptr aponta para o início do vetor
  • te mostrei como calcular o tamanho dele
  • a divisão de inteiros em C trunca o valor para inteiro, 3/2 =1 2/2 =1 por exemplo
  • o primeiro índice é  0, o último é (tam-1)
  • para inverter então
    • se tem por exemplo 3 como fez, vai trocar o da esquerda, índice 0, pelo da direita, índice 3-1
    • se fossem apenas dois não faria diferença: vai mexer com metade dos elementos, 3/2 ou 2/2
    • se fossem 1000 daria na mesma: o primeiro com o último, o segundo com o penúltimo e a vida segue 500 vezes, andando uma casa para a esquerda e uma casa para a direita...
      E isso sugere um único loop em C
       
          for ( int esq=0, dir=tam-1; esq<lim; esq+=1, dir-=1 )
          {
              int temp = *(ptr + esq);
              *(ptr + esq) = *(ptr + dir);
              *(ptr + dir) = temp;
          };


      Qual o valor de tam? já te mostrei. Qual o valor de limite? tam/2. Só isso.

É como está escrito na lista: começa pelas beiradas e vem até a metade, invertendo os caras.

As variáveis só tem sentido dentro do loop então assim são declaradas.

tam é usada em outros lugares, por certo vai precisar imprimir os vetores antes e depois. O limite pode ser calculado antes para evitar fazer as contas a cada iteração.

O * é o operador que traz o conteúdo. C tem aritmética de ponteiros então soma o tamanho certo para o int que estiver usando, ou char ou qualquer coisa.

 

Acha que pode escrever o programa agora? Ou precisa de  um exemplo completo?

  • Obrigado 1
Postado

O @paulo luz magalhaes, um dos meus alunos respondeu, deixar seu exemplo desse ‘loop’ sugerido e que utilize os ponteiros.

 

Sugestão

#include <stdio.h>
 
 int main ()
 {
    int  i, vetorTeste [3]= {4, 7, 1},
            *vetorInicio= vetorTeste,
            *vetorFim= &vetorTeste [2];
            
 
    for (i = 0; i < 3; i++)
    {
       printf("O endereço do índice %d do vetor é %p\n", i, &vetorTeste [i]);
       printf("O valor do índice %d do vetor é %d\n", i, vetorTeste [i]);
    }
    
    /* inverta o vetor */
    while (vetorInicio < vetorFim) {
        int aux= *vetorInicio;
        
        *vetorInicio= *vetorFim;
        *vetorFim= aux;
        
        ++ vetorInicio,
        -- vetorFim;
    }
    
    /*exibir resultado */
    for (i= 0; i < 3; i++) printf("%p ", &vetorTeste [i]); printf ("\n");
    for (i= 0; i < 3; i++) printf("%d ",  vetorTeste [i]); printf ("\n");

    return 0;
 }

 

 

"É obvio que um tipo declarado não constante permite o incremento e decremento de seu valor, um ponteiro nada mais é que uma variável da categoria dos inteiros que guarda o endereço de outra [ou seja, uma referência]. Uma referência para o início de um vetor não pode ser maior ou igual à metade para fim, logo o início incrementa para centro e o fim decrementa enquanto INICIO é MENOR que FIM todos os endereços são de posições inversas."

/* inverta o vetor */
    while (vetorInicio < vetorFim) {
        int aux= *vetorInicio;
        
        *vetorInicio= *vetorFim;
        *vetorFim= aux;
        
        ++ vetorInicio,
        -- vetorFim;
    }

 

Essa é uma boa sugestão, principalmente porque é de uma turminha de 6 - 10 anos.

Espero ter inspirado você também.

  • Obrigado 1

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!