O desenvolvimento inicial de C ocorreu no AT&T Bell Labs entre 1969 e 1973.[5] de acordo com Ritchie, o período mais criativo ocorreu em 1972. A linguagem foi chamada "C", porque suas características foram obtidas a partir de uma linguagem anteriormente chamado de " B", que de acordo com a Ken Thompson era versão reduzida da linguagem de programação BCPL.[6]
A versão original PDP-11 do sistema Unix foi desenvolvido em assembly. Em 1973, com a adição dos tipos
struct, a linguagem C tornou-se poderosa o suficiente para que a maior parte do kernel do Unix fosse reescrito em C. Este foi um dos primeiros núcleos de sistemas operacionais implementados numa linguagem diferente da linguagem Assembly. Em 1977, foram feitas novas mudanças por Ritchie e Stephen C. Johnson para facilitar a portabilidade do sistema operacional Unix. OPortable C Compiler de Johnson serviu de base para várias implementações de C em novas plataformas.Tipos de dados
C tem um sistema de tipos semelhante ao de alguns descendentes da linguagem ALGOL, tais como Pascal. Possui tipos para números inteiros de vários tamanhos com e sem sinal, números de ponto flutuante, caracteres e estruturas (
structs). C usa extensivamente ponteiros, um tipo muito simples de referência que guarda o endereço de memória da variável. O ponteiro pode ser desreferenciado, uma operação que busca o objeto que se encontra na morada da memória que o ponteiro possui, morada essa que pode ser manipulada através de aritmética de ponteiros. Durante o tempo de execução, o ponteiro é simplesmente uma morada de máquina tais como aquelas manipuladas emAssembly, mas em tempo de compilação possui um tipo complexo que indica o tipo do objecto para onde ele aponta, permitindo que se verifique o tipo de expressões, incluindo ponteiros. O tipo "string" (cadeia ou linha de texto) de C é simplesmente um ponteiro para um vetor de caracteres e alocação dinâmica de memória, descrita abaixo, é efetuada através de ponteiros.
Os ponteiros em C possuem um valor reservado especial,
NULL, que indica que não estão a apontar para uma morada. O uso desse valor como morada é muito útil na construção de várias estruturas de dados, mas causa comportamento não-definido (possivelmente uma falha de sistema) ao ser desreferenciado. Um ponteiro que possui o valor NULL é chamado ponteiro nulo. Os ponteiros são declarados (e desreferenciados) com um * (asterisco), portanto o tipo int* denota um ponteiro para número(s) inteiro(s). A linguagem C também fornece um tipo especial de ponteiros, o void*, que se traduz num ponteiro que aponta para um objeto de tipo desconhecido.
A linguagem C também tem apoio em nível de linguagem para vetores estáticos (de dimensão fixa) de tipos. As disposições de tipos podem parecer ter mais que uma dimensão apesar de serem tecnicamente disposições de disposições de tipos. Em memória, tais estruturas são posicionadas com as linhas uma depois da outra (a alternativa seria armazenar os dados em colunas, usado em outras linguagens). O acesso a disposições de tipos é feito através de ponteiros e aritmética de ponteiros; o nome da disposição é tratado como se fosse um ponteiro que aponta para o início da disposição. Em certas aplicações não é razoável usarem-se disposições de tipos de dimensão fixa e por isso a alocação dinâmica de memória pode ser usada para criar disposições de tipos de dimensão variável.
Como a linguagem C é regularmente usada em programação de baixo-nível de sistemas, há casos em que é necessário tratar um número inteiro como sendo um ponteiro, um número de ponto flutuante como sendo um número inteiro ou um tipo de ponteiro como sendo outro. Para estes casos, a linguagem C fornece a capacidade de "moldagem" (também denominado "conversão de tipo" ou "casting"), uma operação que, caso seja possível, força a conversão de um objeto de um tipo para outro. Apesar de ser por vezes necessário, o uso de conversões de tipo sacrifica alguma segurança oferecida pelo sistema de tipos.
- int
O tipo de dado int (inteiro) serve para armazenar valores numéricos inteiros. Existem vários tipos de inteiros, cada um de um tamanho diferente (dependendo do sistema operacional e/ou arquitetura do processador):
int, pode possuir 16 bits, 32 bits ou 64 bitsshort int, deve possuir tamanho de no mínimo 16 bits e não pode ser maior queintlong int, deve possuir tamanho mínimo de 32 bitslong long int, deve possuir tamanho mínimo de 64 bits
Todos estes tipos de inteiros podem ainda ser declarados precedidos da cláusula unsigned, o que faz com que só suporte números positivos. Isto faz com que, com o mesmo tamanho, uma variável suporte mais números positivos do que um signed (todos os inteiros são signed por omissão).
- char
O tipo char ocupa 1 byte, e serve para armazenar caracteres ou inteiros. Isso significa que o programa reserva um espaço de 8 bits na memória RAM ou em registradores do processador para armazenar um valor (char de tamanho maior que 8 bits é permitido pela linguagem, mas os casos são raros). Com vetores do tipo char é possível criarcadeias de caracteres (strings).
- float
O tipo de dado float serve para armazenar números de ponto flutuante, ou seja, com casas decimais. O padrão mais utilizado nos últimos 10 anos é o IEEE 754-1985.
- double
O tipo de dado double serve para armazenar números de ponto flutuante de dupla precisão, normalmente tem o dobro do tamanho do float e portanto o dobro da capacidade. O padrão mais adotado também é o IEEE 754-1985.
- struct
Em C podem ser usadas estruturas (chamados de registos em outras linguagens de programação). As estruturas são grupos de variáveis organizadas arbitráriamente pelo programador. Uma estrutura pode criar um novo tipo de variável caso typedef seja usado em sua declaração.
