Estou pensando em aprender C.
Mas por que as pessoas usam C (ou C ++) se podem ser usadas 'perigosamente'?
Por perigoso, quero dizer com ponteiros e outras coisas semelhantes.
Como a pergunta Estouro de pilha Por que a função gets é tão perigosa que não deve ser usada? . Por que os programadores não usam apenas Java ou Python ou outra linguagem compilada como o Visual Basic?
Respostas:
C é anterior a muitos dos outros idiomas em que você está pensando. Muito do que sabemos agora sobre como tornar a programação "mais segura" vem da experiência com linguagens como C.
Muitos dos idiomas mais seguros lançados desde C dependem de um tempo de execução maior, de um conjunto de recursos mais complicado e / ou de uma máquina virtual para atingir seus objetivos. Como resultado, C permaneceu como um "menor denominador comum" entre todos os idiomas populares / populares.
C é uma linguagem muito mais fácil de implementar porque é relativamente pequena e tem mais probabilidade de ter um desempenho adequado, mesmo nos ambientes mais fracos, por isso muitos sistemas embarcados que precisam desenvolver seus próprios compiladores e outras ferramentas têm mais chances de fornecer um compilador funcional para C.
Como o C é muito pequeno e simples, outras linguagens de programação tendem a se comunicar usando uma API do tipo C. Essa é provavelmente a principal razão pela qual C nunca morrerá verdadeiramente, mesmo que a maioria de nós apenas interaja com ele por meio de invólucros.
Muitas das linguagens "mais seguras" que tentam melhorar o C e o C ++ não estão tentando ser "linguagens de sistema" que oferecem controle quase total sobre o uso da memória e o comportamento em tempo de execução do seu programa. Embora seja verdade que hoje em dia, mais e mais aplicativos simplesmente não precisam desse nível de controle, sempre haverá um pequeno punhado de casos em que é necessário (principalmente dentro de máquinas virtuais e navegadores que implementam todas essas linguagens agradáveis e seguras para o resto de nós).
Hoje, existem algumas linguagens de programação de sistemas (Rust, Nim, D, ...) que são mais seguras que C ou C ++. Eles têm os benefícios da retrospectiva e percebem que, na maioria das vezes, esse controle fino não é necessário; portanto, oferecem uma interface geralmente segura com alguns ganchos / modos inseguros para os quais podemos mudar quando realmente necessário.
Mesmo no C, aprendemos muitas regras e diretrizes que tendem a reduzir drasticamente o número de bugs insidiosos que aparecem na prática. Geralmente, é impossível obter o padrão para impor essas regras retroativamente, porque isso quebraria muito código existente, mas é comum usar avisos do compilador, linters e outras ferramentas de análise estática para detectar esses tipos de problemas facilmente evitáveis. O subconjunto de programas C que passam essas ferramentas com cores voadoras já é muito mais seguro do que "apenas C", e qualquer programador competente de C hoje em dia usará alguns deles.
Além disso, você nunca fará um concurso Java ofuscado tão divertido quanto o concurso C ofuscado .
fonte
Primeiro, C é uma linguagem de programação de sistemas. Portanto, por exemplo, se você escrever uma máquina virtual Java ou um interpretador Python, precisará de uma linguagem de programação de sistemas para gravá-los.
Segundo, C fornece desempenho que linguagens como Java e Python não. Normalmente, a computação de alto desempenho em Java e Python usará bibliotecas escritas em uma linguagem de alto desempenho como C para fazer o trabalho pesado.
Terceiro, C tem uma área de cobertura muito menor do que linguagens como Java e Python. Isso o torna utilizável para sistemas embarcados, que podem não ter os recursos necessários para suportar os grandes ambientes de tempo de execução e as demandas de memória de linguagens como Java e Python.
Uma "linguagem de programação de sistemas" é uma linguagem adequada para a construção de sistemas de força industrial; como estão, Java e Python não são linguagens de programação de sistemas. "O que exatamente faz uma linguagem de programação de sistemas" está fora do escopo desta pergunta, mas uma linguagem de programação de sistemas precisa fornecer suporte para trabalhar com a plataforma subjacente.
Por outro lado (em resposta aos comentários), uma linguagem de programação de sistemas não precisa ser auto-hospedada. Esta questão surgiu porque a pergunta original pediu "por que as pessoas usam C", o primeiro comentário perguntou "por que você precisa de uma linguagem como C" quando você tem PyPy, e notei que PyPy é que de fato usar C. Assim, foi originalmente relevante para a pergunta, mas infelizmente (e de maneira confusa) a "hospedagem automática" não é realmente relevante para esta resposta. Me desculpe, eu trouxe isso à tona.
Portanto, resumindo: Java e Python não são adequados à programação de sistemas, não porque suas implementações principais são interpretadas ou porque implementações compiladas nativamente não são auto-hospedadas, mas porque não fornecem o suporte necessário para trabalhar com a plataforma subjacente.
fonte
Lamento adicionar mais uma resposta, mas acho que nenhuma das respostas existentes aborda diretamente sua primeira frase, afirmando:
Por quê? Deseja fazer o tipo de coisa que C normalmente é usada atualmente (por exemplo, drivers de dispositivo, VMs, mecanismos de jogos, bibliotecas de mídia, sistemas incorporados, kernels de SO)?
Se sim, então sim, com certeza aprenda C ou C ++, dependendo de quem você está interessado. Deseja aprender para ter uma compreensão mais profunda do que sua linguagem de alto nível está fazendo?
Você então menciona as preocupações de segurança. Você não precisa necessariamente de um entendimento profundo do C seguro para fazer o último, da mesma maneira que um exemplo de código em uma linguagem de nível superior pode fornecer a essência sem estar pronto para a produção.
Escreva um código C para entender o essencial. Em seguida, coloque-o de volta na prateleira. Não se preocupe muito com segurança, a menos que queira escrever o código C de produção .
fonte
Esta é uma pergunta ENORME com toneladas de respostas, mas a versão curta é que cada linguagem de programação é especializada para diferentes situações. Por exemplo, JavaScript para web, C para itens de baixo nível, C # para qualquer coisa do Windows etc. É útil saber o que você deseja fazer depois de conhecer a programação para decidir qual linguagem de programação escolher.
Para abordar seu último ponto, por que o C / C ++ sobre Java / Python, muitas vezes se resume à velocidade. Eu faço jogos, e o Java / C # está apenas recentemente atingindo velocidades que são boas o suficiente para os jogos rodarem. Afinal, se você deseja que seu jogo seja executado a 60 quadros por segundo e você quer muito (renderização é particularmente caro), é necessário que o código seja executado o mais rápido possível. Python / Java / C # / Muitos outros executam "intérpretes", uma camada extra de software que lida com todas as coisas tediosas que o C / C ++ não faz, como gerenciar memória e coleta de lixo. Essa sobrecarga extra torna as coisas mais lentas, então quase todos os jogos grandes que você vê foram feitos (nos últimos 10 anos, pelo menos) em C ou C ++. Existem exceções: o mecanismo de jogo Unity usa C # * e o Minecraft usa Java, mas são a exceção, não a regra. Em geral,
* Mesmo o Unity não é apenas C #, grandes pedaços dele são C ++ e você apenas usa C # para o código do jogo.
EDITAR Para responder a alguns dos comentários que apareceram depois que eu postei isso: Talvez eu estivesse simplificando demais, estava apenas dando uma imagem geral. Com a programação, a resposta nunca é simples. Existem intérpretes para C, o Javascript pode ser executado fora do navegador e o C # pode ser executado em praticamente qualquer coisa, graças ao Mono. Diferentes linguagens de programação são especializadas para domínios diferentes, mas algum programador em algum lugar provavelmente descobriu como executar qualquer linguagem em qualquer contexto. Como o OP parecia não conhecer muita programação (suposição da minha parte, desculpe se estou errado), eu estava tentando manter minha resposta simples.
Quanto aos comentários sobre o C # ser quase tão rápido quanto o C ++, a palavra-chave existe quase. Quando eu estava na faculdade, visitamos muitas empresas de jogos, e meu professor (que nos incentivou a deixar o C # e entrar no C ++ o ano inteiro) perguntou aos programadores de todas as empresas que estudamos o porquê do C ++ sobre C # e de todos. disse que C # é muito lento. Em geral, ele é executado rapidamente, mas o coletor de lixo pode prejudicar o desempenho porque você não pode controlar quando é executado e tem o direito de ignorá-lo se não quiser executar quando você recomenda. Se você precisa de algo com alto desempenho, não quer algo tão imprevisível quanto isso.
Para responder ao meu comentário "apenas atingindo velocidades", sim, grande parte da velocidade do C # vem de um hardware melhor, mas como a estrutura .NET e o compilador C # foram aprimorados, houve algumas acelerações por lá.
Sobre o comentário "os jogos são escritos no mesmo idioma que o mecanismo", depende. Alguns são, mas muitos são escritos em um híbrido de idiomas. O Unreal pode executar UnrealScript e C ++, o Unity usa C # Javascript e Boo, muitos outros mecanismos escritos em C ou C ++ usam Python ou Lua como linguagens de script. Não há uma resposta simples lá.
E só porque me incomodou em ler "quem se importa se o seu jogo roda a 200fps ou 120fps", se o seu jogo está rodando acima de 60fps, você provavelmente está perdendo tempo na CPU, já que o monitor médio nem mesmo atualiza velozes. Alguns mais sofisticados e os mais novos, mas ainda não é padrão (ainda ...).
E sobre a observação "ignorar décadas de tecnologia", ainda estou no início dos meus 20 anos; portanto, quando estou extrapolando para trás, estou ecoando o que os programadores mais velhos e mais experientes me disseram. Obviamente, isso será contestado em um site como este, mas vale a pena considerar.
fonte
É engraçado você afirmar que C é inseguro porque "possui indicadores". O oposto é verdadeiro: Java e C # têm praticamente apenas ponteiros (para tipos não nativos). O erro mais comum em Java é provavelmente a exceção do ponteiro nulo (consulte https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare ). O segundo erro mais comum é provavelmente manter referências ocultas a objetos não utilizados (por exemplo, diálogos fechados não são descartados) que, portanto, não podem ser liberados, levando a programas de longa duração com uma pegada de memória cada vez maior.
Existem dois mecanismos básicos que tornam C # e Java mais seguros e de duas maneiras diferentes:
Os ponteiros inteligentes recentes do C ++ facilitam esse trabalho para os programadores.
O tempo de execução não protege contra, por exemplo, tentativas de saturação de buffer, mas, em teoria, não permite explorações de tais programas. Com C e C ++, por outro lado, o programador precisa codificar com segurança para evitar explorações. Isso geralmente não é alcançado imediatamente, mas precisa de revisões e iterações.
Vale ressaltar, porém, que o tempo de execução elaborado também é um risco à segurança. Parece-me que a Oracle está atualizando a JVM a cada duas semanas devido a problemas de segurança recém-descobertos. Obviamente, é muito mais difícil verificar a JVM do que um único programa.
Portanto, a segurança de um tempo de execução elaborado é ambígua e enganosa: seu programa C médio pode, com revisões e iterações, ser razoavelmente seguro. Seu programa Java médio é tão seguro quanto a JVM; isto é, não realmente. Nunca.
O artigo sobre o
gets()
qual você vincula reflete as decisões históricas da biblioteca que seriam tomadas de maneira diferente hoje, não a linguagem principal.fonte
Como a "segurança" custa velocidade, os idiomas "mais seguros" têm desempenho mais lento.
Você pergunta por que usar uma linguagem "perigosa" como C ou C ++, alguém escreveu um driver de vídeo ou algo semelhante em Python ou Java, etc., e ver como você se sente sobre "segurança" :)
Sério, porém, você deve estar o mais próximo possível da memória principal da máquina para poder manipular pixels, registros, etc ... Java ou Python não podem fazer isso com qualquer tipo de velocidade digna de desempenho ... C e C ++ permitem que você faça isso através de ponteiros e similares ...
fonte
Além de tudo acima, também há um caso de uso bastante comum, que está usando C como uma biblioteca comum para outros idiomas.
Basicamente, quase todos os idiomas têm uma interface API para C.
Exemplo simples, tente criar um aplicativo comum para Linux / IOS / Android / Windows. Além de todas as ferramentas disponíveis, acabamos fazendo uma biblioteca principal em C e alterando a GUI para cada ambiente, ou seja:
Meus dois centavos,
fonte
Uma dificuldade fundamental com C é que o nome é usado para descrever um número de dialetos com sintaxe idêntica, mas semântica muito diferente. Alguns dialetos são muito mais seguros que outros.
Em C, como originalmente projetado por Dennis Ritchie, as declarações C geralmente seriam mapeadas para as instruções da máquina de maneira previsível. Como o C podia funcionar em processadores que se comportavam de maneira diferente quando ocorriam coisas como estouro aritmético assinado, um programador que não sabia como uma máquina se comportaria em caso de estouro aritmético também não saberia o código C em execução nessa máquina, mas se se sabia que uma máquina se comporta de uma certa maneira (por exemplo, envolvente silencioso do complemento de dois em dois), as implementações nessa máquina normalmente fazem o mesmo. Uma das razões pelas quais C ganhou reputação de ser rápida foi que, nos casos em que os programadores sabiam que o comportamento natural de uma plataforma em cenários extremos atenderia às suas necessidades, não era necessário que o programador ou o compilador escrevesse o código para gerar esses cenários. .
Infelizmente, os escritores do compilador consideraram que, uma vez que o Padrão não impõe requisitos sobre o que as implementações devem fazer nesses casos (a negligência destinada a permitir implementações de hardware que podem não se comportar de maneira previsível), os compiladores devem se sentir à vontade para gerar código que nega as leis de tempo e causalidade.
Considere algo como:
A teoria do compilador hipermoderno (mas na moda) sugere que o compilador deve gerar "QUACK!" incondicionalmente, pois, em qualquer caso em que a condição fosse falsa, o programa acabaria invocando um comportamento indefinido executando uma multiplicação cujo resultado seria ignorado de qualquer maneira. Como o padrão permitiria que um compilador fizesse o que quisesse nesse caso, ele permite que o compilador produza "QUACK!".
Enquanto C costumava ser mais seguro que a linguagem assembly, ao usar compiladores hiper-modernos, o inverso é verdadeiro. Na linguagem assembly, o excesso de números inteiros pode fazer com que um cálculo produza resultados sem sentido, mas na maioria das plataformas essa será a extensão de seus efeitos. Se os resultados acabarem sendo ignorados, o excesso não importará. No C hiper-moderno, no entanto, mesmo o que normalmente seriam formas "benignas" de comportamento indefinido (como um excesso de número inteiro em um cálculo que acaba sendo ignorado) pode causar a execução arbitrária do programa.
fonte
int arr[5][[5]
, por exemplo , uma tentativa de acessoarr[0][5]
produzirá um comportamento indefinido. Essa regra possibilita a um compilador que recebe algo comoarr[1][0]=3; arr[0][i]=6; arr[1][0]++;
inferir quearr[1][0]
será igual a 4, sem levar em consideração o valor dei
.Razões históricas. Não costumo escrever um código totalmente novo, principalmente para manter e estender o material antigo que está em execução há décadas. Estou feliz que seja C e não Fortran.
Fico irritado quando um aluno diz: "mas por que você faz esse X terrível quando pode estar fazendo Y?". Bem, X é o trabalho que tenho e paga as contas muito bem. Eu fiz Y de vez em quando e foi divertido, mas X é o que a maioria de nós faz.
fonte
O que é "perigoso"?
A alegação de que C é "perigoso" é um ponto de conversa frequente em guerras de chamas na linguagem (mais frequentemente em comparação com Java). No entanto, as evidências para esta alegação não são claras.
C é uma linguagem com um conjunto específico de recursos. Alguns desses recursos podem permitir certos tipos de erros que não são permitidos por outros tipos de idiomas (o risco do gerenciamento de memória de C geralmente é destacado). No entanto, isso não é o mesmo que argumentar que C é mais perigoso do que outras línguas em geral . Não conheço ninguém que forneça evidências convincentes sobre esse ponto.
Além disso, "perigoso" depende do contexto: o que você está tentando fazer e com que tipos de riscos está preocupado?
Em muitos contextos, eu consideraria C mais "perigoso" do que uma linguagem de alto nível, porque exige que você faça uma implementação mais manual da funcionalidade básica, aumentando o risco de erros. Por exemplo, fazer algum processamento básico de texto ou desenvolver um site em C normalmente seria idiota, porque outros idiomas têm recursos que facilitam muito isso.
No entanto, C e C ++ são amplamente utilizados para sistemas de missão crítica, porque uma linguagem menor com controle mais direto do hardward é considerada "mais segura" nesse contexto. De uma resposta muito boa de Stack Overflow :
fonte
Para adicionar às respostas existentes, é bom dizer que você escolherá Python ou PHP para o seu projeto, por causa de sua relativa segurança. Mas alguém precisa implementar essas linguagens e, quando o fizerem, provavelmente o fará em C. (ou, bem, algo assim).
É por isso que as pessoas usam C - para criar as ferramentas menos perigosas que você deseja usar.
fonte
Permita-me reformular sua pergunta:
Qualquer ferramenta interessante pode ser usada perigosamente, incluindo linguagens de programação. Você aprende mais para poder fazer mais (e para que menos perigo seja criado ao usar a ferramenta). Em particular, você aprende a ferramenta para poder fazer o que é bom (e talvez reconheça quando essa ferramenta é a melhor ferramenta que você conhece).
Por exemplo, se você precisar colocar um orifício cilíndrico de 6 mm de diâmetro e 5 cm de profundidade em um bloco de madeira, uma broca é uma ferramenta muito melhor do que um analisador LALR. Se você sabe quais são essas duas ferramentas, você sabe qual é a ferramenta certa. Se você já sabe usar uma broca, voila !, buraco.
C é apenas mais uma ferramenta. É melhor para algumas tarefas do que para outras. As outras respostas aqui tratam disso. Se você aprender um pouco de C, reconhecerá quando é a ferramenta certa e quando não é.
fonte
Não há razão específica para não aprender C, mas eu sugeriria C ++. Ele oferece muito do que C faz (já que C ++ é um superconjunto de C), com uma grande quantidade de "extras". Aprender C antes do C ++ é desnecessário - eles são linguagens efetivamente separadas.
Em outras palavras, se C fosse um conjunto de ferramentas para trabalhar madeira, provavelmente seria:
Você pode criar qualquer coisa com essas ferramentas - mas qualquer coisa legal potencialmente exige muito tempo e habilidade.
C ++ é a coleção de ferramentas elétricas em sua loja de ferragens local.
Se você seguir os recursos básicos da linguagem, o C ++ terá relativamente pouca curva de aprendizado adicional.
Porque algumas pessoas não querem móveis da IKEA. =)
Sério, embora muitas linguagens "mais altas" que C ou C ++ possam ter coisas que as tornam (potencialmente) "mais fáceis" de usar em certos aspectos, isso nem sempre é uma coisa boa. Se você não gosta da maneira como algo é feito ou o recurso não é fornecido, provavelmente não há muito o que fazer sobre isso. Por outro lado, C e C ++ fornecem recursos de linguagem de "baixo nível" suficientes (incluindo ponteiros) para que você possa acessar muitas coisas diretamente (especialmente hardware ou sistema operacional) ou construí-lo você mesmo, o que pode não ser possível em outros idiomas conforme implementado.
Mais especificamente, C possui o seguinte conjunto de recursos que o tornam desejável para muitos programadores:
Compatibilidade - C já existe há muito tempo e todos têm ferramentas e bibliotecas para isso. A linguagem em si também não é exigente - ela espera que um processador execute instruções e memória para armazenar as coisas, e é isso.
Além disso, há algo conhecido como ABI (Application Binary Interface) . Em resumo, é uma maneira de os programas se comunicarem no nível do código da máquina, o que pode ter vantagens sobre uma API (Application Programming Interface) . Enquanto outras linguagens como C ++ podem ter uma ABI, normalmente elas são menos uniformes (acordadas) que as de C, portanto, C é uma boa linguagem básica quando você deseja usar uma ABI para se comunicar com outro programa por algum motivo.
Eficiência (e ocasionalmente esquemas de gerenciamento de memória que não podem ser implementados sem acesso relativamente direto à memória).
O acesso direto à memória com ponteiros apresenta muitos truques legais (geralmente rápidos) quando você pode colocar suas patas sujas nas crianças e zeros nos cubos de memória diretamente e não ter que esperar que o professor velho distribua os brinquedos apenas na hora de brincar, pegue-os novamente.
Em suma, adicionar coisas potencialmente cria lag ou, de outra forma, introduz uma complexidade indesejada.
Com relação às linguagens de script e esse tipo, você precisa trabalhar duro para que as linguagens que exigem que os programas secundários sejam executadas com a mesma eficiência que o C (ou qualquer linguagem compilada) nativamente. A adição de um intérprete on-the-fly introduz inerentemente a possibilidade de menor velocidade de execução e maior uso de memória, porque você está adicionando outro programa ao mix. A eficiência de seus programas depende tanto da eficiência deste programa secundário quanto de quão bem (ruim =)) você escreveu o código do programa original. Sem mencionar que seu programa geralmente depende completamente do segundo programa para ser executado. Esse segundo programa não existe por algum motivo em um sistema específico? Código no go.
De fato, a introdução de algo "extra" potencialmente diminui ou complica seu código. Nas linguagens "sem ponteiros assustadores", você está sempre esperando que outros bits de código sejam limpos atrás de você ou, de outra forma, descubra maneiras "seguras" de fazer as coisas - porque seu programa ainda está fazendo as mesmas operações de acesso à memória que poderiam ser feitas com ponteiros. Você não é quem está lidando com isso (então você não pode f * ck, gênio = P).
De acordo com a resposta aceita:
A noção de que, como algo pode ser feito em um idioma, deve ser feito é bobagem. Os idiomas têm falhas corrigidas. Por motivos de compatibilidade com código antigo, essa construção ainda pode ser usada. Mas não há nada (provável) forçando um programador a usar gets () e, de fato, esse comando foi essencialmente substituído por alternativas mais seguras.
Mais ao ponto, o problema com gets () não é um problema de ponteiro por si só. É um problema com um comando que não necessariamente sabe como usar a memória com segurança. Em um sentido abstrato, tudo isso é questão de ponteiro - ler e escrever coisas que você não deveria. Isso não é um problema com ponteiros; é um problema com a implementação do ponteiro.
Para esclarecer, os ponteiros não são perigosos até você acessar acidentalmente um local de memória que não pretendia. E mesmo assim, isso não garante que o seu computador derreta ou exploda. Na maioria dos casos, seu programa deixará de funcionar (corretamente).
Dito isto, como os ponteiros fornecem acesso aos locais da memória e porque os dados e o código executável existem juntos na memória, há um risco real de corrupção acidental o suficiente para que você queira gerenciar a memória corretamente.
Nesse ponto, como as operações de acesso à memória realmente diretas geralmente oferecem menos benefícios em geral do que poderiam ter anos atrás, mesmo linguagens sem coleta de lixo como o C ++ introduziram coisas como ponteiros inteligentes para ajudar a preencher a lacuna entre eficiência e segurança da memória.
Em resumo, há muito poucas razões para temer o ponteiro, desde que seja usado com segurança. Basta dar uma dica da versão de Steve "The Hunter Crocodile" Irwin, de South Park - não saia por aí enfiando o polegar nos buracos dos crocodilos .
fonte
Como sempre, a linguagem de programação é apenas uma consequência da solução de problemas. Na verdade, você deve aprender não apenas C, mas muitas linguagens diferentes (e outras maneiras de programar um computador, sejam ferramentas da GUI ou intérpretes de comando) a ter uma caixa de ferramentas decente para usar na solução de problemas.
Às vezes, você descobrirá que um problema se presta bem a algo que está incluído nas bibliotecas padrão do Java; nesse caso, você pode escolher Java para aproveitar isso. Em outros casos, pode ser que você precise fazer algo muito mais simples no tempo de execução do .NET no Windows, portanto, você pode usar C # ou VB. Pode haver uma ferramenta gráfica ou script de comando que resolva o seu problema, então você pode usá-los. Talvez você precise escrever um aplicativo GUI em várias plataformas, o Java pode ser uma opção, considerando as bibliotecas incluídas no JDK, mas, novamente, uma plataforma de destino pode não ter um JRE, então talvez você escolha C e SDL (ou similar).
C tem uma posição importante neste conjunto de ferramentas, pois é geral, pequeno e rápido e também compila para o código de máquina. Também é suportado em todas as plataformas sob o sol (não sem recompilar no entanto).
Resumindo, você deve aprender quantas ferramentas, linguagens e paradigmas puder.
Afaste-se da mentalidade: "Sou um programador X" (X = C, C ++, Java, etc.)
Basta usar "Eu sou um programador".
Um programador resolve problemas e cria algoritmos instruindo as máquinas a executar a carga de trabalho. Fim da história. Isso é irrelevante para o idioma. Sua habilidade mais importante é a resolução de problemas e a quebra lógica de problemas estruturados; a habilidade / escolha de idioma SEMPRE é secundária e / ou uma consequência da natureza do problema.
Um caminho interessante se você estiver interessado em C é ampliar seu conjunto de habilidades com o Go. O Go é realmente um C melhorado, com coleta de lixo e interfaces, além de um bom modelo / canais de encadeamento, que também trazem muitos dos benefícios do C (como aritmética de ponteiro e compilação de código de máquina).
fonte
Depende do que você pretende fazer com isso. C foi projetado como um substituto para a linguagem assembly e é a linguagem de alto nível mais próxima da linguagem da máquina. Portanto, possui baixos custos indiretos em tamanho e desempenho e é adequado para programação de sistemas e outras tarefas que exigem uma área ocupada pequena e se aproximam do hardware subjacente.
fonte
Quando você trabalha no nível de bits e bytes, da memória como uma coleta homogênea bruta de dados, como seria frequentemente necessário para implementar efetivamente os alocadores e estruturas de dados mais eficientes, não há segurança. A segurança é predominantemente um conceito forte relacionado ao tipo de dados e um alocador de memória não funciona com tipos de dados. Ele trabalha com bits e bytes para reunir esses mesmos bits e bytes, potencialmente representando um tipo de dado em um momento e outro posteriormente.
Não importa se você usa C ++ nesse caso. Você ainda estaria espalhando
static_casts
todo o código para transmitir a partir devoid*
ponteiros e ainda trabalhando com bits e bytes e apenas lidando com mais aborrecimentos relacionados a respeitar o sistema de tipos nesse contexto do que C, que tem um sistema de tipos muito mais simples, onde você está livre dememcpy
bits e bytes redor sem se preocupar com bulldozing sobre o sistema de tipo.Na verdade, muitas vezes é mais difícil trabalhar em C ++, uma linguagem geral mais segura, em contextos de baixo nível de bits e bytes sem escrever código ainda mais perigoso do que você faria em C, já que você pode estar fazendo um bulldoze no sistema de tipos do C ++ e fazendo coisas como sobrescrevendo vptrs e não invocando construtores e destruidores de cópia em momentos apropriados. Se você dedicar um tempo adequado para respeitar esses tipos e usar a colocação de novos e chamar manualmente os dtors e assim por diante, será exposto ao mundo do tratamento de exceções em um contexto de nível muito baixo para que o RAII seja prático e alcance exceções. a segurança em um contexto de nível tão baixo é muito difícil (você precisa fingir que qualquer função pode lançar e capturar todas as possibilidades e reverter todos os efeitos colaterais como uma transação indivisível, como se nada tivesse acontecido). O código C pode frequentemente "
E seria impossível implementar esses alocadores em idiomas que não permitem que você seja "perigoso" aqui; você teria que se apoiar em qualquer alocador que eles fornecem (implementado provavelmente em C ou C ++) e espero que seja bom o suficiente para seus propósitos. E há quase sempre alocadores e estruturas de dados mais eficientes, mas menos gerais, adequados para seus propósitos específicos, mas muito mais restritos, pois são especificamente adaptados para seus propósitos.
A maioria das pessoas não precisa de C ou C ++, uma vez que pode simplesmente chamar código implementado originalmente em C ou C ++ ou possivelmente até montagem já implementada para eles. Muitos podem se beneficiar da inovação de alto nível, como montar um programa de imagem que apenas usa bibliotecas de funções de processamento de imagem existentes já implementadas em C, onde não estão inovando tanto no nível mais baixo de loop através de pixels individuais, mas talvez oferecendo uma interface de usuário muito amigável e um fluxo de trabalho nunca antes visto. Nesse caso, se o objetivo do software é apenas fazer chamadas de alto nível em bibliotecas de baixo nível ( "processe toda essa imagem para mim, não para cada pixel, faça alguma coisa" ), então pode ser uma otimização prematura. até tentar começar a escrever esse aplicativo em C.
Mas se você está fazendo algo novo em um nível baixo, onde ajuda a acessar dados de um nível mais baixo, como um novo filtro de imagem nunca visto antes, que é rápido o suficiente para trabalhar em vídeo HD em tempo real, geralmente é necessário obter um pouco perigoso.
É fácil tomar essas coisas como garantidas. Lembro-me de uma postagem no Facebook com alguém apontando como é possível criar um videogame 3D com Python, com a implicação de que linguagens de baixo nível estão se tornando obsoletas, e certamente era um jogo de aparência decente. Mas o Python estava fazendo chamadas de alto nível para as bibliotecas implementadas em C para fazer todo o trabalho pesado. Você não pode fazer o Unreal Engine 4 apenas fazendo chamadas de alto nível para as bibliotecas existentes. O Unreal Engine 4 éa biblioteca. Ele fez todos os tipos de coisas que nunca existiram em outras bibliotecas e mecanismos, desde a iluminação até o sistema de projeto nodal e como ele pode compilar e executar o código rapidamente. Se você deseja inovar no tipo de baixo nível de mecanismo / núcleo / kernel, precisa obter um nível baixo. Se todos os desenvolvedores de jogos mudassem para idiomas seguros de alto nível, não haveria o Unreal Engine 5, 6 ou 7. Provavelmente ainda haveria pessoas usando o Unreal Engine 4 décadas depois, porque você não pode inovar no nível necessário para vir com um mecanismo de última geração, fazendo apenas chamadas de alto nível para o antigo.
fonte