Eu acredito que C é uma boa linguagem para aprender os princípios por trás da programação. O que você aprende em idiomas de nível inferior que são "excluídos" dos de alto nível, como Ruby?
Eu acredito que C é uma boa linguagem para aprender os princípios por trás da programação. O que você aprende em idiomas de nível inferior que são "excluídos" dos de alto nível, como Ruby?
Respostas:
Não há princípios, no sentido abstrato geral da ciência da computação, que estejam presentes em C que também não estejam presentes em linguagens de nível superior. Toda a ciência da computação se resume a algoritmos, e todos os algoritmos podem ser implementados em qualquer idioma que seja Turing-completo como C.
A diferença que C separa das linguagens de nível superior é semelhante à diferença que o código de máquina carrega além de C: O relacionamento da máquina com o código.
Ao escrever código em idiomas de alto nível, você geralmente não se preocupa com a maneira como seu código interage com a máquina. A máquina virtual que a linguagem define por si mesma oculta muitos desses aspectos da execução do código.
Em C, a interação do seu programa com a memória é mantida em primeiro plano. É mais do que meramente que você precisa gerenciar o uso da pilha, inclui a interação do seu código com a pilha e como o mero acesso à memória do seu código afeta o comportamento e o desempenho do seu código - nem mesmo a ordem da memória acessa pode deixar sua atenção, pois a leitura da memória errada na hora errada pode prejudicar efetivamente o desempenho.
Em idiomas de nível superior, essas coisas simplesmente não são tão óbvias. A memória é alocada e desalocada sem o seu conhecimento e, às vezes, sem a sua solicitação. Na maioria das vezes, isso está simplesmente fora de seu controle. O quando, onde, como e por que a maioria das alocações de memória está simplesmente oculta.
Da mesma forma, na outra direção, escrever código de máquina ou código de montagem traz ainda mais detalhes para o primeiro plano: quase nada fica fora do seu alcance, e seu código deve ser escrito com conhecimento de todas as alocações, recursos e partes de dados que passam através dos registros da CPU - conhecimento que está tão distante das linguagens de alto nível que é misterioso.
Eu sei que C é uma boa linguagem para aprender os princípios por trás da programação.
Discordo. C está ausente em muitos recursos para aprender princípios por trás da programação. Os recursos de C para criar abstrações são terríveis e a abstração é um dos princípios fundamentais por trás da programação.
Se você quiser aprender como o hardware funciona e, portanto, alguma simpatia mecânica pela máquina, deve aprender o código da máquina, também conhecido como arquitetura do conjunto de instruções, e também estudar a construção de cache das CPUs modernas. Observe que eu não estou recomendando a linguagem assembly, apenas entenda as instruções de hardware para entender o que um compilador gera.
Se você quiser aprender os princípios de programação, use uma linguagem moderna como Java, C # ou Swift, ou uma das dezenas de outras como Rust. Além disso, estude os diferentes tipos de paradigmas de programação, inclusive funcionais.
A maioria das linguagens de programação é descrita em termos de máquinas abstratas. Em seguida, eles são implementados usando conjuntos de ferramentas como compiladores, vinculadores, montadores, intérpretes, analisadores estáticos, linguagens intermediárias e hardware que coletivamente produzirão um resultado que honra pelo menos todo o comportamento esperado da máquina abstrata, conforme observado por um programa .
C não é uma exceção à regra acima. É descrito em termos de uma máquina abstrata que não tem noção do seu hardware real.
Assim, quando as pessoas dizem que C ensina como seu computador realmente funciona, o que elas geralmente querem dizer é que C ensina como C funciona. Como C é tão difundido na programação de sistemas, é compreensível que muitas pessoas comecem a confundi-lo com o próprio computador. E eu pessoalmente diria que saber como C funciona geralmente é mais importante do que saber como o próprio computador funciona.
Mas ainda assim, C e o computador são coisas diferentes. O hardware real é realmente complicado - de uma maneira que faz as especificações C parecerem um livro infantil. Se você estiver interessado em saber como o seu hardware funciona, sempre pode procurar um manual e começar a escrever o código em um assembler. Ou você pode sempre começar a aprender sobre circuitos digitais para poder projetar algum hardware por conta própria. (No mínimo, você apreciará o nível C de alto nível.)
Ok, realmente aprender sobre hardware envolve outras coisas além de C. Mas C pode ensinar mais alguma coisa aos programadores hoje?
Eu acho que depende.
Não seja muito rápido para escolher uma dessas possibilidades. Escrevo códigos há muitos anos e ainda não tenho idéia de qual é a resposta correta, ou se a resposta correta é apenas uma das duas, ou se existe uma resposta correta para esse problema.
Estou um pouco inclinado a acreditar que você provavelmente deve aplicar ambas as opções, vagamente na ordem em que as descrevi. Mas não acho que isso seja realmente um problema técnico, acho que é principalmente educacional. Toda pessoa parece aprender de maneiras significativamente diferentes.
Se você respondeu à pergunta acima pelo menos envolvendo a segunda opção que eu propus, então você já tem algumas respostas: qualquer coisa que possa ser aprendida em idiomas de nível superior pode ser melhor aprendida reinventando-a em C ou em menos expandido adicionando C à mistura.
Mas, independentemente da sua resposta, certamente há algumas coisas que você pode aprender quase exclusivamente com C (e talvez um punhado de outras línguas).
C é historicamente importante. É um marco que você pode ver e apreciar de onde viemos e talvez ter um pouco mais de contexto sobre para onde estamos indo. Você pode entender por que certas limitações existem e você pode saber que certas limitações foram levantadas.
C pode ensiná-lo a trabalhar em ambientes inseguros. Em outras palavras, ele pode treiná-lo para cuidar de você quando o idioma (qualquer idioma) não pode ou não faz isso por você, por qualquer motivo. Isso pode torná-lo um programador melhor, mesmo em ambientes seguros, porque você produzirá menos bugs por conta própria e poderá desativar a segurança temporariamente, a fim de extrair uma velocidade extra do seu programa seguro (por exemplo, uso de ponteiros em C #), nos casos em que a segurança tem um custo de tempo de execução.
C pode ensinar que todo objeto tem requisitos de armazenamento, um layout de memória, o fato de que a memória pode ser acessada através de um espaço de endereço finito e assim por diante. Embora outros idiomas não precisem de sua atenção nessas questões, há alguns casos em que alguma intuição adquirida pode ajudá-lo a tomar decisões mais informadas.
C pode ensinar sobre os detalhes dos arquivos de vinculação e objeto e outras complexidades por meio de seu sistema de construção. Isso pode fornecer uma compreensão prática útil de como um programa compilado nativamente geralmente passa do código-fonte para a execução.
C pode inclinar sua mente para pensar de maneiras novas através do conceito de comportamento indefinido. O comportamento indefinido é um dos meus conceitos favoritos no desenvolvimento de software, porque o estudo de suas implicações em compiladores não clássicos é um exercício mental exclusivo que você não consegue obter de outras línguas. No entanto, você terá que rejeitar a tentativa e erro e começar a estudar o idioma de maneira cuidadosa e deliberada antes de poder apreciar completamente esse aspecto.
Mas talvez a percepção mais importante que C possa lhe conceder, sendo uma linguagem pequena, seja a ideia de que toda a programação se resume a dados e operações . Você pode considerar coisas como classes modulares com hierarquias e interfaces com despacho virtual ou valores imutáveis elegantes que são operados usando funções matemáticas puras. E tudo bem - mas C lembrará que são apenas operações de dados + . É uma mentalidade útil porque permite derrubar algumas barreiras mentais.
A razão pela qual C é bom para aprender não é que ela ensina princípios . Ele ensina como as coisas funcionam .
O C pode ser comparado com um daqueles bons carros antigos dos anos 70 ou 80, que foram construídos para dirigir. Você pode separá-los, parafuso a parafuso, e entender como cada parte funciona e como ela trabalha junto com as outras partes que você pode pegar nas mãos para examinar. Depois de entender todas as partes, você tem uma imagem muito clara de como o todo funciona.
As línguas modernas são mais como um carro moderno, onde o motor é basicamente uma caixa preta, muito complexa para ser entendida pelo proprietário médio. Esses carros podem fazer muito, diabos, atualmente eles estão aprendendo ativamente a dirigir sozinhos. E com essa complexidade e conforto, a interface do usuário foi muito mais longe do que realmente está acontecendo no mecanismo.
Quando você aprende a programar em C, entra em contato com muitos parafusos e porcas de que o computador é feito. Isso permite que você desenvolva um entendimento da própria máquina. Por exemplo, ele permite que você entenda por que não é uma boa ideia criar uma cadeia longa como esta:
java.lang.String result = "";
for(int i = 0; i < components.size; i++) {
result = result + components[i];
};
(Espero que este seja o Java correto, não o uso há algum tempo ...) Neste exemplo de código, não é óbvio por que o loop tem complexidade quadrática. Mas esse é o caso, e é a razão pela qual esse código será interrompido quando você tiver alguns milhões de pequenos componentes para concatenar. O programador C experiente sabe instantaneamente onde está o problema e provavelmente evitará escrever esse código em primeiro lugar.
for(int i = 0; i < strlen(s); i++)
em C, o loop também terá complexidade quadrática, e é tão unobvious como no seu exemplo Java ;-)
Existem linguagens melhores que C para aprender "os princípios por trás da programação", especialmente princípios teóricos, mas C pode ser bom para aprender algumas coisas práticas e importantes sobre o trabalho artesanal. A resposta do greyfade é surpreendentemente correta, mas IMHO, há mais que você pode aprender com C do que como gerenciar a memória sozinho. Por exemplo,
como criar programas com um tratamento completo de erros na ausência de exceções
como criar estrutura em um programa sem ter nenhum suporte de idioma para orientação a objetos
como lidar com dados na ausência de estruturas de dados, como listas dinâmicas de tamanho considerável, dicionários ou uma abstração útil de strings
como evitar erros comuns, como estouros de matriz, mesmo quando o compilador ou o ambiente de tempo de execução não avisa automaticamente
como criar soluções genéricas sem suporte a idiomas para modelos ou genéricos
e eu mencionei que você pode aprender a gerenciar a memória sozinho, é claro? ;-)
Além disso, aprendendo C, você aprenderá de onde vêm as semelhanças sintáticas de C ++, Java, C #, Objetivo C.
Em 2005, Joel Spolsky escreveu uma recomendação para aprender C antes de qualquer outro idioma de nível superior. Seus argumentos são
"você nunca poderá criar código eficiente em idiomas de nível superior."
"Você nunca poderá trabalhar em compiladores e sistemas operacionais, que são alguns dos melhores trabalhos de programação existentes".
"Você nunca será confiável para criar arquiteturas para projetos de grande escala"
"se você não consegue explicar por que while(*s++ = *t++);
copiar uma sequência, ou se isso não é a coisa mais natural do mundo, você está programando com base em superstições
Certamente, o que ele escreveu é certamente discutível, mas muitos dos seus argumentos no IMHO ainda são válidos hoje.
As duas abstrações básicas da computação são as máquinas de Turing e o cálculo Lambda, e C é uma maneira de experimentar a visão da computação da máquina de Turing: principalmente uma sucessão de ações de baixo nível das quais emerge um resultado desejável. Mas você deve ter em mente que C vem com seu próprio modelo de computação. Portanto, aprender C ensinará os detalhes de baixo nível da máquina abstrata C, que está ficando bem diferente das arquiteturas reais. Uma das primeiras coisas que aprendi em C foi nunca tentar enganar o compilador aplicando truques "inteligentes", e parece que a tendência é de mais e mais otimizações nos compiladores. Como em outras linguagens de alto nível, quando você escreve em C, os compiladores meio que entendem o que você espera que seja feito na máquina C abstrata e fazem com que isso aconteça no hardware real,
Então, o que eu quero dizer é que aprender C não necessariamente fornece uma boa imagem do que realmente acontece no hardware. "C está próximo da máquina" deve ser entendido como "mais próximo do que a maioria das linguagens de nível superior". Aprender a arquitetura de software diretamente será mais gratificante se você quiser uma imagem mais precisa de "como funciona".
Por outro lado, aprender C pode familiarizá-lo com a programação do sistema, tipos de baixo nível, ponteiros e, em particular, alocação de memória. Quanto aos algoritmos de aprendizagem e estrutura de dados, não há uma vantagem em aprendê-los em C, e não em outros idiomas.
É uma questão muito aberta, não pode dar uma resposta conclusiva. Você pode aprender praticamente tudo em todos os idiomas, desde que entenda os aspectos internos da estrutura de idiomas. C obriga você a entender detalhes mais baixos porque foi projetado principalmente para escrever um sistema operacional. Mesmo depois de tantos anos, ainda é uma das linguagens mais usadas principalmente graças a sistemas embarcados e projetos de código aberto. Então, a pergunta é o que você quer aprender? E em qual domínio?