1 00:00:00,000 --> 00:00:06,030 >> [REPRODUCCIÓN DE MÚSICA] 2 00:00:06,030 --> 00:00:08,390 >> DOUG LLOYD: Punteros, aquí estamos. 3 00:00:08,390 --> 00:00:11,080 Esta es, probablemente, va a será el tema más difícil 4 00:00:11,080 --> 00:00:12,840 que se habla en el CS50. 5 00:00:12,840 --> 00:00:15,060 Y si has leído nada de apuntadores 6 00:00:15,060 --> 00:00:19,080 antes de que usted puede ser que sea un poco intimidante entrar en este video. 7 00:00:19,080 --> 00:00:21,260 Es cierto los punteros ¿Permite la capacidad 8 00:00:21,260 --> 00:00:23,740 atornillar quizás hasta bastante mal cuando estás 9 00:00:23,740 --> 00:00:27,450 trabajar con variables, y los datos, y haciendo que su programa se bloquee. 10 00:00:27,450 --> 00:00:30,490 Pero en realidad son realmente útiles y nos realmente una gran manera permiten 11 00:00:30,490 --> 00:00:33,340 para pasar los datos hacia atrás y vuelta entre funciones, 12 00:00:33,340 --> 00:00:35,490 que somos de otro modo no puede hacer. 13 00:00:35,490 --> 00:00:37,750 >> Y así lo que realmente quiero hacer aquí es el tren 14 00:00:37,750 --> 00:00:41,060 le permite tener una buena disciplina puntero, por lo que puede utilizar punteros con eficacia 15 00:00:41,060 --> 00:00:43,850 para hacer sus programas que mucho mejor. 16 00:00:43,850 --> 00:00:48,220 Como dije punteros nos dan una diferente manera de pasar los datos entre funciones. 17 00:00:48,220 --> 00:00:50,270 Ahora bien, si usted recuerda de un video anterior, cuando 18 00:00:50,270 --> 00:00:53,720 hablábamos ámbito de variable, mencioné 19 00:00:53,720 --> 00:01:00,610 que todos los datos que se pasa entre funciones en C se pasan por valor. 20 00:01:00,610 --> 00:01:03,070 Y puede que no he usado esa plazo, lo que significaba que 21 00:01:03,070 --> 00:01:07,170 fue que estamos pasando copias de los datos. 22 00:01:07,170 --> 00:01:12,252 Cuando se pasa una variable a una función, no estamos en realidad pasa la variable 23 00:01:12,252 --> 00:01:13,210 a la función, ¿no? 24 00:01:13,210 --> 00:01:17,670 Estamos pasando una copia de que los datos a la función. 25 00:01:17,670 --> 00:01:20,760 La función hace lo que hará y se calcula un valor, 26 00:01:20,760 --> 00:01:23,180 y tal vez usamos ese valor cuando se le da la espalda. 27 00:01:23,180 --> 00:01:26,700 >> Hubo una excepción a esta regla de pasar por valor, 28 00:01:26,700 --> 00:01:31,210 y vamos a volver a lo que es un poco más adelante en este video. 29 00:01:31,210 --> 00:01:34,880 Si utilizamos punteros lugar de utilizar variables, 30 00:01:34,880 --> 00:01:38,180 o en lugar de utilizar las variables ellos mismos o copias de las variables, 31 00:01:38,180 --> 00:01:43,790 ahora podemos pasar a las variables en torno entre las funciones de una manera diferente. 32 00:01:43,790 --> 00:01:46,550 Esto significa que si hacemos un cambio en una función, 33 00:01:46,550 --> 00:01:49,827 que el cambio realmente tomar efectuar en una función diferente. 34 00:01:49,827 --> 00:01:52,160 Una vez más, esto es algo que no podíamos hacer antes, 35 00:01:52,160 --> 00:01:56,979 y si alguna vez has tratado de cambiar la valor de dos variables en una función, 36 00:01:56,979 --> 00:01:59,270 usted ha notado este problema especie de reptil, ¿verdad? 37 00:01:59,270 --> 00:02:04,340 >> Si queremos cambiar X e Y, y pasarlos a una función llamada swap, 38 00:02:04,340 --> 00:02:08,680 dentro de la función de cambiar el variables que hacen los valores de cambio. 39 00:02:08,680 --> 00:02:12,600 Uno se convierte en dos, dos se convierte en uno, pero no lo hacemos realidad 40 00:02:12,600 --> 00:02:16,890 cambiar nada en el original función, en la persona que llama. 41 00:02:16,890 --> 00:02:19,550 Porque no podemos, estamos solamente trabajar con copias de los mismos. 42 00:02:19,550 --> 00:02:24,760 Con punteros embargo, podemos en realidad pasar X e Y a una función. 43 00:02:24,760 --> 00:02:26,960 Esa función puede hacer algo con ellos. 44 00:02:26,960 --> 00:02:29,250 Y los valores de las variables en realidad puede cambiar. 45 00:02:29,250 --> 00:02:33,710 Así que eso es un gran cambio en nuestra capacidad para trabajar con datos. 46 00:02:33,710 --> 00:02:36,100 >> Antes de sumergirse en punteros, creo que vale la pena 47 00:02:36,100 --> 00:02:38,580 tomar un par de minutos a volver a lo básico aquí. 48 00:02:38,580 --> 00:02:41,000 Y echar un vistazo a cómo obras de memoria para computadoras 49 00:02:41,000 --> 00:02:45,340 porque estos dos temas van para ser realmente muy relacionados entre sí. 50 00:02:45,340 --> 00:02:48,480 Como probablemente sabes, en su sistema informático 51 00:02:48,480 --> 00:02:51,310 Tiene un disco duro o tal vez una unidad de estado sólido, 52 00:02:51,310 --> 00:02:54,430 una especie de lugar de almacenamiento de archivos. 53 00:02:54,430 --> 00:02:57,950 Por lo general es un lugar en el vecindad de 250 gigabytes 54 00:02:57,950 --> 00:02:59,810 que tal vez un par de terabytes ahora. 55 00:02:59,810 --> 00:03:02,270 Y es donde todos los de su archivos viven en última instancia, 56 00:03:02,270 --> 00:03:04,870 incluso cuando el ordenador está apagado apagado, puede volver a encenderlo 57 00:03:04,870 --> 00:03:09,190 y usted encontrará los archivos están ahí de nuevo al reiniciar el sistema. 58 00:03:09,190 --> 00:03:14,820 Pero las unidades de disco, como una unidad de disco duro, un disco duro o una unidad de estado sólido, un SSD, 59 00:03:14,820 --> 00:03:16,050 son el espacio de almacenamiento justo. 60 00:03:16,050 --> 00:03:20,400 >> En realidad no podemos hacer nada con los datos que se encuentra en el disco duro, 61 00:03:20,400 --> 00:03:22,080 o en una unidad de estado sólido. 62 00:03:22,080 --> 00:03:24,950 Con el fin de cambiar realmente de datos o moverlo, 63 00:03:24,950 --> 00:03:28,800 tenemos que moverlo a RAM, memoria de acceso aleatorio. 64 00:03:28,800 --> 00:03:31,170 Ahora RAM, usted tiene un montón menos en su ordenador. 65 00:03:31,170 --> 00:03:34,185 Es posible que en algún lugar del barrio de 512 megabytes 66 00:03:34,185 --> 00:03:38,850 si usted tiene un ordenador antiguo, que tal vez dos, cuatro, ocho, 16, 67 00:03:38,850 --> 00:03:41,820 posiblemente incluso un poco más, gigabytes de RAM. 68 00:03:41,820 --> 00:03:46,390 Así que eso es mucho más pequeño, pero eso es donde todos los datos volátiles existe. 69 00:03:46,390 --> 00:03:48,270 Ahí es donde podemos cambiar las cosas. 70 00:03:48,270 --> 00:03:53,350 Pero cuando nos volvemos nuestro ordenador apagado, todos los datos en la RAM se destruye. 71 00:03:53,350 --> 00:03:57,150 >> Así que por eso tenemos que tener el disco duro para la ubicación más permanente de la misma, 72 00:03:57,150 --> 00:03:59,720 de modo que existe- que lo haría ser realmente malo si cada vez que 73 00:03:59,720 --> 00:04:03,310 convertido a nuestro ordenador apagado, cada archivo en nuestro sistema fue borrada. 74 00:04:03,310 --> 00:04:05,600 Así que trabajamos dentro de RAM. 75 00:04:05,600 --> 00:04:09,210 Y cada vez que estamos hablando de memoria, más o menos, en el CS50, 76 00:04:09,210 --> 00:04:15,080 estamos hablando de RAM, no disco duro. 77 00:04:15,080 --> 00:04:18,657 >> Así que cuando nos movemos cosas en la memoria, que ocupa una cierta cantidad de espacio. 78 00:04:18,657 --> 00:04:20,740 Todos los tipos de datos que hemos estado trabajando con 79 00:04:20,740 --> 00:04:23,480 asumir diferentes cantidades de espacio en la RAM. 80 00:04:23,480 --> 00:04:27,600 Así que cada vez que cree un entero variables, cuatro bytes de memoria 81 00:04:27,600 --> 00:04:30,750 se dejan de lado en la memoria RAM para que puede trabajar con ese entero. 82 00:04:30,750 --> 00:04:34,260 Puede declarar el número entero, cambiarlo, asignarlo 83 00:04:34,260 --> 00:04:36,700 a un valor de 10 incrementado por uno, así sucesivamente y así sucesivamente. 84 00:04:36,700 --> 00:04:39,440 Todo lo que tiene que ocurrir en RAM, y se obtiene cuatro bytes 85 00:04:39,440 --> 00:04:42,550 para trabajar con para cada entero que usted cree. 86 00:04:42,550 --> 00:04:45,410 >> Cada carácter que crear consigue un byte. 87 00:04:45,410 --> 00:04:48,160 Eso es sólo la cantidad de espacio necesaria para almacenar un carácter. 88 00:04:48,160 --> 00:04:51,310 Cada flotador, un verdadero número, obtiene cuatro bytes 89 00:04:51,310 --> 00:04:53,390 a menos que sea un doble punto flotante de precisión 90 00:04:53,390 --> 00:04:56,510 número, que le permite tener dígitos más precisas o más 91 00:04:56,510 --> 00:04:59,300 después del punto decimal sin perder precisión, 92 00:04:59,300 --> 00:05:01,820 que tomar hasta ocho bytes de memoria. 93 00:05:01,820 --> 00:05:06,730 Anhela largos, realmente grandes números enteros, También tomar hasta ocho bytes de memoria. 94 00:05:06,730 --> 00:05:09,000 ¿Cuántos bytes de memoria Qué cadenas ocupan? 95 00:05:09,000 --> 00:05:12,990 Bueno vamos a poner un alfiler en esa pregunta por ahora, pero vamos a volver a ella. 96 00:05:12,990 --> 00:05:17,350 >> Así que de vuelta a esta idea de la memoria como una gran variedad de células bytes de tamaño. 97 00:05:17,350 --> 00:05:20,871 Eso es realmente todo lo que es, es sólo una enorme variedad de células, 98 00:05:20,871 --> 00:05:23,370 al igual que cualquier otra matriz que usted está familiarizado con y ver, 99 00:05:23,370 --> 00:05:26,430 excepto cada elemento es un byte de ancho. 100 00:05:26,430 --> 00:05:30,030 Y al igual que una matriz, cada elemento tiene una dirección. 101 00:05:30,030 --> 00:05:32,120 Cada elemento de una matriz tiene un índice, y nosotros 102 00:05:32,120 --> 00:05:36,302 puede utilizar ese índice para hacer la llamada acceso aleatorio en la matriz. 103 00:05:36,302 --> 00:05:38,510 No tenemos que empezar por el principio de la matriz, 104 00:05:38,510 --> 00:05:40,569 iterar a través de todos los solo elemento de la misma, 105 00:05:40,569 --> 00:05:41,860 para encontrar lo que estamos buscando. 106 00:05:41,860 --> 00:05:45,790 Sólo podemos decir que quiero llegar al Elemento 15a o el elemento número 100. 107 00:05:45,790 --> 00:05:49,930 Y que sólo puede pasar en ese número y obtener el valor que usted está buscando. 108 00:05:49,930 --> 00:05:54,460 >> Del mismo modo cada localización en la memoria tiene una dirección. 109 00:05:54,460 --> 00:05:57,320 Así que su memoria podría algo como esto. 110 00:05:57,320 --> 00:06:01,420 Aquí hay una muy pequeña parte de memoria, esta es de 20 bytes de memoria. 111 00:06:01,420 --> 00:06:04,060 Los primeros 20 bytes porque mi aborda hay en la parte inferior 112 00:06:04,060 --> 00:06:08,890 son 0, 1, 2, 3, y así en todo el camino hasta el 19. 113 00:06:08,890 --> 00:06:13,190 Y cuando me declaro variables, y cuando empiezo a trabajar con ellos, 114 00:06:13,190 --> 00:06:15,470 el sistema se va a establecer de lado un poco de espacio para mí 115 00:06:15,470 --> 00:06:17,595 en esta memoria para trabajar con mis variables. 116 00:06:17,595 --> 00:06:21,610 Así que podría decir, char c es igual a la capital H. ¿Y qué va a pasar? 117 00:06:21,610 --> 00:06:23,880 Bueno, el sistema va a reservado para mí un byte. 118 00:06:23,880 --> 00:06:27,870 En este caso se eligió el número de bytes cuatro, el byte en la dirección de cuatro, 119 00:06:27,870 --> 00:06:31,310 y que va a almacenar el letra mayúscula H en allí para mí. 120 00:06:31,310 --> 00:06:34,350 Pues si yo digo velocidad int límite es igual a 65, que es 121 00:06:34,350 --> 00:06:36,806 va a dejar de lado las cuatro bytes de memoria para mí. 122 00:06:36,806 --> 00:06:39,180 Y que va a tratar a las personas cuatro bytes como una sola unidad 123 00:06:39,180 --> 00:06:41,305 porque lo que estamos trabajando con un entero aquí. 124 00:06:41,305 --> 00:06:44,350 Y que va a almacenar 65 en ese país. 125 00:06:44,350 --> 00:06:47,000 >> Ahora ya estoy un poco que le dice un poco de una mentira, 126 00:06:47,000 --> 00:06:50,150 derecha, porque sabemos que ordenadores funcionan en binario. 127 00:06:50,150 --> 00:06:53,100 Ellos no entienden necesariamente lo mayúscula es 128 00:06:53,100 --> 00:06:57,110 o lo que es un 65, es decir, que sólo entienden el binario, ceros y unos. 129 00:06:57,110 --> 00:06:59,000 Y lo que en realidad lo que estamos almacenando allí 130 00:06:59,000 --> 00:07:03,450 no es la letra H y el número 65, sino más bien las representaciones binarias 131 00:07:03,450 --> 00:07:06,980 del mismo, que busque un poco algo como esto. 132 00:07:06,980 --> 00:07:10,360 Y, en particular en el contexto de la variable de número entero, 133 00:07:10,360 --> 00:07:13,559 no va a simplemente escupir en, no va a tratarlo como uno de cuatro 134 00:07:13,559 --> 00:07:15,350 trozo byte necesariamente, en realidad está pasando 135 00:07:15,350 --> 00:07:19,570 tratarlo como cuatro trozos de un byte, que podría ser algo como esto. 136 00:07:19,570 --> 00:07:22,424 E incluso esto no es todo cierto tampoco, 137 00:07:22,424 --> 00:07:24,840 debido a algo llamado un endianness, que no estamos 138 00:07:24,840 --> 00:07:26,965 va a entrar en este momento, pero si eres curioso acerca de, 139 00:07:26,965 --> 00:07:29,030 se puede leer en poco y grandes endianness. 140 00:07:29,030 --> 00:07:31,640 Pero por el bien de este argumento, por el bien de este video, 141 00:07:31,640 --> 00:07:34,860 vamos a suponer que es, en De hecho, cómo el número 65 lo haría 142 00:07:34,860 --> 00:07:36,970 estar representados en memoria en todos los sistemas, 143 00:07:36,970 --> 00:07:38,850 aunque no es del todo cierto. 144 00:07:38,850 --> 00:07:41,700 >> Pero seamos en realidad sólo consiguen deshacerse de todos binario completo, 145 00:07:41,700 --> 00:07:44,460 y sólo pensar en como H y el 65, que es mucho más fácil 146 00:07:44,460 --> 00:07:47,900 pensar en ello como que como ser humano. 147 00:07:47,900 --> 00:07:51,420 Muy bien, por lo que también parece tal vez un poco aleatorio que I've- mi sistema 148 00:07:51,420 --> 00:07:55,130 no me dio bytes 5, 6, 7, y 8 para almacenar el número entero. 149 00:07:55,130 --> 00:07:58,580 Hay una razón para eso, también, que no vamos a entrar en este momento, pero suficiente 150 00:07:58,580 --> 00:08:00,496 con decir que lo que el equipo está haciendo aquí 151 00:08:00,496 --> 00:08:02,810 es probablemente una buena jugada de su parte. 152 00:08:02,810 --> 00:08:06,020 Para no darme memoria que es copia necesariamente con espalda. 153 00:08:06,020 --> 00:08:10,490 A pesar de que va a hacerlo ahora si quiero tener otra cadena, 154 00:08:10,490 --> 00:08:13,080 Llamé apellido, y quiero poner Lloyd allí. 155 00:08:13,080 --> 00:08:18,360 Voy a tener que adaptarse a un solo carácter, cada letra que es 156 00:08:18,360 --> 00:08:21,330 va a requerir de un carácter, un byte de memoria. 157 00:08:21,330 --> 00:08:26,230 Así que si podía poner Lloyd en mi arsenal como esto soy bastante bueno para ir, ¿verdad? 158 00:08:26,230 --> 00:08:28,870 ¿Lo que falta? 159 00:08:28,870 --> 00:08:31,840 >> Recuerde que cada cadena trabajamos con en C termina con barra invertida cero, 160 00:08:31,840 --> 00:08:33,339 y no podemos omitir que aquí, tampoco. 161 00:08:33,339 --> 00:08:36,090 Tenemos que dejar de lado un byte de memoria para sostener que lo que 162 00:08:36,090 --> 00:08:39,130 saber cuándo nuestra cadena ha terminado. 163 00:08:39,130 --> 00:08:41,049 Así que de nuevo este acuerdo de las cosas 164 00:08:41,049 --> 00:08:42,799 aparecerá en la fuerza de la memoria ser un poco al azar, 165 00:08:42,799 --> 00:08:44,870 pero en realidad es cómo la mayoría de los sistemas están diseñados. 166 00:08:44,870 --> 00:08:48,330 Para alinearlos en múltiplos de cuatro, por razones de nuevo 167 00:08:48,330 --> 00:08:50,080 que no necesitamos entrar en este momento. 168 00:08:50,080 --> 00:08:53,060 Pero esto, por lo que basta con decir que después de estas tres líneas de código, 169 00:08:53,060 --> 00:08:54,810 esto es lo que la memoria podría ser similar. 170 00:08:54,810 --> 00:08:58,930 Si necesito posiciones de memoria 4, 8 y 12 para sujetar mis datos, 171 00:08:58,930 --> 00:09:01,100 esto es lo que mi memoria podría ser similar. 172 00:09:01,100 --> 00:09:04,062 >> Y sólo ser particularmente pedante aquí, cuando 173 00:09:04,062 --> 00:09:06,020 estamos hablando de la memoria direcciones Solemos 174 00:09:06,020 --> 00:09:08,390 hacerlo usando notaciones hexadecimales. 175 00:09:08,390 --> 00:09:12,030 Entonces, ¿por qué no nos convertimos todos estos de decimal a notación hexadecimal 176 00:09:12,030 --> 00:09:15,010 simplemente porque eso es en general cómo nos referimos a la memoria. 177 00:09:15,010 --> 00:09:17,880 Así que en lugar de ser de 0 a 19, lo que tenemos es cero 178 00:09:17,880 --> 00:09:20,340 x cero por cero x1 tres. 179 00:09:20,340 --> 00:09:23,790 Esos son los 20 bytes de memoria que hemos o estamos viendo en esta imagen 180 00:09:23,790 --> 00:09:25,540 aquí. 181 00:09:25,540 --> 00:09:29,310 >> Así que todo lo que se dice, vamos a alejarse de la memoria por un segundo 182 00:09:29,310 --> 00:09:30,490 y de nuevo a los punteros. 183 00:09:30,490 --> 00:09:32,420 Aquí es el más importante cosa para recordar 184 00:09:32,420 --> 00:09:34,070 a medida que comenzamos a trabajar con punteros. 185 00:09:34,070 --> 00:09:36,314 Un puntero es nada más de una dirección. 186 00:09:36,314 --> 00:09:38,230 Lo diré otra vez porque que es tan importante, 187 00:09:38,230 --> 00:09:42,730 un puntero no es nada más de una dirección. 188 00:09:42,730 --> 00:09:47,760 Los punteros son direcciones a lugares en la memoria donde viven variables. 189 00:09:47,760 --> 00:09:52,590 Sabiendo que se hace de esperar un poco más fácil trabajar con ellos. 190 00:09:52,590 --> 00:09:54,550 Otra cosa que me gusta que hacer es tener suerte 191 00:09:54,550 --> 00:09:58,510 de los diagramas de representar visualmente lo que es pasando con varias líneas de código. 192 00:09:58,510 --> 00:10:00,660 Y vamos a hacer esto un par de veces en los punteros, 193 00:10:00,660 --> 00:10:03,354 y cuando hablamos de dinámica asignación de memoria también. 194 00:10:03,354 --> 00:10:06,020 Porque creo que estos diagramas puede ser particularmente útil. 195 00:10:06,020 --> 00:10:09,540 >> Así que si yo digo por ejemplo, int k en mi código, ¿qué está sucediendo? 196 00:10:09,540 --> 00:10:12,524 Bueno lo que está sucediendo es, básicamente, Me estoy poniendo de memoria reservado para mí, 197 00:10:12,524 --> 00:10:14,690 pero ni siquiera me gusta pienso así, yo 198 00:10:14,690 --> 00:10:16,300 gustaría pensar en ello como una caja. 199 00:10:16,300 --> 00:10:20,090 Tengo una caja y es de color verde porque 200 00:10:20,090 --> 00:10:21,750 puede poner números enteros en cajas verdes. 201 00:10:21,750 --> 00:10:23,666 Si se trataba de un personaje que podría tener un cuadro azul. 202 00:10:23,666 --> 00:10:27,290 Pero yo siempre digo, si yo estoy creando una caja que puede contener números enteros 203 00:10:27,290 --> 00:10:28,950 esa caja es de color verde. 204 00:10:28,950 --> 00:10:33,020 Y tomo un marcador permanente y escribo k en el lado de la misma. 205 00:10:33,020 --> 00:10:37,590 Así que tengo una caja llamada k, en la que puedo poner enteros. 206 00:10:37,590 --> 00:10:41,070 Así que cuando digo int k, eso es lo que pasa en mi cabeza. 207 00:10:41,070 --> 00:10:43,140 Si digo k es igual a cinco, ¿qué estoy haciendo? 208 00:10:43,140 --> 00:10:45,110 Bueno, me voy a poner de cinco en el cuadro, la derecha. 209 00:10:45,110 --> 00:10:48,670 Esto es bastante sencillo, si Digo int k, crear un cuadro llamado k. 210 00:10:48,670 --> 00:10:52,040 Si digo k es igual a 5, puso cinco en la caja. 211 00:10:52,040 --> 00:10:53,865 Esperemos que eso no es demasiado de un salto. 212 00:10:53,865 --> 00:10:55,990 Aquí es donde las cosas van un poco interesante. 213 00:10:55,990 --> 00:11:02,590 Si digo int * pk, bien incluso si no lo hago sabe lo que esto significa necesariamente, 214 00:11:02,590 --> 00:11:06,150 Es claramente tiene algo que ver con un entero. 215 00:11:06,150 --> 00:11:08,211 Así que voy a colorear esta caja verde-ish, 216 00:11:08,211 --> 00:11:10,210 Sé que tiene algo que ver con un entero, 217 00:11:10,210 --> 00:11:13,400 pero no es un número entero en sí, porque es un int estrellas. 218 00:11:13,400 --> 00:11:15,390 Hay algo un poco diferente al respecto. 219 00:11:15,390 --> 00:11:17,620 Así involucrados de un entero, pero por lo demás es 220 00:11:17,620 --> 00:11:19,830 no muy diferente de lo que estábamos hablando. 221 00:11:19,830 --> 00:11:24,240 Es una caja, su tiene una etiqueta, que lleva un pk etiqueta, 222 00:11:24,240 --> 00:11:27,280 y es capaz de tenencia estrellas int, lo que son. 223 00:11:27,280 --> 00:11:29,894 Tienen algo que ver con números enteros, con claridad. 224 00:11:29,894 --> 00:11:31,060 Aquí está la última línea sin embargo. 225 00:11:31,060 --> 00:11:37,650 Si digo pk = & k, espera, lo que acaba de suceder, ¿verdad? 226 00:11:37,650 --> 00:11:41,820 Así que este número al azar, aparentemente al azar número, se tira en el cuadro de allí. 227 00:11:41,820 --> 00:11:44,930 Todo lo que es, es pk obtiene la dirección de k. 228 00:11:44,930 --> 00:11:52,867 Así que me quedo donde k vive en la memoria, su dirección, la dirección de sus bytes. 229 00:11:52,867 --> 00:11:55,200 Todo lo que estoy haciendo es lo que digo que el valor es lo que voy 230 00:11:55,200 --> 00:11:59,430 para poner dentro de mi caja llamada pk. 231 00:11:59,430 --> 00:12:02,080 Y porque estas cosas son punteros, y porque busca 232 00:12:02,080 --> 00:12:04,955 en una cadena como cero x ocho cero c siete cuatro y ocho 233 00:12:04,955 --> 00:12:07,790 dos cero es, probablemente, no es muy significativa. 234 00:12:07,790 --> 00:12:12,390 Cuando visualizamos general punteros, que en realidad hacemos como punteros. 235 00:12:12,390 --> 00:12:17,000 Pk nos da la información tenemos que encontrar k en la memoria. 236 00:12:17,000 --> 00:12:19,120 Así que, básicamente pk tiene una flecha en él. 237 00:12:19,120 --> 00:12:21,670 Y si caminamos la longitud de esa flecha, imagínese 238 00:12:21,670 --> 00:12:25,280 es algo que se puede caminar, si caminar a lo largo de la longitud de la flecha, 239 00:12:25,280 --> 00:12:29,490 en la punta de la flecha, que será encontrar la ubicación en la memoria 240 00:12:29,490 --> 00:12:31,390 donde k vive. 241 00:12:31,390 --> 00:12:34,360 Y eso es realmente importante porque una vez que sabemos que k vive, 242 00:12:34,360 --> 00:12:37,870 podemos empezar a trabajar con los datos dentro de esa posición de memoria. 243 00:12:37,870 --> 00:12:40,780 A pesar de que estamos recibiendo un pequeñito poco por delante de nosotros por ahora. 244 00:12:40,780 --> 00:12:42,240 >> Entonces, ¿qué es un puntero? 245 00:12:42,240 --> 00:12:45,590 Un puntero es un elemento de datos cuyo valor es una dirección de memoria. 246 00:12:45,590 --> 00:12:49,740 Esa fue que el cero x ocho cero cosas pasando, que era una dirección de memoria. 247 00:12:49,740 --> 00:12:52,060 Esa fue una ubicación en la memoria. 248 00:12:52,060 --> 00:12:55,080 Y el tipo de un puntero describe el tipo 249 00:12:55,080 --> 00:12:56,930 de los datos que encontrará en esa dirección de memoria. 250 00:12:56,930 --> 00:12:58,810 Así que la parte derecha int estrellas. 251 00:12:58,810 --> 00:13:03,690 Si sigo esa flecha, es me va a llevar a una ubicación. 252 00:13:03,690 --> 00:13:06,980 Y ese lugar, lo que encontrarán allí en mi ejemplo, 253 00:13:06,980 --> 00:13:08,240 es un cuadro de color verde. 254 00:13:08,240 --> 00:13:12,650 Es un entero, eso es lo que encontrarán si voy a esa dirección. 255 00:13:12,650 --> 00:13:14,830 El tipo de datos de un puntero describe lo 256 00:13:14,830 --> 00:13:17,936 se encuentra en esa dirección de memoria. 257 00:13:17,936 --> 00:13:19,560 Así que aquí está la cosa muy fresco sin embargo. 258 00:13:19,560 --> 00:13:25,090 Punteros nos permiten pasar variables entre funciones. 259 00:13:25,090 --> 00:13:28,520 Y en realidad pasar variables y no pasar copias de ellos. 260 00:13:28,520 --> 00:13:32,879 Porque si sabemos exactamente dónde en memoria para encontrar una variable, 261 00:13:32,879 --> 00:13:35,670 no necesitamos hacer una copia de ella, que sólo puede ir a ese lugar 262 00:13:35,670 --> 00:13:37,844 y trabajar con esa variable. 263 00:13:37,844 --> 00:13:40,260 Así que en esencia punteros especie de hacer un entorno informático 264 00:13:40,260 --> 00:13:42,360 mucho más como el mundo real, a la derecha. 265 00:13:42,360 --> 00:13:44,640 >> Así que aquí está una analogía. 266 00:13:44,640 --> 00:13:48,080 Digamos que tengo un cuaderno, derecha, y está lleno de notas. 267 00:13:48,080 --> 00:13:50,230 Y me gustaría que actualizarlo. 268 00:13:50,230 --> 00:13:53,960 Usted es una función que Actualizaciones de notas, derecha. 269 00:13:53,960 --> 00:13:56,390 En la forma en que hemos estado trabajando hasta ahora, lo que 270 00:13:56,390 --> 00:14:02,370 que pasa es que usted tome mi cuaderno, te vas a la tienda de copia, 271 00:14:02,370 --> 00:14:06,410 que va a hacer una copia de Xerox cada página del cuaderno. 272 00:14:06,410 --> 00:14:09,790 Vas a dejar mi libreta de vuelta en mi escritorio cuando haya terminado, 273 00:14:09,790 --> 00:14:14,600 irás y tachar cosas en mi cuaderno que están fuera de fecha o erróneo, 274 00:14:14,600 --> 00:14:19,280 y luego pasará de nuevo a me la pila de páginas Xerox 275 00:14:19,280 --> 00:14:22,850 que es una réplica de mi portátil con los cambios que usted ha hecho a ella. 276 00:14:22,850 --> 00:14:27,040 Y en ese punto, le toca a mí como la función de llamada, ya que la persona que llama, 277 00:14:27,040 --> 00:14:30,582 al decidir tomar sus notas y integrarlos de nuevo en mi cuaderno. 278 00:14:30,582 --> 00:14:32,540 Así que hay un montón de pasos involucrado aquí, a la derecha. 279 00:14:32,540 --> 00:14:34,850 Al igual que ¿no sería mejor si acabo de decir, bueno, ¿verdad 280 00:14:34,850 --> 00:14:38,370 actualizar mi cuaderno para yo, que entrego mi cuaderno, 281 00:14:38,370 --> 00:14:40,440 y se toma las cosas y cruzar literalmente fuera 282 00:14:40,440 --> 00:14:42,810 y actualizar mis notas en mi cuaderno. 283 00:14:42,810 --> 00:14:45,140 Y luego me dan mi cuaderno espalda. 284 00:14:45,140 --> 00:14:47,320 Eso es algo de lo que punteros nos permiten hacer, 285 00:14:47,320 --> 00:14:51,320 que hacen de este entorno mucho más como la forma en que operamos en la realidad. 286 00:14:51,320 --> 00:14:54,640 >> Está bien así que eso es lo que un puntero está, vamos a hablar 287 00:14:54,640 --> 00:14:58,040 acerca de cómo funcionan los punteros en C, y cómo podemos empezar a trabajar con ellos. 288 00:14:58,040 --> 00:15:02,550 Así que hay una muy simple puntero en C llamado el puntero nulo. 289 00:15:02,550 --> 00:15:04,830 Los puntos de puntero nulo a nada. 290 00:15:04,830 --> 00:15:08,310 Esto probablemente parece que es En realidad no es una cosa muy útil, 291 00:15:08,310 --> 00:15:10,500 pero como veremos un poco más adelante, el hecho de 292 00:15:10,500 --> 00:15:15,410 la existencia de este puntero nulo realmente realmente puede ser útil. 293 00:15:15,410 --> 00:15:19,090 Y cada vez que se crea un puntero y no establece su valor de inmediato- 294 00:15:19,090 --> 00:15:21,060 un ejemplo de configuración su valor inmediatamente 295 00:15:21,060 --> 00:15:25,401 será un par de diapositivas de regreso donde dije pk es igual a & k, 296 00:15:25,401 --> 00:15:28,740 pk obtiene la dirección de k, como vamos a ver lo que eso significa, 297 00:15:28,740 --> 00:15:32,990 vamos a ver cómo el código que shortly- si no establecemos su valor a algo 298 00:15:32,990 --> 00:15:35,380 inmediatamente significativo, siempre debe 299 00:15:35,380 --> 00:15:37,480 establecer el puntero para apuntar a null. 300 00:15:37,480 --> 00:15:40,260 Usted debe configurarlo para que apunte a nada. 301 00:15:40,260 --> 00:15:43,614 >> Eso es muy diferente a simplemente dejando el valor ya que es 302 00:15:43,614 --> 00:15:45,530 y luego declarar una puntero y acaba asumiendo 303 00:15:45,530 --> 00:15:48,042 es nula porque es rara vez es cierto. 304 00:15:48,042 --> 00:15:50,000 Así que siempre se debe establecer el valor de un puntero 305 00:15:50,000 --> 00:15:55,690 null si no se establece su valor a algo significativo inmediatamente. 306 00:15:55,690 --> 00:15:59,090 Puede comprobar si el valor de un puntero es nulo utilizando el operador de igualdad 307 00:15:59,090 --> 00:16:05,450 (==), Al igual que se compara cualquier entero valores o valores de caracteres utilizando (==) 308 00:16:05,450 --> 00:16:06,320 así como. 309 00:16:06,320 --> 00:16:10,994 Es un tipo especial de constante valor que se puede utilizar para probar. 310 00:16:10,994 --> 00:16:13,160 Así que fue una muy simple puntero, el puntero nulo. 311 00:16:13,160 --> 00:16:15,320 Otra forma de crear un puntero es extraer 312 00:16:15,320 --> 00:16:18,240 la dirección de una variable ya ha creado, 313 00:16:18,240 --> 00:16:22,330 y lo hace utilizando la Y extracción dirección del operador. 314 00:16:22,330 --> 00:16:26,720 Que ya hemos visto con anterioridad en el primer ejemplo diagrama mostré. 315 00:16:26,720 --> 00:16:31,450 Así que si x es una variable que hemos ya creado de tipo entero, 316 00:16:31,450 --> 00:16:35,110 a continuación, y x es un puntero a un entero. 317 00:16:35,110 --> 00:16:39,810 y x es- recuerdan, y se va a extraer la dirección de la cosa a la derecha. 318 00:16:39,810 --> 00:16:45,350 Y puesto que un puntero es sólo una dirección, que y x es un puntero a un entero 319 00:16:45,350 --> 00:16:48,560 cuyo valor es donde en la memoria x vidas. 320 00:16:48,560 --> 00:16:50,460 Es la dirección de x. 321 00:16:50,460 --> 00:16:53,296 Así y x es la dirección de x. 322 00:16:53,296 --> 00:16:55,670 Echemos un paso más allá y conectar a algo 323 00:16:55,670 --> 00:16:58,380 He aludido en un video anterior. 324 00:16:58,380 --> 00:17:06,730 Si arr es una matriz de dobles, a continuación, y corchete arr i es un puntero 325 00:17:06,730 --> 00:17:08,109 a una doble. 326 00:17:08,109 --> 00:17:08,970 OK. 327 00:17:08,970 --> 00:17:12,160 arr corchete i, si arr es una matriz de dobles, 328 00:17:12,160 --> 00:17:19,069 luego arr corchete i es el elemento i de esa matriz, 329 00:17:19,069 --> 00:17:29,270 y Y arr corchete i es donde en existe el elemento i de arr memoria. 330 00:17:29,270 --> 00:17:31,790 >> ¿Cuál es la implicación aquí? 331 00:17:31,790 --> 00:17:34,570 Un nombre de matrices, la implicación de todo este asunto, 332 00:17:34,570 --> 00:17:39,290 es que el nombre de una matriz es en realidad sí mismo un puntero. 333 00:17:39,290 --> 00:17:41,170 Usted ha estado trabajando con punteros a lo largo 334 00:17:41,170 --> 00:17:45,290 cada vez que usted ha utilizado una matriz. 335 00:17:45,290 --> 00:17:49,090 Recuerde el ejemplo el ámbito de las variables, 336 00:17:49,090 --> 00:17:53,420 cerca del final del video que presento un ejemplo en el que tenemos una función 337 00:17:53,420 --> 00:17:56,890 llamada int set y un función llamada matriz de conjuntos. 338 00:17:56,890 --> 00:18:00,490 Y su reto para determinar si o no, o lo que el 339 00:18:00,490 --> 00:18:03,220 valores que imprime el final de la función, 340 00:18:03,220 --> 00:18:05,960 al final del programa principal. 341 00:18:05,960 --> 00:18:08,740 >> Si usted recuerda de ese ejemplo o si has visto el video, 342 00:18:08,740 --> 00:18:13,080 usted sabe que cuando Tú- la llamada a conjunto int hace efectivamente nada. 343 00:18:13,080 --> 00:18:16,390 Pero la llamada para establecer matriz hace. 344 00:18:16,390 --> 00:18:19,280 Y en cierto modo me pasó por alto por qué ese fue el caso en el momento. 345 00:18:19,280 --> 00:18:22,363 Que acabo de decir, así que es una matriz, que es especial, ya sabes, hay una razón. 346 00:18:22,363 --> 00:18:25,020 La razón es que una matriz de nombre es en realidad sólo un puntero, 347 00:18:25,020 --> 00:18:28,740 y hay este especial sintaxis de corchete que 348 00:18:28,740 --> 00:18:30,510 hacer las cosas mucho más agradable para trabajar. 349 00:18:30,510 --> 00:18:34,410 Y hacen la idea de un puntero mucho menos intimidante, 350 00:18:34,410 --> 00:18:36,800 y es por eso que son una especie de presentado de esa manera. 351 00:18:36,800 --> 00:18:38,600 Pero en realidad las matrices son punteros. 352 00:18:38,600 --> 00:18:41,580 Y por eso cuando nos hecho un cambio en la matriz, 353 00:18:41,580 --> 00:18:44,880 cuando pasamos una matriz como un parámetro a una función o como un argumento 354 00:18:44,880 --> 00:18:50,110 a una función, el contenido de la matriz en realidad cambiado tanto en el destinatario de la llamada 355 00:18:50,110 --> 00:18:51,160 y en la persona que llama. 356 00:18:51,160 --> 00:18:55,846 Lo que para cualquier otro tipo de variables que vimos no fue el caso. 357 00:18:55,846 --> 00:18:58,970 Así que eso es algo a tener en mente cuando se trabaja con punteros, 358 00:18:58,970 --> 00:19:01,610 es que el nombre de un array en realidad un puntero 359 00:19:01,610 --> 00:19:04,750 al primer elemento de la matriz. 360 00:19:04,750 --> 00:19:08,930 >> Aceptar lo que ahora tenemos todos estos hechos, vamos a seguir adelante, a la derecha. 361 00:19:08,930 --> 00:19:11,370 ¿Por qué nos preocupamos donde algo vive. 362 00:19:11,370 --> 00:19:14,120 Bueno, como he dicho, es bastante útil saber donde algo vive 363 00:19:14,120 --> 00:19:17,240 por lo que puede ir allí y cambiarlo. 364 00:19:17,240 --> 00:19:19,390 Trabajar con él y, de hecho tener la cosa que usted 365 00:19:19,390 --> 00:19:23,710 quiere hacer en este sentido toma variables, y no tomar efecto en alguna copia de la misma. 366 00:19:23,710 --> 00:19:26,150 Esto se llama eliminación de referencias. 367 00:19:26,150 --> 00:19:28,690 Nos vamos a la referencia y cambiamos el valor allí. 368 00:19:28,690 --> 00:19:32,660 Así que si tenemos un puntero y se llama pc, y apunta a un personaje, 369 00:19:32,660 --> 00:19:40,610 entonces podemos decir * * PC y PC es el nombre de lo que encontraremos si vamos 370 00:19:40,610 --> 00:19:42,910 a la dirección de PC. 371 00:19:42,910 --> 00:19:47,860 ¿Qué vamos a encontrar que hay un personaje y * PC es como nos referimos a los datos en ese 372 00:19:47,860 --> 00:19:48,880 localización. 373 00:19:48,880 --> 00:19:54,150 Así que podríamos decir algo como * pc = D o algo por el estilo, 374 00:19:54,150 --> 00:19:59,280 y eso significa que todo lo que fue en memoria de direcciones de la PC, 375 00:19:59,280 --> 00:20:07,040 cualquier carácter era previamente allí, ahora es D, si decimos * pc = D. 376 00:20:07,040 --> 00:20:10,090 >> Así que aquí vamos de nuevo con algunas cosas raras C, derecha. 377 00:20:10,090 --> 00:20:14,560 Así que hemos visto anteriormente como * de alguna manera parte del tipo de datos, 378 00:20:14,560 --> 00:20:17,160 y ahora se está utilizando en un contexto ligeramente diferente 379 00:20:17,160 --> 00:20:19,605 para acceder a los datos en una ubicación. 380 00:20:19,605 --> 00:20:22,480 Sé que es un poco confuso y eso es en realidad parte de este todo 381 00:20:22,480 --> 00:20:25,740 al igual que, ¿por qué punteros tienen esta mitología alrededor de ellos por ser tan complejo, 382 00:20:25,740 --> 00:20:28,250 es una especie de problema de sintaxis, la verdad. 383 00:20:28,250 --> 00:20:31,810 Pero * se utiliza en ambos contextos, tanto como parte del nombre de tipo, 384 00:20:31,810 --> 00:20:34,100 y vamos a ver un poco algo más tarde lo demás, también. 385 00:20:34,100 --> 00:20:36,490 Y ahora mismo es el operador de eliminar la referencia. 386 00:20:36,490 --> 00:20:38,760 Así que va a la referencia, se accede a los datos 387 00:20:38,760 --> 00:20:43,000 en la ubicación del puntero, y le permite manipular a voluntad. 388 00:20:43,000 --> 00:20:45,900 >> Ahora bien, esto es muy similar a visitar a su vecino, a la derecha. 389 00:20:45,900 --> 00:20:48,710 Si usted sabe lo que su vecino vive, usted es 390 00:20:48,710 --> 00:20:50,730 no salir con su vecino. 391 00:20:50,730 --> 00:20:53,510 Usted sabe usted sucede saber dónde viven, 392 00:20:53,510 --> 00:20:56,870 pero eso no quiere decir que por virtud de tener ese conocimiento 393 00:20:56,870 --> 00:20:59,170 está interactuando con ellos. 394 00:20:59,170 --> 00:21:01,920 Si desea interactuar con ellos, usted tiene que ir a su casa, 395 00:21:01,920 --> 00:21:03,760 tienes que ir a donde viven. 396 00:21:03,760 --> 00:21:07,440 Y una vez que lo haces, entonces usted puede interactuar 397 00:21:07,440 --> 00:21:09,420 con ellos al igual que querrías. 398 00:21:09,420 --> 00:21:12,730 Y de manera similar con las variables, tienes que ir a su domicilio 399 00:21:12,730 --> 00:21:15,320 si quieres interactuar ellos, uno no puede saber la dirección. 400 00:21:15,320 --> 00:21:21,495 Y la manera de ir a la dirección es de usar *, el operador eliminar la referencia. 401 00:21:21,495 --> 00:21:23,620 ¿Qué crees que sucede si tratamos de eliminar la referencia 402 00:21:23,620 --> 00:21:25,260 un puntero cuyo valor es nulo? 403 00:21:25,260 --> 00:21:28,470 Recordemos que la hipótesis nula puntero apunta a nada. 404 00:21:28,470 --> 00:21:34,110 Así que si usted trata de eliminar la referencia nada o ir a una dirección de nada, 405 00:21:34,110 --> 00:21:36,800 ¿qué crees que sucede? 406 00:21:36,800 --> 00:21:39,630 Segmentación Bueno, si usted lo adivinó culpa, estaríamos en lo cierto. 407 00:21:39,630 --> 00:21:41,390 Si tratas de eliminar la referencia un puntero nulo, 408 00:21:41,390 --> 00:21:43,140 usted sufre una segmentación culpa. Pero espera, 409 00:21:43,140 --> 00:21:45,820 No te digo, que si no vas 410 00:21:45,820 --> 00:21:49,220 para establecer su valor de su Puntero a algo significativo, 411 00:21:49,220 --> 00:21:51,000 debe establecer en nulo? 412 00:21:51,000 --> 00:21:55,290 Lo hice y realmente la segmentación culpa es una especie de buen comportamiento. 413 00:21:55,290 --> 00:21:58,680 >> ¿Alguna vez ha declarado una variable y No asignado su valor de inmediato? 414 00:21:58,680 --> 00:22:02,680 Así que usted acaba de decir int x; no lo hace realidad asignarla a nada 415 00:22:02,680 --> 00:22:05,340 y más tarde en su código, imprima el valor de x, 416 00:22:05,340 --> 00:22:07,650 Todavía no tener es asignado a nada. 417 00:22:07,650 --> 00:22:10,370 Frecuentes que obtendrá cero, pero a veces 418 00:22:10,370 --> 00:22:15,000 podría conseguir algo de números aleatorios, y usted no tiene idea de dónde vino. 419 00:22:15,000 --> 00:22:16,750 Del mismo modo puede cosas pasar con punteros. 420 00:22:16,750 --> 00:22:20,110 Cuando se declara un puntero int * pk por ejemplo, 421 00:22:20,110 --> 00:22:23,490 y no se asigna a un valor, usted consigue cuatro bytes para la memoria. 422 00:22:23,490 --> 00:22:25,950 Cualesquiera que sean cuatro bytes de la memoria del sistema puede 423 00:22:25,950 --> 00:22:28,970 encontrar que tienen algún valor significativo. 424 00:22:28,970 --> 00:22:31,760 Y podría haber habido algo que ya existe que 425 00:22:31,760 --> 00:22:34,190 ya no es necesaria por otro función, por lo que sólo tiene 426 00:22:34,190 --> 00:22:35,900 todos los datos que estaba allí. 427 00:22:35,900 --> 00:22:40,570 >> Lo que si se trató de hacer dereference alguna dirección que no- había 428 00:22:40,570 --> 00:22:43,410 ya bytes e información en allí, eso es ahora en el puntero. 429 00:22:43,410 --> 00:22:47,470 Si tratas de eliminar la referencia de ese puntero, usted podría estar metiendo con algo de memoria 430 00:22:47,470 --> 00:22:49,390 que no tenía intención meterse con todo. 431 00:22:49,390 --> 00:22:51,639 Y, de hecho, usted podría hacer algo realmente devastador, 432 00:22:51,639 --> 00:22:54,880 como romper otro programa, o romper otra función, 433 00:22:54,880 --> 00:22:58,289 o hacer algo malicioso que que no tiene la intención de hacerlo en absoluto. 434 00:22:58,289 --> 00:23:00,080 Y por eso es realmente una buena idea 435 00:23:00,080 --> 00:23:04,030 para establecer sus punteros a null si no les establece en algo significativo. 436 00:23:04,030 --> 00:23:06,760 Es probablemente mejor en el final del día para su programa 437 00:23:06,760 --> 00:23:09,840 a estrellarse a continuación para que lo haga algo que mete la pata 438 00:23:09,840 --> 00:23:12,400 otro programa u otra función. 439 00:23:12,400 --> 00:23:15,207 Ese comportamiento es probablemente aún menos ideal que sólo estrellarse. 440 00:23:15,207 --> 00:23:17,040 Y por eso es en realidad un buen hábito 441 00:23:17,040 --> 00:23:20,920 para entrar en establecer sus punteros null si no se establece que 442 00:23:20,920 --> 00:23:24,540 a un valor significativo de inmediato, un valor que usted sabe 443 00:23:24,540 --> 00:23:27,260 y que usted puede de manera segura al eliminar la referencia. 444 00:23:27,260 --> 00:23:32,240 >> Así que volvamos ahora y echar un vistazo en la sintaxis general de la situación. 445 00:23:32,240 --> 00:23:37,400 Si digo int * p ;, lo que he acabo de hacer? 446 00:23:37,400 --> 00:23:38,530 Lo que he hecho es esto. 447 00:23:38,530 --> 00:23:43,290 Sé que el valor de p es una dirección porque todos los indicadores son sólo 448 00:23:43,290 --> 00:23:44,660 direcciones. 449 00:23:44,660 --> 00:23:47,750 Puedo eliminar la referencia p usando el operador *. 450 00:23:47,750 --> 00:23:51,250 En este contexto aquí, en el muy superior recordar la * forma parte del tipo. 451 00:23:51,250 --> 00:23:53,510 Int * es el tipo de datos. 452 00:23:53,510 --> 00:23:56,150 Pero no puedo eliminar la referencia p usando el operador *, 453 00:23:56,150 --> 00:24:01,897 y si lo hago, si me voy a esa dirección, lo que voy a encontrar en esa dirección? 454 00:24:01,897 --> 00:24:02,855 Voy a encontrar un entero. 455 00:24:02,855 --> 00:24:05,910 Así int * p es básicamente diciendo: p es una dirección. 456 00:24:05,910 --> 00:24:09,500 Puedo eliminar la referencia p y si Lo hago, voy a encontrar un entero 457 00:24:09,500 --> 00:24:11,920 en esa ubicación de memoria. 458 00:24:11,920 --> 00:24:14,260 >> OK, así que dijo que había otro cosa molesta con las estrellas 459 00:24:14,260 --> 00:24:17,060 y aquí es donde que cosa molesta con las estrellas es. 460 00:24:17,060 --> 00:24:21,640 ¿Alguna vez ha tratado de declarar múltiples variables del mismo tipo 461 00:24:21,640 --> 00:24:24,409 en la misma línea de código? 462 00:24:24,409 --> 00:24:27,700 Así que por un segundo, pretender que la línea, el código realidad tengo allí en verde 463 00:24:27,700 --> 00:24:29,366 No está ahí y sólo dice int x, y, z ;. 464 00:24:29,366 --> 00:24:31,634 465 00:24:31,634 --> 00:24:34,550 Lo que haría es en realidad crear tres variables enteras para usted, 466 00:24:34,550 --> 00:24:36,930 uno llamado x, uno llamado y, y uno llamado z. 467 00:24:36,930 --> 00:24:41,510 Es una manera de hacerlo sin tener que dividir en tres líneas. 468 00:24:41,510 --> 00:24:43,890 >> Aquí es donde las estrellas obtienen molesto otra vez sin embargo, 469 00:24:43,890 --> 00:24:49,200 porque el * es en realidad parte tanto el nombre del tipo y parte 470 00:24:49,200 --> 00:24:50,320 del nombre de la variable. 471 00:24:50,320 --> 00:24:56,430 Y por lo que si te digo int * px, py, pz, lo que conseguir realmente es un puntero a un entero 472 00:24:56,430 --> 00:25:01,650 llamado px y dos números enteros, py y pz. 473 00:25:01,650 --> 00:25:04,950 Y eso probablemente no lo es que queremos, eso no es bueno. 474 00:25:04,950 --> 00:25:09,290 >> Así que si quiero crear múltiples punteros en la misma línea, del mismo tipo, 475 00:25:09,290 --> 00:25:12,140 y las estrellas, lo que realmente necesita que hacer es decir int * pa, * pb, * pc. 476 00:25:12,140 --> 00:25:17,330 477 00:25:17,330 --> 00:25:20,300 Ahora que acaba de decir que y ahora usted esta diciendo, 478 00:25:20,300 --> 00:25:22,170 usted probablemente nunca va a hacer esto. 479 00:25:22,170 --> 00:25:25,170 Y es probablemente una buena cosa, sinceramente, porque es posible que inadvertidamente 480 00:25:25,170 --> 00:25:26,544 omitir una estrella, algo así. 481 00:25:26,544 --> 00:25:29,290 Es probablemente el mejor para declarar tal vez indicaciones sobre las líneas individuales, 482 00:25:29,290 --> 00:25:31,373 pero es sólo otro de los sintaxis molesto 483 00:25:31,373 --> 00:25:35,310 cosas con las estrellas que hacen punteros tan difícil de trabajar. 484 00:25:35,310 --> 00:25:39,480 Porque es precisamente esta sintáctica lío que tiene que trabajar a través. 485 00:25:39,480 --> 00:25:41,600 Con la práctica lo hace realmente convertido en una segunda naturaleza. 486 00:25:41,600 --> 00:25:45,410 Todavía cometo errores con él todavía después de la programación durante 10 años, 487 00:25:45,410 --> 00:25:49,630 así que no se preocupe si pasa algo a usted, que es bastante común con honestidad. 488 00:25:49,630 --> 00:25:52,850 Es muy amable de un defecto de la sintaxis. 489 00:25:52,850 --> 00:25:54,900 >> Aceptar así que tipo de prometí que íbamos a volver 490 00:25:54,900 --> 00:25:59,370 el concepto de qué tan grande es una cadena. 491 00:25:59,370 --> 00:26:02,750 Bueno si te dijera que un cadena, tenemos muy amable de 492 00:26:02,750 --> 00:26:04,140 estado mintiendo todo el tiempo. 493 00:26:04,140 --> 00:26:06,181 No hay ningún tipo de datos llamado cadena, y de hecho 494 00:26:06,181 --> 00:26:09,730 mencionado esto en una de nuestras primeros videos sobre tipos de datos, 495 00:26:09,730 --> 00:26:13,820 esa cadena era un tipo de datos que fue creado por usted en CS50.h. 496 00:26:13,820 --> 00:26:17,050 Tienes que #include CS50.h con el fin de usarlo. 497 00:26:17,050 --> 00:26:19,250 >> Bueno cadena es realmente sólo un alias para algo 498 00:26:19,250 --> 00:26:23,600 llamado el char *, un Puntero a un personaje. 499 00:26:23,600 --> 00:26:26,010 Bueno punteros, el recuerdo, son sólo aborda. 500 00:26:26,010 --> 00:26:28,780 Entonces, ¿cuál es el tamaño en bytes de una cadena? 501 00:26:28,780 --> 00:26:29,796 Bueno, es de cuatro u ocho. 502 00:26:29,796 --> 00:26:32,170 Y la razón por la que decir cuatro o ocho es porque en realidad 503 00:26:32,170 --> 00:26:36,730 depende del sistema, Si está utilizando Ide CS50, char * es el tamaño de un char 504 00:26:36,730 --> 00:26:39,340 * Es de ocho, que es un sistema de 64 bits. 505 00:26:39,340 --> 00:26:43,850 Cada dirección en la memoria es de 64 bits de longitud. 506 00:26:43,850 --> 00:26:48,270 Si utilizas aparato CS50 o el uso de cualquier máquina de 32 bits, 507 00:26:48,270 --> 00:26:51,640 y usted ha oído ese término de 32 bits máquina, lo que es una máquina de 32 bits? 508 00:26:51,640 --> 00:26:56,090 Bueno, sólo significa que cada dirección en la memoria es de 32 bits de longitud. 509 00:26:56,090 --> 00:26:59,140 Y así 32 bits es de cuatro bytes. 510 00:26:59,140 --> 00:27:02,710 Así que un char * es de cuatro u ocho bytes en función del sistema. 511 00:27:02,710 --> 00:27:06,100 Y de hecho cualquier tipo de datos, y un puntero a los datos 512 00:27:06,100 --> 00:27:12,030 escriba, ya que todos los punteros son sólo direcciones, cuatro u ocho bytes. 513 00:27:12,030 --> 00:27:14,030 Así que vamos a revisar este Diagrama y vamos a llegar a la conclusión 514 00:27:14,030 --> 00:27:18,130 este video con un poco de ejercicio aquí. 515 00:27:18,130 --> 00:27:21,600 Así que aquí está el diagrama lo dejamos con en el comienzo del vídeo. 516 00:27:21,600 --> 00:27:23,110 Entonces, ¿qué pasa ahora si digo * pk = 35? 517 00:27:23,110 --> 00:27:26,370 518 00:27:26,370 --> 00:27:30,530 Así que, ¿qué significa cuando digo, * pk = 35? 519 00:27:30,530 --> 00:27:32,420 Tome un segundo. 520 00:27:32,420 --> 00:27:34,990 * pk. 521 00:27:34,990 --> 00:27:39,890 En el contexto aquí, * es operador de eliminar la referencia. 522 00:27:39,890 --> 00:27:42,110 Así que cuando el dereference se utiliza operador, 523 00:27:42,110 --> 00:27:48,520 vamos a la dirección apuntada por pk y cambiamos lo que encontramos. 524 00:27:48,520 --> 00:27:55,270 Así * pk = 35 con eficacia Hace esto a la imagen. 525 00:27:55,270 --> 00:27:58,110 Así que es básicamente sintácticamente idéntico al de haber dicho k = 35. 526 00:27:58,110 --> 00:28:00,740 527 00:28:00,740 --> 00:28:01,930 >> Uno mas. 528 00:28:01,930 --> 00:28:05,510 Si digo int m, creo una nueva variable llamada m. 529 00:28:05,510 --> 00:28:08,260 Una nueva caja, que es una caja verde porque que va a contener un número entero, 530 00:28:08,260 --> 00:28:09,840 y está etiquetada m. 531 00:28:09,840 --> 00:28:14,960 Si digo m = 4, puse un entero en esa caja. 532 00:28:14,960 --> 00:28:20,290 Si por ejemplo pk = & m, ¿cómo lo hace este cambio diagrama? 533 00:28:20,290 --> 00:28:28,760 Pk = & m, ¿recuerda lo que el Y el operador hace o se llama? 534 00:28:28,760 --> 00:28:34,430 Recuerde que y algún nombre de variable es la dirección de un nombre de variable. 535 00:28:34,430 --> 00:28:38,740 Así que lo que estamos diciendo es pk obtiene la dirección del m. 536 00:28:38,740 --> 00:28:42,010 Y así efectivamente lo que sucede el diagrama es que ya no pk puntos 537 00:28:42,010 --> 00:28:46,420 ak, pero apunta a m. 538 00:28:46,420 --> 00:28:48,470 >> Una vez más punteros son muy difícil de trabajar con 539 00:28:48,470 --> 00:28:50,620 y toman una gran cantidad de práctica, sino porque 540 00:28:50,620 --> 00:28:54,150 de su capacidad de permitir que para pasar los datos entre las funciones 541 00:28:54,150 --> 00:28:56,945 y en realidad tienen los los cambios surtan efecto, 542 00:28:56,945 --> 00:28:58,820 conseguir su cabeza alrededor que es realmente importante. 543 00:28:58,820 --> 00:29:02,590 Es probablemente el más complicado tema se discute en el CS50, 544 00:29:02,590 --> 00:29:05,910 pero el valor que llegar desde el uso de punteros 545 00:29:05,910 --> 00:29:09,200 es mucho mayor que las complicaciones que provienen de aprenderlas. 546 00:29:09,200 --> 00:29:12,690 Así que le deseo la mejor de suerte aprendiendo sobre punteros. 547 00:29:12,690 --> 00:29:15,760 Soy Doug Lloyd, esto es CS50. 548 00:29:15,760 --> 00:29:17,447