Programação C – Tipos de dados

Antes de continuarmos os posts, já que vimos vetores, matrizes e vou entrar em funções, ponteiros, alocações de memoria e estrutura de dados então é bom compreender os tipos de dados em C, será muito útil em qualquer linguagem pois a base é a mesma, o que difere é a forma de declarar e linguagens onde você não declara o tipo você pode fazer um cast com o tipo então é bom saber o que é e porque usar. Verá nomes comuns como (int, char, void e float) combinando com outros nomes como (signed, unsigned, short e long) que as vezes uma combinação e outra apresenta o mesmo resultado mas pode diferenciar no comportamento com a memoria RAM, linkagem e na organização da memoria, ou seja, quando as variaveis são alocadas na memoria e como são.

Não vou mentir, lembro-me quando vi o tipo void, short int, signed int, int e outras combinações eu pensei: “Nossa que idiota um tipo vazio(void) e int, short int e signed int ser 2 bytes com mesma faixa”. E continuei a vida é claro rs, mas conforme fui amadurecendo e ampliando os conhecimentos, aprendendo a desenvolver olhando alguns código do kernel do linux, programando para embarcados, estudando a organização da memoria, debugando as coisas vixii e por ae foi… eu vi que estava errado e a diferença de certos profissionais esta em quem realmente conhece esses tipos, como um desenvolvedor que sabe o que é, serve, funciona e aplicar um ponteiro e alocação, além das maneiras de declarar uma variável global ou local, mas isso é papo para posts futuros, das minhas aventuras em desenvolver em Linux, para Linux e para sistemas embarcados.

Vamos conhecer os tipos, tamanhos, faixas de valores e a sintaxe para exibir o valor:

Tipo Tamanho Faixa Sintaxe printf
void 1 bytes
char 1 byte -128 à 127 %c
unsigned char 1 byte 0 à 255 %c
int 2 bytes -32.768 à 32.767 %d ou %i
unsigned int 2 bytes 0 à 65.535 %d ou %i
signed int 2 bytes -32.768 à 32.767 %d ou %i
short int 2 bytes -32.768 à 32.767 %hi
unsigned short int 2 bytes 0 à 65.535 %hu
signed short int 2 bytes -32.768 à 32.767 %hi
long int 4 bytes -2.147.483.648 à 2.147.483.647 %li
signed long int 4 bytes -2.147.483.648 à 2.147.483.647 %li
unsigned long int 4 bytes 0 à 4.294.967.295 %lu
float 4 bytes 3,4E-38 à 3,4E+38 %f
unsigned float 4 bytes 0 à 3,4E+72 %f
double 8 bytes 1,7E-308 à 1,73E+308 %lf
long double 10 bytes 3,4E-4932 à 3,4E+4932 %Lf

Esse tipo de dado da tabela acima é o dado “informação” que você irá colocar na memoria (numero inteiro, numero real, carácter, string e por ae vai), é importante usar o tipo correto como: porque usar signed int para contar horas sendo que unsigned int seria o mais correto por não haver hora negativa, melhor porque não usar unsigned char já que são 24 horas (char 1 byte [0 255]) e segue esse pensamento abstraindo o que você irá “guardar” naquela variável ou naquele tipo que você criou, ae você deve estar olhando a tabela que forneci acima e perguntando, de onde tirei isso? Posso ter inventado, copiado, mas vamos ver como obter algum desses valores.

OBS: É muito importante atentar que o tamanho esta completamente influenciado pela plataforma utilizada e o compilador, resultados diferentes podem ser apresentados para um 32bits, 64bits, ARM e um microcontrolador 8bits, o mais comum por exemplo é o char ser de 1byte.

Vamos ver alguns tamanhos em plataformas diferentes:

LaunchPad MSP430 da Texas Instruments MSP430G2553 16-bit 16MHz [MSPGCC 20120406 4.6.3]
Tamanho de um char 1 bytes
Tamanho de um unsigned char 1 bytes
Tamanho de um void 1 bytes
Tamanho de um int 2 bytes
Tamanho de um unsigned int 2 bytes
Tamanho de um short int 2 bytes

 

Arduino UNO com Atmel AVR ATmega328P 8-bit 20MHz [WinAVR 20081205 4.3.2]
Tamanho de um char 1 bytes
Tamanho de um unsigned char 1 bytes
Tamanho de um void 1 bytes
Tamanho de um int 2 bytes
Tamanho de um unsigned int 2 bytes
Tamanho de um short int 2 bytes

 

Windows 7 32bits [mingw32-gcc 3.4.2]
Tamanho de um char 1 bytes
Tamanho de um unsigned char 1 bytes
Tamanho de um void 1 bytes
Tamanho de um int 4 bytes
Tamanho de um unsigned int 4 bytes
Tamanho de um short int 2 bytes

 

Linux Mint 13 64bits [gcc 4.7.3]
Tamanho de um char 1 bytes
Tamanho de um unsigned char 1 bytes
Tamanho de um void 1 bytes
Tamanho de um int 4 bytes
Tamanho de um unsigned int 4 bytes
Tamanho de um short int 2 bytes

 

Linux Ubuntu 11.04 32bits [gcc 4.6.1]
Tamanho de um char 1 bytes
Tamanho de um unsigned char 1 bytes
Tamanho de um void 1 bytes
Tamanho de um int 4 bytes
Tamanho de um unsigned int 4 bytes
Tamanho de um short int 2 bytes

 

Raspberry PI B ARM1176JZF-S (ARMv6) com Raspbian 32bits [gcc 4.6.3]
Tamanho de um char 1 bytes
Tamanho de um unsigned char 1 bytes
Tamanho de um void 1 bytes
Tamanho de um int 4 bytes
Tamanho de um unsigned int 4 bytes
Tamanho de um short int 2 bytes

O codigo que utilizei para os testes foi praticamente o mesmo havendo apenas algumas modificações para o LaunchPad MSP430 e o Arduino.

Espero ter deixado claro a ideia do post e os cuidados que deve ter, principalmente quando se desenvolve pensando em portar códigos, vejo por ae em alguns sites que dizem que void é 0 bytes (sem tamanho) isso é um erro, não é porque ele não retorna um valor que ele não tenha uso, senão porque existiria? Futuramente irei mostrar onde o void é aplicado e as sacadas para usar ele.

Até a próxima!

Share Button

CC BY-NC-SA 4.0 Programação C – Tipos de dados by Cleiton Bueno is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

  • Pedro Zorzenon Neto

    Quando eu preciso usar um tamanho fixo de bytes, porque vou compilar o código no PC, no ARM, no MSP430, etc… então eu uso os tipos stdint, exemplo:

    #include
    uint8_t abc; /* unsigned int de 8 bits = 1 byte */
    int8_t def; /* signed int de 8 bits = 1 byte */
    uint32_t ghi; /* unsigned int de 32 bits = 4 bytes */
    e outros nomes similares para signed e unsigned com 8 16 32 64 bits

    O stdint.h deveria ser padrão para todos os compiladores, mas em alguns (geralmente para PIC) não tem esse header, então neste caso eu crio um stdint.h declarando os tipos que vou usar e relacionando eles com um do mesmo tamanho no processador em questão.

    • Verdade Pedro, tanto que o AVR possui também o stdint.h muito útil visando portar código, aqui foi só um gostinho do que vem ainda, quando terminar essa base do C com funções, ponteiro e struct ae da pra começar entrar em Linux C também e ver bastante coisa legal como pthreads, ioctl, signal e unistd em microcontroladores estudar as declarações e ver o uso em heap e stack, quando usar volatile, static, externo (como você comentou comigo :)) mas vamos degrau por degrau se não assusta hehehe.

      Abraço Pedro e obrigado pela informação.