Desenvolva um programa no qual são definidas duas variáveis ( x e y ) do tipo float, com valor inicial 0.0 (zero). Deve-se exibir na tela os endereços e os conteúdos dessas variáveis. O usuário deverá ser questionado para digitar um dos dois endereços e um novo valor. O programa deverá atribuir esse valor ao conteúdo do endereço de memória digitado pelo usuário. Os endereços e os conteúdos das variáveis deverão ser exibidos novamente, assim como o questionamento para digitar um dos dois endereços e um novo valor. Esse processo deverá se repetir até que um endereço diferente dos endereços das variáveis x e y seja digitado pelo usuário. Nesse caso o programa termina.

Passo 1

O enunciado pede que a gente escreva um programa com as seguintes características:
  • Existem duas variáveis do tipo float, chamadas x e y, iniciadas com o valor 0{,}0.
  • O programa deve exibir na tela os endereços de memória e os conteúdos (valores) dessas variáveis.
  • Em seguida o usuário deve digitar um dos dois endereços mostrados e um novo valor (float).
  • O programa deve atribuir o novo valor ao conteúdo do endereço digitado.
  • Depois da atribuição, os endereços e conteúdos devem ser exibidos novamente e o processo se repete.
  • Se o usuário digitar um endereço que seja diferente dos endereços de x e y, o programa deve terminar.
Informações relevantes dadas pelo enunciado:
  • Variáveis: x e y
  • Tipo: float
  • Valores iniciais: 0{,}0
  • Interação: o usuário digita um endereço (um dos que foram mostrados) e um novo valor
  • Critério de parada: endereço digitado diferente dos dois endereços mostrados

Passo 2

Decisão do método/linguagem:
  • Vou usar a linguagem C porque ela permite manipular e mostrar endereços de memória de forma natural (operadores de endereço e ponteiro), que é exatamente o que o problema pede.
  • Outras linguagens (Python, Java) não deixam o usuário interagir com endereços brutos da mesma maneira portável.
  • O objetivo na prova é demonstrar entendimento de ponteiros, operador & e acesso via ponteiro — então C é apropriado.

Passo 3

Conceitos fundamentais que você precisa entender (explicação didática, passo a passo):
  1. O que é endereço e o que é conteúdo?
    • Para uma variável como x do tipo float, a variável ocupa um espaço na memória. O “conteúdo” é o valor guardado (ex.: 0{,}0). O “endereço” é a posição onde esse espaço começa — é um número (normalmente mostrado em hexadecimal).
    • Em C, o operador de endereço é &. Ex.: &x dá o endereço de x.
    • Um ponteiro é uma variável que guarda um endereço. Ex.: \texttt{float *p} declara um ponteiro para float; se \texttt{p = &x} então \texttt{*p} é o conteúdo de x.
  2. Como imprimir um endereço em C?
    • Use o especificador \texttt{"%p"} no \texttt{printf}. Para garantir portabilidade, passe um \texttt{void*}: \texttt{printf("%p", (void*)&x);}.
  3. Como ler texto do usuário e comparar com os endereços?
    • Como o usuário deve digitar um dos endereços exibidos, uma abordagem simples e robusta é:
      • Gerar uma string com a representação do endereço (usando \texttt{snprintf} com \texttt{"%p"}).
      • Ler do usuário uma linha (usando \texttt{fgets}).
      • Remover o ‘\n’ final se houver (usando \texttt{strcspn} para achar e truncar).
      • Comparar a string digitada com as strings dos dois endereços (usando \texttt{strcmp}).
    • Se a string digitada for igual à do endereço de x, atribuiremos o novo valor via um ponteiro para x. Mesmo raciocínio para y.
  4. Entrada do novo valor (float):
    • Após confirmar que o endereço digitado corresponde a x ou y, peça ao usuário o novo valor.
    • Leia a linha com \texttt{fgets} e converta para float com \texttt{strtof} (é mais seguro do que usar \texttt{scanf} direto).
  5. Loop e critério de parada:
    • O programa entra num loop onde repetimos: exibir endereços/valores → pedir endereço → se endereço corresponde a x ou y pedir novo valor e atribuir → repetir.
    • Se o endereço digitado não corresponder a nenhum dos dois endereços, saímos do loop e o programa termina.

Passo 4

Algoritmo (pseudocódigo passo a passo, para você entender antes de ver o código):
  1. Declarar \texttt{float x = 0.0f, y = 0.0f}.
  2. Em loop:
    a) Mostrar o endereço de x e seu conteúdo; mostrar o endereço de y e seu conteúdo.
    b) Gerar strings addr_x e addr_y que contenham as representações textuais dos endereços de x e y .
    c) Ler do usuário uma linha: input (endereço digitado).
    d) Remover newline de input .
    e) Se input == addr_x então p = &x; else se input == addr_y então p = &y; else sair do loop.
    f) Pedir ao usuário o novo valor (linha), converter para float (novo_valor).
    g) Fazer *p = novo_valor).
    h) Repetir (vai voltar a (a) e mostrar endereços e conteúdos atualizados).
  3. Fim do programa.

Passo 5

Implementação em C com explicação linha a linha das partes importantes (vou colocar comentários no código para deixar claro o que cada trecho faz). Leia com calma, eu expliquei as funções mais importantes no Passo 3, então deve ficar tranquilo para entender.
  • Observações práticas:
    • Ao imprimir o endereço com \texttt{"%p"} você obtém algo como \texttt{0x7ffdf3a2b8c0}. O usuário deve digitar exatamente essa string para que o programa reconheça que ele escolheu aquele endereço.
    • No terminal, é comum copiar/colar o endereço. Se preferir, em uma prova o professor pode aceitar digitar x ou y em vez do endereço; aqui implementamos exatamente como o enunciado pediu (entrando com o endereço textual).
    • Para compilar: \texttt{gcc -Wall -Wextra -o alterar endereco.c} (ou qualquer nome de arquivo).

Passo 6

Código-fonte final (explicado nos passos anteriores). Use este código como resposta pronta para rodar — ele implementa exatamente o que o enunciado pede.

Resposta

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
float x = 0.0f, y = 0.0f;
char addr_x[32], addr_y[32];
char input[128];
while (1) {
    /* Exibe endereços e conteúdos */
    printf("Endereco de x: %p\tconteudo: %f\n", (void*)&x, x);
    printf("Endereco de y: %p\tconteudo: %f\n", (void*)&y, y);

    /* Cria strings canônicas com as representações dos endereços */
    snprintf(addr_x, sizeof addr_x, "%p", (void*)&x);
    snprintf(addr_y, sizeof addr_y, "%p", (void*)&y);

    /* Pergunta ao usuário qual endereço ele quer alterar */
    printf("Digite um dos enderecos acima (copie exatamente) ou digite outro endereco para sair:\n");
    if (!fgets(input, sizeof input, stdin)) {
        /* Erro de entrada ou EOF */
        break;
    }
    /* Remove eventual newline */
    input[strcspn(input, "\n")] = '\0';

    float *p = NULL;

    if (strcmp(input, addr_x) == 0) {
        p = &x;
    } else if (strcmp(input, addr_y) == 0) {
        p = &y;
    } else {
        printf("Endereco digitado diferente dos enderecos de x e y. Programa terminando.\n");
        break;
    }

    /* Pede o novo valor para a variável apontada */
    printf("Digite o novo valor (float):\n");
    if (!fgets(input, sizeof input, stdin)) {
        /* Erro de entrada ou EOF */
        break;
    }
    /* Converte string para float */
    float novo = strtof(input, NULL);
    *p = novo;

    /* No final do loop imprimiremos novamente os endereços e conteúdos */
    printf("Valor atribuido com sucesso.\n\n");
}

return 0;
}

Exercícios relacionados