Erros comuns na Linguagem C

Novembro 2016


A linguagem C, inventada em 1972 por Ken Thompson e Dennis Ritchie, é uma das primeiras para programação de sistema. C também é, atualmente, uma das linguagens mais utilizadas e muitas vezes ensinada nas universidades, sendo considerada como simples, graças à sua sintaxe.

As duas principais razões na origem dos programas vulneráveis são a ignorância do programador e a necessidade de sair de um programa rapidamente (tempo a ser respeitado). Assim, as consequências são dramáticas. Quase todos os dias ouvimos falar de programas vulneráveis, forçando-nos a atualizar o aplicativo para evitar problemas de segurança em nossa máquina. Como controlar esses erros? Esta dica mostra vários erros frequentes para melhorar a qualidade dos seus programas.

Exemplo do erro

A Linguagem C é diferente da C++..
Na verdade, essas duas linguagens são regidas por normas diferentes. E, ao contrário do que muitos pensam, todas as instruções em C não são compatíveis com a C++. Logo, um programa em C no fórum C e um programa em C++ no fórum C++.

main()
Os dois únicos protótipos do main() aceitos são:
int main (void)
int main (int argc, char **argv) / int main (int argc, char *argv[]).


Fim do programa
Corolário do erro acima, o main() deve acabar com:
return EXIT_SUCCESS; ou return 0; /*o padrão indica que EXIT_SUCCESS==0*/
return EXIT_FAILURE;
O uso do EXIT_SUCCESS ou EXIT_FAILURE necessita: #define <stdlib.h>

char *buffer;
scanf("%s", buffer);

Segfault garantido! A primeira linha cria uma variável que contém um endereço que aponta para outro. O problema é que você deverá definir este endereço e a área apontada, que deverá ser grande o suficiente para acolher os dados. Então, você deverá fazer, por exemplo:

char *buffer = malloc(254*sizeof *buffer);

ou
char buffer[256]; /*se não quiser fazer a alocação dinâmica*/


if (a = 5)
O operador de comparação é o dobro igual==.
Você deve escrever:
if (a == 5)


type fonction ()
A definição do protótipo está incompleta. Para definir um protótipo sem argumentos, você deve especificar o parâmetro 'vazio'. Isto significa que a função aceita 0 argumento.
Portanto:
type fonction (void)


char buffer[256];
buffer = "olá";

Para copiar uma string em uma tabela, use a função strcpy(), ou melhor, strncpy().
Exemplo:
strcpy (buffer, "coucou");


char buffer[256];
gets(buffer) ou scanf("%s", buffer);

Não use nunca. Na verdade, se o usuário digitar uma cadeia muito grande, isso provocará, no melhor dos casos, um bloqueio de seu programa. O caminho certo é usar:
fgets (buffer, sizeof buffer, stdin)

Note-se que fgets(), se houver lugar, o retorno de '\ n' será armazenado no buffer. Se isso incomodar, remova-o.

char *p = (char *) malloc(...);
Nas primeiras versões da C (a C K&R), era, aliás, o caminho certo a ser feito, porque malloc em C++, também é o caminho certo de fazer (embora haja a instrução 'new' que é mais adequada). Mas hoje, malloc() retorna um void * que será promovido automaticamente para o tipo ad hoc. Assim, o cast é totalmente desnecessário. Pior ainda, isso é até desaconselhado já que em algumas versões do compilador, isso oculta o esquecimento do include <stdlib.h> pelo programador. Assim, a maneira correta é:
char *p = malloc (...);


Saiba que isso se aplica a todas as funções que retornam void * como calloc(), realloc(), etc.

O uso dos float
Certamente, este não é um erro. Mas, a menos que o tamanho da memória seja importante, privilegie sempre o dobro.

duplo a;
printf ("%lf", a);

Um erro frequente consiste em pensar que %If vale o dobro. Se isto for verdade em um scanf(), é falso no printf(). Você deverá escrever:
printf ("%f", a);


printf ("Pequeno erro");
int b;

Não se misturam as declarações e as instruções. Colocamos todas as declarações da variável em primeiro e, depois, as instruções.
Isto dá:
int b;
printf ("Pequeno erro");

Veja também :
Este documento, intitulado « Erros comuns na Linguagem C »a partir de CCM (br.ccm.net) está disponibilizado sob a licença Creative Commons. Você pode copiar, modificar cópias desta página, nas condições estipuladas pela licença, como esta nota aparece claramente.