Const Correctness
Parte da seção Programação Orientada a Objetos do Journey de C da Coddy. Lição 8 de 61.
Ao escrever funções que atuam como métodos, algumas devem modificar o objeto (como player_take_damage), enquanto outras devem apenas ler dados sem alterar nada. A palavra-chave const permite impor essa distinção no nível do compilador.
Ao marcar um parâmetro de ponteiro como const, você está garantindo que a função não modificará os dados para os quais ele aponta. Se você acidentalmente tentar alterar um membro, o compilador produzirá um erro:
typedef struct {
int x;
int y;
} Point;
// Esta função só pode LER o ponto
void point_print(const Point *self) {
printf("(%d, %d)\n", self->x, self->y);
// self->x = 10; // ERROR: não é possível modificar através de ponteiro const
}
// Esta função pode MODIFICAR o ponto
void point_move(Point *self, int dx, int dy) {
self->x += dx;
self->y += dy;
}
O parâmetro const Point *self informa tanto ao compilador quanto a outros programadores que point_print é uma operação de "getter" ou somente leitura. Isso é chamado de correção de const: usar const sempre que a modificação não for necessária.
Esta prática detecta bugs antecipadamente. Se você escrever uma função de exibição e modificar acidentalmente um campo, o compilador interromperá você imediatamente, em vez de deixar o bug passar para o seu programa.
Desafio
FácilVamos criar um módulo Temperature que armazena um valor de temperatura e fornece operações somente de leitura e de modificação. Isso ajudará você a praticar o uso de ponteiros const para distinguir claramente entre funções que apenas leem dados e aquelas que os alteram.
Você criará três arquivos:
temperature.h: Declare uma structTemperaturecom um único membrodouble celsius. Declare também três funções:temp_display: recebe um ponteiroconstpara Temperature e imprime a temperatura atual (somente leitura)temp_adjust: recebe um ponteiro comum para Temperature e um valor double; em seguida, adiciona o valor a celsius (modificação)temp_to_fahrenheit: recebe um ponteiroconstpara Temperature e retorna o valor convertido para Fahrenheit (somente leitura)
TEMPERATURE_H.temperature.c: Implemente as três funções. A funçãotemp_displaydeve imprimir no formatoCurrent: {celsius}C. A funçãotemp_to_fahrenheitdeve retornarcelsius * 9.0 / 5.0 + 32.0. Lembre-se de que funções que usam ponteirosconstnão podem modificar os dados da struct.main.c: Crie uma Temperature, execute operações e exiba os resultados.
Você receberá duas entradas: o valor inicial em celsius (como um double) e o valor do ajuste (como um double).
No seu arquivo principal:
- Inicialize uma
Temperaturecom o valor inicial em celsius - Chame
temp_displaypara exibir a temperatura inicial - Chame
temp_adjustpara modificar a temperatura pelo valor do ajuste - Chame
temp_displaynovamente para exibir a temperatura atualizada - Imprima a conversão para Fahrenheit usando
temp_to_fahrenheit
Imprima os resultados neste formato:
Current: {celsius}C
Current: {celsius}C
Fahrenheit: {fahrenheit}FUse %.1f para todos os valores de temperatura, a fim de exibir uma casa decimal.
Por exemplo, com um valor inicial de 20.0 e um ajuste de 5.0, a saída seria:
Current: 20.0C
Current: 25.0C
Fahrenheit: 77.0FExperimente você mesmo
#include <stdio.h>
#include "temperature.h"
int main() {
double initial_celsius, adjustment;
scanf("%lf", &initial_celsius);
scanf("%lf", &adjustment);
// TODO: Crie uma struct Temperature e inicialize-a com initial_celsius
// TODO: Chame temp_display para mostrar a temperatura inicial
// TODO: Chame temp_adjust para modificar a temperatura pela quantidade de ajuste
// TODO: Chame temp_display novamente para mostrar a temperatura atualizada
// TODO: Imprima a conversão para Fahrenheit usando temp_to_fahrenheit
// Formato: "Fahrenheit: %.1fF\n"
return 0;
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos da Programação Modular
Arquivos de CabeçalhoInclude GuardsArquivos-FonteFunções EstáticasRecapitulação: Calculadora Modular4Encapsulamento
Conceito de Ponteiros OpacosDefinindo Structs OpacasGetters e SettersValidação em SettersRecapitulação: Caixa Secreta2Objetos e Métodos
Structs como ObjetosO Ponteiro 'Self'Const CorrectnessPonteiro vs ValorMétodos AuxiliaresRecapitulação: Point Manager5Projeto: Conta Bancária Simples
Configuração do ProjetoImplementação da Conta3Ciclo de Vida de Objetos
Padrão de ConstrutorPadrão de DestrutorInicialização na StackCópia ProfundaRecapitulação: String Wrapper6Herança via Composição
Incorporação de StructsA Regra do Primeiro MembroAcessando Membros PaiUpcastingRecapitulação: Hierarquia de Formas9Projeto: Desenhador de Formas
Visão Geral do ProjetoImplementação do CírculoImplementação do RetânguloUso PolimórficoContainer de FormasPratique por conta própria: Compilador de C online