C é uma daslinguagens de programação mais populares[4][5] e existem poucas arquiteturas para as quais não existemcompiladores para C. C tem influenciado muitas outras linguagens de programação (por exemplo, a linguagemJava),[6] mais notavelmenteC++, que originalmente começou como uma extensão para C.
A linguagem C encontra-se na versão/padrão internacional C17 (ISO/IEC 9899:2018) lançada em junho de 2018, substituindo a versão C11 (ISO/IEC 9899:2011),[7] disponível em ISO e IEC e com suporte paraGCC8 eClangLLVM6.[8]
O desenvolvimento inicial de C ocorreu no AT&T Bell Labs entre 1969 e 1973.[9] 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 chamada de "B", que de acordo comKen Thompson era a versão reduzida da linguagem de programaçãoBCPL.[10]
A versão original PDP-11 do sistema Unix foi desenvolvido emAssembly. Em 1973, com a adição dos tiposstruct, a linguagem C tornou-se poderosa o suficiente para que a maior parte dokernel doUnix fosse reescrito em C. Este foi um dos primeiros núcleos de sistemas operacionais implementados numa linguagem diferente da linguagemAssembly. 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.[11]
A linguagem C não teve um sucesso imediato após a sua criação e o seu uso ficou restrito a alguns laboratórios,[12] mas em 1978Brian Kernighan e Dennis Ritchie lançam o livroThe C Programming Language[13] que serviu de tutorial e mudou a história da programação em C. De fato essa primeira versão da linguagem é conhecida como "C Kernighan e Ritchie" ou apenas "C K&R".[14]
Esse livro, conhecido pelos programadores de C como "K&R", serviu durante muitos anos como uma especificação informal da linguagem. A versão da linguagem C que ele descreve é usualmente referida como "K&R C". A segunda edição do livro cobriu o padrão posterior, oANSI C. K&R C introduziu as seguintes características na linguagem:
O operador=+ foi alterado para+=, e=- para-= (oanalisador léxico do compilador fazia confusão entrei =+ 10 ei = +10. O mesmo acontecia com=-)
K&R C é frequentemente considerado a parte mais básica da linguagem, cujo suporte deve ser assegurado por umcompilador de C. Durante muitos anos, mesmo após a introdução do padrão ANSI C, K&R C foi considerado o "menor denominador comum", em que programadores de C se apoiavam quando umaportabilidade máxima era desejada, já que nem todos os compiladores eram actualizados o suficiente para suportar o padrão ANSI C.
Nos anos que se seguiram à publicação do K&R C, algumas características "não oficiais" foram adicionadas à linguagem, suportadas por compiladores da AT&T e de outros vendedores. Estas incluíam:
Funçõesvoid e tipos de dadosvoid *
Funções que retornam tiposstruct ouunion
Campos de nomestruct num espaço de nome separado para cada tipostruct
Atribuição a tipos de dadosstruct
Qualificadoresconst para criar um objecto só de leitura
Biblioteca padrão, que incorpora grande parte da funcionalidade implementada por vários vendedores
Enumerações
Cálculos de ponto-flutuante em precisão simples (no K&R C, os cálculos intermediários eram feitos sempre emdouble, porque era mais eficiente na máquina onde a primeira implementação do C foi feita)
Durante os finais da década de 1970, a linguagem C começou a substituir a linguagemBASIC como a linguagem de programação demicrocomputadores mais usada. Durante a década de 1980, foi adaptada para uso no PC IBM, e a sua popularidade começou a aumentar significativamente. Ao mesmo tempo,Bjarne Stroustrup, juntamente com outros nos laboratórios Bell, começou a trabalhar num projecto onde se adicionavam extras para programação orientada por objectos à linguagem C. A linguagem que eles produziram, chamadaC++, é nos dias de hoje a linguagem de programação de aplicações mais comum no sistema operativoWindows da companhiaMicrosoft. A linguagem C permanece a mais popular no mundoUnix.
Em 1983, o instituto norte-americano de padrões (ANSI) formou um comité, X3J11, para estabelecer uma especificação do padrão da linguagem C. Após um processo longo e árduo, o padrão foi completo em 1989 e ratificado como ANSI X3.159-1989 "Programming Language C". Esta versão da linguagem é frequentemente referida como ANSI C. Em 1990, o padrão ANSI C, após sofrer umas modificações menores, foi adotado pelaOrganização Internacional para Padronização (ISO) que cria o grupo de trabalho para cuidar da especificação da linguagem, denominado WG14, assim foi renomeada para ISO/IEC 9899:1990, também conhecido como C89 e C90.[15] Um dos objetivos do processo de padronização ANSI C foi o de produzir um sobreconjunto do K&R C, incorporando muitas das características não oficiais subsequentemente introduzidas. Entretanto, muitos programas tinham sido escritos e que não compilavam em certas plataformas, ou com um certo compilador, devido ao uso de bibliotecas de funções não padrão e ao fato de alguns compiladores não aderirem ao ANSI C.
Após o processo da padronização ANSI, as especificações da linguagem C permaneceram relativamente estáticas por algum tempo, enquanto a linguagem C++ continuou a evoluir. (em 1995, aNormative Amendment 1 criou uma versão nova da linguagem C mas esta versão raramente é tida em conta.) Contudo, o padrão foi submetido a uma revisão nos finais da década de 1990, levando à publicação da normaISO 9899:1999 em 1999. Este padrão é geralmente referido como "C99" e foi adoptado como um padrão ANSI em março de 2000. As novas características do C99 incluem:
Funções em linha
Remoção de restrições sobre a localização da declaração de variáveis (como em C++)
Adição de vários tipos de dados novos, incluindo olong long int (para minimizar problemas na transição de 32-bits para 64-bits), um tipo de dados boolean explicito (chamado_Bool) e um tipocomplex que representanúmeros complexos
Vetores de dados de comprimento variável (o vetor pode ter um tamanho diferente a cada execução de uma função, mas não cresce depois de criado)
Suporte oficial para comentários de uma linha iniciados por//, emprestados da linguagem C++
Várias funções de biblioteca novas, tais comosnprintf()
Vários ficheiros-cabeçalho novos, tais comostdint.h
O interesse em suportar as características novas de C99 parece depender muito das entidades. Apesar doGCC e vários outros compiladores suportarem grande parte das novas características do C99, os compiladores mantidos pela Microsoft e pelaBorland suportam pouquíssimos recursos do C99, e estas duas companhias não parecem estar muito interessadas em adicionar tais funcionalidades, ignorando por completo as normas internacionais. A Microsoft parece preferir dar mais ênfase ao C++.[16]
Em 2007, se iniciou o trabalho em antecipação de outra revisão do padrão de C, informalmente chamada de C11 ou C1X. O comité dos padrões de C adotou regras para limitar a inserção de novos recursos que não tenham ainda sido testados por implementações existentes.[17]
Em dezembro de 2011 foi publicada a versão estável da especificação, como ISO/IEC 9899:2011.
Em 2017 começou a ser desenvolvida uma nova revisão do padrão C, informalmente chamada de C17, substituindo o C11.[18] Esta revisão visou melhorar a revisão anterior sem introduzir nova funcionalidades na linguagem.[19] Em junho de 2018 foi publicada a versão estável da especificação, como ISO/IEC 9899:2018.[19] Como foi publicada em 2018, também é informalmente chamada de C18.[20]
C23 é um nome informal para a revisão atual do padrão principal da linguagem C. Era informalmente conhecido como "C2X" durante a maior parte de seu desenvolvimento[21]. C23 foi publicado em outubro de 2024 como ISO/IEC 9899:2024. A macro padrão__STDC_VERSION__ é definida para202311L indicar que o suporte C23 está disponível.
C é uma linguagem imperativa e procedural para implementação de sistemas. Seus pontos de design foram para ele ser compilado, fornecendo acesso irrestrito àmemória e baixos requerimentos do hardware. Também foi desenvolvido para ser uma linguagem de alto nível, para maior reaproveitamento do código. C foi útil para muitas aplicações que foram codificadas originalmente emAssembly.
Essa propriedade não foi acidental; a linguagem C foi criada com o objectivo principal em mente: facilitar a criação de programas extensos com menos erros recorrendo aoparadigma daprogramação procedural mas sobrecarregando menos o autor docompilador, cujo trabalho complica-se ao ter de realizar as características complexas da linguagem. Para este fim, a linguagem C possui as seguintes características:
Uma linguagem extremamente simples, com funcionalidades não essenciais, tais como funções matemáticas ou manuseamento de ficheiros (arquivos), fornecida por um conjunto debibliotecas de rotinas padronizada
Acesso de baixo nível, através de inclusões de código Assembly no meio do programa C
Parâmetros que são sempre passados por valor para as funções e nunca por referência (É possível simular a passagem por referência com o uso de ponteiros)
Definição do alcance lexical de variáveis
Estruturas de variáveis, (structs), que permitem que dados relacionados sejam combinados e manipulados como um todo
Algumas características úteis, que faltam em C, podem ser encontradas em outras linguagens, que incluem:
Apoio nativo demultithreading e comunicação por rede
Apesar da lista de características úteis que C possui não ser longa, isso não tem sido um impedimento à sua aceitação, pois isso permite que novos compiladores de C sejam escritos rapidamente para novas plataformas, e também permite que o programador permaneça sempre em controle do que o programa está a fazer. Isto é o que por várias vezes permite o código de C correr de uma forma mais eficiente que muitas outras linguagens. Tipicamente, só código de Assembly "afinado à mão" é que corre mais rapidamente, pois possui um controle completo da máquina, mas avanços na área de compiladores juntamente com uma nova complexidade nos processadores modernos permitiram que a diferença tenha sido rapidamente eliminada.Uma consequência da aceitação geral da linguagem C é que frequentemente oscompiladores,bibliotecas e atéinterpretadores de outras linguagens sejam implementados em C.
C tem como ponto forte a sua eficiência, e é a linguagem de programação preferida para o desenvolvimento de sistemas e softwares de base, apesar de também ser usada para desenvolverprogramas de computador. É também muito usada no ensino deciência da computação, mesmo não tendo sido projetada para estudantes e apresentando algumas dificuldades no seu uso. Outra característica importante de C é o seu código resultante emAssembly ter funcionamento idêntico aocódigo fonte, que permite que um projetista seja capaz de fazer algumas previsões de como o software irá se comportar ao ser executado.
O ponto negativo de C está na possibilidade do programador cometer erros graças a liberdade que a linguagem oferece. Por exemplo é possível acessar área de memória que não pertence a um vetor ao acessar um índice maior que seu tamanho, possibilitando que ocorra umbuffer overflow.Isto acontece em C porque o dever de controlar a memória está nas mãos do programador.O motivo de C dar total controle para o programador é porque a linguagem foi projetada para programar osistema operacionalUNIX, onde havia a necessidade desse controle sobre a forma como o sistema iria funcionar.[3]
C tem um sistema de tipos semelhante ao de alguns descendentes da linguagemALGOL, tais comoPascal. 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 extensivamenteponteiros, um tipo muito simples de referência que guarda o endereço de memória da variável. O ponteiro pode serdesreferenciado, 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 otempo de execução, o ponteiro é simplesmente uma morada de máquina tais como aquelas manipuladas emAssembly, mas emtempo 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 valorNULL é chamadoponteiro nulo. Os ponteiros são declarados (e desreferenciados) com um* (asterisco), portanto o tipoint* denota um ponteiro para variável(eis) que comporta(m) número(s) inteiro(s). A linguagem C também fornece um tipo especial de ponteiros, ovoid*, 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 dadoint (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):
long long int, deve possuir tamanho mínimo de64 bits
Todos estes tipos de inteiros podem ainda ser declarados precedidos da cláusulaunsigned, 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 umsigned (todos os inteiros são signed por omissão).
char
O tipochar ocupa 1byte, e serve para armazenarcaracteres ouinteiros. Isso significa que o programa reserva um espaço de 8 bits namemória RAM ou emregistradores 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 dadofloat serve para armazenar números deponto flutuante, ou seja, com casas decimais. O padrão mais utilizado nos últimos 10 anos é oIEEE 754-1985.
double
O tipo de dadodouble 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 casotypedef seja usado em sua declaração.
A linguagem de programaçãoC++ foi originalmente derivada do C para suportar programaçãoorientada a objetos. À medida que as linguagens C e C++ foram evoluindo independentemente, a divisão entre as duas veio a aumentar.O padrão C99 criou um número de características que entram em conflito. Hoje, as principais diferenças entre as duas linguagens são:
inline - em C++, funções em linha encontram-se no espaço global enquanto que em C encontram-se no espaço local. Por outras palavras, isso significa que, em C++, qualquer definição de qualquer função em linha (sem ser a respeito da sobrecarga de funções de C++) tem de estar em conformidade com a "regra de uma definição" da linguagem C++. Mas em C, a mesma função em linha pode ser definida de maneira diferente em diferentes arquivos (ou ficheiros)
A palavra-chavebool, igual à usada em C++, em C99 necessita que se inclua o ficheiro-cabeçalho<stdbool.h> (_Bool está sempre disponível). Padrões anteriores de C não definiam um tipo booleano e vários (e incompatíveis) métodos foram usados para simular um tipo booleano
Algumas características originalmente desenvolvidas em C++ também apareceram em C. Entre elas encontram-se:
protótipos de função (com declaração de tipos de parâmetros) e remoção do "int" implícito
comentários de linha, indicados por//; comentários de linha terminam com um carácter de nova-linha
A seguinte aplicação foi publicada na primeira edição de C de K&R, e tornou-se no programa de introdução padrão da maior parte dos livros sobre C. O programa envia o texto "Olá, Mundo!" para asaída padrão, que é normalmente oconsole, mas que também pode ser um ficheiro (ou arquivo), um outro dispositivo qualquer, ou até mesmo umbit bucket, dependendo de como a saída-padrão é mapeada na altura em que o programa é executado.
intmain(void){puts("Olá, Mundo!");}
Apesar do programa acima correr corretamente, atualmente origina algumas mensagens de aviso quando compilado como C ANSI. Essas mensagens podem ser eliminadas efectuando umas pequenas alterações no programa original:
#include<stdio.h> /* Pacotes com funções de entrada e saída */intmain(void){puts("Olá, Mundo!");return0;/* Retorna 0, pois `main` retorna um `int` */}/* Nova linha após fechar a chave principal */
A primeira linha do programa é umadiretiva de pré-processamento#include, que causa com que o pré-processador substitua aquela linha pela totalidade do conteúdo do arquivo qual diretiva se refere. Neste caso o arquivo padrãostdio.h (que contém protótipos de funções para trabalho com entrada e saída) irá substituir a linha. Os caracteres< e> indicam que o arquivo stdio.h encontra-se no local em que, quando da configuração do compilador, se definiu como padrão para localização dos ficheiros de inclusão (header files, geralmente com a extensão.h).
A linha (não vazia) seguinte indica que uma função denominadamain será definida. A funçãomain tem um significado especial nos programas em C, pois é a função que é inicialmente executada (em inglês,entry point). Os caracteres{ e} delimitam a extensão da função. O termoint define a funçãomain como sendo uma função que retorna um número inteiro. O termovoid indica que a função não aceita parâmetros. A funçãomain, normalmente aceita parâmetros, que são passado pelalinha de comando. Os compiladores e sistemas operacionais atuais reconhecem as seguintes declarações de main:
A linha seguinte "chama", ou executa uma função chamadaputs; o arquivo incluído,stdio.h, contém a informação que descreve a forma como a funçãoputs deve ser chamada. Nesta chamada, é passado à funçãoputs um único argumento, a linha de texto constante "Olá, Mundo!". A funçãoputs retorna um valor, umint, mas como não é usado, é descartado pelo compilador. O comandoreturn retorna o valor 0 para o sistema, que é interpretado pelo mesmo como que a função main() foi executada e encerrada com sucesso (sem erros). Por fim, o caracter} indica o fim da funçãomain. Note-se que texto rodeado por/* e*/ (comentários de texto) é ignorado pelo compilador. Os compiladores que obedecem à norma C99 também aceitam como comentários as linhas de texto que são precedidos por//.
Pode ser compilado e executado com o seguinte comando (considerando que oGCC está instalado):
#include<math.h>#include<stdio.h>doublef(doublet){returnsqrt(fabs(t))+5*pow(t,3);}intmain(void){doublea[11]={0},y;for(inti=0;i<11;i++)scanf("%lf",&a[i]);for(inti=10;i>=0;i--){y=f(a[i]);if(y>400)printf("%d TOO LARGE\n",i);elseprintf("%d %.16g\n",i,y);}}
Pode ser compilado e executado com o seguinte comando:
$gcc-lmtpk.c-otpk$./tpk
-lm instrui olinker a juntar o módulo de matemática (libm).
No exemplo seguinte, é criada uma estrutura composta por 3 membros de tipos diferentes. Os membros podem ser acessados com a seguinte sintaxe:estrutura.membro.
↑Ritchie, Dennis M. (janeiro de 1993).«The Development of the C Language». Consultado em 1 de janeiro de 2008.The scheme of type composition adopted by C owes considerable debt to Algol 68, although it did not, perhaps, emerge in a form that Algol's adherents would approve of.
↑Kernighan, Brian W.; Ritchie, Dennis M (1978).The C Programming Language (em inglês). Upper Saddle River, New Jersey: Prentice hall. 228 páginas.ISBN0-13-110163-3 !CS1 manut: Nomes múltiplos: lista de autores (link)