Conteúdo verificado

C (linguagem de programação)

Assuntos Relacionados: Programação de Computadores

Fundo para as escolas Wikipédia

Crianças SOS feita esta seleção Wikipedia ao lado de outras escolas recursos . Antes de decidir sobre o patrocínio de uma criança, por que não aprender sobre as diferentes instituições de caridade de patrocínio primeiro ?

C
Capa do livro para
A Linguagem de Programação C (aka "K & R"), o livro seminal sobre C
Paradigma (s) Imperativo ( processual), estruturada
Apareceu em 1972
Projetado por Dennis Ritchie
Revelador Dennis Ritchie & Bell Labs (criadores); ANSI X3J11 ( ANSI C); ISO / IEC JTC1 / SC22 / WG14 (ISO C)
Versão estável C11 (Dezembro de 2011)
Disciplina Typing Estática, fraco, manifesto, nominal
As principais implementações Clang, GCC, Intel C, MSVC, Pelles C, Watcom C
Dialetos Cyclone, Unified Parallel C, Split-C, Cilk, C *
Influenciado por B ( BCPL, CPL), ALGOL 68, Assembléia, PL / I, Fortran
Influenciado Numerosos: AMPL, AWK, csh, C ++ , C--, C #, Objective-C, BITC, D, Go, Java , JavaScript, Limbo, LPC, Perl , PHP, Pike, Processing, Seed7
OS Cruz-plataforma (multi-plataforma)
Usual extensões de arquivo .c .h
  • Programação C em Wikibooks

Em computação, C ( / s Eu /, Como em a letra C) é um objectivo geral linguagem de programação inicialmente desenvolvido pela Dennis Ritchie entre 1969 e 1973, AT & T Bell Labs. Como a maioria linguagens imperativas de ALGOL tradição, C dispõe de instalações para programação estruturada e permite escopo de variáveis lexical e recursão, enquanto um sistema de tipo estático impede muitas operações não intencionais. Seu design fornece construções que mapeiam de forma eficiente para típico instruções de máquina e uso duradouro, portanto, ele foi encontrado em aplicações que anteriormente tinha sido codificados em linguagem assembly, mais notavelmente software de sistema como o Unix computador sistema operacional.

C é uma das línguas de todos os tempos de programação mais utilizadas, e compiladores C estão disponíveis para a maioria dos disponível arquiteturas de computadores e sistemas operacionais.

Muitas línguas posteriores ter emprestado directa ou indirectamente de C, incluindo C #, D, Go, Java , JavaScript, Limbo, LPC, Perl , PHP, Python , e Unix Shell C. A influência mais difundido em línguas (excluindo Python) tem sido sintática, e eles tendem a combinar a expressão reconhecível e declaração sintaxe do C com sistemas subjacentes tipo, modelos de dados e semântica que pode ser radicalmente diferente. C ++ começou como um pré-processador para C e é atualmente quase um super conjunto de C.

Antes que houvesse um padrão oficial para C, muitos usuários e implementadores invocado uma especificação informal contido em um livro de Dennis Ritchie e Brian Kernighan; versão que é geralmente referido como "K & R" C. Em 1989, o Instituto Nacional Americano de Normas publicada uma norma para C (geralmente denominado " ANSI C "ou" C89 "). No ano seguinte, a mesma especificação foi aprovada pelo International Organization for Standardization como um padrão internacional (geralmente chamado de "C90"). ISO liberado mais tarde uma extensão para o apoio à internacionalização da norma em 1995, e uma norma revista (conhecido como " C99 ") em 1999. A versão atual da norma (agora conhecido como" C11 ") foi aprovado em Dezembro de 2011.

Projeto

C é um imperativo ( processual) idioma. Ele foi projetado para ser compilado usando um relativamente simples compilador, para fornecer baixo nível de acesso a memória, para proporcionar construções de linguagem que mapeiam de forma eficiente para instruções de máquina, e para exigir mínimo run-time apoio. C foi, por conseguinte, úteis para muitas aplicações que anteriormente tinham sido codificados em linguagem de montagem, tal como em programação do sistema.

Apesar das suas capacidades de baixo nível, a linguagem foi projetada para encorajar programação multi-plataforma. A compatível com os padrões e programa C portably escrito pode ser compilado para uma ampla variedade de plataformas de computadores e sistemas operacionais com poucas alterações em seu código fonte. A linguagem tornou-se disponível em uma grande variedade de plataformas, desde embutido microcontroladores para supercomputadores.

Características

Como a maioria das linguagens imperativas de ALGOL tradição, C dispõe de instalações para programação estruturada e permite escopo de variáveis lexical e recursão, enquanto um estático Tipo de sistema impede que muitas operações não intencionais. Em C, todo o código executável está contido dentro sub-rotinas, que são chamados de "funções" (embora não no sentido estrito programação funcional). Função parâmetros são sempre passados por valor. Passagem por referência é simulada em C pela passagem explicitamente valores de ponteiro. Texto-fonte do programa C é livre de formato, usando o como um ponto e vírgula declaração terminator e chaves para agrupar blocos de instruções.

A linguagem C apresenta também as seguintes características:

  • Há um número pequeno, fixo de palavras-chave, incluindo um conjunto completo de fluxo de primitivas de controlo: for , if/else , while , switch , e do/while . Há um nomes, e definidos pelo usuário nomes não são distinguidos de palavras-chave por qualquer tipo de sigilo.
  • Há um grande número de operadores aritméticos e lógicos, tais como + , += , ++ , & , ~ , etc.
  • Mais de um atribuição pode ser realizada em uma única instrução.
  • Valores de retorno da função pode ser ignorado quando não for necessário.
  • A digitação é estática, mas fracamente aplicadas: todos os dados tem um tipo, mas conversões implícitas podem ser realizadas; por exemplo, os caracteres podem ser utilizados como números inteiros.
  • Declaração imita sintaxe contexto de utilização. C não tem nenhuma palavra-chave "definir"; em vez disso, uma indicação começando com o nome de um tipo é tomado como uma declaração. Não há "função" palavra-chave; em vez disso, uma função é indicado pelos parênteses de uma lista de argumentos.
  • Definidos pelo usuário ( typedef tipos) e compostos são possíveis.
    • Tipos de dados agregados heterogêneos ( struct ) permitir que elementos de dados relacionados a ser acessado e atribuído como uma unidade.
    • Indexação de matriz é uma noção secundário, definido em termos de aritmética de ponteiro. Ao contrário de estruturas, matrizes não são objetos de primeira classe; eles não podem ser cedidos ou comparadas utilizando individuais operadores integrados. Não há nenhuma palavra-chave "matriz", em uso ou definição; em vez disso, colchetes indicam matrizes sintaticamente, por exemplo month[11] .
    • Tipos enumerados são possíveis com a enum de palavras-chave. Eles não são marcadas, e são livremente interconversíveis com números inteiros.
    • As seqüências não são um tipo de dados em separado, mas são convencionalmente implementados como matrizes de terminação nula de caracteres.
  • Acesso de baixo nível para memória do computador é possível através da conversão de endereços de máquina para digitado ponteiros.
  • Procedimentos (sub-rotinas não retornam valores) são um caso especial da função, com um tipo de retorno untyped void .
  • As funções não podem ser definidas no âmbito lexical de outras funções.
  • Função e dados ponteiros permitir ad hoc run-time polimorfismo.
  • A executa pré-processamento macro definição, código-fonte inclusão de arquivos, e compilação condicional.
  • Há uma forma básica de modularidade: arquivos podem ser compilados separadamente e ligados entre si, com controle sobre quais funções e dados objetos são visíveis para outros arquivos via static e extern atributos.
  • Funcionalidade complexa, como I / O, manipulação de cadeia, e matemáticas funções são delegadas a consistentemente rotinas de biblioteca.

C não inclui alguns recursos encontrados no mais recentes, linguagens de alto nível mais modernas, incluindo orientação a objetos e coleta de lixo.

História

Desenvolvimentos início

Ken Thompson e Dennis Ritchie, os desenvolvedores da linguagem de programação C.

O desenvolvimento inicial de C ocorreu no AT & T Bell Labs, entre 1969 e 1973; de acordo com Ritchie, o período mais criativo ocorreu em 1972. Foi nomeado "C", porque suas características foram derivadas de uma língua anterior chamado " B ", que de acordo com a Ken Thompson era uma versão reduzida do Linguagem de programação BCPL.

A origem do C está intimamente ligada ao desenvolvimento do Unix sistema operacional, originalmente implementado em linguagem assembly em um PDP-7 por Ritchie e Thompson, incorporando várias idéias dos colegas. Eventualmente eles decidiram portar o sistema operacional para um PDP-11. A incapacidade de B para aproveitar algumas das características do PDP-11, nomeadamente byte de endereçamento, levou ao desenvolvimento de uma versão inicial do C.

A versão original PDP-11 do sistema Unix foi desenvolvido em linguagem assembly. Por volta de 1973, com a adição de struct tipos, a linguagem C tinha-se tornado bastante poderoso que a maior parte do Unix kernel foi reescrito em C. Este foi um dos primeiros kernels do sistema operacional implementadas em um idioma diferente do assembly. (Casos anteriores incluem o Sistema Multics (escrito em PL / I), e MCP ( Mestre Programa de Controle) para o Burroughs B5000 escrita em ALGOL em 1961.) Circa 1977, novas alterações do idioma foram feitas por Ritchie e Stephen C. Johnson para facilitar a portabilidade do sistema operacional Unix. Johnson Portátil C Compiler serviu de base para várias implementações de C em novas plataformas.

K & R C

Em 1978, Brian Kernighan e Dennis Ritchie publicou a primeira edição de The C Programming Language. Este livro, conhecido pelos programadores C como "K & R", serviu por muitos anos como um informal A indicação da língua. A versão do C que ele descreve é comumente referido como K & R C. A segunda edição do livro cobre o mais tarde Padrão ANSI C.

K & R introduziu vários recursos de linguagem:

  • Eu biblioteca padrão de E / S
  • long int tipo de dados
  • unsigned int tipo de dados
  • operadores de atribuição composto da forma = op (tais como =- ) foram alteradas para a forma op = para remover a ambigüidade semântica criado por tais construções como i=-10 , que tinha sido interpretada como i =- 10 (i decréscimo de 10 ) em vez do possivelmente destina i = -10 (seja I -10)

Mesmo após a publicação do 1989, C padrão, por muitos anos K & R C ainda era considerado o "menor denominador comum" para que programadores C-se restrito quando a portabilidade máxima era desejada, uma vez que muitos compiladores mais velhos ainda estavam em uso, e porque cuidadosamente escrito K & R código C pode ser padrão legal C também.

Nas primeiras versões do C, apenas as funções que retornaram um não- int valor precisava ser declarada se usado antes da definição da função; uma função usada sem qualquer declaração anterior foi assumida para retornar tipo int , se o seu valor foi usado.

Por exemplo:

 longo some_function ();
 / * * Int / other_function ();
 
 / * * Int / calling_function ()
 {
     longo test1;
     registrar / * int * / test2;
 
     test1 = some_function ();
     if (test1> 0)
           Teste2 = 0;
     mais
           test2 = other_function ();
     retornar test2;
 }

Os int tipos específicos que são comentadas poderia ser omitida no K & R C, mas são necessárias em normas posteriores.

Desde declarações de função K & R não incluem qualquer informação sobre argumentos de função, parâmetro de função verificações de tipo não foram realizados, embora alguns compiladores iria emitir uma mensagem de aviso se uma função local foi chamado com o número errado de argumentos, ou se várias chamadas para uma função externa usado diferentes números ou tipos de argumentos. Ferramentas separadas, tais como Unix utilitário lint foram desenvolvidos que (entre outras coisas) pode verificar a consistência do uso de função em vários arquivos de origem.

Nos anos seguintes à publicação da K & R C, várias características não-oficiais foram adicionadas à linguagem, apoiada por compiladores da AT & T e alguns outros fornecedores. Estes incluíram:

  • void funções (ou seja, funções com nenhum valor de retorno)
  • funções que retornam struct ou union tipos (em vez de ponteiros)
  • atribuição para struct tipos de dados
  • tipos enumerados

O grande número de extensões e falta de acordo sobre um biblioteca padrão, juntamente com a popularidade língua e o facto de que nem mesmo o Unix compiladores implementado precisamente a especificação K & R, conduziu à necessidade de normalização.

ANSI C e ISO C

Durante o final dos anos 1970 e 1980, foram implementadas as versões do C para uma ampla variedade de computadores de grande porte, minicomputadores, e microcomputadores, incluindo o IBM PC, como a sua popularidade começou a aumentar significativamente.

Em 1983, o American National Standards Institute (ANSI) formou um comitê, X3J11, para estabelecer uma especificação padrão de C. X3J11 base o padrão C sobre a implementação do Unix; no entanto, a porção não-portáteis da biblioteca Unix C foi transferida para o IEEE 1003 grupo de trabalho para se tornar a base para 1988 Padrão POSIX. Em 1989, o padrão C foi ratificado como ANSI X3.159-1989 "Linguagem de Programação C". Esta versão da linguagem é muitas vezes referida como ANSI C, Standard C, ou às vezes C89.

Em 1990, o padrão ANSI C (com alterações de formatação) foi adoptada pelo International Organization for Standardization (ISO) como ISO / IEC 9899: 1990, que é às vezes chamado C90. Por conseguinte, os termos "C89" e "C90" referem-se a mesma linguagem de programação.

ANSI, como outros organismos nacionais de normalização, não mais se desenvolve o padrão C de forma independente, mas adia para o padrão internacional C, mantido pelo grupo de trabalho ISO / IEC JTC1 / SC22 / WG14. Adoção nacional de uma atualização para o padrão internacional ocorre tipicamente dentro de um ano da publicação ISO.

Um dos objectivos do processo de normalização C era produzir um super conjunto de K & R C, incorporando muitas das características não-oficiais subseqüentemente introduzidas. O comitê de padrões também incluiu várias funcionalidades adicionais, tais como protótipos de função (emprestado do C ++), void ponteiros, o apoio à internacional conjuntos de caracteres e locales e melhorias de pré-processamento. Apesar de sintaxe para declarações de parâmetro foi aumentado para incluir o estilo usado em C ++, o K & R de interface continuou a ser permitida, para compatibilidade com código fonte existente.

C89 é suportado por compiladores C actuais, ea maioria de código C sendo escrito hoje é baseado nele. Qualquer programa escrito apenas em Padrão C e sem quaisquer suposições dependentes de hardware será executado corretamente em qualquer plataforma com uma implementação C em conformidade, dentro de seus limites de recursos. Sem tais precauções, os programas podem compilar apenas numa determinada plataforma ou com um compilador particular, devido, por exemplo, com a utilização de bibliotecas de não-padrão, como o Bibliotecas GUI, ou para uma dependência de atributos específicos de plataforma ou compiler- tais como o tamanho exato de tipos de dados e byte endianness.

Nos casos em que o código deve ser compilable tanto por compiladores ou baseadas em C K & R conforme padrão-, o __STDC__ macro pode ser usada para dividir o código em seções padrão e K & R para evitar o uso de um compilador baseado no C K & R de recursos disponíveis somente em Padrão C.

C99

Após o processo de padronização ANSI / ISO, a especificação da linguagem C manteve-se relativamente estático durante vários anos. Em 1995 Normativa Alteração 1 para o 1990 C padrão (ISO / IEC 9899 / AMD1: 1995, conhecido informalmente como C95) foi publicado, para corrigir alguns detalhes e para adicionar mais amplo suporte para conjuntos de caracteres internacionais. O padrão C foi posteriormente revisto no final de 1990, levando à publicação da norma ISO / IEC 9899: 1999 em 1999, que é comumente referido como " C99 ". Desde então, foi alterado três vezes por corrigenda técnica.

C99 introduziu vários novos recursos, incluindo funções embutidas, vários novos tipos de dados (incluindo long long int e um complex tipo para representar números complexos ), matrizes de comprimento variável, suporte melhorado para IEEE 754 de ponto flutuante, para apoiar macros variádicos (macros de variável arity), e suporte para uma linha Comentários começam com // , como em BCPL ou C ++. Muitos deles já haviam sido implementadas como extensões em vários compiladores C.

C99 é em sua maior parte compatível com C90, mas é mais rigorosa em alguns aspectos; em particular, a declaração de que carece de um especificador de tipo já não tem int implicitamente assumido. A macro padrão __STDC_VERSION__ é definido com valor 199901L para indicar que o apoio C99 está disponível. GCC, Solaris Studio, e outros compiladores C agora suporta muitos ou todos os novos recursos do C99.

C11

Em 2007, iniciou-se uma nova revisão do padrão C, informalmente chamado de "C1X" até a sua publicação oficial, em 2011-12-08. O comitê de padrões C aprovou directrizes para limitar a adoção de novas funcionalidades que não tinham sido testadas por implementações existentes.

O padrão C11 acrescenta vários novos recursos para C ea biblioteca, incluindo macros tipo genérico, estruturas anônimas, melhorou o suporte a Unicode, operações atômicas, multi-threading e funções barrancos-verificados. Também faz algumas porções da biblioteca de C99 existente opcional, e melhora a compatibilidade com C ++.

Embutido C

Historicamente, a programação C incorporado requer extensões fora do padrão para a linguagem C, a fim de oferecer suporte a recursos exóticos, como aritmética de ponto fixo, vários bancos de memória distintas, e as operações básicas de E / S.

Em 2008, o Comitê de Padrões C publicou um relatório técnico estender a linguagem C para abordar estas questões, fornecendo um padrão comum para todas as implementações de aderir. Ele inclui um número de características não disponíveis em C normais, tais como aritmética de ponto fixo, espaços de endereços nomeados, e hardware de base I / O endereçamento.

Sintaxe

C tem um gramática formal especificado pelo padrão C. Ao contrário de linguagens como Fortran 77, o código fonte C é de forma livre que permite o uso arbitrário de espaços em branco para formatar o código, em vez de restrições baseadas em linha de texto baseado na coluna ou. Comentários podem aparecer entre os delimitadores /* e */ , ou (desde C99) seguinte // até que o fim da linha. Comentários delimitados por /* e */ não ninho, e essas seqüências de caracteres não são interpretados como delimitadores de comentários se eles aparecem dentro cordas ou caracteres literais.

Arquivos de origem C contém declarações e definições de função. As definições de função, por sua vez, contêm declarações e declarações. Declarações quer definir novos tipos usando palavras-chave como struct , union , e enum , ou atribuir tipos de armazenamento e talvez reserva para novas variáveis, geralmente por escrito o tipo seguido pelo nome da variável. Palavras-chave, tais como char e int especificar tipos built-in. Seções de código são colocados entre chaves ( { e } , às vezes chamado de "chaves") de limitar o âmbito das declarações e agir como uma única instrução para estruturas de controle.

Como uma linguagem imperativa, C usa instruções para especificar ações. A indicação mais comum é uma indicação da expressão, que consiste de uma expressão a ser avaliada, seguido por um ponto e vírgula; como um efeito colateral da avaliação, as funções podem ser chamado e variáveis podem ser atribuídos novos valores. Para modificar a execução sequencial normal de declarações, C oferece várias instruções de controle de fluxo identificadas por palavras-chave reservadas. Programação estruturada é suportado por if (- else ) execução condicional e por do - while , while , e for a execução iterativo (looping). O for declaração tem de inicialização separado, testes e expressões de reinicialização, qualquer uma ou todas das quais podem ser omitidos. break e continue pode ser usado para deixar a instrução de loop mais interno ou pular para a sua reinicialização. Há também um não-estruturada goto declaração que se ramifica diretamente para a designada etiquetar no interior da função. switch selecciona um case a ser executado com base no valor de uma expressão inteira.

As expressões podem usar uma variedade de operadores nativos e podem conter chamadas de função. A ordem em que os argumentos para funções e operandos para a maioria dos operadores são avaliados não é especificado. As avaliações podem ainda ser intercalada. No entanto, todos os efeitos secundários (incluindo o armazenamento de variáveis) irá ocorrer antes da próxima " ponto de seqüência ", pontos de seqüência incluem o final de cada instrução de expressão, ea entrada e retorno de cada chamada de função pontos de seqüência também ocorrer durante a avaliação de expressões que contêm determinados operadores (. && , || , ?: eo operador vírgula). Isto permite um alto grau de otimização de código objeto pelo compilador, mas requer programadores C tomar mais cuidado para se obter resultados confiáveis do que é necessário para outras linguagens de programação.

Kernighan e Ritchie diz na introdução da linguagem de programação C: "C, como qualquer outra língua, tem seus defeitos Alguns dos operadores tem a precedência errado, algumas partes da sintaxe poderia ser melhor.". O padrão C não tentou corrigir muitas destas manchas, devido ao impacto de tais alterações no software já existente.

Conjunto de caracteres

O conjunto básico C caráter fonte inclui os seguintes caracteres:

  • Cartas: a - z , A - Z , _
  • Dígitos: 0 - 9
  • Pontuação: ~ ! @ # % ^ & * ( ) - + = : ; " ' < > , . ? | / \ { } [ ] ~! @ #% ^ & * () - + =:; " ' < > , . ? | / \ { } [ ]
  • Caracteres em branco: espaço, guia horizontal, guia vertical, alimentação de formulário, nova linha

Nova linha indica o final de uma linha de texto; não precisa corresponder a um personagem real único, embora por conveniência C trata-o como um.

Pode ser utilizado de vários bytes adicionais caracteres codificados, mas não são portátil. O mais recente padrão C ( C11) permite multinacional Caracteres Unicode para ser incorporado dentro portably C texto original usando um \u DDDD codificação (onde DDDD indica um código de caracteres Unicode), embora esse recurso ainda não é amplamente aplicada.

O conjunto básico C caráter de execução contém os mesmos personagens, juntamente com representações para alerta, backspace, e retorno de carro. Apoio em tempo de execução para conjuntos de caracteres estendidos tem aumentado a cada revisão do padrão C.

Palavras-chave

C89 tem 32 palavras-chave (palavras reservadas com significado especial):

automático
parar
caso
carbonizar
const
continuar
padrão
Faz
duplo
outro
enum
extern
flutuador
para
vá para
E se
int
grandes
registrar
Retorna
baixo
assinado
tamanho de
estático
struct
interruptor
typedef
união
não assinado
vazio
volátil
enquanto

C99 acrescenta mais cinco palavras-chave:

_Bool
_Complex
_Imaginary
em linha
restringir

C11 acrescenta mais sete palavras-chave:

_Alignas
_Alignof
_Atomic
_Generic
_Sem Retorno
_Static_assert
_Thread_local

A maioria das palavras-chave adicionadas recentemente começar com um sublinhado seguido por uma letra maiúscula, porque os identificadores de que forma foram previamente reservado pelo padrão C para uso somente por implementações. Desde código fonte do programa existente não deveria ter vindo a utilizar esses identificadores, não seriam afetados quando as implementações de C começou a apoiar essas extensões para a linguagem de programação. Alguns cabeçalhos padrão definir sinônimos fazer mais convenientes para identificadores sublinhados. A linguagem utilizada para incluir uma palavra-chave reservada chamada entry , mas isso nunca foi implementado e agora foi removido como uma palavra reservada.

Operadores

C suporta um conjunto rico de operadores, que são símbolos usados dentro de um expressão para especificar as manipulações para ser executada ao mesmo tempo que avaliar a expressão. C tem operadores para:

  • aritmética : + , - , * , / , %
  • atribuição: =
  • atribuição aumentada: += , -= , *= , /= , %= , &= , |= , ^= , <<= , >>=
  • bitwise lógica: ~ , & , | , ^
  • turnos bit a bit: << , >>
  • lógica booleana: ! , && , ||
  • avaliação condicional: ? :
  • teste de igualdade: == , !=
  • chamar funções: ( )
  • incremento e decremento: ++ , --
  • seleção de membro: . , ->
  • tamanho do objeto: tamanho de
  • relações de ordem: < , <= , > , >=
  • referência e dereference: & , * , [ ]
  • seqüenciamento: ,
  • subexpression agrupamento: ( )
  • conversão de tipo: ( typename )

C usa o = operador, reservados em matemática para expressar a igualdade, para indicar atribuição, seguindo o precedente de Fortran e PL / I, mas ao contrário ALGOL e seus derivados. A semelhança entre o operador de C para a atribuição e que a igualdade ( == ) tem sido criticado, pois torna mais fácil de substituir acidentalmente um para o outro. Em muitos casos, cada um deles pode ser utilizado no contexto da outra sem um erro de compilação (embora alguns compiladores produzem avisos). Por exemplo, a expressão condicional no if(a=b+1) é verdadeiro se a não é zero após a atribuição. Para além disso, C de precedência do operador é não-intuitivo, como == ligação com mais força do que & e | em expressões como x & 1 == 0 , que teriam de ser escritos (x & 1) == 0 para ser devidamente avaliado.

"Olá, mundo" exemplo

O " Olá, mundo "exemplo, que apareceu na primeira edição do K & R, tornou-se o modelo para um programa de introdução na maioria dos livros de programação, independentemente da linguagem de programação. O programa imprime "Olá, mundo" para o saída padrão, que geralmente é uma tela do terminal ou na tela.

A versão original foi:

 main ()
 {
     printf ("Olá, mundo \ n");
 }

Um padrão conformes "Olá, mundo" programa é:

 #include 
 
 int main (void)
 {
     printf ("Olá, mundo \ n");
 }

A primeira linha do programa contém um diretiva de pré-processamento, indicado por #include . Isto faz com que o compilador para substituir a linha com todo o texto da stdio.h cabeçalho padrão, que contém declarações para as funções de entrada e saída padrão, tais como printf . Os suportes angulares em torno stdio.h indicam que stdio.h situa-se utilizando uma estratégia de pesquisa que prefere cabeçalhos padrão para outros cabeçalhos com o mesmo nome. (As aspas duplas são usadas para incluir arquivos de cabeçalho ou locais específicos do projeto.)

A linha seguinte indica que uma função chamada main está sendo definida. O main função serve a um propósito especial em programas em C; o ambiente de tempo de execução chama a main função para iniciar a execução do programa. O tipo especificador int indica que o valor que é devolvido para o chamador (neste caso, o ambiente de tempo de execução) como um resultado de se avaliar a main função, é um número inteiro. A palavra-chave void como uma lista de parâmetros indica que esta função não tem argumentos.

A chave de abertura indica o início da definição do main função.

A próxima linha chama (desvia a execução a) uma função chamada printf , que é fornecido a partir de um sistema biblioteca. Nesta chamada, o printf função é passada (fornecido) com um único argumento, o endereço do primeiro caractere na string literal "hello, world\n" . A string literal é um sem nome matriz com elementos do tipo char , criado automaticamente pelo compilador com um caractere final 0-valorizado para marcar o fim do array ( printf precisa saber disso). O \n é uma seqüência de escape que se traduz em um C nova linha de caracteres, o qual na saída significa o fim da linha corrente. O valor de retorno do printf função é do tipo int , mas é descartado silenciosamente, uma vez que não é utilizado. (Um programa mais cuidadosa pode testar o valor de retorno para determinar se ou não o printf função com êxito.) O ponto e vírgula ; finaliza o comunicado.

A chave de fechamento indica o fim do código para a main função. De acordo com a especificação do C99 e mais recente, main implicitamente retornar um status 0 ao atingir o} que termina a função. Isto é interpretado pelo sistema em tempo de execução como um código de saída indica execução bem-sucedida.

Os tipos de dados

C tem um estático tipagem fraca Tipo de sistema que compartilha algumas semelhanças com a de outro ALGOL descendentes, tais como Pascal. Há built-in tipos de inteiros de vários tamanhos, ambos assinados e não assinados, números de ponto flutuante, personagens e tipos enumerados ( enum ). C99 acrescentou um tipo de dados boolean. Há também os tipos derivados, incluindo matrizes, ponteiros, (registros struct ), e não marcado sindicatos ( union ).

C é frequentemente usado em programação de sistemas de baixo nível onde escapa do sistema de tipo pode ser necessária. O compilador tenta assegurar tipo correção da maioria das expressões, mas o programador pode substituir os cheques de várias maneiras, usando um digite converter para converter explicitamente um valor a partir de um tipo para outro, ou usando ponteiros ou sindicatos para reinterpretar os bits subjacentes de um objeto de dados de alguma outra forma.

Alguns acham sintaxe de declaração de C unintuitive, particularmente para ponteiros de função. (A idéia de Ritchie foi declarar identificadores em contextos que assemelham-se a sua utilização: " declaração reflete o uso ".)

Conversões aritméticas usuais de C para permitir que código eficiente a ser gerado, mas às vezes pode produzir resultados inesperados. Por exemplo, uma comparação de inteiros assinados e não assinados de igual largura requer uma conversão do valor assinado para não assinado. Isto pode gerar resultados inesperados se o valor assinado é negativo.

Ponteiros

C suporta o uso de ponteiros, um tipo de referência que registra o endereço ou localização de um objeto ou função na memória. Ponteiros podem ser dereferenced para acessar os dados armazenados no endereço apontado, ou para invocar um apontado para funcionar. Ponteiros podem ser manipulados usando cessão ou aritmética de ponteiro. A representação de tempo de execução de um valor de ponteiro é tipicamente um endereço de memória em bruto (talvez agravado por um campo de compensar-dentro-palavra), mas desde o tipo de um ponteiro inclui o tipo da coisa apontada, expressões, incluindo ponteiros pode ser verificado de tipo em tempo de compilação. Aritmética de ponteiro é automaticamente ajustada por o tamanho da a-aguçado tipo de dados. Os ponteiros são usados para diversos fins em C. Cadeias de texto são comumente manipulados usando ponteiros para arrays de caracteres. Alocação dinâmica de memória é realizada usando ponteiros. Muitos tipos de dados, tais como árvores, são comumente implementado como alocação dinâmica struct objetos ligados entre si usando ponteiros. Ponteiros para funções são úteis para passar funções como argumentos para funções de ordem superior (por exemplo, qsort ou bsearch) ou como retornos de chamada a ser invocadas pelos manipuladores de eventos.

A valor de ponteiro nulo explicitamente aponta para nenhum local válido. Dereferencing um valor de ponteiro nulo é indefinido, muitas vezes resultando em uma falha de segmentação. Valores ponteiro nulo são úteis para indicar casos especiais, como no "próximo" ponteiro no nó final de uma lista ligada, ou como uma indicação de erro de funções que retornam ponteiros. Em contextos apropriados em código fonte, tais como, por atribuição de um ponteiro variável, uma constante de ponteiro nulo pode ser escrito como 0 , com ou sem conversão explícita para um tipo de ponteiro, ou como o NULL macro definida por vários cabeçalhos padrão. Em contextos condicionais, os valores de ponteiro nulo avaliar como false, enquanto todos os outros valores de ponteiro avaliar a verdade.

Ponteiros void ( void * ) apontam para objetos do tipo não especificado, e pode, portanto, ser usado como ponteiros de dados "genéricos". Desde o tamanho eo tipo do ponteiro aritmética apontou-a objeto não é conhecido, ponteiros void não pode ser dereferenced, nem é sobre eles autorizados, embora eles podem facilmente ser (e em muitos contextos implicitamente são) convertido de e para qualquer outro objeto ponteiro escreva.

O uso descuidado de ponteiros é potencialmente perigosa. Porque eles são tipicamente controlada, uma variável de ponteiro pode ser feita para apontar para qualquer localização arbitrária, que pode causar efeitos indesejáveis. Embora ponteiros corretamente utilizados apontam para lugares seguros, eles podem ser feitas para apontar para locais inseguros usando inválido aritmética de ponteiro; os objetos que apontam para pode ser desalocada e reutilizada ( ponteiros oscilantes); eles podem ser utilizados sem ter sido inicializado ( ponteiros selvagens); ou podem ser atribuídos diretamente um valor inseguro usando um molde, união, ou através de outro ponteiro corrupto. Em geral, C é permissiva em permitindo a manipulação de e conversão entre tipos de ponteiro, embora compiladores normalmente fornecem opções para vários níveis de verificação. Algumas outras linguagens de programação resolver esses problemas usando mais restritiva tipos de referência.

Arrays

Tipos de matrizes em C são, tradicionalmente, de, um tamanho estático fixo especificado em tempo de compilação. (A recente padrão C99 mais também permite uma forma de matrizes de comprimento variável.) No entanto, também é possível alocar um bloco de memória (de tamanho arbitrário) em tempo de execução, utilizando a biblioteca padrão malloc função, e tratá-lo como uma matriz. Unificação do C de arrays e ponteiros meios que declarou matrizes e essas matrizes simulados atribuídos dinamicamente são praticamente intercambiáveis.

Desde matrizes são sempre acessado (em vigor) através de ponteiros, os acessos de matriz geralmente não são verificadas em relação ao tamanho da matriz subjacente, embora alguns compiladores podem fornecer verificação de limites como uma opção. Violações de limites de matriz são, portanto, possível e bastante comum no código escrito sem cuidado, e pode levar a várias repercussões, incluindo memória acessa ilegal, corrupção de dados, estouros de buffer e exceções de tempo de execução. Se a verificação de limites é desejado, ele deve ser feito manualmente.

C não tem uma disposição especial para declarar arrays multidimensionais, mas sim depende de recursão dentro do sistema de tipo para declarar arrays de arrays, o que efetivamente realiza a mesma coisa. Os valores do índice da "matriz multidimensional" resultante pode ser pensado como o aumento em linha principal ordem.

Matrizes multidimensionais são comumente utilizados em algoritmos numéricos (principalmente a partir aplicada álgebra linear ) para armazenar as matrizes. A estrutura da matriz C é bem adequado para esta tarefa particular. No entanto, já que matrizes são passados apenas como ponteiros, os limites da matriz deve ser conhecido valores fixos ou então explicitamente passado para qualquer sub-rotina que lhes exige, e matrizes de tamanho de forma dinâmica de matrizes não podem ser acessados usando dupla indexação.(A solução para isso é para alocar a matriz com um "vetor linha" adicional de ponteiros para as colunas.)

C99 introduziu "matrizes de comprimento variável" que abordam alguns, mas não todos, dos problemas com matrizes C comuns.

Ponteiro-array permutabilidade

O índice notação x [i] (onde x designa um ponteiro) é um açúcar sintático para * (X + i) . Aproveitando o conhecimento do compilador do tipo de ponteiro, o endereço que x + i aponta para é não o endereço de base (apontada por x ) incrementado em Eu bytes, mas é definida como sendo o endereço base incrementado por Eu multiplicada pelo tamanho de um elemento que x pontos para.

Além disso, na maioria dos contextos de expressão (a exceção notável é como operando de tamanho de ), o nome de uma matriz é automaticamente convertido para um ponteiro para primeiro elemento da matriz; assim, para uma matriz declarada com o nome UMA , A [i] designa o i + 1 º elemento da matriz. Isto também implica que uma disposição nunca é copiado como um todo, quando chamado como um argumento para uma função, mas sim apenas o endereço de seu primeiro elemento é passado. Portanto, apesar de chamadas de função em uso C passar por valor semântica, as matrizes são de fato passado por referência.

O tamanho de um elemento pode ser determinada aplicando o operador tamanho de a qualquer elemento de não referenciado x , como em n = sizeof * x ou n = sizeof X [0] , e o número de elementos em uma matriz declarada UMA pode ser determinada como sizeof A / sizeof A [0] . O último única aplica-se a nomes de arrays: variáveis ​​declaradas com subscritos ( A int [20] ). Devido à semântica do C, não é possível determinar o tamanho total de matrizes através de ponteiros para arrays ou aqueles criados por alocação dinâmica ( malloc ); de código, tais como sizeof arr / sizeof arr [0] (em que arr = A designa um ponteiro) não irá funcionar desde que o compilador assume o tamanho do ponteiro em si está a ser solicitada. Desde argumentos de nome de matriz para tamanho de não são convertidos em ponteiros, eles não apresentam essa ambiguidade. No entanto, as matrizes criadas pela alocação dinâmica são inicializados com ponteiros em vez de variáveis ​​de matriz verdadeiras, então eles sofrem dos mesmos tamanho de problemas como ponteiros de matriz.

Assim, apesar de esta equivalência aparente entre variáveis ​​de matriz e o ponteiro, ainda há uma distinção a ser feita entre elas. Mesmo que o nome de uma matriz é, na maior parte dos contextos de expressão, convertido em um ponteiro (para o primeiro elemento), este indicador não ocupam qualquer armazenamento em si; o nome da matriz não é um lvalue, e seu endereço é uma constante , ao contrário de uma variável ponteiro. Por conseguinte, o que é uma matriz "aponta para" não pode ser mudado, e é impossível atribuir um novo endereço para um nome de matriz. Conteúdo da matriz pode ser copiado, no entanto, usando a memcpy função, ou acessando os elementos individuais.

Gerenciamento de memória

Uma das funções mais importantes de uma linguagem de programação é proporcionar facilidades para o gerenciamento de memória e os objetos que estão armazenados na memória. C oferece três maneiras distintas para alocar memória para objetos:

  • Alocação de memória estática: espaço para o objeto é fornecido no binário em tempo de compilação; estes objectos têm uma extensão (ou tempo de vida), enquanto o binário que contém lhes é carregado na memória.
  • Alocação de memória automática: objetos temporários podem ser armazenados napilha, e este espaço é automaticamente liberado e reutilizável após o bloco em que elas são declaradas é encerrado.
  • Alocação dinâmica de memória: blocos de memória de tamanho arbitrário pode ser solicitado em tempo de execução usando funções de biblioteca, tais como malloc a partir de uma região de memória chamado de heap; estes blocos persistir até que posteriormente liberado para reutilização chamando a função de biblioteca realloc ou livre

Estas três abordagens são apropriadas em situações diferentes e têm várias vantagens e desvantagens. Por exemplo, a alocação de memória estática tem pouca sobrecarga de alocação, alocação automática pode envolver um pouco mais em cima, e alocação dinâmica de memória pode, potencialmente, ter uma grande quantidade de sobrecarga tanto para alocação e desalocação. A natureza persistente de objetos estáticos é útil para manter informações de estado através de chamadas de função, atribuição automática é fácil de usar, mas espaço de pilha é tipicamente muito mais limitado e transitório do que qualquer memória estática ou espaço de pilha e alocação de memória dinâmica permite a alocação conveniente de objetos cujas tamanho é conhecido apenas em tempo de execução. A maioria dos programas em C fazem uso extensivo de todos os três.

Sempre que possível, a atribuição automática ou estática é geralmente mais simples, porque o armazenamento é gerenciado pelo compilador, liberando o programador da tarefa potencialmente sujeito a erros de alocação e liberação de armazenamento manualmente. No entanto, muitas estruturas de dados pode mudar de tamanho em tempo de execução, e desde que as alocações estáticas (e alocações automáticas antes C99) deve ter um tamanho fixo em tempo de compilação, há muitas situações em que a alocação dinâmica é necessária. Antes do padrão C99, matrizes de tamanho variável foram um exemplo comum disso. (Veja o artigo sobre malloc um exemplo de matrizes alocadas dinamicamente.) Ao contrário de alocação automática, que pode falhar em tempo de execução com consequências incontroláveis, as funções de alocação dinâmica retornar uma indicação (sob a forma de um valor de ponteiro nulo), quando o armazenamento necessário não pode ser alocado. (Alocação estática que é muito grande é normalmente detectada pelo ligante ou carregador, antes de o programa pode até mesmo começar a execução.)

Salvo disposição em contrário, objetos estáticos conter zero ou nulos valores de ponteiro na inicialização do programa. Objetos automaticamente e dinamicamente alocados são inicializados somente se um valor inicial é especificado explicitamente; caso contrário, eles inicialmente ter valores indeterminados (tipicamente, qualquer que seja o padrão do bit passa a estar presente no armazenamento, que pode até não representam um valor válido para o tipo). Se o programa tenta acessar um valor não inicializado, os resultados são indefinidos. Muitos compiladores modernos tentam detectar e alertar sobre este problema, mas ambos os falsos positivos e falsos negativos podem ocorrer.

Outra questão é que a atribuição de memória heap tem de ser sincronizado com o seu uso real em qualquer programa para que ele seja reutilizado, tanto quanto possível. Por exemplo, se o único ponteiro para uma alocação de memória heap sai do escopo ou tiver seu valor substituído antes free () é chamado, em seguida, que a memória não pode ser recuperado para reutilização posterior e é essencialmente perdeu para o programa, um fenômeno conhecido como uma fuga de memória. Por outro lado, é possível para a memória para ser libertado, mas continuam a ser referenciado, levando a resultados imprevisíveis. Normalmente, os sintomas aparecerão em uma parte do programa distante do erro real, o que torna difícil rastrear o problema. (Essas questões são melhorados em línguas com coleta de lixo automática.)

Bibliotecas

A linguagem de programação C utiliza bibliotecas como seu principal método de extensão. Em C, uma biblioteca é um conjunto de funções contidas em um único arquivo "arquivo". Cada biblioteca tem, tipicamente, um ficheiro de cabeçalho, o qual contém os protótipos das funções contidas dentro da biblioteca que pode ser utilizado por um programa, e declarações de tipos de dados especiais e símbolos usados ​​macro com estas funções. Para que um programa para usar uma biblioteca, ele deve incluir arquivo de cabeçalho da biblioteca, a biblioteca e deve ser vinculado com o programa, que em muitos casos requer sinalizadores de compilador (por exemplo, -lm , abreviação de "biblioteca de matemática").

A biblioteca mais comum C é a biblioteca padrão C, que é especificado pelos ISO e normas ANSI C e vem com todas as implementações C. (Implementações que têm como alvo ambientes limitados, tais como sistemas embarcados podem fornecer apenas um subconjunto da biblioteca padrão). Esta biblioteca suporta a entrada de fluxo e de saída, de alocação de memória, matemática, cadeias de caracteres, e valores de tempo. Vários cabeçalhos padrão separadas (por exemplo, stdio.h ) especifica as interfaces para essas e outras instalações da biblioteca padrão.

Outro conjunto comum de funções de biblioteca C são aqueles usados ​​por aplicativos especificamente orientadas para Unix e sistemas Unix-like, especialmente funções que proporcionam uma interface para o kernel. Estas funções são detalhadas em vários padrões como POSIX e do Single UNIX Specification.

Uma vez que muitos programas foram escritos em C, há uma grande variedade de outras bibliotecas disponíveis. Bibliotecas são muitas vezes escritos em C, porque compiladores C gerar eficiente código de objeto; programadores, em seguida, criar interfaces para a biblioteca para que as rotinas podem ser utilizados a partir de linguagens de alto nível como Java , Perl , e Python .

Ferramentas de idioma

Ferramentas foram criados para ajudar os programadores C evitar alguns dos problemas inerentes à linguagem, tais como declarações com um comportamento indefinido ou declarações que não são uma boa prática, porque eles são susceptíveis de resultar em um comportamento intencional ou tempo de execução erros.

Automatizado fonte código de verificação e auditoria são benéficos em qualquer idioma, e para C existem muitas dessas ferramentas, tais como Lint. Uma prática comum é usar Lint para detectar código questionável quando um programa é escrito em primeiro lugar. Uma vez que um programa passa Lint, é então compilado usando o compilador C. Além disso, muitos compiladores podem opcionalmente alertar sobre construções sintaticamente válidos que são susceptíveis de ser realmente erros. MISRA C é um conjunto proprietário de orientações para evitar tal código questionável, desenvolvido para sistemas embarcados.

Há também compiladores, bibliotecas e mecanismos de nível de sistema operacional para executar ações que não são uma parte padrão de C, tais como limites de matriz verificação,detecção de estouro de buffer,serialização ecoleta de lixo automática.

Ferramentas como oPurify ouValgrind e vinculação com bibliotecas contendo versões especiais dasfunções de alocação de memória pode ajudar a descobrir erros de execução no uso de memória.

Usos

C é muitas vezes usada para " programação do sistema ", incluindo a implementação de sistemas operacionais e aplicações de sistemas embarcados, devido a uma combinação de características desejáveis, como a portabilidade de código e eficiência, capacidade de acesso a endereços de hardware específicas, capacidade de trocadilho tipos de combinar acesso a dados impostos externamente requisitos e baixa demanda de tempo de execução dos recursos do sistema. C também pode ser usado para a programação de site usando CGI como uma "porta de entrada" para informações entre o aplicativo Web, o servidor eo navegador. Algumas razões para a escolha de C sobre linguagens interpretadas são sua velocidade, estabilidade e disponibilidade quase universal.

Uma conseqüência da ampla disponibilidade e eficiência de C é que compiladores, bibliotecas e intérpretes deoutraslinguagens de programação são freqüentemente implementados em C. As principais implementações doPython(CPython),Perl5 ePHP são todos escritos em C.

Devido à sua fina camada de abstração e baixa sobrecarga, C permite implementações eficientes de algoritmos e estruturas de dados, o que é útil para programas que executam uma série de cálculos. Por exemplo, a GNU Multi-Precision Biblioteca, oGNU Scientific Library,Mathematica eMATLAB são completamente ou parcialmente escrito em C.

C é por vezes utilizado como uma linguagem intermediária por implementações de outras línguas. Esta abordagem pode ser utilizada para a portabilidade ou de conveniência; usando C como uma linguagem intermediária, não é necessário o desenvolvimento de geradores de códigos específicos da máquina. C tem algumas características, como a linha-número pré-processamento diretivas e vírgulas supérfluos opcionais no final das listas de inicializador, que oferecem suporte a compilação de código gerado. No entanto, algumas deficiências de C ter solicitado o desenvolvimento de outras linguagens baseadas em C concebidos especificamente para utilização como línguas intermediárias, tais como C--.

C também tem sido amplamente utilizada para implementaraplicativos de usuário final, mas muito do que o desenvolvimento deslocou-se para novas linguagens.

Línguas relacionadas

C tem, directa ou indirectamente influenciadas muitas línguas posteriores, como C #, D, Go, Java , JavaScript, Limbo, LPC, Perl , PHP, Python , e Unix C Shell. A influência mais penetrante tem sido sintática: todas as línguas mencionadas combinar a declaração e (mais ou menos reconhecível) expressão sintaxe do C com sistemas do tipo, modelos de dados e / ou estruturas de programas de grande escala que diferem dos de C, às vezes radicalmente .

Existem vários intérpretes C-C ou próximo, incluindoCh eCINT, que também pode ser usado para scripting.

Quando linguagens orientadas a objeto tornou-se popular, C ++ e Objective-C foram duas extensões diferentes de C que forneceu as capacidades orientadas a objetos. Ambas as línguas foram originalmente implementado como fonte-a-fonte compiladores; código-fonte foi traduzido para o C, e em seguida, compilado com um compilador C.

O C ++ linguagem de programação foi elaborado por Bjarne Stroustrup como uma abordagem para fornecer funcionalidade orientada a objetos com a sintaxe C-like. C ++ acrescenta mais força digitação, escopo, e outras ferramentas úteis na programação orientada a objeto e permite a programação genérica através de modelos. Quase um super conjunto de C, C ++ agora oferece suporte a mais de C, com algumas exceções (ver Compatibilidade de C e C ++).

Objective-C foi originalmente uma camada muito "magro" em cima de C, e continua a ser um super rigoroso de C que permite a programação orientada a objetos usando uma dinâmica de digitação paradigma híbrido / estática. Objective-C deriva sua sintaxe do C e Smalltalk: sintaxe que envolve o pré-processamento, expressões, declarações de função e função chamadas é herdado do C, enquanto a sintaxe para recursos orientados a objetos provém originalmente do Smalltalk.

Além deC ++e Objective-C, Ch,Cilk eUnified Parallel C são quase supersets de C.

Retirado de " http://en.wikipedia.org/w/index.php?title=C_(programming_language)&oldid=556129868 "