O que é uma boa explicação para os ponteiros? [fechadas]

71

Em seus próprios estudos (sozinho ou para uma turma) você teve um momento de "ah ha" quando finalmente entendeu os ponteiros? Você tem uma explicação que você usa para programadores iniciantes que parece particularmente eficaz?

Por exemplo, quando os iniciantes encontram ponteiros em C, eles podem adicionar & se * s até que ele compile (como eu mesmo fiz). Talvez tenha sido uma foto, ou um exemplo muito bem motivado, que fez os ponteiros "clicarem" para você ou seu aluno. O que foi, e o que você tentou antes disso não pareceu funcionar? Houve pré-requisitos de algum tópico (por exemplo, estruturas ou matrizes)?

Em outras palavras, o que era necessário para entender o significado de & se * , quando você poderia usá-los com confiança? Aprender a sintaxe e a terminologia ou os casos de uso não são suficientes, em algum momento a ideia precisa ser internalizada.

Atualização: Eu realmente gostei das respostas até agora; Por favor, mantenha-os próximos. Há muitas grandes perspectivas aqui, mas acho que muitas são boas explicações / slogans para nós mesmos após nós internalizamos o conceito. Estou procurando contextos e circunstâncias detalhados quando você se deu conta.

Por exemplo:

I only somewhat understood pointers syntactically in C. I heard two of my friends explaining pointers to another friend, who asked why a struct was passed with a pointer. The first friend talked about how it needed to be referenced and modified, but it was just a short comment from the other friend where it hit me: "It's also more efficient." Passing 4 bytes instead of 16 bytes was the final conceptual shift I needed.

    
por Macneil 30.07.2015 / 15:56
fonte

32 respostas

25

Diagrama de memória como grade

Normalmente o que eu faço é representar a memória como uma "grade", para que eu possa criar endereços, destacar diferentes espaços de memória e escrever nos valores das células (ou ainda mais, suas representações binárias) e vincular os ponteiros na memória os valores que eles apontam. (E ainda menciona que é uma simplificação).

Geralmente é um momento "ohhh" para a maioria dos meus alunos.

Malabarismo de símbolos

Então, quando se trata de fazê-los parar de esquecer como usar & e *, é muito simples: apresentá-lo da mesma maneira que fazem cálculos matemáticos ou físicos. Se você dividir uma distância em km por hora, você terá uma velocidade em km / h. O que precisa estar fora. Simples.

printf para o Rescue

Fazer apenas alguns exemplos básicos que representam visualmente o que você explicou com eles irá confortá-los naquilo que eles acham que entenderam, ou dar a eles a oportunidade de dizer "ah, eu não entendo esse".

Seja extenso

Encaminhe os ponteiros para tipos simples e verifique se eles entendem a diferença entre o endereçamento e o tamanho de um tipo de dados, em seguida, estruturas, arrays e vários níveis.

Em seguida, inicie a aritmética do ponteiro.

Adendo: Recursão

Eu geralmente explico a recursão de maneira semelhante, usando uma representação visual. Peça-lhes que imprimam o alfabeto usando uma função pré-fabricada que escreve um único caractere e, em seguida, peça-lhes para imprimi-lo na ordem inversa, alterando apenas duas linhas.

Normalmente há um "o que o ...?" momento, e quando você adiciona apenas outro parâmetro ao seu printf para imprimir valores numéricos e recuar os passos, torna-se um suspiro de alívio.

Alternativas: o modelo Play-Doh e os copos de água

Na verdade, eu tinha alguns colegas de trabalho em uma universidade que mostravam aos alunos um vídeo explicando ponteiros e acessos à memória usando a pasta play-doh. Foi incrivelmente inteligente e bem feito, embora eu nunca tenha realmente usado essa técnica, a não ser para alunos muito jovens interessados em entender programação (mas geralmente eu não os levaria a um idioma usando ponteiros muito cedo). Basicamente, usando minúsculas bolas de jogo-doh que você pode anexar a outras bolas maiores de play-doh representando espaços de memória, e que podem ser combinados para vinculá-los (como em uma estrutura de dados vinculada) ou mesclar juntos (como em um contíguo). espaço de memória). Usando cores diferentes para os espaços de memória apontados e os ponteiros também ajudam. Mas eu ainda acho que a coisa Memória-como-Grade funciona melhor, pois você pode mostrar claramente que apontar é realmente uma questão de "endereçamento", como em um "mapa / grade". Considerando que o modo Play-doh ainda os confunde em pensar que as coisas realmente "tocam" umas às outras na memória.

A coisa da Copa da Água também foi usada diretamente por uma colega, mas eu não sei se ela veio com ela. Foi uma abordagem interessante, mas notei que muitos alunos ficaram perplexos com a explicação. Algo parecido com a técnica do Coffee Cup do DevSolo . Mas acho que na verdade é enganoso, pois você faz os alunos confundirem contêineres, estruturas de dados, ponteiros e matrizes. Pode ser uma abordagem interessante para explicar as matrizes no começo, eu presumo, mas eu não ficaria por muito tempo.

    
por 12.04.2017 / 09:31
fonte
79

Alguém muito mais sábio do que eu disse uma vez:

The nun Wu Jincang asked the Sixth Patriach Huineng, "I have studied the Mahaparinirvana sutra for many years, yet there are many areas i do not quite understand. Please enlighten me."

The patriach responded, "I am illiterate. Please read out the characters to me and perhaps I will be able to explain the meaning."

Said the nun, "You cannot even recognize the characters. How are you able then to understand the meaning?"

"Truth has nothing to do with words. Truth can be likened to the bright moon in the sky. Words, in this case, can be likened to a finger. The finger can point to the moon’s location. However, the finger is not the moon. To look at the moon, it is necessary to gaze beyond the finger, right?"

    
por 09.11.2010 / 16:16
fonte
46

Descobri que os diagramas foram muito úteis. Exemplo:


Esse tipo de diagrama me ajudou a ver que os ponteiros eram sua própria variável, mas continha um valor que era o local de outro objeto, ou seja, matriz ou string. Além disso, quando feito a lápis, eu poderia usá-lo para traçar meu programa em papel ou em uma lousa / quadro branco.

    
por 09.11.2010 / 21:02
fonte
32

Quando eu "aprendi" primeiro sobre ponteiros, eu estava meio que empurrado para isso. Minha universidade tomou a decisão muito tempo antes de eu me inscrever para centrar o currículo em Java, então quando meu professor de Estruturas de Dados fez uma palestra sobre C e nos pediu para implementar uma Lista XOR com ponteiros, senti que estava me envolvendo em algo. caminho sobre minha cabeça.

Eu entendi a definição:

A pointer is a variable that contains an address of a variable

Mas ainda não entendi grande parte do conceito. Olhando para trás, acho que centrava-se em três coisas:

  1. O que exatamente é um local de memória? (Na época eu não fiz uma aula de Organização de Computadores)

  2. A sintaxe desajeitada (Então, hum ... por que exatamente é definido como "int * ip" mas depois me refiro ao variável como "ip"?)

  3. Como exatamente é benéfico armazenar o endereço de uma variável em vez de apenas usar a variável?

Não foi até que eu comprei o livro K & R e completei todos os problemas que eu realmente compreendi. Além do fato de que eu já havia completado a classe Computer Organization (que eu acho que deveria ser necessária antes de aprender C), parte disso tinha a ver com o fato de que percebi que ponteiros podem ser usados para funções, arrays, structs ... para fazer coisas úteis e não apenas como armazenamento para endereços de variáveis comuns.

Mas meu momento "aha" foi de longe o jeito que K & R explicou a sintaxe estranha de definir um ponteiro simples. Tomei notas ao longo do livro (em que eu refrasso pontos feitos pelo livro em minhas próprias palavras, a fim de aprofundar o meu entendimento), e este é o que se relaciona com isso:

A pointer is a variable that contains an address to a variable. A pointer is both defined and dereferenced (yielding the value stored at the memory location that it points to) with the '*' operator; the expression is mnemonic.

Ex.: 
   int a;      /* Variable 'a' is an integer */

   int *ip;   /* Variable ip is a pointer and dereferencing it gives an integer.
                 In other words, the expression *ip is an int, so ip is a pointer
                 to an int */
Sempre senti que não conseguia entender os conceitos mais avançados de ponteiros até ter algo tão elementar na minha mente. Ele havia me incomodado incessantemente depois daquela tarefa (a qual eu não fiz muito bem, a propósito);) por que "* ip" não existia logo após eu (pensei que eu) definia "* ip". Dominar isso é essencial para conceitos mais avançados envolvendo ponteiros, como ponteiros de função e definições mais complicadas como esta:

char (*(x())[])()

Em suma, acho que o conceito de ponteiros requer:

  1. Uma compreensão básica de como a memória é colocado em um computador (e o que memória é).

  2. Conhecimento de quão poderoso     ponteiros podem ser (uso no mundo real,     não apenas outro conceito abstrato     que eles aprendem por uma questão de     aprendizado).

  3. Decifrando o     hieróglifos coloquialmente conhecidos como     "uma definição de um ponteiro"

Portanto, acho que deveria haver pelo menos três momentos "aha" ao aprender sobre ponteiros. Eu ainda sou um estudante, então achei que você apreciaria o ponto de vista de alguém que ainda está (relativamente) fresco aprendendo o conceito.

    
por 10.11.2010 / 01:01
fonte
18

O ponteiro é um pouco parecido com os atalhos de aplicativos em sua área de trabalho. Exclua o atalho e o destino ainda existe. Inicie o atalho e o alvo é iniciado.

Eu sempre explico o funcionamento disso simplesmente criando um arquivo txt na minha área de trabalho e dois atalhos para o arquivo. Depois de copiar e excluir os atalhos, você pode ver as pessoas entenderem a ideia por trás de 'referências'.

Quando o grupo entender os detalhes básicos dos atalhos, você poderá começar a explicar os ponteiros da maneira que quiser. Eles provavelmente entenderão isso facilmente.

    
por 10.11.2010 / 12:00
fonte
12

8-10 anos atrás, eu ensinei um curso de introdução "C" em uma faculdade comunitária. Este foi sempre um tema divertido para explorar. O que parecia funcionar melhor, e isso foi depois de discutir w / a colega de trabalho algumas vezes foi usar uma xícara de café e sua mão.

Eu usei a analogia de uma xícara de café (ou linha deles para matrizes) como uma variável (ela pode conter alguma coisa). Eu então usei minha mão, que também poderia segurar alguma coisa ou, estendendo meu dedo indicador para "apontar para" uma xícara de café.

Uma mão fechada era nula, um dedo apontando para minha cabeça (como uma arma falsa) era um ponteiro pendente.

Depois, com algumas demonstrações e viagens pelo depurador, ele clicou com a maioria.

    
por 09.11.2010 / 16:20
fonte
10

Eu realmente fico muito preocupado quando ouço a pergunta "como você conseguiu entender os ponteiros". Eu sempre achei que o conceito era incrivelmente simples e uma evolução lógica das linguagens fornecendo grande poder aos programadores.

O que me preocupa é que nunca achei difícil entender o conceito de ponteiros. Então, quando você aqui "quando você finalmente conseguiu" várias vezes, você começa a pensar:

Do I actually get it? Maybe I never did?

Talvez a razão pela qual o conceito parece ser complicado, é porque continuamos dizendo a todos que ainda não os encontraram que ponteiros são tão difíceis, e aqui estão centenas de maneiras pelas quais você pode aprender?

Apenas jogando essa idéia lá fora, é claro, pessoalmente, eu adoro um bom diagrama e Steve Gibson sempre faz um trabalho fantástico de explicar qualquer coisa !

    
por 11.11.2010 / 09:45
fonte
7

Eu nunca tive um grande problema com ponteiros em C, mas isso pode ser porque eu tive que aprender assembler primeiro. Na verdade, foi um alívio não ter mais que gerenciar endereços. Então, talvez a resposta (supondo que isso é algo que você está ensinando) é dar aos alunos uma linguagem assembly emulada para trabalhar. Eles descobrirão no processo de escrever algo mais sofisticado do que "Olá, mundo".

    
por 09.11.2010 / 18:31
fonte
6

Como eu realmente aprendi sobre ponteiros? Escrevendo um compilador simples ano de calouros da faculdade.

Como explicar ponteiros em termos leigos? Eu gosto da analogia (datada?) De um catálogo de biblioteca armazenado em cartões de índice. Cada cartão ("ponteiro") contém informações sobre onde algum livro ("dados") está localizado, mas na verdade não contém o livro em si. Se você modificar o cartão ("aritmética de ponteiro"), tudo o que ele faz é mudar o livro para o qual aponta e não tem impacto no livro em si - apenas tome cuidado para não estragar o endereço ou você pode apontar para um livro inexistente ou até mesmo a biblioteca errada. No entanto, se você seguir o "endereço" no cartão e ir para a parte correta da biblioteca ("desreferenciar o ponteiro"), poderá ver / modificar o próprio livro.

    
por 09.11.2010 / 19:36
fonte
6

Um ponteiro é uma variável cujo valor é o endereço de memória de outra variável.

    
por 09.11.2010 / 20:26
fonte
5

Eu vou assumir que alguém vai aprender ponteiros sabe quais são as variáveis normais e como elas funcionam em C. Agora, vamos tentar definir ponteiros com alguns de seus atributos -

  • Eles também são variáveis, mas de natureza diferente. Suponha que existam duas camadas no espaço variável. As variáveis normais de tipos diferentes residem na camada superior e os ponteiros na camada inferior. Como esta figura -

  • Comoonome'Pointer'sugere,osponteirospodemapontarparaalgo.Comoonossodedopodeapontarparaalgumobjeto.Quaissãoascoisasparaasquaiselesapontam?Estassãoasvariáveisnormais.Emsuma,"Ponteiros apontam para variáveis normais".

  • Como as variáveis normais, os ponteiros também são do mesmo número de tipos, como int, char ou float. E um ponteiro de um tipo específico pode apontar apenas para o mesmo tipo de variáveis.
  • Um ponteiro pode apontar para uma variável e, posteriormente, o mesmo ponteiro pode apontar para outra variável. Apenas o tipo deve ser o mesmo. Portanto, a associação do ponteiro com alguma variável não é permanente e pode ser alterada.
  • Então, como um ponteiro é declarado? Quase como variáveis normais. Você precisa preceder o nome com um asterisco ( * ). Como-

    int *pointer;
    
  • Então, como um ponteiro é associado a uma variável? Usando o operador & antes da variável como esta declaração

    pointer = &variable;
    
  • Como um ponteiro é usado apontando para uma variável? Isso também é feito precedendo o nome com um asterisco ( * ). Então ele pode ser usado no lugar da variável que está apontando agora -

    *pointer = var1 + var2;
    

    em vez de

    variable = var1 + var2;
    
  • Agora, jogue com ponteiros com algum código. Apenas se acostumar com essas características de ponteiros agora. Até este ponto, estamos falando sobre o que os ponteiros fazem. Uma vez que você esteja bem, comece estudando como os ponteiros estão apontando para alguma variável e como eles reagem se operações aritméticas normais forem aplicadas a elas. Em seguida, vá para a relação entre ponteiros e matrizes e ponteiros para ponteiros.

É tudo o que vou sugerir sobre os ponteiros de aprendizagem.

    
por 10.11.2010 / 06:30
fonte
5

Editado em apoio ao requisito revisado da pergunta

Meu caminho para o entendimento "pós-ponteiro" (se bem me lembro) foi assim. Eu tinha uma experiência simples de programação de montagem de quando eu ainda estava mexendo com um BBC Micro então eu tinha o conceito de memória como um monte de caixas (veja abaixo para isso). Isso foi reforçado pelo uso de matrizes. No entanto, eu estava indo para o mundo de C e tive que lidar com seqüências de caracteres e isso significava ponteiros. No BASIC isso era trivial, no montador eu nunca tive que trabalhar com eles, e agora no C clássico é tudo ponteiros e outras coisas. Ah, mas posso voltar às matrizes com strings (null terminadas) assim:

char s[] = "Hello, world!";
printf("%s",s);

Tudo bem, isso é apenas uma matriz de chars (8 bits por caractere no meu mundinho) com um caractere zero no final para mostrar onde termina. O printf pega o array e o imprime. Mas e se eu quiser passar essa string para uma função?

void print_str(char* p) {
  printf("%s",p);
}

É o que o manual diz, mas o que é isso? Hmm, char * significa "ponteiro para um char". OK ... me perdeu. Então me dei conta de que o char * faz p equivalente a s [0]. OK, eu posso usar isso, mas eu ainda não tenho twigged quais são os ponteiros. Quero dizer, como eu defino alguns dados com uma dessas coisas? Para o manual novamente ...

char* p = "Hello World!";

Enquanto escrevo o texto acima, estou dizendo para mim mesmo "declarar um ponteiro para um caractere e defini-lo como igual a essa matriz de caracteres". De alguma forma, esse ponteiro acaba com a necessidade de um array. Acho que é o compilador fazendo algumas coisas para mim para variar. Então, como eu posso mudar o array com esse ponteiro? Eu sei que eu poderia usar a versão da matriz

 s[2] = 'L'; 

mas qual é o equivalente em "pointer speak"? Para aquele manual novamente ...

*(p+2) = 'L';

Suponho que * simplesmente significa "o conteúdo do endereço de memória" e (p+2) é s[2] . O que significava que o ponteiro p era ... apenas ... um ... endereço ... bong!

Que há o som da iluminação. De repente, eu fiz ponteiros (foi há muito tempo atrás, nós, veteranos não "grok" até mais tarde). Foi apenas indireto.

Original:

OK, meu valor de 2c:

Imagine a memória é um monte de caixas. Cada caixa tem um número ao lado (o endereço). Cada caixa contém um número (o conteúdo). Você pode trabalhar com essas caixas de duas maneiras: variáveis (eu quero o conteúdo da caixa N), ponteiros (eu quero o conteúdo da caixa o que estiver na caixa N ). Ponteiros são simplesmente indiretos.

E para a grande resposta que cobre tudo o que você precisa saber - leia isto .

    
por 02.12.2010 / 01:04
fonte
4

Pegue alguns pequenos blocos de madeira.

adicione os ganchos de metal em uma extremidade e os olhos de metal na outra.

agora você pode fazer uma lista vinculada em coisas que você pode jogar.

Tente explicar com este suporte físico. Eu sempre desejei ter isso ao ensinar ponteiros para alunos do primeiro ano (calouros).

O pequeno gancho de metal é o ponteiro, o bloco de madeira que a coisa apontou.

Eu DEFICO ninguém a não conseguir depois de brincar com os blocos.

    
por 11.11.2010 / 23:45
fonte
4

Eu facilitei a minha vida quando acabei de remover todo o fluff e comecei a tratar o ponteiro como qualquer outra variável em vez de alguma entidade mágica (há muito tempo atrás, no 11º ano) .. apenas conheça 3 coisas:

  1. Ponteiro é uma variável que armazena o endereço de outra variável (ou qualquer endereço).
  2. * é usado para obter o valor no local da memória armazenado na variável do ponteiro.
  3. & operador fornece o endereço de um local de memória.

O resto é açúcar sintático e bom senso. Basta escrever alguns programas C simples (como implementar uma biblioteca de listas ligadas) usando ponteiros para obter um jeito.

    
por 11.11.2010 / 23:59
fonte
2
  1. O ponteiro pode ser considerado como uma generalização de um índice em uma matriz.
    • Considere que uma matriz grande pode ser dividida em vários arrays menores, não sobrepostos e de tamanho variável. Agora, esses arrays menores são o que geralmente consideramos array. O maior é, então, todo o espaço da memória do computador. O processo de corte de matrizes menores é chamado de alocação de memória.
  2. Um conjunto de estruturas vinculadas por alguns ponteiros pode ser considerado um gráfico direcionado .
    • Cada vértice é uma variável que pode conter algum valor.
    • Algumas variáveis são ponteiros e cada ponteiro pode ter exatamente uma borda de saída em outra coisa.
    • Variáveis que não são ponteiros não terão nenhuma borda de saída. Eles poderiam ter qualquer número de borda de entrada.
por 10.11.2010 / 06:23
fonte
2

Eu não consigo me lembrar das circunstâncias em torno dos meus ponteiros - aha momento, mas eu retroativamente reajustei a memória em torno do meu entendimento de uma matriz no estilo c. (ou seja, arr[3] é o mesmo que *(arr+3) )

Por alguma razão, acho imensamente útil ver ponteiros como matrizes sempre que eu me deparo com uma situação de ponteiro.

    
por 10.11.2010 / 09:16
fonte
2

Basicamente, @Gary Rowe apresentou o modelo certo. Memória como um conjunto de caixas com endereços (números) nelas. Cada caixa armazena um valor (número).

A ideia de um ponteiro é interpretar o valor em uma caixa como o endereço de outra caixa. Este valor é usado para referir a uma caixa específica, e é por isso que é chamado de referência . Assim, desreferenciamento é o processo de abertura da caixa a que se refere.

se v é uma variável (caixa), então a declaração

  • v significa valor de v , ou seja, me dê o que está na caixa
  • *v significa desreferenciar o valor de v , ou seja, dar-me o que está na caixa referenciada pelo valor de v
  • &v significa referência v , ou seja, informe o endereço na caixa

Eu acho que não é um servidor o propósito de introduzir ponteiros como algo completamente diferente. Foi um conceito difícil de entender para mim quando eu era criança. Sempre parecia uma magia negra que eu nunca entendi de verdade, que precisava de muitos personagens especiais. A primeira vez que eu entendi foi quando eu escrevi um pequeno jogo usando dupla indireção em uma linguagem que não tem aritmética de ponteiro. Isso me iluminou.

Os ponteiros são uma questão de interpretação. Eu acho que explicar isso torna as coisas muito mais fáceis. E as aritméticas de ponteiros são operações extremamente simples e intuitivas se forem mostradas um exemplo simples com uma memória de 10 variáveis.

    
por 10.11.2010 / 13:04
fonte
2

A explicação que eu realmente grutei foi:

Consider a city grid with different houses built on pieces of land. In your hand you hold a piece of paper. On the paper you have written:


David's house,

112 So and so street.


The piece of paper (pointer variable) contains an address that points to David's house. When you want to tell a friend to have a look at David's cool house it is much easier to use the pice of paper as a reference to the house than to send the actual two story building in the mail.

As with real pointers you can get into some trouble when you follow the address on your piece of paper. David could have moved and when you get there you just find a big hole in the ground. In this case it would have been better to erase the address on the paper when David moved or at least change it to the new one. You could also find that you go to the address and enter what you think is your friend David's living room but this time you end up in a complete strangers swimming pool. Someone else has used the space at the address you had for something completely different.

    
por 12.11.2010 / 00:20
fonte
2

Se você quiser explicar ponteiros, você deve primeiro explicar a memória. Eu costumo fazer isso usando papel milimetrado / papel quadrado com linhas e colunas. Se o "aluno" entender a memória, ela poderá entender o que é um endereço. Se você tem endereço você tem ponteiros.

Você pode brincar com essa abstração. Por exemplo. escreva o endereço (número) de um quadrado em outro quadrado. Agora desenhe uma seta do quadrado do ponteiro para o quadrado de destino. Agora, sobrescreva o ponteiro (por exemplo, incrementá-lo) e ajuste a seta. Escreva um endereço em outro quadrado e deixe o aluno desenhar a seta ...

Próximo passo: Dê a certos quadrados (como o ponteiro) um nome. Agora você pode explicar a desreferenciação. É isso aí.

    
por 13.11.2010 / 16:27
fonte
2

Talvez seja apenas eu, mas eu trabalho bem com analogias. Então, digamos que você tem um amigo (função / classe) "Foo", que quer ter alguém (função / classe diferente), "Barra", entre em contato com você por algum motivo. "Foo" poderia levá-lo para ver o "Bar", mas isso não é conveniente, movendo todos esses seres (instâncias) ao redor. No entanto, "Foo" poderia enviar "Bar" seu número de telefone (ponteiro). Dessa forma, não importa onde você esteja, "Foo" sabe como contatá-lo sem ter que encontrá-lo.

E digamos que "Bar" tenha um conhecido, "Baz", que também quer entrar em contato com você. Mas você é protetor do seu número de telefone e você não quer que todos tenham, "Baz" pode chamar "Bar" (telefone como ponteiro), que pode então encaminhar a chamada para você (outro ponteiro). E assim por diante, na cadeia de amigos e amigos de amigos de "Baz".

    
por 14.11.2010 / 03:44
fonte
2

Ponteiros tornam caminho mais sentido se você estudou linguagem assembly e / ou arquitetura de computadores. Eu acho que se eu ensinar uma classe C, eu começaria com algumas semanas de arquitetura para explicar o modelo de memória e os tipos de instruções que o processador realmente executa.

    
por 18.11.2010 / 22:39
fonte
2

Meu "aha!" momento veio neste tutorial:

Um tutorial sobre ponteiros e matrizes em C

Para ser exato, ele veio neste capítulo: Capítulo 3: Ponteiros e Strings

Para ser ainda mais preciso, veio com esta frase:

The parameter passed to puts() is a pointer, that is the value of a pointer (since all parameters in C are passed by value), and the value of a pointer is the address to which it points, or, simply, an address.

Quando eu li isso, as nuvens se separaram e os anjos tocaram fanfarras de trombeta.

Pois, você vê, todo tutorial C ou livro que eu li antes disso afirmava que C poderia passar por valor ou por referência, uma mentira nefasta. A verdade é que C sempre passa por valor, mas às vezes o valor passado passa a ser um endereço. Dentro do método, é feita uma cópia desse endereço, assim como uma cópia seria feita de um int passado. Uma cópia é não feita do valor para o qual o ponteiro aponta. Assim, usando o ponteiro dentro do método, você pode acessar o valor original e alterá-lo.

Eu nunca me tornei um programador C, mas me tornei um programador .NET e objetos e referências de objetos funcionam da mesma maneira; a referência ao objeto é passada por valor (e, portanto, copiada), mas o objeto em si não é copiado. Eu trabalhei em torno de muitos programadores que não entendem isso porque nunca aprenderam ponteiros.

    
por 21.04.2011 / 22:11
fonte
1
O truque é explicar que a localização de uma coisa e a coisa em si não são as mesmas, assim como a imagem de um cachimbo /MODERNISM-Images/modern31.jpg">não é um tubo . Quando você move uma coisa, sua localização muda. A localização permanece e alguma outra coisa pode ser colocada lá.

    
por 09.11.2010 / 16:24
fonte
1

Um ponteiro é uma nota adesiva que informa onde algo é útil. Ele contém a localização da coisa e diz o quão grande é a coisa (em C, pelo menos). Então, um ponteiro duplo é como uma nota que diz "Há um pacote de seis na geladeira". Você tem que pegar o pacote para descobrir se é Coca-Cola ou Budweiser.

    
por 09.11.2010 / 17:47
fonte
1

Dado o código:

int v=42; // declarando e inicializando uma variável simples

int *p = &v; // criando um ponto p para a variável v

A seguir pode ser dito sobre o código acima:

int * p // "ponteiro int p" ... é assim que você declara um ponteiro para a variável do tipo int

*p // "apontado por p" ... são os dados para os quais p aponta, o mesmo que v.

&v // "endereço da variável v" ... isto representa o valor literal para p

    
por 09.11.2010 / 23:50
fonte
1

link

Este site tem ótimos tutoriais para aprender ponteiros e gerenciamento de memória.

Eu sugeriria que você passasse pelos ponteiros básicos, ponteiros e memória fornecidos no site. Você também pode ver os problemas de listas vinculadas fornecidos no link para fortalecer ainda mais os conceitos de ponteiro.

    
por 15.11.2010 / 07:43
fonte
1

A chave para explicar os ponteiros é garantir que as pessoas a quem você está explicando já tenham uma compreensão do conceito de memória. Ainda assim, seria bom se eles realmente o entendessem de baixo nível, acreditando que a memória existe como uma matriz massiva, e entender que você pode acessar qualquer posição na matriz por sua localização de índice é suficiente.

O próximo passo, ter o conceito de passar a localização do índice em vez de copiar toda a memória, faz sentido para a maioria das pessoas. E isso é suficiente para permitir que a maioria das pessoas entenda por que os ponteiros são úteis.

a etapa final para entender os ponteiros é explicar como você pode passar como parâmetro uma localização de índice de memória para o método de armazenar o local do índice para onde todos os dados são armazenados. Eu descobri que isso pode ser um passo longe demais para algumas pessoas lidarem.

Uma vez que alguém tenha compreendido essas etapas básicas, é possível entender que você pode encadear indefinidamente ponteiros, contanto que você observe quantas vezes precisa procurar endereços para encontrar o objeto de dados real.

Uma vez que alguém tenha percebido os ponteiros, a próxima coisa que eles devem entender rapidamente é a diferença entre memória de pilha e memória de pilha, e porque os ponteiros para empilhar a memória são perigosos quando passados fora do método.

    
por 02.12.2010 / 02:25
fonte
0

Eu me lembro de um livro "quebra-cabeças C" ou similar, que eu li puramente porque era um dos poucos livros relacionados com programação / informática disponíveis na biblioteca, minha compreensão de C era rudimentar. Ele jogou um expresison C em você, e pediu para explodi-lo, ficando cada vez mais complicado.

    
por 10.11.2010 / 13:07
fonte
0

Quando eu estava na universidade, meu professor tinha alguns slides do PowerPoint mostrando um ponto como uma variável separada por si só com uma seta para um local de memória (representado como um array) e quando estávamos fazendo Linked Lists, ele faça isso passo a passo, mostrando quando a seta muda, quando o ponteiro é desreferenciado, etc ..., não havia como não ser possível compreendê-lo em alguns minutos. O conceito em si é realmente fácil, mas fazer o certo ou aplicá-lo em programas práticos requer mais prática.

    
por 10.12.2010 / 14:38
fonte
0

Antes de fazer isso, explico que na programação "tudo utiliza memória" e alocação de variável (estática) na memória. Também explicarei o que é um endereço de memória e a relação entre espaço de memória, endereço de memória e variáveis.

Por fim, explico que existem tipos e variáveis de dados inteiros, tipo de dados de string e variáveis ... e assim por diante, até explicar que há um tipo de dados especial que armazena endereços de memória, que tem um valor vazio como 0 "", chamado null .

E, finalmente, variáveis dinamicamente alocadas através do uso de ponteiros.

    
por 11.03.2011 / 22:27
fonte