As mentes jovens precisam aprender os conceitos de ponteiro?


89

Por que o mestre C, Dennis Ritchie, introduziu indicadores em C? E por que as outras linguagens de programação como VB.NET ou Java ou C # as eliminaram? Encontrei alguns pontos no Google e também quero ouvir seus comentários. Por que eles estão eliminando conceitos de ponteiros nas linguagens modernas?

As pessoas dizem que C é a linguagem básica e ponteiros é o conceito que torna C poderoso e excelente e ainda faz C competir com idiomas mais modernos. Então, por que eles eliminaram indicadores em idiomas mais modernos?

Você acha que o conhecimento de ponteiros ainda é importante para novos programadores? Atualmente, as pessoas estão usando VB.NET ou Java, que suporta recursos mais avançados do que C (e não usa conceitos de ponteiros) e muitas pessoas como eu vejo agora (meus amigos) escolhem essas linguagens ignorando C, pois suportam recursos avançados. Eu digo a eles para começarem com C. Eles dizem que é um desperdício aprender os conceitos de ponteiros quando você está fazendo coisas avançadas em VB.NET ou Java que não são possíveis em C.

O que você acha?

Atualizado :

Os comentários que li no Google são:

  1. Os computadores anteriores eram muito lentos e não otimizados.

  2. O uso de ponteiros torna possível acessar um endereço diretamente e isso economiza tempo, em vez de fazer uma cópia dele em chamadas de função.

  3. A segurança é significativamente pior usando ponteiros, e é por isso que Java e C # não os incluíram.

Estes e mais um pouco do que encontrei. Eu ainda preciso de algumas respostas valiosas. Isso iria ser incrivelmente apreciado.


52
Java não tem ponteiros? Isso não é verdade. Toda referência de objeto em Java é, basicamente, um ponteiro.
quant_dev 5/09/11

20
O que quant_dev significa é que o Java está cheio de ponteiros que são usados ​​de forma transparente, enquanto os programadores não podem usá-los explicitamente.
Sakisk

9
Aqui está um artigo de Joel Spolsky que é relevante ... joelonsoftware.com/articles/fog0000000319.html
Joe Internet

11
"Por que o mestre C, Dennis Ritchie, introduziu indicadores em c?" Os ponteiros não foram introduzidos em c, eles vieram diretamente da prática de montagem, incluindo o nome.
dmckee

14
@quaint_dev: Bem, o Java realmente não tem ponteiros. As referências não podem fazer tudo o que os ponteiros podem fazer, portanto, tentar entender os ponteiros em termos de referências não é o caminho a seguir (e é um erro que muitos programadores aprendendo C ou C ++ cometem). Ponteiros podem fazer aritmética. Referências não podem. (A limitação que realmente fede cada vez que eu sou forçado a usar Java)
Billy ONeal

Respostas:


128

Naquela época, os desenvolvedores estavam trabalhando muito mais próximos do metal. C era essencialmente uma substituição de nível superior para montagem, que é quase o mais próximo possível do hardware, por isso era natural que você precisasse de indicadores para ser eficiente na solução de problemas de codificação. No entanto, os ponteiros são ferramentas afiadas, que podem causar grandes danos se usadas de forma descuidada. Além disso, o uso direto de ponteiros abre a possibilidade de muitos problemas de segurança, que não eram um problema na época (em 1970, a Internet consistia em cerca de algumas dúzias de máquinas em algumas universidades, e nem era chamada assim. ...), mas tornou-se cada vez mais importante desde então. Atualmente, linguagens de nível superior são projetadas conscientemente para evitar indicadores de memória não processada.

Dizer que "coisas avançadas feitas em VB.Net ou Java não são possíveis em C" mostra um ponto de vista muito limitado, para dizer o mínimo :-)

Antes de tudo, todas essas linguagens (inclusive montagem) são Turing completas, portanto, em teoria, o que for possível em um idioma, é possível em todos. Apenas pense no que acontece quando um pedaço de código VB.Net ou Java é compilado e executado: eventualmente, é traduzido (ou mapeado para) código de máquina, porque essa é a única coisa que a máquina entende. Em linguagens compiladas como C e C ++, é possível obter todo o corpo do código de máquina equivalente ao código fonte original de nível superior, como um ou mais arquivos / bibliotecas executáveis. Em linguagens baseadas em VM, é mais complicado (e talvez nem seja possível) obter toda a representação equivalente de código de máquina do seu programa, mas ainda assim ela está presente em algum lugar, dentro dos recessos profundos do sistema de tempo de execução e do JIT.

Agora, é claro, é uma questão totalmente diferente se alguma solução é viável em um idioma específico. Nenhum desenvolvedor sensato começaria a escrever um aplicativo Web no assembly :-) Mas é útil ter em mente que a maioria ou todas essas linguagens de nível superior são criadas com base em uma enorme quantidade de código de tempo de execução e de biblioteca de classes, uma grande parte da que é implementado em um idioma de nível inferior, normalmente em C.

Então, para chegar à pergunta,

Você acha importante o conhecimento de indicadores para os jovens [...]?

O conceito por trás dos ponteiros é indireto . Este é um conceito muito importante e IMHO todo bom programador deve entender em um determinado nível. Mesmo se alguém estiver trabalhando apenas com idiomas de nível superior, a indireção e as referências ainda serão importantes. Não compreender isso significa ser incapaz de usar toda uma classe de ferramentas muito potentes, limitando seriamente a capacidade de resolução de problemas a longo prazo.

Portanto, minha resposta é sim, se você quiser se tornar um programador realmente bom, também deve entender os ponteiros (assim como a recursão - esse é o outro obstáculo típico para desenvolvedores iniciantes). Você pode não precisar começar com isso - não acho que o C seja ótimo como primeira língua hoje em dia. Mas em algum momento deve-se familiarizar com a indireção. Sem ele, nunca podemos entender como as ferramentas, bibliotecas e estruturas que estamos usando realmente funcionam. E um artesão que não entende como suas ferramentas funcionam é muito limitado. Justo o suficiente, pode-se entender também em linguagens de programação de nível superior. Um bom teste decisivo está implementando corretamente uma lista duplamente vinculada - se você pode fazê-lo no seu idioma favorito, pode afirmar que entende bem a indireção.

Mas, se não fosse por mais alguma coisa, deveríamos fazê-lo para aprender a respeitar os programadores antigos que conseguiram construir coisas inacreditáveis ​​usando as ferramentas ridiculamente simples que possuíam (em comparação com o que temos agora). Estamos todos de pé sobre os ombros dos gigantes, e é bom para nós reconhecer isso, em vez de fingir que somos os próprios gigantes.


5
Essa é uma boa resposta, mas na verdade não responde à pergunta: "As mentes jovens precisam aprender os conceitos dos ponteiros?"
Falcon

11
+1 boa resposta. No entanto, deixaria de lado o argumento da integridade - para a programação prática, é um arenque vermelho, como você também notará mais tarde. É a teoria da computabilidade, ou seja, completar apenas significa que existe um programa no espaço (para muitas línguas, infinito) de programas em potencial que implementa o mesmo algoritmo, não se é realmente possível ou humanamente possível. Apenas apontar que é todo o código de máquina no final prova o ponto tão bem sem plantar o estúpido "Eu posso fazer tudo em um idioma, pois são todos iguais, harhar!" semente.

5
+1 para "E um artesão que não entende como suas ferramentas funcionam é muito limitado".
rapid_now 5/11

6
Além disso, não entender a mecânica dos ponteiros (e por referências de extensão) significa, conseqüentemente, que você não entende os conceitos de cópia superficial / profunda da estrutura de dados, o que pode causar sérios erros difíceis de rastrear. Mesmo em idiomas "modernos" de alto nível.
Mavrik

1
C foi projetado para ser montador portátil para Unix, ou seja, próximo ao metal.

39

Eu acho que você precisa diferir.

Java e outras linguagens de nível superior não removeram ponteiros. O que eles fizeram foi remover a aritmética simples do ponteiro.

De fato, Java ainda permite uma aritmética de ponteiro protegido e restrito : o acesso ao array. No C antigo, o acesso ao array nada mais é do que desreferenciamento. É uma notação diferente, um açúcar sintático, se você quiser, para comunicar claramente o que está fazendo.
Ainda assim, array[index]é equivalente a *(array+index). Por isso, também é equivalente a, index[array]embora eu suponha que alguns compiladores C possam lhe dar um aviso, se você fizer isso.
Como corolário, pointer[0]é equivalente a *pointer. Isso é simplesmente porque o "ponteiro para uma matriz" é o endereço da primeira entrada da matriz e os endereços dos elementos subseqüentes são calculados adicionando o índice.

Em Java, a aritmética simples de ponteiro (referência e desreferenciação) não existe mais. No entanto, existem indicadores. Eles os chamam de referências, mas isso não muda o que é. E o acesso ao array ainda é exatamente o mesmo: verifique o endereço, adicione o índice e use esse local de memória. No entanto, em Java, ele verificará se esse índice está ou não dentro dos limites da matriz que você alocou originalmente. Caso contrário, lançará uma exceção.

Agora, a vantagem da abordagem Java é que você não possui código, que grava cegamente bytes arbitrários em locais de memória arbitrários. Isso melhora a segurança e também a segurança, porque se você não verificar os estouros de buffer, o tempo de execução fará isso por você.

A desvantagem disso é que é simplesmente menos poderoso. É possível fazer uma programação segura de memória em C. É impossível se beneficiar da velocidade e das possibilidades de programação insegura em Java.

Na verdade, não há nada difícil sobre ponteiros ou aritmética de ponteiros. Eles normalmente são explicados de maneira complicada, enquanto tudo que um ponteiro é é um índice para uma matriz gigante (seu espaço de memória), tudo que faz referência a um valor fornece o índice onde encontrá-lo, tudo o que a desreferenciação é procurar o valor em um determinado índice. (Isso é um pouco simplificado, porque não leva em conta que os valores têm tamanho diferente na memória, dependendo do tipo. Mas isso é um detalhe circunstancial, e não uma parte do conceito real)

IMHO, todos em nosso trabalho devem ser capazes de entender isso, ou eles estão simplesmente no campo errado.


13
+1 Java e C # ainda têm ponteiros e, é claro, NullPointerExceptions
jk.

5
Observe também que as referências podem apontar para diferentes áreas ao longo do tempo, à medida que o coletor de lixo move as coisas. Os ponteiros são geralmente estáticos.

3
+1: isso! E acho que há duas coisas difíceis de entender sobre ponteiros (em geral): indireção (que acontece em C, C #, Java, ...) e aritmética de ponteiros (que não acontece da mesma maneira em Java). Na minha opinião, ambos são conceitos importantes para aprender e ambos são grandes obstáculos para iniciantes. Mas eles não devem ser confundidos: a indireção pode acontecer sem a aritmética do ponteiro.
Joachim Sauer

2
Na verdade, back2dosestava certo na primeira vez, já que (array + index)já leva em conta o tamanho dos objetos (em C).
Matthew Flaschen

4
@ CyberSkull, a resposta estava dando o equivalente sintático de array[index], e é isso *(array+index). Se você quiser mostrar como o compilador faz as coisas internamente, é possível falar explicitamente sobre bytes ou fornecer o assembly.
Matthew Flaschen

24

O conceito de ponteiros é importante no conhecimento geral da programação de computadores. Compreender o conceito é bom para programadores ou programadores de qualquer idioma, mesmo que o idioma não o suporte diretamente.

Os ponteiros têm seu uso nas estruturas de dados (listas vinculadas) e no design do banco de dados (chave estrangeira).

Idiomas como VB e C # podem passar dados por "referência" a métodos, que podem ser considerados como um tipo de ponteiro.

Compreender onde os dados são alocados na memória (pilha x pilha) ainda é importante para a eficiência dos algoritmos.

Aprender o básico direito é importante na minha opinião.


Acho o conceito geral útil, mas nunca encontrei uma situação em que precise de um ponteiro (desde que eu use Java e PHP principalmente). Os únicos exemplos meus cursos C ++ já veio com para ponteiros foi usá-los para criar estruturas de dados mais complexas, como listas e dicionários que existem em qualquer linguagem de programação de alto nível para começar ..
Ben Brocka

2
Você está correto de certa forma, mas quando passa dados para métodos, é provável que, em alguns casos, você esteja passando um ponteiro para a variável. No entanto, o conceito de ponteiro é útil (na minha opinião), independentemente de sua implementação em uma linguagem de software.
precisa saber é o seguinte

1
@SirTapTap: Isso porque se você aprendeu C ++ em algum tipo de curso, eles ensinam C ++. Não é a melhor maneira de usar C ++. A aritmética dos ponteiros geralmente é encoberta porque é algo com o qual você pode ter um conhecimento passageiro de C ++ e não saber. Mas mesmo coisas como iterar sobre uma coleção geral são feitas com ponteiros em C ++ real / idiomático. (Como é a base de como a Standard Template Library funciona)
Billy ONeal

Os @BillyONeal Pointers estavam quase na metade do curso, na verdade, eu ainda nunca encontrei um uso prático para ponteiros (inteligentes) como programador, desde que eu nunca precisei daquele controle direto sobre a memória em qualquer coisa que eu fiz. É claro que sempre há a possibilidade de o curso ter sido mal ministrado, não era exatamente o meu favorito.
Ben Brocka

1
@SirTapTap: Uso prático: toda coleção e algoritmo no STL. std::sort, std::partition, std::find, Etc. Eles trabalham com ponteiros, e eles trabalham com objetos que agem como ponteiros (iterators). E eles trabalham sobre qualquer coleção geral; listas vinculadas, matrizes dinâmicas, deques, árvores ou qualquer outro tipo de coleção definida pelo usuário. Você não pode esse tipo de abstração sem ponteiros.
Billy ONeal

19

Sim, sim, sim, sim e sim !!!

Se você não souber o básico, NUNCA será capaz de resolver os problemas realmente difíceis, estranhos, difíceis e complicados que surgirem no seu caminho.

E se você entende muito bem o básico, é MUITO mais comercializável no mercado de trabalho.


Trabalhei uma vez com um sujeito que programava há 10 anos e não fazia ideia de como os ponteiros funcionavam. Eu (muito mais júnior) passei horas em um quadro branco educando-o. Isso abriu meus olhos. Ele não tinha idéia de tantas coisas básicas.

Saiba o máximo que puder.


Mas o que é básico? Assembly, código binário?
SiberianGuy

5
Embora seu ponto de vista geral de "saiba o máximo que puder" seja sensato, eu questionaria a idéia de que "NUNCA conseguirá resolver os problemas realmente difíceis, estranhos, difíceis e complicados que surgem no seu caminho" se você não entendo ponteiros. De alguma forma, isso implica que todos os problemas difíceis podem ser resolvidos usando esses indicadores "mágicos", o que não é o caso. Os conceitos entre ponteiros são úteis, mas não são diretamente essenciais para muitos campos da programação.
Dan Diplo

4
@Idsa: não, ainda mais básico, hoje em dia muitos programadores nem sabem como funcionam os transistores e portas lógicas nos chips goo 'ole', e certamente deveriam saber como os elétrons se movem e o efeito da incerteza quântica na miniaturização; Eu nem comecei com charlatões, liptons e bisões! e as partículas de bisonte dos soluços!
Lie Ryan

2
Noções básicas ... coisas como armazenamento de coisas. A diferença entre um byte, uma palavra, como o trabalho assinado e o não assinado. Como os ponteiros funcionam. O que é um personagem. Como as coisas são codificadas em ASCII (e atualmente, Unicode). Como uma lista vinculada pode ser criada na memória usando apenas estruturas simples. Como as strings REALMENTE funcionam. A partir dessas pequenas coisas, coisas maiores crescem.
quickly_now

5
Saiba o máximo que puder é um bom princípio, mas acho que você tem a carroça diante do cavalo. Bons desenvolvedores se esforçam para aprender o que podem, porque são bons desenvolvedores. O desejo de conhecimento é uma característica de um bom desenvolvedor. Não é a causa de um bom desenvolvedor. Sair e aprender o máximo que puder não fará de você um bom desenvolvedor. Isso fará de você uma enciclopédia ambulante, nada mais. Se você é um bom desenvolvedor, ENTÃO, APLIQUE esse conhecimento que adquiriu para resolver problemas. Mas se você ainda não era um bom desenvolvedor, o conhecimento não o ajudará muito.
CorsiKa 6/09/11

18

Sim, a compreensão é importante.

Alguns meses atrás, eu estava programando em C # e queria fazer uma cópia de uma lista. Claro que o que fiz foi NewList = OldList;e depois comecei a modificar NewList. Quando tentei imprimir as duas listas, elas eram as mesmas, já que NewListeram apenas um ponteiro para OldListe não uma cópia, então eu estava realmente mudando o tempo OldListtodo. Não demorei muito para descobrir isso, mas alguns dos meus colegas de classe não foram tão rápidos e tiveram que ser explicados por que isso está acontecendo.

Exemplo:

List<int> a = new List<int>();
a.Add(2);
a.Add(9);
a.Add(8);
a.Add(1);
List<int> b = new List<int>();
b = a; //Does not make a copy, b is just a synonym!
b.Sort();
for (int i = 0; i < a.Count; i++)
{
    Console.WriteLine("a: " + a[i] + " b: " + b[i]);
}

E, claro, o resultado é assim:

a: 1 b: 1
a: 2 b: 2
a: 8 b: 8
a: 9 b: 9

Saber usá-los não é tão importante, mas entendê-los é crucial!


2
Em vez disso por que usá-los e quando usá-los é :) mais importante
niko

5
" NewListera apenas um ponteiro para OldList" - para ser preciso, ambos NewListe OldListeram apenas ponteiros, referindo-se ao mesmo Listobjeto.
Péter Török

Também é importante entender que a nova lista que você criou bnão tem mais referências a ela e agora é lixo.
TMN

14

Ponteiro do conceito! = Ponteiro da aritmética! = Ponteiro da sintaxe

O primeiro importa sempre, se você precisa (e precisa) de uma cópia profunda / superficial, passa por referência / passa por valor, etc. Os outros dois importam apenas se o seu idioma do dia permitir que você os use.


1
Atualmente, você precisa conhecer apenas o conceito básico de referências, não a sintaxe do ponteiro / matemática. Eu aprendi ponteiros (com aritmética e sintaxe) em C na época. As linguagens em que eu programo agora não lidam com ponteiros no estilo C que permitem fazer coisas inseguras. Pode-se entender por que em python a=[1,2]; b=a; a.append(3)que tanto ae bvão ambos referenciar o mesmo objeto [1,2,3]sem saber coisas como em C o ielemento th de uma matriz pode ser referenciado por arr[i]ou i[arr]como ambos são *(arr+i). Eu prefiro quando o idioma não deixa i[arr]ser usado.
precisa saber é o seguinte

" Os outros dois importam apenas se o seu idioma du jour permitir que você os use. " - Essa frase está carregando seu próprio autodestruidor. A linguagem do dia é, por definição, muito improvável que seja a mesma linguagem usada amanhã. E amanhã você poderá se deparar com um idioma ativado por ponteiro. Bottom line? Melhor entender agora, de uma vez para sempre. Não é tão difícil, mas vale a pena.
JensG #

14

Por que o mestre C, Dennis Ritchie, introduziu indicadores em C?

Porque os ponteiros são um mecanismo muito poderoso que pode ser usado de várias maneiras.

E por que as outras linguagens de programação como VB.NET ou Java ou C # as eliminaram?

Porque os ponteiros são um mecanismo muito perigoso que pode ser mal utilizado de várias maneiras.

Eu acho que os programadores devem aprender sobre indicadores, mas de uma perspectiva educacional, não é aconselhável apresentá-los cedo. A razão é que eles são usados ​​para diversos fins, é difícil dizer como iniciante por que você está usando um ponteiro em uma circunstância específica.

Aqui está uma lista incompleta para que os ponteiros são usados:

  • alocação dinâmica ( new T)
  • estruturas de dados recursivas ( struct T { T* next; /* ... */ };)
  • iteradores sobre matrizes ( for (T* p = &a[0]; p != &a[0] + n; ++p) { ... })
  • acesso compartilhado a objetos ( T* new_pointer = existing_pointer;)
  • polimorfismo de subtipo ( T* pointer_to_base = pointer_to_derived;)
  • chamada herdada por referência ( mutate(&object);)
  • tipos opcionais ( if (p) { /* ... */ })

Observe que o uso de um único mecanismo para todos esses conceitos demonstra o poder e a elegância do programador experiente e o grande potencial de confusão para alguém novo em programação.


" Por que o mestre C, Dennis Ritchie, introduziu ponteiros em C ? Porque os ponteiros são um mecanismo muito poderoso que pode ser usado de várias maneiras". - Não sei de fato, mas acho que tem algo a ver com as instruções da máquina para serem inseridas na linguagem C, e os antecessores dos programadores C. Assembler costumam pensar em ponteiros, então seria uma surpresa se ele não tivesse usado esses mecanismos poderosos conhecidos. Qualquer outra coisa estaria muito longe para 1978 ou até a década de 1960.
JensG

12

Por quê? Você pode escrever um sistema enorme com designer de formulários e gerador de código. Não é suficiente? (ironia)

E agora, falando sério, os indicadores não são parte crucial da programação em muitas áreas, mas permitem que as pessoas entendam como os internos funcionam. E se não tivermos ninguém que entenda como funcionam os internos, haverá uma situação em que SQL2020, Windows 15 e Linux 20.04 serão gravados em uma máquina virtual coletada de lixo executando mais de 30 camadas de abstração, com código gerado via IDE, em JavaScript .

Definitivamente não é o que eu quero ver.

Então, sim, eles precisam, definitivamente!


2
Bom humor! +1 e concordo totalmente.
heltonbiker

7

Nem Java nem C # eliminaram ponteiros, eles têm referências quase iguais. O que foi eliminado é a aritmética dos ponteiros, que pode ser omitida em um curso introdutório.
Nenhuma aplicação não trivial poderia ser feita sem o conceito de ponteiros ou referências, portanto vale a pena ensinar (nenhuma alocação dinâmica de memória poderia ser feita sem eles).

Considere o seguinte em C ++ e Java, e acho que não é muito diferente em C #:
aClass *x = new aClass();
aClass x = new aClass();
não há realmente muita diferença entre ponteiros e referências, certo?
A aritmética dos ponteiros deve ser evitada, a menos que seja necessário e ao programar com modelos de alto nível, para que não haja muito problema.


6

O programador profissional deve dominar os indicadores.

As pessoas que desejam conhecer programação devem aprender sobre sua existência e implicações, mas não necessariamente usá-las.

As pessoas que desejam resolver problemas pessoais via programação (como eu, que usam muitos scripts Python) podem muito bem ignorá-los.

Bem, essa é a minha opinião ...; o)


3

Ponteiros de endereço variável são um caso específico do conceito mais generalizado de indireção. O indireto é usado na maioria dos idiomas (todos?) Modernos em muitas construções, como delegados e retornos de chamada. Compreender o conceito de indireção permite saber quando e como usar melhor essas ferramentas.


3

Absufreakinglutely SIM ! Todo mundo que programa precisa entender ponteiros e indiretos.

Os indicadores são como uma grande quantidade de acesso a dados é realizada em todos os idiomas. Ponteiros são um recurso de hardware de todos os microprocessadores. Linguagens de alto nível, como Java, VB e C #, essencialmente impedem o acesso direto aos ponteiros dos usuários da linguagem com referências. As referências se referem a objetos por meio do esquema de gerenciamento de memória do idioma (pode ser um ponteiro com metadados ou apenas um número para uma tabela de memória, por exemplo).

Compreender como os ponteiros funcionam é fundamental para entender como os computadores realmente funcionam. Os ponteiros também são mais flexíveis e poderosos que as referências.

Por exemplo, a razão pela qual matrizes começam no índice zero é porque elas são, na verdade, atalhos para a aritmética do ponteiro. Sem aprender como os ponteiros funcionam, muitos programadores iniciantes não conseguem arrays.

int a, foo[10];
foo[2] = a;

A linha 2 na aritmética do ponteiro seria:

*(foo + sizeof(int) * 2) = a;

Sem entender os ponteiros, não se pode entender o gerenciamento de memória, a pilha, a pilha ou mesmo matrizes! Além disso, é preciso entender ponteiros e desreferenciamento para entender como as funções e os objetos são transmitidos.

TL: DR : entender os ponteiros é fundamental para entender como os computadores realmente funcionam .


2

Eu acho que tudo se resume ao fato de que a necessidade de lidar com ponteiros desapareceu à medida que os programadores lidavam menos com o hardware direto em que estavam executando. Por exemplo, alocar uma estrutura de dados de lista vinculada de forma que caiba perfeitamente na sequência de módulos de memória de 640 bytes que o hardware especializado possuía.

Lidar com ponteiros manualmente pode ser propenso a erros (levando a vazamentos de memória e código explorável) e é demorado para acertar. Portanto, Java e C # etc agora gerenciam sua memória e seus ponteiros para você através de suas Máquinas Virtuais (VMs). Isso é sem dúvida menos eficiente do que usar C / C ++ bruto, embora as VMs estejam melhorando constantemente.

C (e C ++) ainda são linguagens amplamente usadas, especialmente nos espaços de computação de alto desempenho, jogos e hardware incorporado. Pessoalmente, sou grato por ter aprendido sobre ponteiros, pois a transição para as referências do Java (um conceito semelhante aos ponteiros) foi muito fácil e não fiquei perdida quando vi meu primeiro NullPointerException (que realmente deveria ser chamado de NullReferenceException, mas discordo). .

Eu recomendaria aprender sobre o conceito de ponteiros, pois eles ainda sustentam muitas estruturas de dados, etc. Em seguida, escolha uma linguagem na qual você goste de trabalhar, sabendo que, se algo como um NPE aparecer, você saberá o que realmente está acontecendo. .


0

Esta é a verdade objetiva:

Alguns idiomas suportam acesso direto à memória (ponteiros), outros não. Existem boas razões para cada caso.

  1. Como alguém disse aqui, nos dias de C, o gerenciamento automático de memória não era tão elaborado quanto é hoje. E as pessoas estavam acostumadas a isso, de qualquer maneira. Os bons programadores da época tinham um entendimento muito mais profundo dos programas de computador do que da nossa geração (tenho 21 anos). Eles estão usando cartões perfurados e dias de espera há algum tempo de compilação no mainframe. Eles provavelmente sabiam por que cada parte do código existia.

  2. A vantagem óbvia de linguagens como C é que elas permitem que você tenha um controle mais preciso sobre seu programa. Quando você realmente precisa hoje em dia? Somente quando você estiver criando aplicativos de infraestrutura, como programas relacionados ao SO e ambientes de tempo de execução. Se você deseja apenas desenvolver um software bom, rápido, robusto e confiável, o gerenciamento automático de memória costuma ser sua melhor escolha.

  3. O fato é que o acesso direto à memória foi abusado principalmente ao longo do histórico de desenvolvimento de software. As pessoas estavam criando programas que vazavam memória e eram mais lentas por causa da alocação de memória redundante (em C é fácil e comum estender o espaço de memória virtual do processo para cada alocação).

  4. Atualmente, máquinas virtuais / tempos de execução fazem um trabalho muito melhor do que 99% dos programadores na alocação e liberação de memória. Além disso, eles permitem flexibilidade extra no fluxo que você deseja que seu programa tenha, porque você (em sua maioria) não está ocupado com a liberação de memória alocada no local e hora certos.

  5. Quanto ao conhecimento. Eu acho admirável que os programadores saibam como os ambientes nos quais eles programam são implementados. Não necessariamente nos mínimos detalhes, mas no quadro geral.

Eu acho que saber como os ponteiros funcionam (no mínimo) é interessante. O mesmo que saber como o polimorfismo é implementado. De onde seu processo obtém sua memória e como. Essas são coisas que sempre me interessaram pessoalmente. Posso dizer honestamente que eles me tornaram um programador melhor, mas não posso dizer que eles são uma necessidade educacional para quem quer se tornar um bom programador. Em qualquer um dos casos, saber mais geralmente o tornará melhor no seu trabalho.

  1. Do meu ponto de vista, se tudo o que você precisa fazer é criar um aplicativo em Java ou C # ou algo parecido, precisará se concentrar nas técnicas de design e implementação adequadas. Código testável, código limpo, código flexível. Naquela ordem.

Porque, mesmo que você não conheça todos os pequenos detalhes, alguém que o faça poderá mudar o que você criou para algo que simplesmente tenha um desempenho melhor. E isso geralmente não é um trabalho difícil, uma vez que você tem um design adequado, limpo e testável (e isso geralmente é a maior parte do trabalho).

Se eu fosse um entrevistador procurando contratar alguém para um aplicativo de idioma de alto nível, essas seriam as coisas pelas quais eu estaria mais interessado.

Conhecimento de baixo nível é um bônus. É bom para depuração e, ocasionalmente, para criar soluções um pouco melhores. Faz de você uma pessoa interessante, profissionalmente. Concede-lhe algum respeito no seu local de trabalho.

Mas no mundo de hoje, não é um requisito sagrado.


-1

Para propósitos mais práticos em linguagens OO de alto nível, é necessário entender as referências. Você realmente não precisa entender como essas linguagens implementam as referências em termos de ponteiros.

Existem abordagens multi-paradigma muito mais funcionais e modernas que eu valorizaria muito mais do que ser capaz de fazer aritmética de ponteiro sofisticada para dizer, escreva a 1000ª função de cópia de string otimizada provavelmente com desempenho pior que String.copy da sua biblioteca std de qualquer maneira.

Aconselho que você aprenda muito mais conceitos diferentes e de nível superior primeiro, e comece a aprender linguagens de projetos diferentes para ampliar seu horizonte antes de tentar se especializar em coisas próximas ao hardware.

Frequentemente, vejo tentativas totalmente fracassadas de otimizar o servlet da Web ou código semelhante para obter um ganho de 5%, quando o cache (memorização), otimização de SQL ou apenas o ajuste da configuração do servidor da web pode render 100% ou mais com pouco esforço. Brincar com ponteiros é uma otimização prematura na maioria dos casos.


-1

Definitivamente, precisamos ter um conceito completo de ponteiro, se você realmente deseja ser um bom programador. O motivo do conceito de ponteiro foi um acesso direto ao seu valor, que se torna mais eficiente e eficaz com restrições de tempo ...

Além disso, hoje em dia, considerando os aplicativos móveis, que têm memória muito limitada, precisamos usá-lo com muito cuidado para que sua operação seja muito rápida com a resposta do usuário ... Portanto, para esse fim, precisamos de uma referência direta ao valor ...

Considere os dispositivos da Apple, ou a linguagem Objective C, que funciona totalmente apenas com o conceito de ponteiro. Toda a variável declarada no Objetivo C está tendo Ponteiro. Você precisa acessar o wiki do Objective C


Atualmente, os aplicativos móveis têm mais memória disponível do que alguns datacenters em que o C foi concebido. Muitos aplicativos móveis são escritos em Java ou html + javascript, todos sem ponteiros (eles têm REFERÊNCIAS). Apenas uma pequena fração de programadores muito especializados consegue ver as camadas subjacentes do SO.
Jürgen Strobel
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.