Unixtopia

main/ artigos/

C

É uma linguagem compilada, imperativa, estaticamente tipada, estruturada, low-level, rápida, eficiente e possivelmente a linguagem mais comumente usada por programadores minimalistas, incluindo SMR. Embora por padrões muito rígidos ainda seja considerada bloated, comparada a qualquer linguagem moderna convencional, é muito bem otimizada, culturalmente estabelecida e estável, é a linguagem preferida da comunidade suckless, bem como da maioria dos especialistas como desenvolvedores do OpenBSD, devido ao seu design simples, desempenho incontestável, amplo suporte, grande número de compiladores, alto nível de controle e um status de linguagem testada e estabelecida. C não pertence as linguagens minimalistas como Forth, Lisp e Brainfuck, mas está entre os tipos de linguagens tradicionais. C é a linguagem mais importante da história, influenciou basicamente todas as linguagens amplamente utilizadas hoje, como C++, Java e JavaScript, mas não é uma relíquia, ainda é usada ativamente, na área de programação de baixo nível, C provavelmente ainda é a linguagem insuperável. C não é de forma alguma perfeita ou elegante matematicamente, mas é uma das melhores escolhas práticas de uma linguagem de programação.

Normalmente não é considerada uma linguagem fácil de aprender por causa de sua natureza low-level e alto controle, oportunidades de foder, requer um bom entendimento de como um computador funciona no nível mais baixo e não impede que o programador atire no próprio pé. O programador recebe controle total e, portanto, responsabilidade. Há coisas consideradas complicadas das quais é preciso estar ciente, como comportamento indefinido de certos operadores ou gerenciamento manual de memória.Isso pode desencorajar muitos retardados de Java de escolher C, mas também é o que inevitavelmente permite um desempenho bom, comportamento indefinido permite que o compilador escolha a implementação mais eficiente. C é simples, sem conceitos modernos de merda como POO, e não é difícil de aprender, mas sim de dominar, como qualquer outra arte verdadeira. Em qualquer caso, você tem que aprender C, mesmo que não planeje programar regularmente, é a língua franca da programação, você encontrará C em muitos lugares e terá que pelo menos entendê-la, os programadores muitas vezes usam C em vez de pseudocódigo para explicar algoritmos, C é usado para otimizar partes críticas mesmo em projetos não C, muitas linguagens compilam para C, C é tudo e você tem que entendê-lo como entende sua língua.

Algumas de suas características típicas é a utilização abundante do pré-processador, macros, #ifdef por todo o lugar que modificam o código antes da compilação. Isso é usado principalmente para configuração em tempo de compilação ou obtenção de melhor desempenho e para portabilidade. Ponteiros, acesso direto à memória, usado para alocação de memória, mas se você for um ooper, é um tiro no próprio pé, obtendo vazamentos de memória e comportamentos indefinidos, muitas coisas são propositalmente deixadas indefinidas em C para permitir que os compiladores sejam eficientes, mas leva a bugs estranhos ou o programa funcionar em uma máquina, mas não em outra. Então C requer algum conhecimento de sua especificação. Pode-se encontrar declarações de tipo complicadas como void (*float(int,void (*n)(int)))(int).

Ao contrário de linguagens modernas, C não oferece funcionalidades como exibir gráficos, trabalhar com rede, obter estado bruto do teclado e assim por diante. A linguagem base nem mesmo tem I/O, é um processador puro de valores na memória. A biblioteca padrão oferece fluxos de I/O padrão, manipulação de arquivos, manipulação de strings, manipulação de tempo, avaliação de funções matemáticas e outras coisas, para algo mais avançado você precisará de uma biblioteca externa como SDL ou definidas pelo POSIX. C é um Assembly portátil, não apenas porque é low-level e possui alto desempenho, mas também porque muitas linguagens escolhem compilar para C em vez de compilar para Assembly. Embora C seja estruturado, tem estruturas de controle como ramificações e loops, e possa ser usado com high-level, é possível escrever código semelhante ao Assembly que opera diretamente com bytes na memória por meio de ponteiros sem mecanismos de segurança, então é frequentemente usado para escrever coisas como drivers de hardware. Alguns se abstêm de comparar C com assembly porque os compiladores ainda realizam muitas transformações do código e o que você escreve não é necessariamente sempre o que obtém.

O consenso reconhece que C está entre as melhores linguagens para escrever código low-level e que requer desempenho, como sistemas operacionais, drivers ou jogos. Até mesmo bibliotecas científicas com interfaces de linguagem normie, como várias bibliotecas Python de aprendizado de máquina, geralmente têm o núcleo crítico de desempenho escrito em C. Normies dirão que fora desse escopo C não é uma boa linguagem, que discordamos. Recomendamos usar para tudo que deve durar, se você quiser escrever um website dinâmico, provavelmente deve escrevê-lo em C. C ser low-level depende do contexto. Antigamente, quando a maioria dos computadores era programada em Assembly, C era visto como high-level, simplesmente porque oferecia o mais alto nível de abstração na época, enquanto hoje em dia, com linguagens como Python e JavaScript, as pessoas veem C como de nível muito baixo em comparação, então realmente depende se você fala sobre C no contexto de programação antiga ou moderna e com quais linguagens você compara. Também depende de como você programa em C, você pode escolher imitar bastante a programação Assembly em C, evitar usar bibliotecas, tocar diretamente no hardware, evitar usar recursos complexos e criar suas próprias abstrações. Você pode emular o estilo de programação high-level moderno em C, pode até imitar POO e torná-lo um C++ com syntax diferente, pode usar bibliotecas que permitem que você trabalhe facilmente com strings, macros pesadas que transformam a linguagem em alguma abominação espetacular e pode escrever seu próprio coletor de lixo.

Exemplo

O programa divisor tree lerá interativamente números positivos menor que 1000 e, para cada um, ele imprimirá a árvore binária dos divisores de números para que se um número tiver divisores, os que estiverem mais próximos uns do outros serão seus filhos. A árvore será escrita no formato LNR, onde N é o número do nó da árvore, L é a subárvore esquerda do nó e R é a subárvore direita. Este problema é feito para que ele mostre a maioria dos recursos básicos de uma linguagem, como estruturas de controle, definição de função, recursão, e I/O.

#include <stdio.h>

void printDivisorTree(unsigned int x)
{
  int a = -1, b = -1;
 
  for (int i = 2; i <= x / 2; ++i)
    if (x % i == 0)
    {
      a = i;
      b = x / i;

      if (b <= a)
        break;
    }
    
  putchar('(');
  
  if (a > 1)
  {
    printDivisorTree(a);
    printf(" %d ",x);
    printDivisorTree(b);
  }
  else
    printf("%d",x);   
    
  putchar(')');
}

int main(void)
{
  while (1) 
  {
    unsigned int number;
    printf("enter a number: ");
    
    printf("enter a number: ");
    {
      printDivisorTree(number);
      putchar('\n');
    }
    else
      break;
  }

  return 0;
}

História

C foi desenvolvido em 72 na Bell Labs junto com o UNIX por Ritchie e Kerninghan, como um sucessor da linguagem B portátil com recursão, que foi inspirada no escopo léxico do ALGOL. C estava intimamente interconectado com o UNIX e sua cultura hacker, ambos projetos foram desenvolvidos juntos, influenciando um ao outro. Em 73, o UNIX foi reescrito em C. Em 78, Keninghan e Ritchie publicaram o The C Programming Language, ou KêR. Em março de 87, Stallman, com outros hackers, lançou a primeira versão do compilador GNU C, compilador oficial do projeto GNU e o compilador que se tornaria um dos mais usados. Em 89, o padrão ANSI C, também conhecido como C89, foi lançado pela ANSI americana, um padrão muito bem suportado e até bom. O mesmo padrão também foi adotado um ano depois pela ISO internacional. Em 99, a ISO emite um novo padrão conhecido como C99, adotado pelo SMR. Mais tarde, em 2011 e 2017, o padrão foi revisado novamente para C11 e C17, que são uma merda.

Padrões

C teve alguns padrões ao longo dos anos desde seu início. O padrão define a linguagem base e a biblioteca padrão. Padrões e versões notáveis são:

Há uma referência online boa para todos os diferentes padrões em en.cppreference.com.

O SMR deve usar KêR, C99 ou C89, pois as versões recentes são pragas e não têm um suporte grande em compiladores, tornando-as menos portáteis e menos gratuitas. Os padrões C99 e anteriores são considerados à prova do futuro e usá-los ajudará seu programa a ser à prova do futuro. Isso se deve em grande parte ao fato de C ter sido estabelecido e testado melhor do que qualquer outra linguagem, o compilador C é uma das primeiras coisas que uma nova plataforma de hardware precisa implementar, então os compiladores sempre estarão por aí. C também foi projetado de uma forma mínima, antes do advento do aumento de recursos e besteiras como POO, que paralisa quase todas as linguagens modernas.

Compiladores

Biblioteca padrão

Além da linguagem pura, o padrão especifica um conjunto de bibliotecas que devem vir com uma implementação compatível. Como a biblioteca stdio para executar I/O padrão ou a biblioteca matemática para funções matemáticas. É aceitável usar essas bibliotecas, pois elas são exigidas pelo padrão para existir, então a dependência que elas criam não é tão perigosa, no entanto, muitas implementações não são completamente compatíveis com o padrão e podem vir sem a biblioteca padrão. Além disso, muitas implementações stdlib são ruins ou você simplesmente não pode ter certeza do que a implementação irá preferir tamanho oi velocidade. Então, por uma questão de portabilidade, evita a biblioteca padrão.

A libc é debatível, embora sua interface e comportamento sejam dados pelo padrão, sua implementação é questão de cada compilador, já que a biblioteca padrão é comumente usada, devemos tomar muito cuidado para garantir que ela seja bem escrita, mas sempre temos que escolher nossas prioridades e fazer concessões, simplesmente não pode haver uma implementação final que seja rápida, eficiente em termos de memória, portátil e pequena. Então, escolher seu ambiente C geralmente envolve escolher o compilador e a implementação stdlib. Como você provavelmente adivinhou, as implementações populares, glibc et al, são bloated e são uma merda. Felizmente, existem alternativas.

Coisas boas e ruins sobre C

Primeiramente, algumas razões pelas quais C é tão foda.

C foi uma das primeiras linguagens high-level, embora tenha se mostrado bem projetada, algumas coisas não saíram não bem. É bom estar ciente de suas desvantagens e problemas menores. Tudo aqui são apenas sugestões, elas podem ser objeto de contra-argumentos e discussões futuras. Aqui estão algumas das coisas ruins sobre a linguagem:

Exemplo

Para um tutorial aprofundado, veja tutorial de c.

Um programa simples que imprime "bem-vindo ao C".

#include <stdio.h>

int

main(void)
{
    puts("bem-vindo ao C");

    return 0;
}

Compilação: tcc -o program program.c

Execução: ./program


Impulsionado por nada. Todo conteúdo é disponível sob CC0 1.0 domínio público. Envie comentários e correções para Mr. Unix em victor_hermian@disroot.org.