Posts tagged ‘especificador de formato’

29/09/2010

Linguagem C – %d vs %i

por Alex.S.R

Desde que começei a aprender a linguagem C na faculdade aprendi que tem dois especificador de formato para o tipo de dado inteiro (int no caso da linguagem C), o %i e o %d.

Sempre me disseram que eram iguais. Até ai tudo bem, na verdade nunca tive problemas com isso até que, já em outra faculdade (que o professor só ensinou o %i) tive um exercício que descobri que existe diferença entre os dois. Era um programa que a pessoa entrava com o dia e mês do seu aniversário no formado ddmm e a saida era o signo da pessoa (sem comentários)

Obs: Não era preciso tratar validação de dados.

Primeiramente fiz com o %i, segue o código:

#include <stdio.h>

int main()
{
   int data, mes, dia;
   
   printf("Informe o dia e o mes do seu nascimento (ddmm): ");
   scanf("%i", &data);
   
   dia = data / 100;
   mes = data % 100;
   
   if((mes == 1 && dia >= 21) || (mes == 2 && dia <= 18)){
      printf("Aquario\n");
   }
   else if((mes == 2 && dia >= 19) || (mes == 3 && dia <= 19)){
      printf("Peixes\n");
   }
   else if((mes == 3 && dia >= 20) || (mes == 4 && dia <= 20)){
      printf("Aries\n");
   }
   else if((mes == 4 && dia >= 21) || (mes == 5 && dia <= 20)){
      printf("Touro\n");
   }
   else if((mes == 5 && dia >= 21) || (mes == 6 && dia <= 20)){
      printf("Gemeos\n");
   }
   else if((mes == 6 && dia >= 21) || (mes == 7 && dia <= 21)){
      printf("Cancer\n");
   }
   else if((mes == 7 && dia >= 22) || (mes == 8 && dia <= 22)){
      printf("Leao\n");
   }
   else if((mes == 8 && dia >= 23) || (mes == 9 && dia <= 22)){
      printf("Virgem\n");
   }
   else if((mes == 9 && dia >= 23) || (mes == 10 && dia <= 22)){
      printf("Libra\n");
   }
   else if((mes == 10 && dia >= 23) || (mes == 11 && dia <= 21)){
      printf("Escorpiao\n");
   }
   else if((mes == 11 && dia >= 22) || (mes == 12 && dia <= 21)){
      printf("Sargitario\n");
   }
   else if((mes == 12 && dia >= 22) || (mes == 1 && dia <= 21)){
      printf("Capricornio\n");
   }
      
   return 0;
}

Quando tava testando o programa vi que se eu entrasse com algum dado que não começasse com 0 funcionava e se entrasse com 0 não funcionava. Fiquei encucado com isso, era claro que era o 0 que estava causando problemas.

Na cagada resolvi usar o %d (linha 8) e pra minha surpresa funcinou com todos os dados!

Ai eu fiquei encucado com isso, pois, eu sempre pensei que os dois fossem iguais, mas agora descobri que não eram, só que não sabia qual era a diferença.

Na faculdade alguns amigos disseram que o %i desprezava 0 e várias outras coisas. Até que um colega disse o certo, usando o %i ele da a possibilidade de trabalhar com números em outras bases numericas e começando um número com 0 ele subentendia que era um número octal. Já o %d (d de decimal) só aceita números na base decimal.

Fiz um pequeno programinha para testar se isso era verdade. Para octal entre com 0 na frente do número e para hexadecimal entre com 0x na frente do número.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>

int main()
{
   int n1, n2;

   printf("Informe um numero: ");
   scanf("%i", &n1);
   printf("Informe outro numero: ");
   scanf("%d", &n2);

   printf("Numero do %%i: %i\n", n1);
   printf("Numero do %%d: %d\n", n2);
   
   return 0;
}

O programa recebe 2 números, sendo um com o %i e outro com o %d(insira numeros começando com 0 e pra ficar mais facil a visualização o mesmo número para os dois) e depois exibe os números recebidos.

Por exemplo: Se inserirmos 010 no primeiro e 010 no segundo vai ser entendido da seguinte forma:

  • Primeiro %i: recebe 010 = (10) em base octal, que é igual 8 em base decimal
  • Segundo %d: recebe 010 = (10) em base decimal

Logo a saida será:

Numero do %i: 8
Numero do %d: 10

Se alguém souber mais sobre isso comente.

Até mais.

Alex.S.R