4 erros de programação C++ que são difíceis de encontrar

4 erros de programação C++ que são difíceis de encontrar

Uma parte significativa do trabalho de um programador é encontrar e eliminar erros. Aplica-se o princípio de que os erros devem ser encontrados o mais cedo possível no processo de desenvolvimento. Claro, é ainda melhor evitar erros em primeiro lugar. Este artigo mostra quatro erros típicos que geralmente não são detectados pelo compilador e, portanto, são difíceis de encontrar. Se você não sabia desses erros antes, poderá programar um pouco melhor depois de ler este artigo.

Resumo

  • Variável não inicializada: Em C++, as variáveis ​​não são inicializadas automaticamente quando são criadas, o que pode levar a um comportamento indefinido.
  • Confusão entre operador de atribuição e operador de comparação (=/==): A confusão pode levar a erros fatais porque o operador de atribuição (=) é usado em vez do operador de comparação (==).
  • Sem interrupção na instrução switch: A ausência da instrução break em uma instrução switch pode resultar na execução de todas as instruções a seguir após a correspondência da constante case.
  • Divisão Inteira: Ao dividir valores inteiros, o resultado também se torna um número inteiro, o que pode resultar no corte da parte fracionária.

Como surgem os erros?

Para que um erro se torne um erro de tempo de execução, ele deve permanecer sem ser detectado pelo compilador. Ajude o compilador definindo o nível de aviso o mais alto possível. Avisos do compilador podem ser desagradáveis, mas ainda mais desagradáveis ​​são erros sutis de tempo de execução. Você só deve ignorar os avisos se tiver um motivo muito convincente para fazê-lo.

Abaixo você encontrará quatro exemplos de erros típicos de C++ que podem não ser reconhecidos pelo compilador. É melhor experimentar esses exemplos em seu ambiente de desenvolvimento para poder ver se o seu compilador o avisaria sobre um ou outro erro.

Variável não inicializada

Em C++, as variáveis ​​não são inicializadas automaticamente quando são criadas. Se você trabalhar com uma variável não inicializada, o comportamento do programa será indefinido. No exemplo a seguir, a variável counter pode ter qualquer valor que provavelmente seja maior que 10. Provavelmente é por isso que o loop while nem sequer é inserido. Em qualquer caso, o programa não se comportará como originalmente pretendido.

Variável não inicializada
int counter;

while(counter < 10) { cout << counter; ++counter; }

O exemplo abaixo mostra o código corrigido. O número inteiro é inicializado explicitamente como 0 e os números de 0 a 9 são exibidos no console.

Variável inicializada

int counter = 0;

while(counter < 10) { cout << counter; ++counter; }

Em C++, as variáveis ​​não são inicializadas automaticamente, então você mesmo deve atribuir um valor inicial a cada variável.

Confusão entre operador de atribuição e operador de comparação (=/==)

O operador de atribuição é usado para atribuir um valor específico a uma variável ou objeto, geralmente retornando uma referência ao objeto que foi atribuído. O operador de comparação é usado para comparar duas variáveis ​​ou objetos entre si, o resultado é um booleano que diz se os objetos comparados são iguais. Uma confusão pode ter consequências graves, como ilustra o exemplo a seguir.

Em vez de verificar se o valor da variável contador é 5, é atribuído à variável o valor 5. A condição é verdadeira porque o valor de retorno da atribuição é 5 e um número inteiro diferente de 0 é avaliado como verdadeiro. Como isso acontece em cada loop executado, a condição de término (contador <10) nunca é atingida e o programa é executado em um loop infinito que gera ciclicamente “5” para o console. int counter = 0;

while(counter < 10) { // do some stuff here... // ... // here is a quick check if(counter = 5) { cout << counter; } ++counter; }

Em contraste, no exemplo correto a seguir, “5” é emitido apenas uma vez, conforme desejado pelo programador.

Comparação correta

int counter = 0;

while(counter < 10) { // do some stuff here... // ... // here is a quick check if(counter == 5) { cout << counter; } ++counter; }

Portanto, sempre certifique-se de usar dois “=”, ou seja, o operador de comparação, ao fazer comparações.

Sem interrupção na instrução switch

A instrução switch é usada para diferenciar claramente os casos com base em valores inteiros. Um erro típico de programação que acontece frequentemente aqui é esquecer o intervalo. Se uma constante case corresponder ao valor consultado, todas as instruções a seguir serão executadas até que ocorra uma quebra. O exemplo a seguir mostra como isso não se destina:

Faltam pausas

// get random number between 1 and 10
int myNumber = rand % 10 + 1;

// check if this is an important number to me
switch(myNumber)
{
case 1: cout << "Meine liebste Zahl wurde gezogen!"; case 3: cout << "Meine zweitliebste Zahl wurde gezogen!"; default: cout << "Eine für mich unbedeutende Zahl wurde gezogen."; }

Se o gerador aleatório selecionar 1 aqui, todas as três sentenças serão geradas porque as seções de caso não têm uma quebra final. Se você estiver ciente disso, também poderá usar isso para criar uma conexão OR, que pode, no entanto, ser considerada uma técnica avançada.

Bloqueio de interruptor correto

// get random number between 1 and 10
int myNumber = rand % 10 + 1;

// check if this is an important number to me
switch(myNumber)
{
case 1:
cout << "Meine liebste Zahl wurde gezogen!"; break; case 3: cout << "Meine zweitliebste Zahl wurde gezogen!"; break; default: cout << "Eine für mich unbedeutende Zahl wurde gezogen."; break; }

Aqui as quebras foram definidas corretamente e o código faz o que deveria. Para evitar erros como os acima, você pode adquirir o hábito de quebrar imediatamente cada caso e padrão antes de escrever o código real. Com a seguinte regra para iniciantes, esse erro não pode acontecer com você.

Dentro de uma instrução switch, defina imediatamente um break para cada caso e o padrão. Remova-o apenas se tiver certeza do que acontecerá.

Divisão inteira

Um problema numérico clássico pode surgir quando você faz divisão com valores inteiros. Se tanto o dividendo quanto o divisor forem números inteiros, o resultado também será um número inteiro e isso significa que a parte decimal será cortada. Mesmo se você atribuir o resultado a uma variável de ponto flutuante, isso não muda nada:

Resultado inesperado em uma divisão

int dividend = 6;
int divisor = 4;

double result = dividend / divisor;
cout << result; // result is 1.0!

Ao contrário do esperado, a variável de resultado aqui contém 1,0, pois o resultado da divisão já é um número inteiro que é convertido silenciosamente (“convertido”) em duplo. Existem várias maneiras de contornar esse problema. Uma delas é usar double ou float para dividendo e divisor:

Alternativa correta I

double dividend = 6;
double divisor = 4;

double result = dividend / divisor;
cout << result; // result is 1.5

Se você tiver apenas o dividendo e o divisor disponíveis como números inteiros, não será necessário criar uma variável intermediária. Aqui basta simplesmente converter um dos dois valores para double ou float:

Alternativa correta II

int dividend = 6;
int divisor = 4;

double result = static_cast(dividend) / divisor;
cout << result; // result is 1.5

Neste exemplo, o resultado da divisão já é duplo e portanto nenhuma casa decimal é perdida na atribuição ao resultado.

Conclusão

Agora você aprendeu sobre 4 erros típicos de programação em C++. Mesmo em um ambiente profissional, a probabilidade de encontrar um desses erros é relativamente alta, especialmente com bases de código maiores. Como você viu, esses erros são muito fáceis de evitar.

O artigo foi útil para você? Se sim, ajude-nos e compartilhe!

Programação

Conteúdo Relacionado

Assistente de Inteligência Artificial: Redução de Custos e Eficiência Empresarial
A evolução tecnológica tem impactado significativamente a forma como...
O GLOBO Inova com IA: Tradução Automática de Notícias para Inglês
O comprometimento com o avanço tecnológico e a expansão...
Apple e o ChatGPT: Estratégia de assinatura e impacto no mercado
A Apple, conhecida por sua tradição em desenvolver internamente...
Microsoft Windows Co-piloto: APIs de IA Generativa chegam ao Windows
A Microsoft anunciou uma série de atualizações empolgantes para...
Por que as Unidades de Nuvem não funcionam para a maioria das empresas
Se aprendemos alguma coisa com a evolução constante da...
Observabilidade como Pilar essencial para Ambientes de Nuvem Modernos
Em seu relatório de 2024, a Splunk divide as...
Futuro da Computação em Nuvem: Agentes de IA e a Revolução da Orquestração
De acordo com um relatório recente do SNS Insider,...
Acelerando o Desenvolvimento de IA Generativa Empresarial com a Gencore AI
Embora a criação de um protótipo básico do ChatGPT...
IA está revolucionando os testes em DevOps
A Inteligência Artificial encontrou seu lugar no desenvolvimento de...
Inteligência Artificial que transforma a Justiça Brasileira
A tecnologia está cada vez mais presente em nosso...
Cachaça criada por Inteligência Artificial custa R$ 697
Nos últimos anos, a Inteligência Artificial (IA) vem revolucionando...
Estratégias comprovadas para manter sua Equipe Remota Produtiva e Focada
O trabalho remoto não é mais uma tendência —...
7 Métodos de Análise de Riscos para Garantir a Segurança de Pessoas, Ativos e Operações
Quando falamos de segurança, o gerenciamento de riscos é...
Como a Inteligência Artificial está Revolucionando a Pesquisa Empresarial
A inteligência artificial (IA) está revolucionando o campo da...
Ascensão da IA Acionável: Transformando Vendas e Operações
A IA está avançando muito. Não estamos mais apenas...
PHP 8.4.1: Atualização da API DOM
O PHP, uma das linguagens de programação mais populares...
TypeScript 5.7: Melhorias no Sistema de Tipos e Novos Recursos
O TypeScript 5.7, a última versão planejada da variante...
Sessões de Interpretador de Código Python e JavaScript no Azure Container Apps
A Microsoft anunciou recentemente a disponibilidade geral do interpretador...
블로그로 돌아가기

댓글 남기기

댓글 게시 전에는 반드시 승인이 필요합니다.