Tipos básicos

Inteiros em C

        int i;          // com sinal
        unsigned int j; // sem sinal 
        unsigned j;      // unsigned int 

Inteiros com e sem sinal

Exemplo: 16 bits sem sinal

\[ \begin{array}{ccc} \text{mínimo} & 0 & (0000000000000000)_2 \\ & 1 & (0000000000000001)_2 \\ & 2 & (0000000000000010)_2 \\ & \vdots & \vdots \\ \text{máximo} & {2^{16} -1} & (1111111111111111)_2 \end{array} \]

Exemplo: 16 bits com sinal

\[ \begin{array}{ccc} \text{mínimo} & {-2^{15}} & (1000000000000000)_2 \\ & \vdots & \vdots \\ & -1 & (1111111111111111)_2 \\ & 0 & (0000000000000000)_2 \\ & +1 & (0000000000000001)_2 \\ & \vdots & \vdots \\ \text{máximo} & {+2^{15} -1} & (0111111111111111)_2 \end{array} \]

Tamanhos

   short int       unsigned short int
   int             unsigned int 
   long int        unsigned long int

Tamanhos

Imprimir os limites

#include <stdio.h>
#include <limits.h>

int main(void) {
  printf("SHRT_MIN = %d\n", SHRT_MIN);
  printf("SHRT_MAX = %d\n", SHRT_MAX);

  printf("INT_MIN = %d\n", INT_MIN);
  printf("INT_MAX = %d\n", INT_MAX);

  printf("LONG_MIN = %ld\n", LONG_MIN);
  printf("LONG_MAX = %ld\n", LONG_MAX);
     // %ld para formatar long int
}

Exemplo

Execução no meu portátil (GNU/Linux X86-64):

$ ./tamanhos 
SHRT_MIN = -32768
SHRT_MAX = 32767
INT_MIN = -2147483648
INT_MAX = 2147483647
LONG_MIN = -9223372036854775808
LONG_MAX = 9223372036854775807

Constantes

         17   // int
     -1000L   // long int 
     2500UL   // unsigned long int
   long int i = 17;     // 17 -> 17L

Ler e escrever inteiros

Para ler ou escrever inteiros short, long ou unsigned devemos usar formatos específicos em scanf e printf.

Casos mais comuns:

"%u"

inteiro decimal unsigned

"%ld"

inteiro decimal long

"%lu"

inteiro decimal unsigned long

Exemplo

Versão 1

#include <stdio.h>

int main(void) {
   unsigned l, w, h, v;

   printf("L=?"); scanf("%u", &l);
   printf("W=?"); scanf("%u", &w);
   printf("H=?"); scanf("%u", &h);
   v = l*w*h; // cálculo do volume

   printf("LxWxH: %u*%u*%u (cm)\n", l,w,h);
   printf("Volume: %u (cm^3)\n", v);
}

Execução 1

Esta versão calcula o volume correto para

l = w = h = 1500

mas obtemos de novo overflow para

l = w = h = 2000

Versão 2

#include <stdio.h>

int main(void) {
   unsigned long l, w, h, v;

   printf("L=?"); scanf("%lu", &l);
   printf("W=?"); scanf("%lu", &w);
   printf("H=?"); scanf("%lu", &h);
   v = l*w*h; // cálculo do volume

   printf("LxWxH: %lu*%lu*%lu (cm)\n", l,w,h);
   printf("Volume: %lu (cm^3)\n", v);
}

Execução 2

Vírgula flutuante

Limites IEEE 754

tipo menor positivo maior valor precisão
float \(\approx 1.17\times 10^{-38}\) \(\approx 3.40\times 10^{38}\) 6 algarismos
double \(\approx 2.22\times 10^{-308}\) \(\approx 1.79\times 10^{308}\) 15 algarismos

Constantes

5.7e1 \(5.7\times 10^1\)
5.7E-3 \(5.7\times 10^{-3}\)

Ler e escrever vírgula flutuante

Exemplo

#include <stdio.h>

int main(void) {
  double l, w, h, v;

  printf("L=?"); scanf("%lf", &l);
  printf("W=?"); scanf("%lf", &w);
  printf("H=?"); scanf("%lf", &h);
  v = l*w*h; // cálculo do volume

  printf("LxWxH: %.3f*%.3f*%.3f (cm)\n", 
         l, w, h);
  printf("Volume: %.3g (cm^3)\n", v);
}

Conversões explícitas

Conversão explicita de tipos ("cast"):

(int) expr converter para inteiro
(float) expr converter para vírgula flutuante
(tipo) expr forma geral
int k = 2, n = 3; 
printf("%f\n", (float)k/(float)n); // 0.66666
printf("%f\n", (float)k/n);        // 0.66666
printf("%f\n", (float)(k/n));      // 0.00000

Conversões explícitas (cont.)

Também podemos converter entre tamanhos:

int i = 1500;
long j;
j = (long)i;

Devemos efetuar conversões antes de operações que possam causar overflow:

int i = 1500;
long j;
j = (long)(i*i*i);  // "overflow"(?)
j = (long)i*i*i;    // OK

Carateres

Carateres

char ch;
ch = 'A';
'A'   // letra A maiúscula
'a'   // letra A minúscula
'?'   // sinal de pontuação
' '   // espaço

Códigos de carateres

       'A'  // 65
       'a'  // 97
       ' '  // 32
       '0'  // 48

Operações sobre carateres

int i;
char ch;

i = 'a';     // i é 97
ch = 65;     // c é código de 'A'
ch = ch + 1; // c é código de 'B'
ch ++;       // c é código de 'C'

Operações sobre carateres

if ('A' <= ch && ch <= 'Z') ...
if (65 <= ch && ch <= 90) ...

Sequências de escape

\n mudança de linha \b backspace
\t tabulação horizontal \\ contra-barra
\' aspa simples \a alert (campainha)

Imprimir e ler carateres

char ch;
scanf("%c", &ch);  // ler um carater
printf("%c", ch);  // escrever um carater

Exemplo

Programa

#include <stdio.h>

int main(void) 
{
  char ch;

  for (ch = 32; ch<127; ch++) {
    if (ch % 8 == 0) {
      printf("\n"); /* mudar de linha */
    }
    printf("%3d: %c ", ch, ch);
  }
  printf("\n");
}

Tabela ASCII

 32:    33: !  34: "  35: #  36: $  37: %  38: &  39: ' 
 40: (  41: )  42: *  43: +  44: ,  45: -  46: .  47: / 
 48: 0  49: 1  50: 2  51: 3  52: 4  53: 5  54: 6  55: 7 
 56: 8  57: 9  58: :  59: ;  60: <  61: =  62: >  63: ? 
 64: @  65: A  66: B  67: C  68: D  69: E  70: F  71: G 
 72: H  73: I  74: J  75: K  76: L  77: M  78: N  79: O 
 80: P  81: Q  82: R  83: S  84: T  85: U  86: V  87: W 
 88: X  89: Y  90: Z  91: [  92: \  93: ]  94: ^  95: _ 
 96: `  97: a  98: b  99: c 100: d 101: e 102: f 103: g 
104: h 105: i 106: j 107: k 108: l 109: m 110: n 111: o 
112: p 113: q 114: r 115: s 116: t 117: u 118: v 119: w 
120: x 121: y 122: z 123: { 124: | 125: } 126: ~