1 00:00:00,000 --> 00:00:06,030 >> [Música tocando] 2 00:00:06,030 --> 00:00:08,390 >> DOUG LLOYD: Ponteiros, aqui estamos nós. 3 00:00:08,390 --> 00:00:11,080 Este é provavelmente vai ser o tema mais difícil 4 00:00:11,080 --> 00:00:12,840 que falamos em CS50. 5 00:00:12,840 --> 00:00:15,060 E se você leu nada sobre ponteiros 6 00:00:15,060 --> 00:00:19,080 antes que você pode ser um pouco intimidador entrar em um vídeo. 7 00:00:19,080 --> 00:00:21,260 É verdade que os ponteiros não permitir-lhe a capacidade 8 00:00:21,260 --> 00:00:23,740 talvez para estragar muito mal quando você está 9 00:00:23,740 --> 00:00:27,450 trabalhar com variáveis, e os dados, e fazendo com que seu programa trave. 10 00:00:27,450 --> 00:00:30,490 Mas eles são realmente muito útil e eles nos realmente uma ótima maneira permitir 11 00:00:30,490 --> 00:00:33,340 para passar dados de volta e para trás entre funções, 12 00:00:33,340 --> 00:00:35,490 que somos de outro modo incapaz de fazer. 13 00:00:35,490 --> 00:00:37,750 >> E assim o que realmente quero fazer aqui é trem 14 00:00:37,750 --> 00:00:41,060 que você tenha uma boa disciplina ponteiro, assim que você pode usar ponteiros de forma eficaz 15 00:00:41,060 --> 00:00:43,850 para fazer seus programas que muito melhor. 16 00:00:43,850 --> 00:00:48,220 Como eu disse ponteiros nos dar uma diferente maneira de passar dados entre funções. 17 00:00:48,220 --> 00:00:50,270 Agora, se você se lembrar de um vídeo anterior, quando 18 00:00:50,270 --> 00:00:53,720 nós estávamos falando sobre escopo de variáveis, eu mencionei 19 00:00:53,720 --> 00:01:00,610 que todos os dados que passam entre funções em C é passado por valor. 20 00:01:00,610 --> 00:01:03,070 E eu não pode ter usado que prazo, o que eu quis dizer lá 21 00:01:03,070 --> 00:01:07,170 foi a de que estamos passando cópias de dados. 22 00:01:07,170 --> 00:01:12,252 Quando passar uma variável para uma função, nós não estamos realmente passando a variável 23 00:01:12,252 --> 00:01:13,210 para a função, certo? 24 00:01:13,210 --> 00:01:17,670 Estamos passando uma cópia do que os dados para a função. 25 00:01:17,670 --> 00:01:20,760 A função faz o que ele vai e calcula algum valor, 26 00:01:20,760 --> 00:01:23,180 e talvez nós usamos esse valor quando dá-lo de volta. 27 00:01:23,180 --> 00:01:26,700 >> Houve uma exceção para esta regra de passar por valor, 28 00:01:26,700 --> 00:01:31,210 e nós vamos voltar para o que é um pouco mais tarde, em um vídeo. 29 00:01:31,210 --> 00:01:34,880 Se usarmos ponteiros vez do uso de variáveis, 30 00:01:34,880 --> 00:01:38,180 ou em vez de utilizar as variáveis si ou cópias das variáveis, 31 00:01:38,180 --> 00:01:43,790 agora podemos passar as variáveis ​​em torno de entre as funções de uma maneira diferente. 32 00:01:43,790 --> 00:01:46,550 Isto significa que se fizermos uma mudança de uma função, 33 00:01:46,550 --> 00:01:49,827 que a mudança vai realmente tomar efeito em uma função diferente. 34 00:01:49,827 --> 00:01:52,160 Novamente, isso é algo que não podíamos fazer antes, 35 00:01:52,160 --> 00:01:56,979 e se você já tentou trocar o valor de duas variáveis ​​em uma função, 36 00:01:56,979 --> 00:01:59,270 você percebeu esse problema tipo de rastejando-se, certo? 37 00:01:59,270 --> 00:02:04,340 >> Se queremos trocar X e Y, e nós passá-las para uma função chamada swap, 38 00:02:04,340 --> 00:02:08,680 dentro da função trocar o variáveis ​​fazer valores de troca. 39 00:02:08,680 --> 00:02:12,600 Um torna-se dois, dois torna-se um, mas nós não, na verdade, 40 00:02:12,600 --> 00:02:16,890 mudar nada no original função, o chamador. 41 00:02:16,890 --> 00:02:19,550 Porque nós não podemos, nós somos somente trabalhar com cópias deles. 42 00:02:19,550 --> 00:02:24,760 Com ponteiros embora, nós podemos realmente passar X e Y para uma função. 43 00:02:24,760 --> 00:02:26,960 Essa função pode fazer algo com eles. 44 00:02:26,960 --> 00:02:29,250 E esses valores variáveis pode realmente mudar. 45 00:02:29,250 --> 00:02:33,710 Então, isso é uma grande mudança em nossa capacidade de trabalhar com dados. 46 00:02:33,710 --> 00:02:36,100 >> Antes de mergulharmos ponteiros, eu acho que vale a pena 47 00:02:36,100 --> 00:02:38,580 Tomar alguns minutos para voltar ao básico aqui. 48 00:02:38,580 --> 00:02:41,000 E ter um olhar em como obras de memória de computador 49 00:02:41,000 --> 00:02:45,340 porque estes dois assuntos vão para realmente ser bastante inter-relacionados. 50 00:02:45,340 --> 00:02:48,480 Como você provavelmente sabe, no seu sistema informático 51 00:02:48,480 --> 00:02:51,310 você tem um disco rígido ou talvez uma unidade de estado sólido, 52 00:02:51,310 --> 00:02:54,430 algum tipo de local de armazenamento de arquivos. 53 00:02:54,430 --> 00:02:57,950 É geralmente em algum lugar no bairro de 250 gigabytes 54 00:02:57,950 --> 00:02:59,810 para talvez um par de terabytes agora. 55 00:02:59,810 --> 00:03:02,270 E é onde todo o seu arquivos, finalmente, viver, 56 00:03:02,270 --> 00:03:04,870 mesmo quando o computador é desligado fora, você pode ligá-lo novamente 57 00:03:04,870 --> 00:03:09,190 e você vai encontrar os seus arquivos estão lá novamente quando você reiniciar o sistema. 58 00:03:09,190 --> 00:03:14,820 Mas as unidades de disco, como uma unidade de disco rígido, um disco rígido ou uma unidade de estado sólido, um SSD, 59 00:03:14,820 --> 00:03:16,050 são apenas o espaço de armazenamento. 60 00:03:16,050 --> 00:03:20,400 >> Nós não podemos realmente fazer alguma coisa com Os dados que está no disco rígido, 61 00:03:20,400 --> 00:03:22,080 ou em uma unidade de estado sólido. 62 00:03:22,080 --> 00:03:24,950 A fim de realmente mudar dados ou movê-lo, 63 00:03:24,950 --> 00:03:28,800 temos de movê-lo para RAM, memória de acesso aleatório. 64 00:03:28,800 --> 00:03:31,170 Agora RAM, você tem um monte menos de em seu computador. 65 00:03:31,170 --> 00:03:34,185 Você pode ter em algum lugar no bairro de 512 megabytes 66 00:03:34,185 --> 00:03:38,850 se você tiver um computador mais antigo, para talvez dois, quatro, oito, 16, 67 00:03:38,850 --> 00:03:41,820 possivelmente até mesmo um pouco mais gigabytes de RAM. 68 00:03:41,820 --> 00:03:46,390 Então, isso é muito menor, mas isso é onde todos os dados voláteis existe. 69 00:03:46,390 --> 00:03:48,270 É aí que podemos mudar as coisas. 70 00:03:48,270 --> 00:03:53,350 Mas quando voltamos nossa computador desligado, todos os dados na memória RAM é destruído. 71 00:03:53,350 --> 00:03:57,150 >> Então é por isso que precisamos ter disco rígido para a localização de mais permanente que, 72 00:03:57,150 --> 00:03:59,720 de modo que ela seria exists- ser muito ruim se cada vez que 73 00:03:59,720 --> 00:04:03,310 virou nosso computador desligado, cada arquivo no nosso sistema foi obliterada. 74 00:04:03,310 --> 00:04:05,600 Por isso, trabalhamos dentro da RAM. 75 00:04:05,600 --> 00:04:09,210 E cada vez que estamos falando memória, praticamente, em CS50, 76 00:04:09,210 --> 00:04:15,080 estamos falando de RAM, disco rígido não. 77 00:04:15,080 --> 00:04:18,657 >> Então, quando nós mudar as coisas na memória, leva-se uma certa quantidade de espaço. 78 00:04:18,657 --> 00:04:20,740 Todos os tipos de dados que temos vindo a trabalhar com 79 00:04:20,740 --> 00:04:23,480 assumir diferentes quantidades de espaço na RAM. 80 00:04:23,480 --> 00:04:27,600 Então, toda vez que você cria um inteiro variáveis, quatro bytes de memória 81 00:04:27,600 --> 00:04:30,750 são postos de lado na memória RAM para que você pode trabalhar com esse inteiro. 82 00:04:30,750 --> 00:04:34,260 Você pode declarar o número inteiro, mudá-lo, associá-la 83 00:04:34,260 --> 00:04:36,700 para um valor de 10 incrementado por um, assim por diante e assim por diante. 84 00:04:36,700 --> 00:04:39,440 Tudo o que precisa acontecer em RAM, e você terá quatro bytes 85 00:04:39,440 --> 00:04:42,550 a trabalhar com para cada inteiro que você cria. 86 00:04:42,550 --> 00:04:45,410 >> Cada personagem que você criar recebe um byte. 87 00:04:45,410 --> 00:04:48,160 Isso é apenas a quantidade de espaço necessários para armazenar um personagem. 88 00:04:48,160 --> 00:04:51,310 Cada float, uma verdadeira número, recebe quatro bytes 89 00:04:51,310 --> 00:04:53,390 a menos que seja um duplo Precisão de ponto flutuante 90 00:04:53,390 --> 00:04:56,510 número, o que lhe permite dígitos tem mais precisas ou mais 91 00:04:56,510 --> 00:04:59,300 depois do ponto decimal sem perder precisão, 92 00:04:59,300 --> 00:05:01,820 que ocupam oito bytes de memória. 93 00:05:01,820 --> 00:05:06,730 Anseia por muito tempo, realmente grandes números inteiros, também ocupam oito bytes de memória. 94 00:05:06,730 --> 00:05:09,000 Quantos bytes de memória não cordas assumir? 95 00:05:09,000 --> 00:05:12,990 Bem, vamos colocar um pino em questão que por agora, mas vamos voltar a ele. 96 00:05:12,990 --> 00:05:17,350 >> Então, de volta a esta ideia de memória como uma grande variedade de células de tamanho de byte. 97 00:05:17,350 --> 00:05:20,871 Isso é realmente tudo o que é, é apenas uma enorme variedade de células, 98 00:05:20,871 --> 00:05:23,370 assim como qualquer outra matriz que você está familiarizado com e ver, 99 00:05:23,370 --> 00:05:26,430 exceto cada elemento é um byte de largura. 100 00:05:26,430 --> 00:05:30,030 E, assim como uma matriz, cada elemento tem um endereço. 101 00:05:30,030 --> 00:05:32,120 Cada elemento de um array tem um índice, e nós 102 00:05:32,120 --> 00:05:36,302 pode usar esse índice de fazer chamada de acesso aleatório na matriz. 103 00:05:36,302 --> 00:05:38,510 Não temos de começar a o início da matriz, 104 00:05:38,510 --> 00:05:40,569 iterar através de cada único elemento do mesmo, 105 00:05:40,569 --> 00:05:41,860 para encontrar o que estamos procurando. 106 00:05:41,860 --> 00:05:45,790 Nós podemos apenas dizer, eu quero chegar ao 15th elemento ou do elemento 100a. 107 00:05:45,790 --> 00:05:49,930 E você pode apenas passar esse número e obter o valor que você está procurando. 108 00:05:49,930 --> 00:05:54,460 >> Da mesma forma cada local na memória tem um endereço. 109 00:05:54,460 --> 00:05:57,320 Portanto, sua memória pode algo parecido com isto. 110 00:05:57,320 --> 00:06:01,420 Aqui está um pequeno pedaço de memória, esta é de 20 bytes de memória. 111 00:06:01,420 --> 00:06:04,060 Os primeiros 20 bytes, porque o meu aborda lá no fundo 112 00:06:04,060 --> 00:06:08,890 são 0, 1, 2, 3, e assim em todo o caminho até a 19. 113 00:06:08,890 --> 00:06:13,190 E quando eu declarar variáveis ​​e quando eu começar a trabalhar com eles, 114 00:06:13,190 --> 00:06:15,470 o sistema vai definir reservar algum espaço para me 115 00:06:15,470 --> 00:06:17,595 nesta memória para trabalhar com meus variáveis. 116 00:06:17,595 --> 00:06:21,610 Então, eu poderia dizer, char c é igual a de capital H. E o que vai acontecer? 117 00:06:21,610 --> 00:06:23,880 Bem, o sistema vai reservado para me um byte. 118 00:06:23,880 --> 00:06:27,870 Neste caso, ele escolheu o número de bytes quatro, o byte no endereço quatro, 119 00:06:27,870 --> 00:06:31,310 e está indo para armazenar o letra H de capital em lá para mim. 120 00:06:31,310 --> 00:06:34,350 Se eu, então, dizer velocidade int limite é igual a 65, é 121 00:06:34,350 --> 00:06:36,806 vai destinar quatro bytes de memória para mim. 122 00:06:36,806 --> 00:06:39,180 E vai para tratar aqueles quatro bytes como uma única unidade 123 00:06:39,180 --> 00:06:41,305 porque o que nós estamos trabalhando é um número inteiro com aqui. 124 00:06:41,305 --> 00:06:44,350 E está indo para armazenar 65 em lá. 125 00:06:44,350 --> 00:06:47,000 >> Agora já estou meio dizendo-lhe um pouco de uma mentira, 126 00:06:47,000 --> 00:06:50,150 direito, porque sabemos que computadores trabalhar em binário. 127 00:06:50,150 --> 00:06:53,100 Eles não entendem necessariamente o que é um capital H 128 00:06:53,100 --> 00:06:57,110 ou o que é um 65, eles só compreender binários, zeros e uns. 129 00:06:57,110 --> 00:06:59,000 E assim, na verdade, o que nós estamos armazenando lá 130 00:06:59,000 --> 00:07:03,450 não é a letra H e o número 65, mas sim as representações binárias 131 00:07:03,450 --> 00:07:06,980 destes, que parecem um pouco algo como isto. 132 00:07:06,980 --> 00:07:10,360 E, em particular no contexto da variável número inteiro, 133 00:07:10,360 --> 00:07:13,559 ele não vai apenas cuspi-lo em, ele não está indo para tratá-lo como um de quatro 134 00:07:13,559 --> 00:07:15,350 byte pedaço necessariamente, ele está realmente acontecendo 135 00:07:15,350 --> 00:07:19,570 tratá-la como um quatro pedaços de byte, o que poderia ser algo como isto. 136 00:07:19,570 --> 00:07:22,424 E mesmo isso não é inteiramente verdade, quer, 137 00:07:22,424 --> 00:07:24,840 por causa de algo chamado uma ordenação, que não estamos 138 00:07:24,840 --> 00:07:26,965 vai entrar agora, mas Se você está curioso para saber, 139 00:07:26,965 --> 00:07:29,030 você pode ler-se em pouco e grande endianness. 140 00:07:29,030 --> 00:07:31,640 Mas por causa desse argumento, por causa deste vídeo, 141 00:07:31,640 --> 00:07:34,860 vamos supor que é, em fato, como o número 65 seria 142 00:07:34,860 --> 00:07:36,970 ser representado em memória em cada sistema, 143 00:07:36,970 --> 00:07:38,850 embora não é inteiramente verdade. 144 00:07:38,850 --> 00:07:41,700 >> Mas vamos realmente apenas obter livrar de todos binário inteiramente, 145 00:07:41,700 --> 00:07:44,460 e só pensar em como H e 65, é muito mais fácil 146 00:07:44,460 --> 00:07:47,900 pensar nisso como que, como um ser humano. 147 00:07:47,900 --> 00:07:51,420 Tudo bem, então também parece talvez um pouco aleatório que I've- meu sistema 148 00:07:51,420 --> 00:07:55,130 não me deu bytes 5, 6, 7, e 8 para armazenar o número inteiro. 149 00:07:55,130 --> 00:07:58,580 Há uma razão para isso, também, que não vamos entrar agora, mas basta 150 00:07:58,580 --> 00:08:00,496 dizer que o que o computador está fazendo aqui 151 00:08:00,496 --> 00:08:02,810 é provavelmente uma boa jogada da sua parte. 152 00:08:02,810 --> 00:08:06,020 Para não me dar a memória que é necessariamente de volta para trás. 153 00:08:06,020 --> 00:08:10,490 Embora ele vai fazê-lo agora se eu quiser obter outra seqüência, 154 00:08:10,490 --> 00:08:13,080 chamado sobrenome, e eu quero para colocar Lloyd lá. 155 00:08:13,080 --> 00:08:18,360 Eu vou precisar para caber um caráter, cada letra do que é 156 00:08:18,360 --> 00:08:21,330 vai exigir um caráter, um byte de memória. 157 00:08:21,330 --> 00:08:26,230 Então, se eu poderia colocar Lloyd em minha matriz assim eu sou muito bom para ir, certo? 158 00:08:26,230 --> 00:08:28,870 O que está a faltar? 159 00:08:28,870 --> 00:08:31,840 >> Lembre-se que cada corda trabalhamos com em C termina com barra invertida zero, 160 00:08:31,840 --> 00:08:33,339 e não podemos omitir que aqui, também. 161 00:08:33,339 --> 00:08:36,090 Precisamos deixar de lado um byte de memória para armazenar que assim nós 162 00:08:36,090 --> 00:08:39,130 saber quando nossa string terminou. 163 00:08:39,130 --> 00:08:41,049 Então, novamente este arranjo de como as coisas 164 00:08:41,049 --> 00:08:42,799 aparecem em poder de memória ser um pouco aleatório, 165 00:08:42,799 --> 00:08:44,870 mas, na verdade, é como a maioria dos sistemas são concebidos. 166 00:08:44,870 --> 00:08:48,330 Para alinhá-los em múltiplos de quatro, por razões de novo 167 00:08:48,330 --> 00:08:50,080 que não precisa entrar agora. 168 00:08:50,080 --> 00:08:53,060 Mas isso, então basta dizer que Depois destas três linhas de código, 169 00:08:53,060 --> 00:08:54,810 este é o que a memória pode parecer. 170 00:08:54,810 --> 00:08:58,930 Se eu precisar de locais de memória 4, 8, e 12 para manter os dados, 171 00:08:58,930 --> 00:09:01,100 isto é o que a minha memória pode parecer. 172 00:09:01,100 --> 00:09:04,062 >> E apenas ser particularmente pedante aqui, quando 173 00:09:04,062 --> 00:09:06,020 estamos falando de memória endereços que costumamos 174 00:09:06,020 --> 00:09:08,390 fazê-lo utilizando notações hexadecimais. 175 00:09:08,390 --> 00:09:12,030 Então, por que não podemos converter todos estes de decimal para notação hexadecimal 176 00:09:12,030 --> 00:09:15,010 só porque isso é geralmente como nos referimos a memória. 177 00:09:15,010 --> 00:09:17,880 Então, ao invés de ser de 0 a 19, o que temos é zero 178 00:09:17,880 --> 00:09:20,340 x zero a zero, três x1. 179 00:09:20,340 --> 00:09:23,790 Esses são os 20 bytes de memória que ter ou nós estamos olhando nesta imagem 180 00:09:23,790 --> 00:09:25,540 aqui mesmo. 181 00:09:25,540 --> 00:09:29,310 >> Então, tudo o que foi dito, vamos se afastar da memória para um segundo 182 00:09:29,310 --> 00:09:30,490 e de volta para ponteiros. 183 00:09:30,490 --> 00:09:32,420 Aqui é o mais importante coisa a lembrar 184 00:09:32,420 --> 00:09:34,070 à medida que começar a trabalhar com ponteiros. 185 00:09:34,070 --> 00:09:36,314 Um ponteiro é nada mais do que um endereço. 186 00:09:36,314 --> 00:09:38,230 Eu vou dizer outra vez porque é tão importante, 187 00:09:38,230 --> 00:09:42,730 um ponteiro não é nada mais do que um endereço. 188 00:09:42,730 --> 00:09:47,760 Os ponteiros são endereços para locais na memória onde variáveis ​​viver. 189 00:09:47,760 --> 00:09:52,590 Sabendo que ela se torna um esperançosamente pouco mais fácil trabalhar com eles. 190 00:09:52,590 --> 00:09:54,550 Outra coisa que eu gosto a fazer é ter sorte 191 00:09:54,550 --> 00:09:58,510 de diagramas visualmente representando o que é acontecendo com várias linhas de código. 192 00:09:58,510 --> 00:10:00,660 E nós vamos fazer isso um par de tempos em ponteiros, 193 00:10:00,660 --> 00:10:03,354 e quando falamos de dinâmica alocação de memória também. 194 00:10:03,354 --> 00:10:06,020 Porque eu acho que estes diagramas pode ser particularmente útil. 195 00:10:06,020 --> 00:10:09,540 >> Então, se eu dizer, por exemplo, int k no meu código, que está acontecendo? 196 00:10:09,540 --> 00:10:12,524 Bem o que está acontecendo é, basicamente, Estou ficando memória reservada para mim, 197 00:10:12,524 --> 00:10:14,690 mas eu não gosto nem de pense nisso como esse, eu 198 00:10:14,690 --> 00:10:16,300 gosto de pensar nisso como uma caixa. 199 00:10:16,300 --> 00:10:20,090 Eu tenho uma caixa e é de cor verde porque eu 200 00:10:20,090 --> 00:10:21,750 pode colocar inteiros em caixas verdes. 201 00:10:21,750 --> 00:10:23,666 Se fosse um personagem que eu pode ter uma caixa azul. 202 00:10:23,666 --> 00:10:27,290 Mas eu sempre digo, se eu estou criando uma caixa que pode conter inteiros 203 00:10:27,290 --> 00:10:28,950 que a caixa é de cor verde. 204 00:10:28,950 --> 00:10:33,020 E eu tomo um marcador permanente e eu k escrever sobre o lado do mesmo. 205 00:10:33,020 --> 00:10:37,590 Então, eu tenho uma caixa chamada k, para que eu possa colocar inteiros. 206 00:10:37,590 --> 00:10:41,070 Portanto, quando digo int k, que é o que acontece na minha cabeça. 207 00:10:41,070 --> 00:10:43,140 Se eu disser que k é igual a cinco, o que estou fazendo? 208 00:10:43,140 --> 00:10:45,110 Bem, eu estou colocando cinco na caixa, certo. 209 00:10:45,110 --> 00:10:48,670 Isto é bastante simples, se Eu digo int k, criar uma caixa chamada k. 210 00:10:48,670 --> 00:10:52,040 Se eu disser que k é igual a 5, colocar cinco na caixa. 211 00:10:52,040 --> 00:10:53,865 Esperemos que isso não é muito de um salto. 212 00:10:53,865 --> 00:10:55,990 Aqui é onde as coisas vão um pouco interessante embora. 213 00:10:55,990 --> 00:11:02,590 Se eu disser int * pk, bem, mesmo se eu não fizer sabe o que isto significa, necessariamente, 214 00:11:02,590 --> 00:11:06,150 é claramente tem algo a ver com um número inteiro. 215 00:11:06,150 --> 00:11:08,211 Então eu vou para colorir esta caixa verde-ish, 216 00:11:08,211 --> 00:11:10,210 Eu sei que tem algo a ver com um número inteiro, 217 00:11:10,210 --> 00:11:13,400 mas não é um número inteiro em si, porque é uma estrela int. 218 00:11:13,400 --> 00:11:15,390 Há algo ligeiramente diferente sobre isso. 219 00:11:15,390 --> 00:11:17,620 Tão envolvido de um número inteiro, mas caso contrário, é 220 00:11:17,620 --> 00:11:19,830 não muito diferente do o que estávamos falando. 221 00:11:19,830 --> 00:11:24,240 É uma caixa, o seu tem um rótulo, ela está vestindo um pk etiqueta, 222 00:11:24,240 --> 00:11:27,280 e é capaz de exploração estrelas int, quaisquer que sejam. 223 00:11:27,280 --> 00:11:29,894 Eles têm algo a ver com números inteiros, de forma clara. 224 00:11:29,894 --> 00:11:31,060 Aqui é a última linha embora. 225 00:11:31,060 --> 00:11:37,650 Se eu disser pk = & k, whoa, o que aconteceu, certo? 226 00:11:37,650 --> 00:11:41,820 Portanto, este número aleatório, aparentemente aleatória número, é jogado na caixa lá. 227 00:11:41,820 --> 00:11:44,930 Tudo o que é, é pk obtém o endereço de k. 228 00:11:44,930 --> 00:11:52,867 Então, eu estou aderindo onde k vive na memória, seu endereço, o endereço de seus bytes. 229 00:11:52,867 --> 00:11:55,200 Tudo o que eu estou fazendo é que eu estou dizendo esse valor é o que eu vou 230 00:11:55,200 --> 00:11:59,430 para colocar dentro da minha caixa chamada pk. 231 00:11:59,430 --> 00:12:02,080 E porque essas coisas são ponteiros, e porque procura 232 00:12:02,080 --> 00:12:04,955 em uma string como nula x oito zero ° C sete quatro oito 233 00:12:04,955 --> 00:12:07,790 dois zero é provavelmente não muito significativa. 234 00:12:07,790 --> 00:12:12,390 Quando nós geralmente visualizar ponteiros, nós realmente fazê-lo como ponteiros. 235 00:12:12,390 --> 00:12:17,000 Pk nos dá a informação precisamos encontrar k na memória. 236 00:12:17,000 --> 00:12:19,120 Então, basicamente pk tem uma seta nela. 237 00:12:19,120 --> 00:12:21,670 E se andarmos o comprimento de que a flecha, imagine 238 00:12:21,670 --> 00:12:25,280 é algo que você pode andar sobre, se nós caminhar ao longo do comprimento da seta, 239 00:12:25,280 --> 00:12:29,490 na ponta de flecha que, nós vai encontrar o local na memória 240 00:12:29,490 --> 00:12:31,390 onde k vive. 241 00:12:31,390 --> 00:12:34,360 E isso é realmente importante porque uma vez que nós sabemos onde k vive, 242 00:12:34,360 --> 00:12:37,870 podemos começar a trabalhar com os dados no interior do referido local de memória. 243 00:12:37,870 --> 00:12:40,780 Embora nós estamos começando um pequenininho pouco à frente de nós mesmos para agora. 244 00:12:40,780 --> 00:12:42,240 >> Então, o que é um ponteiro? 245 00:12:42,240 --> 00:12:45,590 Um ponteiro é um item de dados cujo valor é um endereço de memória. 246 00:12:45,590 --> 00:12:49,740 Isso foi que o zero x oito coisas de zero acontecendo, que era um endereço de memória. 247 00:12:49,740 --> 00:12:52,060 Essa era uma posição na memória. 248 00:12:52,060 --> 00:12:55,080 E do tipo de um ponteiro descreve o tipo 249 00:12:55,080 --> 00:12:56,930 de dados que você vai encontrar no esse endereço de memória. 250 00:12:56,930 --> 00:12:58,810 Portanto, há a parte direita int estrela. 251 00:12:58,810 --> 00:13:03,690 Se eu seguir essa flecha, é vai me levar para um local. 252 00:13:03,690 --> 00:13:06,980 E esse local, o que eu vai encontrar lá no meu exemplo, 253 00:13:06,980 --> 00:13:08,240 é uma caixa de cor verde. 254 00:13:08,240 --> 00:13:12,650 É um inteiro, que é o que eu vai encontrar se eu ir para esse endereço. 255 00:13:12,650 --> 00:13:14,830 O tipo de dados a ponteiro descreve o que 256 00:13:14,830 --> 00:13:17,936 você vai encontrar nesse endereço de memória. 257 00:13:17,936 --> 00:13:19,560 Então aqui está a coisa muito legal embora. 258 00:13:19,560 --> 00:13:25,090 Ponteiros nos permitem passar variáveis ​​entre funções. 259 00:13:25,090 --> 00:13:28,520 E, na verdade, passar variáveis e não passar cópias deles. 260 00:13:28,520 --> 00:13:32,879 Porque se nós sabemos exatamente onde na memória para encontrar uma variável, 261 00:13:32,879 --> 00:13:35,670 nós não precisamos de fazer uma cópia de -lo, podemos apenas ir para esse local 262 00:13:35,670 --> 00:13:37,844 e trabalhar com essa variável. 263 00:13:37,844 --> 00:13:40,260 Assim, em essência ponteiros espécie de fazer um ambiente de computador 264 00:13:40,260 --> 00:13:42,360 muito mais parecido com o mundo real, certa. 265 00:13:42,360 --> 00:13:44,640 >> Então aqui vai uma analogia. 266 00:13:44,640 --> 00:13:48,080 Vamos dizer que eu tenho um notebook, direito, e é cheio de notas. 267 00:13:48,080 --> 00:13:50,230 E eu gostaria que você atualizá-lo. 268 00:13:50,230 --> 00:13:53,960 Você é uma função que atualizações notas, certo. 269 00:13:53,960 --> 00:13:56,390 No caminho nós estivemos funcionando até agora, o que 270 00:13:56,390 --> 00:14:02,370 acontece é que você vai tomar o meu notebook, você ir até a loja de cópia, 271 00:14:02,370 --> 00:14:06,410 você vai fazer uma cópia de Xerox todas as páginas do caderno. 272 00:14:06,410 --> 00:14:09,790 Você vai deixar o meu notebook de volta na minha mesa quando estiver pronto, 273 00:14:09,790 --> 00:14:14,600 você vai passar e riscar coisas na minha notebook que estão desatualizados ou errado, 274 00:14:14,600 --> 00:14:19,280 e então você vai passar de volta para me a pilha de páginas Xerox 275 00:14:19,280 --> 00:14:22,850 que é uma réplica do meu notebook com as mudanças que você fez a ela. 276 00:14:22,850 --> 00:14:27,040 E nesse ponto, cabe a mim como a função de chamada, como o chamador, 277 00:14:27,040 --> 00:14:30,582 para decidir tomar as suas notas e integrá-los de volta para o meu notebook. 278 00:14:30,582 --> 00:14:32,540 Portanto, há uma série de etapas envolvido aqui, certo. 279 00:14:32,540 --> 00:14:34,850 Como não seria melhor se eu apenas dizer, hey, você pode 280 00:14:34,850 --> 00:14:38,370 atualizar o meu notebook para me, entregar-lhe o meu notebook, 281 00:14:38,370 --> 00:14:40,440 e você levar as coisas e literalmente cruzá-los fora 282 00:14:40,440 --> 00:14:42,810 e atualizar as minhas notas no meu caderno. 283 00:14:42,810 --> 00:14:45,140 E, em seguida, dar-me o meu notebook de volta. 284 00:14:45,140 --> 00:14:47,320 Esse é o tipo do que ponteiros nos permitem fazer, 285 00:14:47,320 --> 00:14:51,320 eles fazem este ambiente muito mais como como atuamos na realidade. 286 00:14:51,320 --> 00:14:54,640 >> Tudo bem então é isso que um ponteiro é, vamos falar 287 00:14:54,640 --> 00:14:58,040 ponteiros sobre como trabalhar em C, e como podemos começar a trabalhar com eles. 288 00:14:58,040 --> 00:15:02,550 Portanto, há um ponteiro muito simples em C chamado de ponteiro nulo. 289 00:15:02,550 --> 00:15:04,830 O ponteiro pontos nulos a nada. 290 00:15:04,830 --> 00:15:08,310 Isso provavelmente parece que é na verdade, não é uma coisa muito útil, 291 00:15:08,310 --> 00:15:10,500 mas como nós vamos ver uma pouco mais tarde, o fato 292 00:15:10,500 --> 00:15:15,410 que existe esse ponteiro nulo na verdade, realmente pode vir a calhar. 293 00:15:15,410 --> 00:15:19,090 E sempre que você criar um ponteiro, e você não definir seu valor imediatamente- 294 00:15:19,090 --> 00:15:21,060 um exemplo de configuração o seu valor imediatamente 295 00:15:21,060 --> 00:15:25,401 será um par de lâminas de volta onde eu disse pk k é igual e, 296 00:15:25,401 --> 00:15:28,740 pk recebe o endereço de k, como vamos ver o que isso significa, 297 00:15:28,740 --> 00:15:32,990 vamos ver como codificar que shortly- se não definir o valor para algo 298 00:15:32,990 --> 00:15:35,380 significativa imediatamente, você deve sempre 299 00:15:35,380 --> 00:15:37,480 definir o ponteiro para apontar para null. 300 00:15:37,480 --> 00:15:40,260 Você deve configurá-lo para apontar para nada. 301 00:15:40,260 --> 00:15:43,614 >> Isso é muito diferente do que deixando apenas o valor é tão 302 00:15:43,614 --> 00:15:45,530 e, em seguida, declara uma ponteiro e apenas supondo 303 00:15:45,530 --> 00:15:48,042 é nula porque é isso raramente é verdade. 304 00:15:48,042 --> 00:15:50,000 Então você deve sempre definir o valor de um ponteiro 305 00:15:50,000 --> 00:15:55,690 como nulo se você não definir seu valor para algo significativo imediatamente. 306 00:15:55,690 --> 00:15:59,090 Você pode verificar se o valor de um ponteiro é nulo usando o operador de igualdade 307 00:15:59,090 --> 00:16:05,450 (==), Assim como você comparar qualquer número inteiro valores ou valores de caracteres usando (==) 308 00:16:05,450 --> 00:16:06,320 também. 309 00:16:06,320 --> 00:16:10,994 É um tipo especial de constante valor que você pode usar para testar. 310 00:16:10,994 --> 00:16:13,160 Então essa foi uma forma muito simples ponteiro, o ponteiro nulo. 311 00:16:13,160 --> 00:16:15,320 Outra forma de criar um apontador é para extrair 312 00:16:15,320 --> 00:16:18,240 o endereço de uma variável você já criou, 313 00:16:18,240 --> 00:16:22,330 e você fazer isso usando o & extração endereço operador. 314 00:16:22,330 --> 00:16:26,720 Que já vimos anteriormente no primeiro exemplo diagrama eu mostrei. 315 00:16:26,720 --> 00:16:31,450 Então, se x é uma variável que nós temos já criada do tipo inteiro, 316 00:16:31,450 --> 00:16:35,110 em seguida, & x é um ponteiro para um inteiro. 317 00:16:35,110 --> 00:16:39,810 & x é- me lembro, e vai extrair o endereço do coisa à direita. 318 00:16:39,810 --> 00:16:45,350 E uma vez que um ponteiro é apenas um endereço, que & x é um ponteiro para um inteiro 319 00:16:45,350 --> 00:16:48,560 cujo valor é, onde na memória x vidas. 320 00:16:48,560 --> 00:16:50,460 É o endereço de x. 321 00:16:50,460 --> 00:16:53,296 Assim & X é o endereço de x. 322 00:16:53,296 --> 00:16:55,670 Vamos dar um passo mais e conectar-se a algo 323 00:16:55,670 --> 00:16:58,380 Eu, em alusão a um vídeo anterior. 324 00:16:58,380 --> 00:17:06,730 Se arr é uma matriz de duplas, em seguida, & colchete arr i é um ponteiro 325 00:17:06,730 --> 00:17:08,109 para um casal. 326 00:17:08,109 --> 00:17:08,970 ESTÁ BEM. 327 00:17:08,970 --> 00:17:12,160 arr quadrado suporte i, se arr é uma matriz de duplas, 328 00:17:12,160 --> 00:17:19,069 em seguida, arr colchete i é o elemento i-th dessa matriz, 329 00:17:19,069 --> 00:17:29,270 e & arr colchete i é onde em memória o elemento i-th de arr existe. 330 00:17:29,270 --> 00:17:31,790 >> Então, qual é a implicação aqui? 331 00:17:31,790 --> 00:17:34,570 Um nome de matrizes, a implicação de tudo isso, 332 00:17:34,570 --> 00:17:39,290 é que o nome de uma matriz é na verdade em si um ponteiro. 333 00:17:39,290 --> 00:17:41,170 Você tem trabalhado com ponteiros ao longo de toda 334 00:17:41,170 --> 00:17:45,290 toda vez que você usou uma matriz. 335 00:17:45,290 --> 00:17:49,090 Lembre-se do exemplo escopo de variáveis, 336 00:17:49,090 --> 00:17:53,420 perto do fim do vídeo apresento um exemplo em que temos uma função 337 00:17:53,420 --> 00:17:56,890 chamado int set e uma função chamada matriz set. 338 00:17:56,890 --> 00:18:00,490 E seu desafio para determinar se ou não, ou o que o 339 00:18:00,490 --> 00:18:03,220 valores que nós imprimimos o final da função, 340 00:18:03,220 --> 00:18:05,960 no final do programa principal. 341 00:18:05,960 --> 00:18:08,740 >> Se você se lembrar de que o exemplo ou se você assistiu o vídeo, 342 00:18:08,740 --> 00:18:13,080 você sabe que quando você- a chamada para conjunto int efetivamente não faz nada. 343 00:18:13,080 --> 00:18:16,390 Mas a chamada para definir matriz faz. 344 00:18:16,390 --> 00:18:19,280 E eu meio que encoberto por que era o caso na época. 345 00:18:19,280 --> 00:18:22,363 Eu apenas disse, bem, é um array, é especial, você sabe, há uma razão. 346 00:18:22,363 --> 00:18:25,020 A razão é que uma matriz de nome é realmente apenas um ponteiro, 347 00:18:25,020 --> 00:18:28,740 e há esta especial sintaxe colchete que 348 00:18:28,740 --> 00:18:30,510 tornar as coisas muito mais agradável para trabalhar. 349 00:18:30,510 --> 00:18:34,410 E eles fazem a idéia de um ponteiro muito menos intimidante, 350 00:18:34,410 --> 00:18:36,800 e é por isso que eles são tipo da apresentada dessa forma. 351 00:18:36,800 --> 00:18:38,600 Mas realmente matrizes são apenas apontadores. 352 00:18:38,600 --> 00:18:41,580 E é por isso que quando nós fez uma mudança para a matriz, 353 00:18:41,580 --> 00:18:44,880 quando passamos uma matriz como um parâmetro para uma função ou como um argumento 354 00:18:44,880 --> 00:18:50,110 a uma função, o conteúdo da matriz realmente mudado tanto no receptor 355 00:18:50,110 --> 00:18:51,160 e em que o chamador. 356 00:18:51,160 --> 00:18:55,846 Que para qualquer outro tipo de variável que vimos não foi o caso. 357 00:18:55,846 --> 00:18:58,970 Então, isso é apenas algo para se manter em mente quando você está trabalhando com ponteiros, 358 00:18:58,970 --> 00:19:01,610 que é o nome de um matriz, na verdade, um ponteiro 359 00:19:01,610 --> 00:19:04,750 para o primeiro elemento do array. 360 00:19:04,750 --> 00:19:08,930 >> OK então agora temos todos estes fatos, vamos continuar, certo. 361 00:19:08,930 --> 00:19:11,370 Por que nos preocupamos onde algo vive. 362 00:19:11,370 --> 00:19:14,120 Bem, como eu disse, é muito útil saber onde algo vive 363 00:19:14,120 --> 00:19:17,240 assim você pode ir lá e mudá-lo. 364 00:19:17,240 --> 00:19:19,390 Trabalhar com ele e realmente tem a coisa que você 365 00:19:19,390 --> 00:19:23,710 quer fazer para que entrem em vigor a variável, e não produz efeitos em alguns cópia do mesmo. 366 00:19:23,710 --> 00:19:26,150 Isso é chamado de dereferencing. 367 00:19:26,150 --> 00:19:28,690 Nós vamos para a referência e nós mudamos o valor lá. 368 00:19:28,690 --> 00:19:32,660 Então, se temos um ponteiro e é chamado pc, e ele aponta para um personagem, 369 00:19:32,660 --> 00:19:40,610 então podemos dizer * * pc e pc é o nome do que vamos encontrar, se formos 370 00:19:40,610 --> 00:19:42,910 para o pc endereço. 371 00:19:42,910 --> 00:19:47,860 O que vamos encontrar lá é um personagem e * pc é a forma como nos referimos aos dados a que 372 00:19:47,860 --> 00:19:48,880 localização. 373 00:19:48,880 --> 00:19:54,150 Assim, poderíamos dizer algo como * pc = D ou algo parecido, 374 00:19:54,150 --> 00:19:59,280 e isso significa que qualquer que seja Foi no endereço de memória pc, 375 00:19:59,280 --> 00:20:07,040 qualquer personagem que estava anteriormente lá, é agora D, se dissermos * PC = D. 376 00:20:07,040 --> 00:20:10,090 >> Então, aqui vamos nós de novo com algumas coisas C estranho, certo. 377 00:20:10,090 --> 00:20:14,560 Então nós vimos anteriormente como sendo * de alguma forma parte do tipo de dados, 378 00:20:14,560 --> 00:20:17,160 e agora ele está sendo usado em num contexto ligeiramente diferente 379 00:20:17,160 --> 00:20:19,605 para acessar os dados em um local. 380 00:20:19,605 --> 00:20:22,480 Eu sei que é um pouco confuso e que é, na verdade, parte desse todo 381 00:20:22,480 --> 00:20:25,740 como, por ponteiros têm essa mitologia em torno deles como sendo tão complexo, 382 00:20:25,740 --> 00:20:28,250 é um tipo de problema de sintaxe, honestamente. 383 00:20:28,250 --> 00:20:31,810 Mas * é usado em ambos os contextos, tanto como parte do nome do tipo, 384 00:20:31,810 --> 00:20:34,100 e vamos ver um pouco depois outra coisa, também. 385 00:20:34,100 --> 00:20:36,490 E agora é o operador de remoção de referência. 386 00:20:36,490 --> 00:20:38,760 Por isso, vai para a referência, ele acessa os dados 387 00:20:38,760 --> 00:20:43,000 na localização do ponteiro, e permite que você manipulá-lo à vontade. 388 00:20:43,000 --> 00:20:45,900 >> Agora, este é muito similar ao visitar seu vizinho, certo. 389 00:20:45,900 --> 00:20:48,710 Se você sabe o que o seu vizinho vive, você é 390 00:20:48,710 --> 00:20:50,730 não sair com seu vizinho. 391 00:20:50,730 --> 00:20:53,510 Você sabe que você acontecer sabe onde eles vivem, 392 00:20:53,510 --> 00:20:56,870 mas isso não significa que, por virtude de ter esse conhecimento 393 00:20:56,870 --> 00:20:59,170 você está interagindo com eles. 394 00:20:59,170 --> 00:21:01,920 Se você quiser interagir com eles, você tem que ir para sua casa, 395 00:21:01,920 --> 00:21:03,760 você tem que ir para onde eles vivem. 396 00:21:03,760 --> 00:21:07,440 E uma vez que você fizer isso, em seguida, você pode interagir 397 00:21:07,440 --> 00:21:09,420 com eles apenas como você iria querer. 398 00:21:09,420 --> 00:21:12,730 E da mesma forma com as variáveis, você precisa ir para seu endereço 399 00:21:12,730 --> 00:21:15,320 se você quiser interagir eles, você não pode apenas saber o endereço. 400 00:21:15,320 --> 00:21:21,495 E a maneira como você ir para o endereço é de usar *, o operador de remoção de referência. 401 00:21:21,495 --> 00:21:23,620 O que você acha que acontece se nós tentamos e dereference 402 00:21:23,620 --> 00:21:25,260 um ponteiro cujo valor é nulo? 403 00:21:25,260 --> 00:21:28,470 Lembre-se que o nulo ponteiro aponta para nada. 404 00:21:28,470 --> 00:21:34,110 Então, se você tentar eliminar referência nada ou ir a um endereço de nada, 405 00:21:34,110 --> 00:21:36,800 o que você acha que acontece? 406 00:21:36,800 --> 00:21:39,630 Segmentação Bem, se você adivinhou falha, você estaria certo. 407 00:21:39,630 --> 00:21:41,390 Se você tentar e dereference um ponteiro nulo, 408 00:21:41,390 --> 00:21:43,140 você sofre uma segmentação falha. Mas espera, 409 00:21:43,140 --> 00:21:45,820 não vos digo, que se você não está indo 410 00:21:45,820 --> 00:21:49,220 para definir o valor da sua ponteiro para algo significativo, 411 00:21:49,220 --> 00:21:51,000 você deve definir como nulo? 412 00:21:51,000 --> 00:21:55,290 Eu fiz e, na verdade, a segmentação culpa é uma espécie de bom comportamento. 413 00:21:55,290 --> 00:21:58,680 >> Alguma vez você já declarou uma variável e Não atribuído o valor imediatamente? 414 00:21:58,680 --> 00:22:02,680 Então você acabou de dizer int x; você não faz na verdade, atribuí-lo a nada 415 00:22:02,680 --> 00:22:05,340 e depois, mais tarde, em seu código, imprimir o valor de x, 416 00:22:05,340 --> 00:22:07,650 ainda não ter atribuído a qualquer coisa. 417 00:22:07,650 --> 00:22:10,370 Freqüentemente você vai ter zero, mas às vezes você 418 00:22:10,370 --> 00:22:15,000 pode obter algum número aleatório, e você não tem idéia de onde ele veio. 419 00:22:15,000 --> 00:22:16,750 Da mesma forma pode coisas acontecer com ponteiros. 420 00:22:16,750 --> 00:22:20,110 Quando você declarar um ponteiro int * pk por exemplo, 421 00:22:20,110 --> 00:22:23,490 e você não atribuí-la a um valor, você recebe quatro bytes para memória. 422 00:22:23,490 --> 00:22:25,950 Quaisquer que sejam os quatro bytes de memória do sistema pode 423 00:22:25,950 --> 00:22:28,970 achar que tem algum valor significativo. 424 00:22:28,970 --> 00:22:31,760 E não poderia ter sido algo que já existe 425 00:22:31,760 --> 00:22:34,190 não é mais necessário por outro função, então você apenas tem 426 00:22:34,190 --> 00:22:35,900 todos os dados que estava lá. 427 00:22:35,900 --> 00:22:40,570 >> E se você tentou fazer dereference algum endereço que você não- havia 428 00:22:40,570 --> 00:22:43,410 já bytes e informações lá, que está agora em seu ponteiro. 429 00:22:43,410 --> 00:22:47,470 Se você tentar cancelar a referência desse ponteiro, você pode estar mexendo com alguma memória 430 00:22:47,470 --> 00:22:49,390 que você não tinha a intenção para mexer com tudo. 431 00:22:49,390 --> 00:22:51,639 E na verdade, você poderia fazer algo realmente devastador, 432 00:22:51,639 --> 00:22:54,880 como quebrar outro programa, ou quebrar uma outra função, 433 00:22:54,880 --> 00:22:58,289 ou fazer algo malicioso que você não tinha a intenção de fazer em tudo. 434 00:22:58,289 --> 00:23:00,080 E é por isso que ele é realmente uma boa idéia 435 00:23:00,080 --> 00:23:04,030 para definir os ponteiros como nulo se você não configurá-los para algo significativo. 436 00:23:04,030 --> 00:23:06,760 É provavelmente melhor no final do dia, para o seu programa 437 00:23:06,760 --> 00:23:09,840 a falhar, em seguida, para que ele faça algo que estraga 438 00:23:09,840 --> 00:23:12,400 outro programa ou outra função. 439 00:23:12,400 --> 00:23:15,207 Esse comportamento é provavelmente ainda menos ideal do que apenas deixar de funcionar. 440 00:23:15,207 --> 00:23:17,040 E é por isso que ele é realmente um bom hábito 441 00:23:17,040 --> 00:23:20,920 para entrar para definir os ponteiros como nulo se você não configurá-los 442 00:23:20,920 --> 00:23:24,540 a um valor significativo imediatamente, um valor que você sabe 443 00:23:24,540 --> 00:23:27,260 e que você pode com segurança a eliminar referência. 444 00:23:27,260 --> 00:23:32,240 >> Então, vamos voltar agora e dê uma olhada na sintaxe global da situação. 445 00:23:32,240 --> 00:23:37,400 Se eu disser int * p ;, o que eu acabei de fazer? 446 00:23:37,400 --> 00:23:38,530 O que eu tenho feito é este. 447 00:23:38,530 --> 00:23:43,290 Eu sei o valor de p é um endereço porque todos os ponteiros são apenas 448 00:23:43,290 --> 00:23:44,660 endereços. 449 00:23:44,660 --> 00:23:47,750 Eu posso excluir a referência p utilizando o operador *. 450 00:23:47,750 --> 00:23:51,250 Neste contexto aqui, no próprio top recordar a * é parte do tipo. 451 00:23:51,250 --> 00:23:53,510 Int * é o tipo de dados. 452 00:23:53,510 --> 00:23:56,150 Mas eu posso dereference p usando o operador *, 453 00:23:56,150 --> 00:24:01,897 e se eu fizer isso, se eu ir para esse endereço, o que vou encontrar nesse endereço? 454 00:24:01,897 --> 00:24:02,855 Eu vou encontrar um inteiro. 455 00:24:02,855 --> 00:24:05,910 Assim, int * p é basicamente dizendo: p é um endereço. 456 00:24:05,910 --> 00:24:09,500 Eu posso excluir a referência p e se Eu faço, eu vou encontrar um número inteiro 457 00:24:09,500 --> 00:24:11,920 em que a localização de memória. 458 00:24:11,920 --> 00:24:14,260 >> OK, então eu disse que não havia outra coisa chata com estrelas 459 00:24:14,260 --> 00:24:17,060 e aqui é onde que coisa chata com estrelas é. 460 00:24:17,060 --> 00:24:21,640 Alguma vez você já tentou declarar múltiplas variáveis ​​do mesmo tipo 461 00:24:21,640 --> 00:24:24,409 na mesma linha de código? 462 00:24:24,409 --> 00:24:27,700 Então, por um segundo, fingir que a linha, o código Na verdade, tenho lá em verde 463 00:24:27,700 --> 00:24:29,366 não está lá e ele apenas diz int x, y, z ;. 464 00:24:29,366 --> 00:24:31,634 465 00:24:31,634 --> 00:24:34,550 O que gostaria de fazer é realmente criar três variáveis ​​inteiras para você, 466 00:24:34,550 --> 00:24:36,930 um chamado x, uma chamada y, z e um chamado. 467 00:24:36,930 --> 00:24:41,510 É uma maneira de fazê-lo sem ter que dividir em três linhas. 468 00:24:41,510 --> 00:24:43,890 >> Aqui é onde as estrelas chegar irritante novamente embora, 469 00:24:43,890 --> 00:24:49,200 porque o * é na verdade parte tanto o nome do tipo e parte 470 00:24:49,200 --> 00:24:50,320 do nome da variável. 471 00:24:50,320 --> 00:24:56,430 E por isso, se eu digo int * px, py, pz, o que eu na verdade é um ponteiro para um inteiro 472 00:24:56,430 --> 00:25:01,650 chamado px e dois inteiros, e py pz. 473 00:25:01,650 --> 00:25:04,950 E isso provavelmente não o que é nós queremos, isso não é bom. 474 00:25:04,950 --> 00:25:09,290 >> Então, se eu quiser criar vários ponteiros na mesma linha, do mesmo tipo, 475 00:25:09,290 --> 00:25:12,140 e estrelas, o que eu realmente precisa a fazer é dizer int * pa, * pb, * pc. 476 00:25:12,140 --> 00:25:17,330 477 00:25:17,330 --> 00:25:20,300 Agora, tendo apenas dito que e agora lhe dizendo isso, 478 00:25:20,300 --> 00:25:22,170 você provavelmente nunca vai fazer isso. 479 00:25:22,170 --> 00:25:25,170 E é provavelmente uma coisa boa, honestamente, porque você pode inadvertidamente 480 00:25:25,170 --> 00:25:26,544 omitir uma estrela, algo assim. 481 00:25:26,544 --> 00:25:29,290 É provavelmente o melhor para declarar talvez ponteiros em linhas individuais, 482 00:25:29,290 --> 00:25:31,373 mas é apenas mais um daqueles sintaxe irritante 483 00:25:31,373 --> 00:25:35,310 coisas que fazem com estrelas ponteiros tão difícil de se trabalhar. 484 00:25:35,310 --> 00:25:39,480 Porque é apenas isso sintática bagunça que você tem que trabalhar. 485 00:25:39,480 --> 00:25:41,600 Com a prática que faz realmente se tornar uma segunda natureza. 486 00:25:41,600 --> 00:25:45,410 Eu ainda cometer erros com ele ainda após a programação por 10 anos, 487 00:25:45,410 --> 00:25:49,630 por isso não fique chateado se algo acontecer para você, é muito comum honestamente. 488 00:25:49,630 --> 00:25:52,850 É realmente tipo de uma falha da sintaxe. 489 00:25:52,850 --> 00:25:54,900 >> OK então eu meio que prometeu que gostaríamos de revisitar 490 00:25:54,900 --> 00:25:59,370 o conceito de quão grande é uma string. 491 00:25:59,370 --> 00:26:02,750 Bem, se eu lhe dissesse que um corda, nós temos realmente uma espécie de 492 00:26:02,750 --> 00:26:04,140 mentindo para você o tempo todo. 493 00:26:04,140 --> 00:26:06,181 Não há nenhum tipo de dados chamado corda, e na verdade eu 494 00:26:06,181 --> 00:26:09,730 mencionei isso em um dos nossos primeiros vídeos sobre tipos de dados, 495 00:26:09,730 --> 00:26:13,820 essa seqüência foi um tipo de dados que foi criado para você em CS50.h. 496 00:26:13,820 --> 00:26:17,050 Você tem que # include CS50.h, a fim de usá-lo. 497 00:26:17,050 --> 00:26:19,250 >> Bem string é realmente apenas um alias para algo 498 00:26:19,250 --> 00:26:23,600 chamado de char *, um Ponteiro para um personagem. 499 00:26:23,600 --> 00:26:26,010 Bem ponteiros, recall, são apenas aborda. 500 00:26:26,010 --> 00:26:28,780 Então, qual é o tamanho em bytes de uma seqüência? 501 00:26:28,780 --> 00:26:29,796 Bem, é quatro ou oito. 502 00:26:29,796 --> 00:26:32,170 E a razão de eu dizer quatro ou oito é porque ele realmente 503 00:26:32,170 --> 00:26:36,730 depende do sistema, Se você estiver usando CS50 ide, char * é do tamanho de um char 504 00:26:36,730 --> 00:26:39,340 * É de oito, é um sistema de 64 bits. 505 00:26:39,340 --> 00:26:43,850 Cada endereço na memória é de 64 bits de comprimento. 506 00:26:43,850 --> 00:26:48,270 Se você estiver usando aparelho CS50 ou a utilização de máquinas de 32 bits, 507 00:26:48,270 --> 00:26:51,640 e você já ouviu esse termo 32-bit máquina, o que é uma máquina de 32 bits? 508 00:26:51,640 --> 00:26:56,090 Bem, isso só significa que cada endereço na memória é de 32 bits de comprimento. 509 00:26:56,090 --> 00:26:59,140 E assim 32 bits é de quatro bytes. 510 00:26:59,140 --> 00:27:02,710 Assim, um char * é de quatro ou oito bytes dependendo do seu sistema. 511 00:27:02,710 --> 00:27:06,100 E, de fato qualquer tipo de dados, e um ponteiro para todos os dados 512 00:27:06,100 --> 00:27:12,030 escreva, uma vez que todos os ponteiros são apenas endereços, quatro ou oito bytes. 513 00:27:12,030 --> 00:27:14,030 Então, vamos voltar a esta diagramar e vamos concluir 514 00:27:14,030 --> 00:27:18,130 este vídeo com um pouco de exercício aqui. 515 00:27:18,130 --> 00:27:21,600 Então aqui está o diagrama paramos com no início do vídeo. 516 00:27:21,600 --> 00:27:23,110 Então o que acontece agora, se eu digo * pk = 35? 517 00:27:23,110 --> 00:27:26,370 518 00:27:26,370 --> 00:27:30,530 Então, o que quero dizer quando digo, * pk = 35? 519 00:27:30,530 --> 00:27:32,420 Tome um segundo. 520 00:27:32,420 --> 00:27:34,990 * pk. 521 00:27:34,990 --> 00:27:39,890 No contexto aqui, é * operador de remoção de referência. 522 00:27:39,890 --> 00:27:42,110 Assim, quando o dereference operador é usado, 523 00:27:42,110 --> 00:27:48,520 vamos para o endereço apontado por pk, e nós mudamos o que encontramos. 524 00:27:48,520 --> 00:27:55,270 Assim * pk = 35 eficaz faz isso com a imagem. 525 00:27:55,270 --> 00:27:58,110 Então é basicamente sintaticamente idêntico ao de ter dito k = 35. 526 00:27:58,110 --> 00:28:00,740 527 00:28:00,740 --> 00:28:01,930 >> Mais um. 528 00:28:01,930 --> 00:28:05,510 Se eu disser int m, eu crio uma nova variável chamada m. 529 00:28:05,510 --> 00:28:08,260 Uma nova caixa, é uma caixa verde porque que vai realizar um número inteiro, 530 00:28:08,260 --> 00:28:09,840 e é rotulado m. 531 00:28:09,840 --> 00:28:14,960 Se eu disser que m = 4, eu coloquei um inteiro em que a caixa. 532 00:28:14,960 --> 00:28:20,290 Se digamos pk = & m, como é esta mudança diagrama? 533 00:28:20,290 --> 00:28:28,760 Pk = & m, você se lembra o que o Operador & faz ou é chamado? 534 00:28:28,760 --> 00:28:34,430 Lembre-se que o nome da variável e alguns é o endereço de um nome de variável. 535 00:28:34,430 --> 00:28:38,740 Então, o que nós estamos dizendo é pk obtém o endereço de m. 536 00:28:38,740 --> 00:28:42,010 E assim efetivamente o que acontece no diagrama é que já não pk pontos 537 00:28:42,010 --> 00:28:46,420 para k, mas aponta para m. 538 00:28:46,420 --> 00:28:48,470 >> Novamente ponteiros são muito complicado para trabalhar com 539 00:28:48,470 --> 00:28:50,620 e eles tomam um monte de prática, mas porque 540 00:28:50,620 --> 00:28:54,150 da sua capacidade de permitir que você para transmitir dados entre funções 541 00:28:54,150 --> 00:28:56,945 e realmente tem aqueles alterações entrem em vigor, 542 00:28:56,945 --> 00:28:58,820 recebendo sua cabeça em torno é realmente importante. 543 00:28:58,820 --> 00:29:02,590 É provavelmente o mais complicado tópico que discutimos em CS50, 544 00:29:02,590 --> 00:29:05,910 mas o valor que você começa de usar ponteiros 545 00:29:05,910 --> 00:29:09,200 supera em muito as complicações que vêm de aprendê-las. 546 00:29:09,200 --> 00:29:12,690 Então, eu desejo-lhe o melhor de sorte de aprender sobre ponteiros. 547 00:29:12,690 --> 00:29:15,760 Eu sou Doug Lloyd, este é CS50. 548 00:29:15,760 --> 00:29:17,447