Quais princípios são aprendidos com C que não podem ser aprendidos em idiomas de nível superior? [fechadas]

11

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?

Andrew
fonte
2
Você aprende a magia, ou parte dela, de qualquer maneira. Como C está "mais próximo do metal", você aprende mais sobre o metal.
Robert Harvey
1
Eu nunca entendi completamente o conceito de referência até encontrar o C ++.
user6245072
6
C ensinará o que realmente é um estouro de pilha. O jeito difícil.
precisa saber é o seguinte
1
Eu gostaria que novos programadores começassem aprendendo o bom e velho Pascal e a programação estruturada. Você aprende a se expressar de maneira lógica e estruturada.
Bent
2
Algo que apenas C e C ++ ensinam é que o compilador é seu pior inimigo.
precisa saber é o seguinte

Respostas:

9

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.

greyfade
fonte
6
Eu nunca entendi direito por que as pessoas sempre mencionam a integridade de Turing nesses tipos de discussões. Turing-completeness não é significativo neste contexto; C não é diferente de outras linguagens de programação a esse respeito, portanto, não há nada a ser aprendido sobre a completude de Turing mudando para C. A única vez que a completude de Turing se torna relevante é quando se discute algo que não é completo em Turing, como CSS ou HTML . Inferno, se você apertar os olhos com força suficiente, mesmo aqueles são completos para Turing . As perguntas mais significativas se concentram na usabilidade.
Robert Harvey
3
@RobertHarvey Meu argumento é que, desde que uma linguagem tenha um mínimo razoável de capacidade computacional, seu "nível" se torna irrelevante do ponto de vista dos algoritmos, que são as únicas coisas importantes nesse contexto.
greyfade
3
Porque você está fazendo uma observação totalmente irrelevante para a pergunta do OP. Programadores fazem isso o tempo todo; eles usam a frase "Turing-complete" como se ela tivesse algum uso significativo em termos práticos. Não importa, exceto salientar que não importa.
Robert Harvey
2
<irony> A biologia é apenas um caso especial de química, que é um caso especial de física de partículas. Não há nada que você possa aprender com a biologia se conhecer a física de partículas. Certo? </irony>
Florian F
3
Vale ressaltar que C simplesmente exige que você explique alocações e desalocações, mas elas ainda dizem respeito a uma máquina abstrata, como nas linguagens de "nível superior" - a máquina física (por exemplo) x86 ainda está fora do escopo de C. pode criar uma VM perfeitamente em área restrita que interpreta o código C, mas não tem controle sobre as alocações de memória da máquina física e ainda pode ser uma implementação 100% compatível.
Theodoros Chatzigiannakis
13

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.

Erik Eidt
fonte
12
C é bom em criar abstrações. Você pode escrever métodos em C e pode empacotar dados como estruturas em C. Sistemas operacionais inteiros foram criados usando C. O que C não é bom é satisfazer a idéia "moderna" de todos de como a orientação a objetos deve parecer gostar.
Robert Harvey
4
Nem tanto. C é um nível um pouco mais alto que o ASM. Só não espere usar classes nele, embora haja maneiras de fazer isso , se você estiver tão inclinado.
Robert Harvey
4
Substitua "Brainfuck" por "assembler" no seu comentário, e ele ainda deve ser verdadeiro. Mas isso não significa que vou usar o Brainfuck tão cedo.
Robert Harvey
6
Seu argumento sobre os recursos de C realmente só tem mérito se você acredita que as aulas (e a coleta de lixo etc.) são um elemento necessário para ensinar um novo programador (o que eu não acredito). Ninguém aqui defende a tentativa de usar classes em um idioma sem classe.
Robert Harvey
5
@ Robert, meu argumento é que C é uma linguagem de nível inferior e, como tal, dificilmente é a melhor linguagem para entender os princípios de programação, o que também podemos dizer sobre assembler, e, apenas porque são linguagens de nível inferior, não significa eles estão de alguma forma mais próximos dos "verdadeiros" princípios de programação. Essas linguagens são melhores para entender como o hardware e os sistemas operacionais funcionam e, se esse for o seu interesse, recomendo pular para o nível mais baixo, aprendendo a arquitetura do conjunto de instruções e a linguagem da máquina. Caso contrário, há muitos idiomas para você escolher.
Erik Eidt
8

C e a máquina (abstrata)

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.)

Como é que você aprendeu? E como você aprende?

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.

  • Há quem diga que você pode aprender melhor um conceito trabalhando em um ambiente que o oferece e o incentiva, geralmente de várias maneiras.
  • Há quem diga que você pode aprender melhor um conceito trabalhando em um ambiente que não o oferece e onde você deve construí-lo.

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.

Exclusivamente em C

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.

Theodoros Chatzigiannakis
fonte
5

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.

cmaster - restabelece monica
fonte
Eu concordo completamente. C ensinará muito sobre como as coisas funcionam, o que ajuda bastante a entender a) por que os idiomas de nível superior foram escritos (por exemplo, o que eles pretendem abstrair) eb) como esses idiomas de nível superior funcionam nos bastidores, o que com certeza um bom conhecimento para ter. Ele não ensinará princípios e pode não ser tão fácil, mas você terá um respeito por isso, computadores e um entendimento mais profundo das linguagens de nível superior como resultado. Leia também Back to Basic de Joel Spolsky: joelonsoftware.com/articles/fog0000000319.html
jleach
1
A sua resposta é certamente bom, mas se você escrever 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 ;-)
Doc Brown
Não tenho certeza, mas eu confio que o compilador Java para optimiz esta longe :-)
de Bruno Schapper
O experiente programador Java também sabe instantaneamente onde está o problema e provavelmente evitará escrever esse código em primeiro lugar. Esse problema específico é discutido nos tutoriais elementares sobre Java. Portanto, isso certamente não é algo que pode ser aprendido com C, mas não com Java.
Peter Taylor
@ PeterTaylor Se você tem um instrutor de Java que conhece o C, sim. Mas duvido que esse tipo de conhecimento permaneça por perto quando as pessoas que conhecem C estiverem mortas. Para o programador C, é a própria definição do que é uma string C, o que indica que meu exemplo de código não pode ser eficiente. Para o programador Java, é um conhecimento profundo, misterioso e pouco usado sobre as abstrações que eles usam, o que lhes diz para evitar esse tipo de código. Ok, estou exagerando um pouco aqui, mas você entendeu: o programador C deve saber disso, o programador Java pode se safar sem saber.
cmaster - reinstala monica em 23/08/16
2

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.

Doc Brown
fonte
1
C é uma linguagem muito boa para aprender antes de aprender as "coisas de nível superior que você acha que C não suporta", porque ajuda a entender como essas coisas realmente funcionam (e quão caras são).
Brendan
@Brendan: Não tenho certeza se a intenção do seu comentário é expressar um acordo, um desacordo ou apenas uma nota de rodapé da minha resposta.
Doc Brown
Os programas C escritos por profissionais são lançados com saturação de buffer e falhas graves. Assim, enquanto um programador disciplinado pode optar por aprender essas coisas , o C que a linguagem não ensina inerentemente apenas por ser empobrecido. Existem muitas maneiras ruins (e pior, misturar várias maneiras inconsistentes) de manipular erros sem exceções e criar estrutura sem objetos, por exemplo.
Erik Eidt
@ErikEidt: de fato, mas especialmente na ecosfera C, existem muitos livros, tutoriais e outros materiais que abordarão esses tópicos. Por exemplo, "Writing Solid Code", de Steve Maguire. Claro, se alguém escolher a primeira edição do K&R por aprender a sintaxe da linguagem, provavelmente não se tornará um programador melhor.
Doc Brown
1

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.

coredump
fonte
1
Então, o que C pode ensinar a você que idiomas de nível superior não podem?
Philip Kendall
2
Penso que a resposta implícita é: " Nada , pelo menos não as coisas que os proponentes costumam reivindicar". É assim que eu entendo a resposta de qualquer maneira.
Jörg W Mittag
-3

É 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?

Varun Mishra
fonte