int
e float
int
têm sinal: podem ser negativos, positivos ou zerounsigned int
para inteiros sem sinal: apenas positivos ou zero int i; // com sinal
unsigned int j; // sem sinal
unsigned
: unsigned j; // unsigned int
int
e unsigned int
são ambos representados por palavras de comprimento fixo
\[ \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} \]
\[ \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} \]
int
é tipicamente representado usando 32-bits (pode ser menor em CPUs de 8 e 16-bits)long
e short
para especificar tamanhos maiores ou menoresunsigned
temos 6 tipos diferentes de inteiros: short int unsigned short int
int unsigned int
long int unsigned long int
int
short
\(\leq\) int
\(\leq\) long
<limits.h>
define os limites de cada tipo#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
}
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
int
long int
long
terminando com L
ou l
e unsigned
com U
ou u
: 17 // int
-1000L // long int
2500UL // unsigned long int
long int i = 17; // 17 -> 17L
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
int
para as dimensõesl = w = h = 1500
resulta em overflow (inteiros de 32-bits)unsigned
unsigned long
#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);
}
Esta versão calcula o volume correto para
l = w = h = 1500
mas obtemos de novo overflow para
l = w = h = 2000
#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);
}
l = w = h = 2000
l = w = h
para os quais não ocorre overflow (assumindo unsigned long
com 64-bits)float
para precisão simples;double
para precisão dupla.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 |
double
é usado para a maior parte das aplicaçõesfloat
é usando apenas se a precisão for pouco importante ou para poupar memória57.0 57. 57E0 5.7e1
E
(ou e
)5.7e1 |
\(5.7\times 10^1\) |
5.7E-3 |
\(5.7\times 10^{-3}\) |
"%lf"
para ler valores double
float
ou double
devemos usar apenas "%f"
"%g"
para formatar usando notação científica#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ã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
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
char
é usado para representar caratereschar
guarda um carater qualquer:char ch;
ch = 'A';
'A' // letra A maiúscula
'a' // letra A minúscula
'?' // sinal de pontuação
' ' // espaço
'A' // 65
'a' // 97
' ' // 32
'0' // 48
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'
A
e Z
if ('A' <= ch && ch <= 'Z') ... |
✔ |
if (65 <= ch && ch <= 90) ... |
✘ |
\n |
mudança de linha | \b |
backspace |
\t |
tabulação horizontal | \\ |
contra-barra |
\' |
aspa simples | \a |
alert (campainha) |
char ch = '\n'; // mudança de linha
"%c"
para ler ou escrever carateres usando scanf
e printf
char ch;
scanf("%c", &ch); // ler um carater
printf("%c", ch); // escrever um carater
#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");
}
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: ~