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:
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 |
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 |
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 |
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 |
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 |
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.
#include <stdio.h> int main(void) { printf("Tamanho de um char =tt%lu bytesn",sizeof(char)); printf("Tamanho de um unsigned char =t%lu bytesn",sizeof(unsigned char)); printf("Tamanho de um void =tt%lu bytesn",sizeof(void)); printf("Tamanho de um int =tt%lu bytesn",sizeof(int)); printf("Tamanho de um unsigned int =t%lu bytesn",sizeof(unsigned int)); printf("Tamanho de um short int =t%lu bytesn",sizeof(short int)); return 0; }
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!
Programação C – Tipos de dados by Cleiton Bueno is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.