1 00:00:00,000 --> 00:00:02,520 [Powered by Google Translate] [Sección 4 - Más Cómodo] 2 00:00:02,520 --> 00:00:04,850 [Rob Bowden - Harvard University] 3 00:00:04,850 --> 00:00:07,370 [Esta es CS50. - CS50.TV] 4 00:00:08,920 --> 00:00:13,350 Tenemos un futuro examen, en caso de que ustedes no lo sabía. 5 00:00:14,810 --> 00:00:20,970 Es, básicamente, en todo lo que podría haber visto en clase o deberían haber visto en clase. 6 00:00:20,970 --> 00:00:26,360 Eso incluye a los punteros, a pesar de que es un tema muy reciente. 7 00:00:26,360 --> 00:00:29,860 Al menos debe comprender los altos niveles de las mismas. 8 00:00:29,860 --> 00:00:34,760 Todo lo que pasase en la clase que usted debe entender para el concurso. 9 00:00:34,760 --> 00:00:37,320 Así que si usted tiene preguntas sobre ellos, usted puede pedirles ahora. 10 00:00:37,320 --> 00:00:43,280 Pero esto va a ser una sesión muy dirigida por los estudiantes donde ustedes hacer preguntas, 11 00:00:43,280 --> 00:00:45,060 así que espero que la gente tiene preguntas. 12 00:00:45,060 --> 00:00:48,020 ¿Alguien tiene alguna pregunta? 13 00:00:49,770 --> 00:00:52,090 Sí. >> [Estudiante] ¿Se puede pasar punteros de nuevo? 14 00:00:52,090 --> 00:00:54,350 Voy a ir más punteros. 15 00:00:54,350 --> 00:00:59,180 Todas las variables necesariamente viven en la memoria, 16 00:00:59,180 --> 00:01:04,450 pero por lo general usted no se preocupe por eso y sólo dices x + 2 y + 3 y 17 00:01:04,450 --> 00:01:07,080 y el compilador se darán cuenta de que las cosas se están viviendo por ti. 18 00:01:07,080 --> 00:01:12,990 Una vez que usted está tratando con punteros, ahora que está explícitamente usando esas direcciones de memoria. 19 00:01:12,990 --> 00:01:19,800 Así que una sola variable sólo alguna vez vivir en una sola dirección en un momento dado. 20 00:01:19,800 --> 00:01:24,040 Si queremos declarar un puntero, lo que el tipo va a parecer? 21 00:01:24,040 --> 00:01:26,210 >> Quiero declarar un puntero p. ¿Qué significa el tipo parece? 22 00:01:26,210 --> 00:01:33,530 [Estudiante] int * p. Sí >>. Así int * p. 23 00:01:33,530 --> 00:01:38,030 ¿Y cómo puedo hacer que apunte a x? >> [Estudiante] Ampersand. 24 00:01:40,540 --> 00:01:45,300 [Bowden] Así es, literalmente, llama ampersand la dirección del operador. 25 00:01:45,300 --> 00:01:50,460 Así que cuando digo x y se está haciendo la dirección de memoria de la variable x. 26 00:01:50,460 --> 00:01:56,790 Así que ahora tengo el puntero p, y en cualquier parte de mi código que pueda usar p * 27 00:01:56,790 --> 00:02:02,960 o podría usar x, y será exactamente lo mismo. 28 00:02:02,960 --> 00:02:09,520 (* P). ¿Qué hace esto? ¿Qué hace que la estrella de decir? 29 00:02:09,520 --> 00:02:13,120 [Estudiante] Se refiere a un valor en ese punto. Sí >>. 30 00:02:13,120 --> 00:02:17,590 Así que si nos fijamos en él, puede ser muy útil para extraer los diagramas 31 00:02:17,590 --> 00:02:22,230 donde se trata de una pequeña caja de memoria para x, que pasa a tener el valor 4, 32 00:02:22,230 --> 00:02:25,980 entonces tenemos una pequeña caja de memoria para p, 33 00:02:25,980 --> 00:02:31,590 por lo que p apunta a x, por lo que dibujar una flecha de p para x. 34 00:02:31,590 --> 00:02:40,270 Así que cuando decimos que p * que estamos diciendo vaya a la caja que es p. 35 00:02:40,270 --> 00:02:46,480 Star es seguir la flecha y luego hacer lo que quieras con esa caja ahí. 36 00:02:46,480 --> 00:03:01,090 Así que puedo decir * p = 7, y que irá a la caja que es x y el cambio que a 7. 37 00:03:01,090 --> 00:03:13,540 O podría decir z = int * p * 2; Eso es confuso, ya que la estrella, estrella. 38 00:03:13,540 --> 00:03:19,230 La estrella se desreferencia p, la otra estrella se multiplica por 2. 39 00:03:19,230 --> 00:03:26,780 Tenga en cuenta que podría tener tan bien sustituir el p * con x. 40 00:03:26,780 --> 00:03:29,430 Usted las puede utilizar de la misma manera. 41 00:03:29,430 --> 00:03:38,000 Y más tarde que puede tener el punto P a una cosa completamente nueva. 42 00:03:38,000 --> 00:03:42,190 Yo sólo puedo decir p = &z; 43 00:03:42,190 --> 00:03:44,940 Así que ahora ap ya no lleva a x, sino que apunta a z. 44 00:03:44,940 --> 00:03:50,510 Y cada vez que hago p * es lo mismo que hacer z. 45 00:03:50,510 --> 00:03:56,170 Así que lo útil de esto es que una vez que comienza a recibir en funciones. 46 00:03:56,170 --> 00:03:59,790 >> Es un poco inútil para declarar un puntero que apunta a algo 47 00:03:59,790 --> 00:04:03,140 y si uno la eliminación de referencias 48 00:04:03,140 --> 00:04:06,060 cuando se podría haber utilizado la variable original, para empezar. 49 00:04:06,060 --> 00:04:18,190 Pero cuando te metes en funciones - así que vamos a decir que tenemos alguna función, int foo, 50 00:04:18,190 --> 00:04:32,810 que toma un puntero y sólo hace * p = 6; 51 00:04:32,810 --> 00:04:39,990 Como vimos antes, con swap, no se puede hacer una permuta de efectivo y una función separada 52 00:04:39,990 --> 00:04:45,180 con sólo pasar enteros porque todo en C siempre pasa por valor. 53 00:04:45,180 --> 00:04:48,360 Incluso cuando estás pasando punteros estás pasando por valor. 54 00:04:48,360 --> 00:04:51,940 Lo que pasa es que esos valores son direcciones de memoria. 55 00:04:51,940 --> 00:05:00,770 Así que cuando digo foo (p), estoy pasando el puntero a la función foo 56 00:05:00,770 --> 00:05:03,910 y luego foo está haciendo * p = 6; 57 00:05:03,910 --> 00:05:08,600 Así que dentro de esa función, * p sigue siendo equivalente a x, 58 00:05:08,600 --> 00:05:12,720 pero no puedo usar x dentro de esa función, porque no es de ámbito dentro de esa función. 59 00:05:12,720 --> 00:05:19,510 Así que * p = 6 es la única forma en que puede acceder a una variable local desde otra función. 60 00:05:19,510 --> 00:05:23,600 O, bueno, los punteros son la única forma en que puede acceder a una variable local desde otra función. 61 00:05:23,600 --> 00:05:31,600 [Estudiante] Vamos a decir que quería devolver un puntero. ¿Exactamente cómo se hace eso? 62 00:05:31,600 --> 00:05:44,270 [Bowden] Devuelve un puntero como en algo como int y = 3; & y vuelta? >> [Estudiante] Yeah. 63 00:05:44,270 --> 00:05:48,480 [Bowden] Bueno. Usted nunca debe hacer esto. Esto es malo. 64 00:05:48,480 --> 00:05:59,480 Creo que he visto en estas diapositivas de conferencias que comenzó a ver este diagrama completo de la memoria 65 00:05:59,480 --> 00:06:02,880 donde hasta aquí tienes la dirección de memoria 0 66 00:06:02,880 --> 00:06:09,550 y aquí tienes la dirección de memoria 4 gigas o 2 a la 32. 67 00:06:09,550 --> 00:06:15,120 Así que tienes algunas cosas y algunas cosas y luego tienes tu stack 68 00:06:15,120 --> 00:06:21,780 y tienes tu montón, que acaba de comenzar a aprender acerca de, creciendo. 69 00:06:21,780 --> 00:06:24,390 [Estudiante] ¿No es el montón encima de la pila? 70 00:06:24,390 --> 00:06:27,760 >> Si. El montón está arriba, ¿no? >> [Estudiante] Bueno, poner 0 en la parte superior. 71 00:06:27,760 --> 00:06:30,320 [Estudiante] Oh, poner 0 en la parte superior. >> [Estudiante] Oh, está bien. 72 00:06:30,320 --> 00:06:36,060 Descargo de responsabilidad: En cualquier lugar con CS50 vas a ver de esta manera. >> [Estudiante] Bueno. 73 00:06:36,060 --> 00:06:40,290 Es sólo que cuando estás viendo primero las pilas, 74 00:06:40,290 --> 00:06:45,000 como cuando usted piensa en una pila piensas de apilar cosas encima de la otra. 75 00:06:45,000 --> 00:06:50,810 Por lo tanto, tienden a girar en torno a este por lo que la pila está creciendo como una pila de costumbre 76 00:06:50,810 --> 00:06:55,940 en lugar de la pila colgando hacia abajo. >> [Los estudiantes] no montones técnicamente crecer demasiado, sin embargo? 77 00:06:55,940 --> 00:07:01,100 Depende de lo que entiendas por crecer. 78 00:07:01,100 --> 00:07:04,010 La pila y montón siempre crecer en direcciones opuestas. 79 00:07:04,010 --> 00:07:09,420 Una pila siempre está creciendo en el sentido de que está creciendo 80 00:07:09,420 --> 00:07:12,940 al aumento de las direcciones de la memoria y el montón crece hacia abajo 81 00:07:12,940 --> 00:07:17,260 en que está creciendo hacia direcciones bajas de memoria. 82 00:07:17,260 --> 00:07:20,250 Así que la parte superior es 0 y la parte inferior es de alta dirección de memoria. 83 00:07:20,250 --> 00:07:26,390 Los dos están en crecimiento, sólo en direcciones opuestas. 84 00:07:26,390 --> 00:07:29,230 [Estudiante] Yo sólo quería decir que porque usted ha dicho que poner la pila en la parte inferior 85 00:07:29,230 --> 00:07:33,640 porque parece más intuitivo porque para la pila para empezar en la parte superior de un montón, 86 00:07:33,640 --> 00:07:37,520 pila está por encima de sí mismo también, así que eso es - >> Yeah. 87 00:07:37,520 --> 00:07:44,960 También pensar en el montón como crecía y más grande, pero la pila más. 88 00:07:44,960 --> 00:07:50,280 Así que la pila es la que nos tipo de ganas de mostrar su crecimiento. 89 00:07:50,280 --> 00:07:55,390 Pero en todas partes se mira de otra manera se va a mostrar la dirección 0 en la parte superior 90 00:07:55,390 --> 00:07:59,590 y la dirección de memoria más alta en la parte inferior, por lo que este es su vista habitual de la memoria. 91 00:07:59,590 --> 00:08:02,100 >> ¿Tiene una pregunta? 92 00:08:02,100 --> 00:08:04,270 [Estudiante] ¿Puedes decirnos más sobre el montón? 93 00:08:04,270 --> 00:08:06,180 Si. Voy a llegar a eso en un segundo. 94 00:08:06,180 --> 00:08:12,220 En primer lugar, ¿por qué volver a volver y que y es una cosa mala, 95 00:08:12,220 --> 00:08:18,470 en la pila tiene un montón de marcos de pila que representan todas las funciones 96 00:08:18,470 --> 00:08:20,460 que han sido llamados. 97 00:08:20,460 --> 00:08:27,990 Así que haciendo caso omiso de las cosas anteriores, la parte superior de la pila siempre va a ser la función principal 98 00:08:27,990 --> 00:08:33,090 ya que es la primera función que está siendo llamado. 99 00:08:33,090 --> 00:08:37,130 Y luego, cuando se llama a otra función, la pila va a crecer hacia abajo. 100 00:08:37,130 --> 00:08:41,640 Así que si llamo a alguna función, foo, y se pone su propio marco de pila, 101 00:08:41,640 --> 00:08:47,280 puede llamar a alguna función, bar, sino que obtiene su propio marco de pila. 102 00:08:47,280 --> 00:08:49,840 Y bar podía ser recursiva y puede llamarse a sí misma, 103 00:08:49,840 --> 00:08:54,150 y para que la segunda llamada a la barra se va a poner su propio marco de pila. 104 00:08:54,150 --> 00:08:58,880 Y así, lo que sucede en estos marcos de pila son todas las variables locales 105 00:08:58,880 --> 00:09:03,450 y todos los argumentos de la función que - 106 00:09:03,450 --> 00:09:08,730 Las cosas que son de ámbito local a esta función vaya en estos marcos de pila. 107 00:09:08,730 --> 00:09:21,520 Eso quiere decir que cuando me dijo algo así como bar es una función, 108 00:09:21,520 --> 00:09:29,270 Sólo voy a declarar un entero y luego devolver un puntero a ese entero. 109 00:09:29,270 --> 00:09:33,790 Entonces, ¿dónde y vivir? 110 00:09:33,790 --> 00:09:36,900 [Estudiante] y vive en el bar. >> [Bowden] Yeah. 111 00:09:36,900 --> 00:09:45,010 En algún lugar de esta pequeña plaza de la memoria es una plaza más escasos y que tiene en ella. 112 00:09:45,010 --> 00:09:53,370 Cuando regrese & y, estoy devolviendo un puntero a este pequeño bloque de memoria. 113 00:09:53,370 --> 00:09:58,400 Pero cuando una función retorna, su marco de pila se extrae de la pila. 114 00:10:01,050 --> 00:10:03,530 Y es por eso que se llama pila. 115 00:10:03,530 --> 00:10:06,570 Es como si la estructura de datos pila, si sabes lo que es. 116 00:10:06,570 --> 00:10:11,580 O incluso como una pila de bandejas es siempre el ejemplo, 117 00:10:11,580 --> 00:10:16,060 principal va a ir en la parte inferior, la función primera vez que llame se va a ir por encima de eso, 118 00:10:16,060 --> 00:10:20,400 y no se puede volver a principal hasta que regrese de todas las funciones que han sido llamados 119 00:10:20,400 --> 00:10:22,340 que han sido colocados en la parte superior de la misma. 120 00:10:22,340 --> 00:10:28,650 >> [Estudiante] Así que si usted hizo volver la y &, ese valor está sujeto a cambios sin previo aviso. 121 00:10:28,650 --> 00:10:31,290 Sí, es - >> [estudiante] Podría ser sobreescrito. Sí >>. 122 00:10:31,290 --> 00:10:34,660 Es completamente - Si intenta - 123 00:10:34,660 --> 00:10:38,040 Este sería también un bar * int porque está devolviendo un puntero, 124 00:10:38,040 --> 00:10:41,310 por lo que su tipo de retorno es int *. 125 00:10:41,310 --> 00:10:46,500 Si intenta utilizar el valor de retorno de esta función, es un comportamiento indefinido 126 00:10:46,500 --> 00:10:51,770 porque ese puntero apunta al mal recuerdo. >> [Estudiante] Bueno. 127 00:10:51,770 --> 00:11:01,250 ¿Y qué si, por ejemplo, declaró int * y = malloc (sizeof (int))? 128 00:11:01,250 --> 00:11:03,740 Eso está mejor. Sí. 129 00:11:03,740 --> 00:11:07,730 [Estudiante] Hablamos de cómo las cosas cuando arrastramos a nuestra papelera de reciclaje 130 00:11:07,730 --> 00:11:11,750 no están realmente borrado, nosotros sólo pierden sus punteros. 131 00:11:11,750 --> 00:11:15,550 Así que en este caso es lo que realmente borrar el valor o todavía hay en la memoria? 132 00:11:15,550 --> 00:11:19,130 En su mayor parte, va a estar todavía allí. 133 00:11:19,130 --> 00:11:24,220 Pero digamos que nos pasó a llamar a otra función, baz. 134 00:11:24,220 --> 00:11:28,990 Baz se va a poner su propio marco de pila en aquí. 135 00:11:28,990 --> 00:11:31,470 Va a ser sobrescribir todas estas cosas, 136 00:11:31,470 --> 00:11:34,180 y si luego tratar de utilizar el puntero que obtuvo antes, 137 00:11:34,180 --> 00:11:35,570 no va a ser el mismo valor. 138 00:11:35,570 --> 00:11:38,150 Va a haber cambiado sólo porque se llama el baz función. 139 00:11:38,150 --> 00:11:43,080 [Estudiante] Pero si no nosotros, que seguimos recibiendo 3? 140 00:11:43,080 --> 00:11:44,990 [Bowden] Lo más probable es que sí. 141 00:11:44,990 --> 00:11:49,670 Pero no se puede confiar en eso. C sólo dice un comportamiento indefinido. 142 00:11:49,670 --> 00:11:51,920 >> [Estudiante] Oh, sí. Bien. 143 00:11:51,920 --> 00:11:58,190 Así que cuando usted desea devolver un puntero, aquí es donde viene malloc en uso. 144 00:12:00,930 --> 00:12:15,960 Estoy escribiendo en realidad sólo devuelve malloc (3 * sizeof (int)). 145 00:12:17,360 --> 00:12:24,050 Vamos a repasar malloc más en un segundo, pero es la idea de malloc todas sus variables locales 146 00:12:24,050 --> 00:12:26,760 siempre van a la pila. 147 00:12:26,760 --> 00:12:31,570 Cualquier cosa que malloced va a la pila, y será por siempre y siempre estar en el montón 148 00:12:31,570 --> 00:12:34,490 hasta que explícitamente se lo libere. 149 00:12:34,490 --> 00:12:42,130 Así que esto significa que cuando malloc algo, que va a sobrevivir después de que la función regrese. 150 00:12:42,130 --> 00:12:46,800 [Estudiante] ¿Va a sobrevivir después de que el programa deje de funcionar? No. >> 151 00:12:46,800 --> 00:12:53,180 Muy bien, así que va a estar allí hasta que el programa es todo el camino hecho correr. Sí >>. 152 00:12:53,180 --> 00:12:57,510 Podemos repasar los detalles de lo que sucede cuando el programa deja de ejecutarse. 153 00:12:57,510 --> 00:13:02,150 Es posible que necesite que me recuerde, pero eso es una cosa separada del todo. 154 00:13:02,150 --> 00:13:04,190 [Estudiante] Así malloc crea un puntero? Sí >>. 155 00:13:04,190 --> 00:13:13,030 Malloc - >> [estudiante] Creo que malloc designa un bloque de memoria que puede utilizar un puntero. 156 00:13:15,400 --> 00:13:19,610 [Bowden] Quiero ese diagrama nuevo. >> [Estudiante] Así funciona esta función, sin embargo? 157 00:13:19,610 --> 00:13:26,430 [Estudiante] Sí, malloc designa un bloque de memoria que puede utilizar, 158 00:13:26,430 --> 00:13:30,470 y, a continuación, devuelve la dirección del primer bloque de esa memoria. 159 00:13:30,470 --> 00:13:36,750 >> [Bowden] Yeah. Así que cuando malloc, que está agarrando un poco de bloque de memoria 160 00:13:36,750 --> 00:13:38,260 que está actualmente en el montón. 161 00:13:38,260 --> 00:13:43,040 Si la pila es demasiado pequeño, entonces el montón es sólo va a crecer, y que crece en esta dirección. 162 00:13:43,040 --> 00:13:44,650 Así que digamos que el montón es demasiado pequeño. 163 00:13:44,650 --> 00:13:49,960 Luego se trata de hacer crecer un poco y devolver un puntero a este bloque que acaba de crecer. 164 00:13:49,960 --> 00:13:55,130 Cuando cosas gratis, que está haciendo más espacio en el montón, 165 00:13:55,130 --> 00:14:00,030 Así que una tarde llamar a malloc puede reutilizar la memoria que había liberado previamente. 166 00:14:00,030 --> 00:14:09,950 Lo importante de malloc y libre es lo que le da un control completo 167 00:14:09,950 --> 00:14:12,700 durante la vida útil de estos bloques de memoria. 168 00:14:12,700 --> 00:14:15,420 Las variables globales son siempre viva. 169 00:14:15,420 --> 00:14:18,500 Las variables locales están vivos dentro de su ámbito de aplicación. 170 00:14:18,500 --> 00:14:22,140 Tan pronto como se pasa de una llave, las variables locales están muertos. 171 00:14:22,140 --> 00:14:28,890 Memoria Malloced está vivo cuando usted quiere que sea vivo 172 00:14:28,890 --> 00:14:33,480 y luego se libera cuando se lo dices a ser puesto en libertad. 173 00:14:33,480 --> 00:14:38,420 Esas son realmente las únicas tres tipos de memoria, la verdad. 174 00:14:38,420 --> 00:14:41,840 Hay gestión de memoria automática, que es la pila. 175 00:14:41,840 --> 00:14:43,840 Las cosas suceden de forma automática. 176 00:14:43,840 --> 00:14:46,910 Cuando dices int x, se asigna memoria para x int. 177 00:14:46,910 --> 00:14:51,630 Cuando x está fuera de ámbito, la memoria se recupera para x. 178 00:14:51,630 --> 00:14:54,790 Luego está la gestión de memoria dinámica, que es lo que malloc es, 179 00:14:54,790 --> 00:14:56,740 que es cuando usted tiene el control. 180 00:14:56,740 --> 00:15:01,290 Usted decide cuándo dinámicamente la memoria debe y no debe ser asignado. 181 00:15:01,290 --> 00:15:05,050 Y luego está estática, lo que significa que sólo vive para siempre, 182 00:15:05,050 --> 00:15:06,610 que es lo que son las variables globales. 183 00:15:06,610 --> 00:15:10,240 Sólo están siempre en la memoria. 184 00:15:10,960 --> 00:15:12,760 >> ¿Preguntas? 185 00:15:14,490 --> 00:15:17,230 [Estudiante] ¿Se puede definir un bloque sólo mediante el uso de llaves 186 00:15:17,230 --> 00:15:21,220 pero no tener que tener una? if o while o algo por el estilo 187 00:15:21,220 --> 00:15:29,130 Se puede definir como un bloque en una función, pero que tiene las llaves también. 188 00:15:29,130 --> 00:15:32,100 [Estudiante] Por lo que no se puede tener como un par de llaves al azar en el código 189 00:15:32,100 --> 00:15:35,680 que tiene variables locales? >> Sí, se puede. 190 00:15:35,680 --> 00:15:45,900 En el interior de la barra int podríamos tener {int y = 3;}. 191 00:15:45,900 --> 00:15:48,440 Que se supone que es justo aquí. 192 00:15:48,440 --> 00:15:52,450 Pero eso define completamente el alcance de int y. 193 00:15:52,450 --> 00:15:57,320 Después de que la segunda llave, y no se puede utilizar más. 194 00:15:57,910 --> 00:16:00,630 Casi nunca hago eso, sin embargo. 195 00:16:02,940 --> 00:16:07,370 Volviendo a lo que sucede cuando un programa termina, 196 00:16:07,370 --> 00:16:18,760 hay una especie de mentira error / medio que le damos con el fin de hacer sólo las cosas más fáciles. 197 00:16:18,760 --> 00:16:24,410 Les decimos que cuando se asigna memoria 198 00:16:24,410 --> 00:16:29,860 que está asignando parte pedazo de RAM para esa variable. 199 00:16:29,860 --> 00:16:34,190 Pero usted no está realmente en contacto directo con RAM nunca en sus programas. 200 00:16:34,190 --> 00:16:37,490 Si se piensa en ello, ¿cómo dibujé - 201 00:16:37,490 --> 00:16:44,330 Y de hecho, si usted va a través de GDB verá la misma cosa. 202 00:16:51,120 --> 00:16:57,590 Sin importar cuántas veces se ejecuta el programa o qué programa está funcionando, 203 00:16:57,590 --> 00:16:59,950 la pila siempre va a comenzar - 204 00:16:59,950 --> 00:17:06,510 siempre vas a ver las variables alrededor de algo oxbffff dirección. 205 00:17:06,510 --> 00:17:09,470 Por lo general, en algún lugar de esa región. 206 00:17:09,470 --> 00:17:18,760 Pero, ¿cómo puede posiblemente tener 2 programas punteros a la misma memoria? 207 00:17:20,640 --> 00:17:27,650 [Estudiante] Hay un poco de designación arbitraria de oxbfff donde se supone que debe estar en la RAM 208 00:17:27,650 --> 00:17:31,320 que en realidad puede estar en diferentes lugares dependiendo de cuando la función fue llamada. 209 00:17:31,320 --> 00:17:35,920 Si. El término es la memoria virtual. 210 00:17:35,920 --> 00:17:42,250 La idea es que cada proceso, cada programa que se ejecuta en su computadora 211 00:17:42,250 --> 00:17:49,450 tiene su propio - supongamos - 32 bits espacio de direcciones completamente independiente. 212 00:17:49,450 --> 00:17:51,590 Este es el espacio de direcciones. 213 00:17:51,590 --> 00:17:56,220 Tiene sus propios completamente independientes 4 gigabytes para su uso. 214 00:17:56,220 --> 00:18:02,220 >> Así que si usted ejecuta dos programas al mismo tiempo, este programa de 4 gigabytes ve a sí mismo, 215 00:18:02,220 --> 00:18:04,870 Este programa de 4 gigabytes ve a sí mismo, 216 00:18:04,870 --> 00:18:07,720 y es imposible que este programa para eliminar la referencia de un puntero 217 00:18:07,720 --> 00:18:10,920 y acabar con la memoria de este programa. 218 00:18:10,920 --> 00:18:18,200 ¿Y qué es la memoria virtual es una asignación de un espacio de direcciones de procesos 219 00:18:18,200 --> 00:18:20,470 a las cosas reales de RAM. 220 00:18:20,470 --> 00:18:22,940 Así que depende de su sistema operativo para saber que, 221 00:18:22,940 --> 00:18:28,080 hey, cuando este tipo oxbfff desreferencia puntero, que realmente significa 222 00:18:28,080 --> 00:18:31,040 que quiere byte RAM 1000, 223 00:18:31,040 --> 00:18:38,150 mientras que si este programa oxbfff desreferencia, que realmente quiere byte RAM 10000. 224 00:18:38,150 --> 00:18:41,590 Pueden ser arbitrariamente lejos. 225 00:18:41,590 --> 00:18:48,730 Esto es cierto incluso de las cosas dentro de un espacio de direcciones de procesos único. 226 00:18:48,730 --> 00:18:54,770 Así que, como ve los 4 gigabytes a sí mismo, pero vamos a decir - 227 00:18:54,770 --> 00:18:57,290 [Estudiante] ¿Cada proceso individual - 228 00:18:57,290 --> 00:19:01,350 Digamos que usted tiene una computadora con sólo 4 GB de RAM. 229 00:19:01,350 --> 00:19:06,430 ¿Tiene cada proceso ve los 4 gigabytes enteros? Sí >>. 230 00:19:06,430 --> 00:19:13,060 Pero los 4 gigabytes que ve es una mentira. 231 00:19:13,060 --> 00:19:20,460 Es sólo que piensa que tiene todo esto de memoria, ya que no conozco a ningún otro proceso existe. 232 00:19:20,460 --> 00:19:28,140 Sólo se utilizará la memoria todo lo que realmente necesita. 233 00:19:28,140 --> 00:19:32,340 El sistema operativo no se va a dar a este proceso RAM 234 00:19:32,340 --> 00:19:35,750 si no se utiliza ninguna memoria en toda esta región. 235 00:19:35,750 --> 00:19:39,300 No va a darle la memoria de esa región. 236 00:19:39,300 --> 00:19:54,780 Pero la idea es que - Estoy tratando de pensar - No puedo pensar en una analogía. 237 00:19:54,780 --> 00:19:56,780 Las analogías son difíciles. 238 00:19:57,740 --> 00:20:02,700 Uno de los temas de la memoria virtual o una de las cosas que está resolviendo 239 00:20:02,700 --> 00:20:06,810 es que los procesos deben ser completamente inconsciente de uno al otro. 240 00:20:06,810 --> 00:20:12,140 Y para que pueda escribir cualquier programa que acaba de desreferencia cualquier puntero, 241 00:20:12,140 --> 00:20:19,340 como acaba de escribir un programa que dice * (ox1234), 242 00:20:19,340 --> 00:20:22,890 y que la memoria dereferencing dirección 1234. 243 00:20:22,890 --> 00:20:28,870 >> Pero depende del sistema operativo para traducir Entonces, ¿qué significa 1234. 244 00:20:28,870 --> 00:20:33,960 Así que si 1234 resulta ser una dirección de memoria válida para este proceso, 245 00:20:33,960 --> 00:20:38,800 como si estuviera en la pila o algo así, entonces esto va a devolver el valor de esa dirección de memoria 246 00:20:38,800 --> 00:20:41,960 por lo que el proceso sabe. 247 00:20:41,960 --> 00:20:47,520 Pero si 1234 no es una dirección válida, al igual que ocurre a la tierra 248 00:20:47,520 --> 00:20:52,910 en algún pedacito de memoria aquí que está más allá de la pila y el montón más allá 249 00:20:52,910 --> 00:20:57,200 y no se ha utilizado realmente eso, entonces es cuando usted consigue cosas como segfaults 250 00:20:57,200 --> 00:21:00,260 porque estás tocando de memoria que no se debe tocar. 251 00:21:07,180 --> 00:21:09,340 Esto también es cierto - 252 00:21:09,340 --> 00:21:15,440 Un sistema de 32-bits, 32 bits significa que usted tiene 32 bits para definir una dirección de memoria. 253 00:21:15,440 --> 00:21:22,970 Es por eso que los punteros son 8 bytes ya que 32 bits son 8 bytes - o 4 bytes. 254 00:21:22,970 --> 00:21:25,250 Los punteros son 4 bytes. 255 00:21:25,250 --> 00:21:33,680 Así que cuando usted ve un puntero como oxbfffff, que es - 256 00:21:33,680 --> 00:21:40,080 Dentro de cualquier programa dado que sólo puede construir cualquier puntero arbitrario, 257 00:21:40,080 --> 00:21:46,330 en cualquier lugar de ox0 buey a 8 f's - FFFFFFFF. 258 00:21:46,330 --> 00:21:49,180 [Estudiante] ¿No dicen que son 4 bytes? Sí >>. 259 00:21:49,180 --> 00:21:52,730 [Estudiante] Luego, cada byte tendrá - >> [Bowden] Hexadecimal. 260 00:21:52,730 --> 00:21:59,360 Hexadecimal - 5, 6, 7, 8. Así punteros que vas a ver siempre en hexadecimal. 261 00:21:59,360 --> 00:22:01,710 Es sólo la forma en que clasificar punteros. 262 00:22:01,710 --> 00:22:05,240 Cada 2 dígitos hexadecimal es de 1 byte. 263 00:22:05,240 --> 00:22:09,600 Así que va a ser de 8 dígitos hexadecimales de 4 bytes. 264 00:22:09,600 --> 00:22:14,190 Así, cada indicador individual en un sistema de 32-bit que va a ser de 4 bytes, 265 00:22:14,190 --> 00:22:18,550 lo que significa que en el proceso se puede construir cualquier arbitrarias 4 bytes 266 00:22:18,550 --> 00:22:20,550 y hacer un puntero fuera de él, 267 00:22:20,550 --> 00:22:32,730 lo que significa que la medida de lo que es consciente, se puede tratar un entero 2 a los 32 bytes de memoria. 268 00:22:32,730 --> 00:22:34,760 A pesar de que en realidad no se tiene acceso a que, 269 00:22:34,760 --> 00:22:40,190 aunque el equipo sólo tiene 512 megabytes, que piensa que tiene suficiente memoria. 270 00:22:40,190 --> 00:22:44,930 Y el sistema operativo es lo suficientemente inteligente que sólo asignar lo que realmente necesita. 271 00:22:44,930 --> 00:22:49,630 No sólo tiene que ir, oh, un nuevo proceso: 4 gigas. 272 00:22:49,630 --> 00:22:51,930 >> Si. >> [Estudiante] ¿Qué hace el buey decir? ¿Por qué lo escribió? 273 00:22:51,930 --> 00:22:54,980 Es sólo el símbolo de hexadecimal. 274 00:22:54,980 --> 00:22:59,590 Cuando usted ve un número de inicio con el buey, las cosas son sucesivas hexadecimal. 275 00:23:01,930 --> 00:23:05,760 [Estudiante] Usted estaba explicando acerca de lo que sucede cuando un programa termina. Sí >>. 276 00:23:05,760 --> 00:23:09,480 ¿Qué sucede cuando un programa termina es el sistema operativo 277 00:23:09,480 --> 00:23:13,600 sólo borra las asignaciones que tiene para estas direcciones, y eso es todo. 278 00:23:13,600 --> 00:23:17,770 El sistema operativo puede simplemente dar ese recuerdo a otro programa para utilizarlo. 279 00:23:17,770 --> 00:23:19,490 [Estudiante] Bueno. 280 00:23:19,490 --> 00:23:24,800 Así que cuando usted asigna algo en el montón o las variables de pila o global ni nada, 281 00:23:24,800 --> 00:23:27,010 todos ellos sólo desaparecen tan pronto como termine el programa 282 00:23:27,010 --> 00:23:32,120 porque el sistema operativo es ahora libre para dar que la memoria a cualquier otro proceso. 283 00:23:32,120 --> 00:23:35,150 [Estudiante] A pesar de que es probable que haya todavía valores escritos en? Sí >>. 284 00:23:35,150 --> 00:23:37,740 Los valores son probablemente todavía allí. 285 00:23:37,740 --> 00:23:41,570 Es sólo que va a ser difícil llegar a ellos. 286 00:23:41,570 --> 00:23:45,230 Es mucho más difícil llegar a ellos de lo que es llegar a un archivo eliminado 287 00:23:45,230 --> 00:23:51,450 debido a que el tipo de archivo borrado se sienta allí durante mucho tiempo y el disco duro es mucho más grande. 288 00:23:51,450 --> 00:23:54,120 Así que va a sobrescribir las diferentes partes de la memoria 289 00:23:54,120 --> 00:23:58,640 antes de que suceda para sobrescribir el bloque de memoria que utiliza ese archivo para estar en. 290 00:23:58,640 --> 00:24:04,520 Pero la memoria principal, memoria RAM, se desplaza por mucho más rápido, 291 00:24:04,520 --> 00:24:08,040 así que va a ser muy rápidamente sobrescrito. 292 00:24:10,300 --> 00:24:13,340 Las preguntas sobre esta o cualquier otra cosa? 293 00:24:13,340 --> 00:24:16,130 [Estudiante] Tengo preguntas sobre un tema diferente. >> Okay. 294 00:24:16,130 --> 00:24:19,060 ¿Alguien tiene alguna duda sobre esto? 295 00:24:20,170 --> 00:24:23,120 >> Bien. Tema diferente. >> [Estudiante] Bueno. 296 00:24:23,120 --> 00:24:26,550 Yo estaba pasando por algunas de las pruebas de la práctica, 297 00:24:26,550 --> 00:24:30,480 y en una de ellas se refería a la sizeof 298 00:24:30,480 --> 00:24:35,630 y el valor que devuelve o diferentes tipos de variables. Sí >>. 299 00:24:35,630 --> 00:24:45,060 Y dijo que tanto int y largo plazo tanto el retorno 4, por lo que ambos son 4 bytes de longitud. 300 00:24:45,060 --> 00:24:48,070 ¿Hay alguna diferencia entre un int y un largo, o es lo mismo? 301 00:24:48,070 --> 00:24:50,380 Sí, hay una diferencia. 302 00:24:50,380 --> 00:24:52,960 El estándar de C - 303 00:24:52,960 --> 00:24:54,950 Probablemente voy a meter la pata. 304 00:24:54,950 --> 00:24:58,800 El estándar de C es igual que lo que C es la documentación oficial de C. 305 00:24:58,800 --> 00:25:00,340 Esto es lo que dice. 306 00:25:00,340 --> 00:25:08,650 Así que el estándar de C sólo dice que será un char para siempre y será siempre 1 byte. 307 00:25:10,470 --> 00:25:19,040 Todo después de que - un corto es siempre acaba de definir como siendo mayor que o igual a un char. 308 00:25:19,040 --> 00:25:23,010 Esto podría ser estrictamente mayor que, pero no positivo. 309 00:25:23,010 --> 00:25:31,940 Un int se acaba de definir como siendo mayor que o igual a un corto. 310 00:25:31,940 --> 00:25:36,210 Y una larga se acaba de definir como siendo mayor que o igual a un entero. 311 00:25:36,210 --> 00:25:41,600 Y un largo tiempo es mayor que o igual a un tiempo. 312 00:25:41,600 --> 00:25:46,610 Así que lo único que el estándar de C define es el orden relativo de todo. 313 00:25:46,610 --> 00:25:54,880 La cantidad real de memoria que las cosas sigan por lo general hasta la ejecución, 314 00:25:54,880 --> 00:25:57,640 pero está bastante bien definido en este punto. >> [Estudiante] Bueno. 315 00:25:57,640 --> 00:26:02,490 Así que los pantalones cortos son casi siempre va a ser de 2 bytes. 316 00:26:04,920 --> 00:26:09,950 Ints son casi siempre va a ser de 4 bytes. 317 00:26:12,070 --> 00:26:15,340 Largos largos son casi siempre va a ser de 8 bytes. 318 00:26:17,990 --> 00:26:23,160 Y anhela, depende de si usted está usando un 32-bit o un sistema de 64-bit. 319 00:26:23,160 --> 00:26:27,450 Así un largo va a corresponder con el tipo de sistema. 320 00:26:27,450 --> 00:26:31,920 Si usted está usando un sistema de 32-bit como el Appliance, que va a ser de 4 bytes. 321 00:26:34,530 --> 00:26:42,570 Si usted está usando un 64-bit como un montón de computadoras recientes, que va a ser de 8 bytes. 322 00:26:42,570 --> 00:26:45,230 >> Ints son casi siempre 4 bytes en este punto. 323 00:26:45,230 --> 00:26:47,140 Largos largos son casi siempre de 8 bytes. 324 00:26:47,140 --> 00:26:50,300 En el pasado, ints solía ser sólo 2 bytes. 325 00:26:50,300 --> 00:26:56,840 Pero nótese que esto satisface completamente todas estas relaciones de superior e igual a. 326 00:26:56,840 --> 00:27:01,280 Mientras está perfectamente autorizado a tener el mismo tamaño como un entero, 327 00:27:01,280 --> 00:27:04,030 y también se les permite tener el mismo tamaño como un largo tiempo. 328 00:27:04,030 --> 00:27:11,070 Y da la casualidad de que esté en 99,999% de los sistemas, que va a ser igual a 329 00:27:11,070 --> 00:27:15,800 un int o un largo plazo. Sólo depende de 32-bit o 64-bit. >> [Estudiante] Bueno. 330 00:27:15,800 --> 00:27:24,600 En carrozas, ¿cómo está el punto decimal designado en términos de bits? 331 00:27:24,600 --> 00:27:27,160 Al igual que como binario? Sí >>. 332 00:27:27,160 --> 00:27:30,570 No es necesario saber que para CS50. 333 00:27:30,570 --> 00:27:32,960 Ni siquiera enterarse de que en el 61. 334 00:27:32,960 --> 00:27:37,350 No se aprende que realmente en cualquier curso. 335 00:27:37,350 --> 00:27:42,740 Es sólo una representación. 336 00:27:42,740 --> 00:27:45,440 Me olvido de las asignaciones de bits exactas. 337 00:27:45,440 --> 00:27:53,380 La idea de punto flotante es que se puede asignar un número específico de bits para representar - 338 00:27:53,380 --> 00:27:56,550 Básicamente, todo está en notación científica. 339 00:27:56,550 --> 00:28:05,600 Así que asignar un número específico de bits para representar el número en sí, al igual que 1,2345. 340 00:28:05,600 --> 00:28:10,200 Nunca puede representar un número con más dígitos de los que 5. 341 00:28:12,200 --> 00:28:26,300 Entonces también asignar un número específico de bits de modo que tiende a ser como 342 00:28:26,300 --> 00:28:32,810 sólo se puede subir a un cierto número, como que es el mayor exponente que puede tener, 343 00:28:32,810 --> 00:28:36,190 y sólo se puede bajar a un cierto exponente, 344 00:28:36,190 --> 00:28:38,770 como que es el más pequeño exponente que puede tener. 345 00:28:38,770 --> 00:28:44,410 >> No me acuerdo de los bits de forma exacta se asignan a todos estos valores, 346 00:28:44,410 --> 00:28:47,940 pero un cierto número de bits se dedica a 1,2345, 347 00:28:47,940 --> 00:28:50,930 otro cierto número de bits se dedica a la exponente, 348 00:28:50,930 --> 00:28:55,670 y es sólo posible representar un exponente de un cierto tamaño. 349 00:28:55,670 --> 00:29:01,100 [Estudiante] Y un doble? ¿Es como un float extra larga? Sí >>. 350 00:29:01,100 --> 00:29:07,940 Es lo mismo que un flotador excepto que ahora está utilizando 8 bytes en lugar de 4 bytes. 351 00:29:07,940 --> 00:29:11,960 Ahora podrás utilizar 9 cifras o dígitos 10, 352 00:29:11,960 --> 00:29:16,630 y éste será capaz de subir a 300 en lugar de 100. >> [Estudiante] Bueno. 353 00:29:16,630 --> 00:29:21,550 Y flotadores son también 4 bytes. Sí >>. 354 00:29:21,550 --> 00:29:27,520 Bueno, de nuevo, probablemente lo general depende de la aplicación general, 355 00:29:27,520 --> 00:29:30,610 pero los flotadores son de 4 bytes, los dobles son 8. 356 00:29:30,610 --> 00:29:33,440 Dobles se llama doble, ya que son el doble del tamaño de la flota. 357 00:29:33,440 --> 00:29:38,380 [Estudiante] Bueno. Y hay dos dobles? >> No hay. 358 00:29:38,380 --> 00:29:43,660 Creo que - >> [estudiante] Al igual que anhela largas? Sí >>. No lo creo. Sí. 359 00:29:43,660 --> 00:29:45,950 [Estudiante] El ensayo del año pasado había una pregunta acerca de la función principal 360 00:29:45,950 --> 00:29:49,490 tener que ser parte de su programa. 361 00:29:49,490 --> 00:29:52,310 La respuesta fue que no tiene por qué ser parte de su programa. 362 00:29:52,310 --> 00:29:55,100 ¿En qué situación? Eso es lo que vi. 363 00:29:55,100 --> 00:29:59,090 [Bowden] Parece - >> [estudiante] ¿Qué situación? 364 00:29:59,090 --> 00:30:02,880 ¿Tiene el problema? >> [Estudiante] Sí, lo puedo tirar de él hacia arriba. 365 00:30:02,880 --> 00:30:07,910 No tiene por qué ser, técnicamente, pero básicamente va a ser. 366 00:30:07,910 --> 00:30:10,030 [Estudiante] Yo vi uno en una de año diferente. 367 00:30:10,030 --> 00:30:16,220 Era como Verdadero o Falso: Un válido - >> Oh, un archivo c.? 368 00:30:16,220 --> 00:30:18,790 . [Estudiante] Cualquier archivo c debe tener - [ambos términos a la vez - ininteligible] 369 00:30:18,790 --> 00:30:21,120 Bien. Así que eso es aparte. 370 00:30:21,120 --> 00:30:26,800 >> Un archivo. C sólo necesita contener funciones. 371 00:30:26,800 --> 00:30:32,400 Usted puede compilar un archivo en código máquina, binario, lo que sea, 372 00:30:32,400 --> 00:30:36,620 sin que sea ejecutable todavía. 373 00:30:36,620 --> 00:30:39,420 Un ejecutable válido debe tener una función principal. 374 00:30:39,420 --> 00:30:45,460 Usted puede escribir 100 funciones en 1 archivo pero no principales 375 00:30:45,460 --> 00:30:48,800 y luego compilar que a binario, 376 00:30:48,800 --> 00:30:54,460 entonces usted escribir otro archivo que sólo tiene principal tiene que llamar a un montón de estas funciones 377 00:30:54,460 --> 00:30:56,720 en el archivo binario aquí. 378 00:30:56,720 --> 00:31:01,240 Así que cuando usted está haciendo el ejecutable, que es lo que hace el enlazador 379 00:31:01,240 --> 00:31:05,960 Se combina estos dos archivos binarios en un archivo ejecutable. 380 00:31:05,960 --> 00:31:11,400 Así que un archivo. C no necesita tener una función principal en absoluto. 381 00:31:11,400 --> 00:31:19,220 Y en grandes bases de código verás miles de archivos. C y 1 archivo principal. 382 00:31:23,960 --> 00:31:26,110 Más preguntas? 383 00:31:29,310 --> 00:31:31,940 [Estudiante] Hubo otra pregunta. 384 00:31:31,940 --> 00:31:36,710 Dijo que hacer es un compilador. Verdadero o Falso? 385 00:31:36,710 --> 00:31:42,030 Y la respuesta era falsa, y entendí por qué no es como Clang. 386 00:31:42,030 --> 00:31:44,770 Pero, ¿cómo llamamos a hacer si no? 387 00:31:44,770 --> 00:31:49,990 Hacer es básicamente - Puedo ver exactamente lo que lo llama. 388 00:31:49,990 --> 00:31:52,410 Pero simplemente ejecuta los comandos. 389 00:31:53,650 --> 00:31:55,650 Make. 390 00:31:58,240 --> 00:32:00,870 Yo puedo tirar esto. Si. 391 00:32:10,110 --> 00:32:13,180 Oh, sí. Asegúrese también lo hace. 392 00:32:13,180 --> 00:32:17,170 Esto dice que el propósito de la utilidad make es determinar automáticamente 393 00:32:17,170 --> 00:32:19,610 qué piezas de un programa necesitan ser recompilados 394 00:32:19,610 --> 00:32:22,350 y emitir las órdenes para compilar. 395 00:32:22,350 --> 00:32:27,690 Usted puede hacer que los archivos que son absolutamente enorme. 396 00:32:27,690 --> 00:32:33,210 Hacer mira las marcas de tiempo de los archivos y, como hemos dicho antes, 397 00:32:33,210 --> 00:32:36,930 puede compilar archivos individuales hacia abajo, y no es hasta que llegue al enlazador 398 00:32:36,930 --> 00:32:39,270 que están juntas en un ejecutable. 399 00:32:39,270 --> 00:32:43,810 Así que si usted tiene 10 diferentes archivos y realizar un cambio en una de ellas, 400 00:32:43,810 --> 00:32:47,870 entonces, ¿qué marca va a hacer es recompilar que 1 archivo 401 00:32:47,870 --> 00:32:50,640 y luego volver a vincular todo junto. 402 00:32:50,640 --> 00:32:53,020 Pero es mucho más tonto que eso. 403 00:32:53,020 --> 00:32:55,690 Depende de usted para definir completamente que eso es lo que debería estar haciendo. 404 00:32:55,690 --> 00:32:59,560 Es por defecto tiene la capacidad de reconocer estas cosas sello de tiempo, 405 00:32:59,560 --> 00:33:03,220 pero usted puede escribir un archivo make para hacer nada. 406 00:33:03,220 --> 00:33:09,150 Usted puede escribir un archivo para hacer que al escribir lo hacen sólo cd a otro directorio. 407 00:33:09,150 --> 00:33:15,560 Estaba frustrado porque todo tachuela interior de mi Appliance 408 00:33:15,560 --> 00:33:21,740 y luego ver el PDF desde el Mac. 409 00:33:21,740 --> 00:33:30,720 >> Así que ir a Finder y puedo ir a hacer, Conectar al servidor, 410 00:33:30,720 --> 00:33:36,950 y el servidor me conecto a mi es Appliance, y luego abrir el PDF 411 00:33:36,950 --> 00:33:40,190 que se compila por LaTeX. 412 00:33:40,190 --> 00:33:49,320 Pero yo estaba frustrado porque cada vez que tenía que actualizar el PDF, 413 00:33:49,320 --> 00:33:53,900 Tuve que copiar a un directorio específico que pueda acceder 414 00:33:53,900 --> 00:33:57,710 y se hacía molesto. 415 00:33:57,710 --> 00:34:02,650 Así que en vez escribí un archivo de marca, que tiene que definir la forma en que hace las cosas. 416 00:34:02,650 --> 00:34:06,130 ¿Cómo hacer que en esto es PDF LaTeX. 417 00:34:06,130 --> 00:34:10,090 Al igual que cualquier otro archivo de marca - o supongo que no has visto los archivos Make, 418 00:34:10,090 --> 00:34:13,510 pero tenemos en el aparato un archivo de marca global que sólo dice: 419 00:34:13,510 --> 00:34:16,679 si está compilando un archivo de C, utilice Clang. 420 00:34:16,679 --> 00:34:20,960 Y aquí en mi archivo de marca que hago yo digo, 421 00:34:20,960 --> 00:34:25,020 el archivo que vas a querer compilar con PDF LaTeX. 422 00:34:25,020 --> 00:34:27,889 Y lo que es LaTeX PDF que está haciendo la compilación. 423 00:34:27,889 --> 00:34:31,880 Hacer no está compilando. Es simplemente ejecutar estos comandos en la secuencia que se especifica. 424 00:34:31,880 --> 00:34:36,110 Así se ejecuta LaTeX PDF, lo copia al directorio que desea que se copian, 425 00:34:36,110 --> 00:34:38,270 que el cd en el directorio y hace otras cosas, 426 00:34:38,270 --> 00:34:42,380 pero lo único que hace es reconocer cuando cambia un archivo, 427 00:34:42,380 --> 00:34:45,489 y si cambia, entonces se ejecutan los comandos que se supone para funcionar 428 00:34:45,489 --> 00:34:48,760 cuando cambia el archivo. >> [Estudiante] Bueno. 429 00:34:50,510 --> 00:34:54,420 No sé donde están los archivos make globales son para mí comprobar que funciona. 430 00:34:57,210 --> 00:35:04,290 Otras preguntas? Cualquier cosa del pasado pruebas? Las cosas puntero? 431 00:35:06,200 --> 00:35:08,730 Hay cosas sutiles con punteros como - 432 00:35:08,730 --> 00:35:10,220 Yo no voy a ser capaz de encontrar una pregunta de cuestionario en él - 433 00:35:10,220 --> 00:35:16,250 pero al igual que este tipo de cosas. 434 00:35:19,680 --> 00:35:24,060 Asegúrese de entender que cuando digo int * x * y - 435 00:35:24,890 --> 00:35:28,130 Esto no es exactamente nada aquí, supongo. 436 00:35:28,130 --> 00:35:32,140 Pero al igual que * x * y, esos son dos variables que están en la pila. 437 00:35:32,140 --> 00:35:37,220 Cuando digo x = malloc (sizeof (int)), x es todavía una variable en la pila, 438 00:35:37,220 --> 00:35:41,180 malloc algún bloque más en el montón, y vamos a tener el punto x al montón. 439 00:35:41,180 --> 00:35:43,900 >> Así que algo sobre los puntos de la pila a la pila. 440 00:35:43,900 --> 00:35:48,100 Siempre que malloc nada, usted está inevitablemente guardarla dentro de un puntero. 441 00:35:48,100 --> 00:35:55,940 Así que el puntero está en la pila, el bloque malloced está en el montón. 442 00:35:55,940 --> 00:36:01,240 Muchas personas se confunden y dicen int * x = malloc, x está en el montón. 443 00:36:01,240 --> 00:36:04,100 No. Lo que señala es x en el montón. 444 00:36:04,100 --> 00:36:08,540 x sí mismo está en la pila, salvo que por la razón que sea que haya x una variable global, 445 00:36:08,540 --> 00:36:11,960 en cuyo caso pasa a ser en otra región de memoria. 446 00:36:13,450 --> 00:36:20,820 Así que hacer el seguimiento, estos diagramas de caja y la flecha son muy comunes para la prueba. 447 00:36:20,820 --> 00:36:25,740 O si no está en concurso de 0, se estará a quiz 1. 448 00:36:27,570 --> 00:36:31,940 Usted debe saber todo esto, los pasos de compilación 449 00:36:31,940 --> 00:36:35,740 ya que tuvo que responder a preguntas sobre ellas. Sí. 450 00:36:35,740 --> 00:36:38,940 [Estudiante] ¿Podemos repasar los pasos - >> Claro. 451 00:36:48,340 --> 00:36:58,640 Antes de los pasos y la compilación tenemos preprocesamiento, 452 00:36:58,640 --> 00:37:16,750 compilar, organizar y vincular. 453 00:37:16,750 --> 00:37:21,480 Preprocesamiento. ¿Qué significa eso? 454 00:37:29,720 --> 00:37:32,290 Es el paso más fácil en - bueno, no como - 455 00:37:32,290 --> 00:37:35,770 eso no significa que debería ser obvio, pero es el paso más fácil. 456 00:37:35,770 --> 00:37:38,410 Ustedes podrían implementar ustedes mismos. Si. 457 00:37:38,410 --> 00:37:43,410 [Estudiante] Tome lo que usted tiene en su incluye como este y lo copia y luego define también. 458 00:37:43,410 --> 00:37:49,250 Se ve las cosas como # include y # define, 459 00:37:49,250 --> 00:37:53,800 y sólo copia y pega lo que los que realmente significan. 460 00:37:53,800 --> 00:37:59,240 Así que cuando dices # include cs50.h, el preprocesador es copiar y pegar cs50.h 461 00:37:59,240 --> 00:38:01,030 en esa línea. 462 00:38:01,030 --> 00:38:06,640 Cuando dices # define x para ser 4, el preprocesador atraviesa todo el programa 463 00:38:06,640 --> 00:38:10,400 y sustituye a todos los casos de x con 4. 464 00:38:10,400 --> 00:38:17,530 Así que el preprocesador toma un archivo de C válido y envía un archivo válido de C 465 00:38:17,530 --> 00:38:20,300 donde las cosas se han copiado y pegado. 466 00:38:20,300 --> 00:38:24,230 Así que ahora compilar. ¿Qué significa eso? 467 00:38:25,940 --> 00:38:28,210 [Estudiante] Va de C a binario. 468 00:38:28,210 --> 00:38:30,970 >> [Bowden] No va todo el camino a binario. 469 00:38:30,970 --> 00:38:34,220 [Estudiante] a código de máquina, entonces? >> No es código máquina. 470 00:38:34,220 --> 00:38:35,700 [Estudiante] Asamblea? >> Asamblea. 471 00:38:35,700 --> 00:38:38,890 Se va a la Asamblea antes de que va todo el camino a código C, 472 00:38:38,890 --> 00:38:45,010 y la mayoría de lenguajes hacer algo como esto. 473 00:38:47,740 --> 00:38:50,590 Elija cualquier lenguaje de alto nivel, y, si lo vas a compilar 474 00:38:50,590 --> 00:38:52,390 lo más probable es que compile en pasos. 475 00:38:52,390 --> 00:38:58,140 En primer lugar se va a compilar Python a C, entonces va a compilar C a la Asamblea, 476 00:38:58,140 --> 00:39:01,600 y luego la Asamblea va a ser traducido a binario. 477 00:39:01,600 --> 00:39:07,800 Así que compilar lo va a traer de C a la Asamblea. 478 00:39:07,800 --> 00:39:12,130 La palabra generalmente significa compilar llevarlo desde un nivel superior 479 00:39:12,130 --> 00:39:14,340 a un lenguaje de programación de bajo. 480 00:39:14,340 --> 00:39:19,190 Así que este es el único paso en la recopilación de donde empiezas con un lenguaje de alto nivel 481 00:39:19,190 --> 00:39:23,270 y terminan en un lenguaje de bajo nivel, y es por eso que el paso se llama compilación. 482 00:39:25,280 --> 00:39:33,370 [Estudiante] Durante la compilación, digamos que usted ha hecho # include cs50.h. 483 00:39:33,370 --> 00:39:42,190 ¿El compilador recompilar el cs50.h, al igual que las funciones que se encuentran allí, 484 00:39:42,190 --> 00:39:45,280 y traducir eso en código ensamblador, así, 485 00:39:45,280 --> 00:39:50,830 o va a copiar y pegar algo que ha sido pre-Asamblea? 486 00:39:50,830 --> 00:39:56,910 cs50.h bastante mucho que nunca terminan en la Asamblea. 487 00:39:59,740 --> 00:40:03,680 Cosas como prototipos de las funciones y las cosas son sólo para que tengas cuidado. 488 00:40:03,680 --> 00:40:09,270 Garantiza que el compilador puede comprobar las cosas como si estuvieras llamando a las funciones 489 00:40:09,270 --> 00:40:12,910 con los tipos de devolución de derechos y los argumentos de derecho y esas cosas. 490 00:40:12,910 --> 00:40:18,350 >> Así cs50.h se preprocesado en el archivo y, a continuación, cuando se está compilando 491 00:40:18,350 --> 00:40:22,310 que es básicamente tirar después se asegura de que todo lo que se llama correctamente. 492 00:40:22,310 --> 00:40:29,410 Pero las funciones definidas en la biblioteca CS50, que están separados de cs50.h, 493 00:40:29,410 --> 00:40:33,610 los que no se compilan por separado. 494 00:40:33,610 --> 00:40:37,270 Que en realidad se reducirá en la etapa de enlace, así que vamos a llegar a eso en un segundo. 495 00:40:37,270 --> 00:40:40,100 Pero primero, ¿qué es el montaje? 496 00:40:41,850 --> 00:40:44,500 [Estudiante] Asamblea a binario? Sí >>. 497 00:40:46,300 --> 00:40:48,190 Maquila. 498 00:40:48,190 --> 00:40:54,710 Nosotros no lo llamamos compilar porque la Asamblea es casi una pura traducción de binario. 499 00:40:54,710 --> 00:41:00,230 Hay una lógica muy poco al pasar de la Asamblea a binario. 500 00:41:00,230 --> 00:41:03,180 Es como buscar en una tabla, oh, tenemos esta instrucción; 501 00:41:03,180 --> 00:41:06,290 que corresponde a binario 01110. 502 00:41:10,200 --> 00:41:15,230 Y para que los archivos que el montaje generalmente resultados son. Archivos o. 503 00:41:15,230 --> 00:41:19,020 Y los archivos. O son lo que decíamos antes, 504 00:41:19,020 --> 00:41:21,570 cómo un fichero no necesita tener una función principal. 505 00:41:21,570 --> 00:41:27,640 Cualquier archivo puede ser compilado a un archivo. O como mucho, ya que es un archivo válido de C. 506 00:41:27,640 --> 00:41:30,300 Puede ser compilado a. O. 507 00:41:30,300 --> 00:41:43,030 Ahora, la vinculación es lo que realmente trae un montón de. Archivos o y los lleva a un ejecutable. 508 00:41:43,030 --> 00:41:51,110 Y así lo hace es la vinculación que se pueda imaginar la biblioteca CS50 como un archivo. O. 509 00:41:51,110 --> 00:41:56,980 Es un archivo binario ya compilado. 510 00:41:56,980 --> 00:42:03,530 Y así, cuando se compila el archivo, su hello.c, que llama a GetString, 511 00:42:03,530 --> 00:42:06,360 hello.c se compila a hello.o, 512 00:42:06,360 --> 00:42:08,910 hello.o está ahora en binario. 513 00:42:08,910 --> 00:42:12,830 Utiliza GetString, por lo que tiene que ir a cs50.o, 514 00:42:12,830 --> 00:42:16,390 y el enlazador ellos smooshes juntos y lo copia en el archivo GetString 515 00:42:16,390 --> 00:42:20,640 y sale con un ejecutable que tiene todas las funciones que necesita. 516 00:42:20,640 --> 00:42:32,620 Así cs50.o no es en realidad un archivo de O, pero está lo suficientemente cerca que no hay una diferencia fundamental. 517 00:42:32,620 --> 00:42:36,880 Así que la vinculación sólo trae un montón de archivos juntos 518 00:42:36,880 --> 00:42:41,390 que contienen por separado todas las funciones que necesito para usar 519 00:42:41,390 --> 00:42:46,120 y crea el ejecutable que realmente funciona. 520 00:42:48,420 --> 00:42:50,780 >> Y eso es también lo que decíamos antes 521 00:42:50,780 --> 00:42:55,970 donde se puede tomar 1000. archivos c, se compila a todos a. archivos o, 522 00:42:55,970 --> 00:43:00,040 que probablemente tomará un tiempo, y luego se cambia 1. archivo c. 523 00:43:00,040 --> 00:43:05,480 Sólo es necesario recompilar que 1. Archivo c y luego todo vuelve a vincular más, 524 00:43:05,480 --> 00:43:07,690 vincular todo de nuevo juntos. 525 00:43:09,580 --> 00:43:11,430 [Estudiante] Cuando estamos vinculando escribimos lcs50? 526 00:43:11,430 --> 00:43:20,510 Sí, así lcs50. Que las señales de las banderas al enlazador que debe ser la vinculación en esa biblioteca. 527 00:43:26,680 --> 00:43:28,910 ¿Preguntas? 528 00:43:41,310 --> 00:43:46,860 ¿Hemos ido binario excepto que 5 segundos en la primera conferencia? 529 00:43:50,130 --> 00:43:53,010 No lo creo. 530 00:43:55,530 --> 00:43:58,820 Usted debe saber todo de las grandes salidas que hemos repasado, 531 00:43:58,820 --> 00:44:02,670 y usted debería ser capaz de hacerlo, si te damos una función, 532 00:44:02,670 --> 00:44:09,410 usted debería ser capaz de decir que es grande O, más o menos. O bien, gran O es áspera. 533 00:44:09,410 --> 00:44:15,300 Así que si usted ve bucles for anidados recorrer el mismo número de cosas, 534 00:44:15,300 --> 00:44:22,260 como int i, i > [estudiante] n al cuadrado. >> Que tiende a ser n al cuadrado. 535 00:44:22,260 --> 00:44:25,280 Si ha triples anidada, que tiende a ser cortado en cubos n. 536 00:44:25,280 --> 00:44:29,330 Así que ese tipo de cosa que usted debe ser capaz de señalar inmediatamente. 537 00:44:29,330 --> 00:44:33,890 Usted necesita saber la ordenación por inserción y ordenación de burbuja y fusionar clase y todo eso. 538 00:44:33,890 --> 00:44:41,420 Es más fácil entender por qué son los n al cuadrado y n log n y todo eso 539 00:44:41,420 --> 00:44:47,810 porque creo que había un concurso en un año en el que básicamente le dio 540 00:44:47,810 --> 00:44:55,050 una implementación de tipo burbuja y dijo: "¿Cuál es el tiempo de ejecución de esta función?" 541 00:44:55,050 --> 00:45:01,020 Así que si usted lo reconoce como una especie de burbuja, entonces inmediatamente se puede decir n al cuadrado. 542 00:45:01,020 --> 00:45:05,470 Pero si lo que se mire, usted ni siquiera necesita para darse cuenta de que es una especie de burbuja; 543 00:45:05,470 --> 00:45:08,990 sólo puedo decir que está haciendo esto y esto. Este es n al cuadrado. 544 00:45:12,350 --> 00:45:14,710 [Estudiante] ¿Hay ejemplos difíciles que pueden surgir con, 545 00:45:14,710 --> 00:45:20,370 como una idea similar de averiguar? 546 00:45:20,370 --> 00:45:24,450 >> No creo que le damos algunos ejemplos difíciles. 547 00:45:24,450 --> 00:45:30,180 Lo especie de burbuja es casi tan duro como nos gustaría ir, 548 00:45:30,180 --> 00:45:36,280 e incluso que, siempre y cuando usted entienda que usted está interactuando sobre la matriz 549 00:45:36,280 --> 00:45:41,670 para cada elemento de la matriz, que va a ser algo que n al cuadrado. 550 00:45:45,370 --> 00:45:49,940 Hay cuestiones generales, como la que tenemos aquí - Oh. 551 00:45:55,290 --> 00:45:58,530 Justo el otro día, Doug afirmó: "He inventado un algoritmo que puede ordenar una matriz 552 00:45:58,530 --> 00:46:01,780 "De n números en O (log n) tiempo!" 553 00:46:01,780 --> 00:46:04,900 Entonces, ¿cómo sabemos que es imposible? 554 00:46:04,900 --> 00:46:08,850 [Respuesta de los estudiantes inaudible] >> Si. 555 00:46:08,850 --> 00:46:13,710 Por lo menos, tiene que tocar cada elemento de la matriz, 556 00:46:13,710 --> 00:46:16,210 por lo que es imposible ordenar una matriz de - 557 00:46:16,210 --> 00:46:20,850 Si todo está en orden sin clasificar, entonces usted va a estar en contacto con todo lo que en la matriz, 558 00:46:20,850 --> 00:46:25,320 por lo que es imposible hacerlo en menos de O de n. 559 00:46:27,430 --> 00:46:30,340 [Estudiante] Usted nos mostró el ejemplo de ser capaz de hacerlo en O de n 560 00:46:30,340 --> 00:46:33,920 si se utiliza una gran cantidad de memoria. Sí >>. 561 00:46:33,920 --> 00:46:37,970 Y eso es - no recuerdo qué eso es - ¿Está contando cosas semejantes? 562 00:46:47,360 --> 00:46:51,330 Hmm. Que es un algoritmo de clasificación entero. 563 00:46:59,850 --> 00:47:05,100 Yo estaba buscando el nombre especial para esto que yo no recordaba la semana pasada. 564 00:47:05,100 --> 00:47:13,000 Si. Estos son los tipos de clases que pueden lograr las cosas en gran O de n. 565 00:47:13,000 --> 00:47:18,430 Sin embargo, hay limitaciones, como que sólo se puede utilizar números enteros hasta un número determinado. 566 00:47:20,870 --> 00:47:24,560 Además, si usted está tratando de ordenar algo Es. - 567 00:47:24,560 --> 00:47:30,750 Si la matriz es 012, -12, 151, 4 millones, 568 00:47:30,750 --> 00:47:35,120 entonces ese elemento solo se va a arruinar por completo la clasificación completa. 569 00:47:42,060 --> 00:47:44,030 >> ¿Preguntas? 570 00:47:49,480 --> 00:47:58,870 [Estudiante] Si usted tiene una función recursiva y sólo hace que las llamadas recursivas 571 00:47:58,870 --> 00:48:02,230 dentro de una instrucción de retorno, que es la cola recursiva, 572 00:48:02,230 --> 00:48:07,360 por lo que no habría que utilizar más memoria en tiempo de ejecución 573 00:48:07,360 --> 00:48:12,550 o que por lo menos comparable utilizar la memoria como un proceso iterativo de solución? 574 00:48:12,550 --> 00:48:14,530 [Bowden] Sí. 575 00:48:14,530 --> 00:48:19,840 Probablemente sería un poco más lento, pero en realidad no. 576 00:48:19,840 --> 00:48:23,290 Tail recursiva es bastante bueno. 577 00:48:23,290 --> 00:48:32,640 Mirando de nuevo a los marcos de pila, digamos que tenemos principal 578 00:48:32,640 --> 00:48:42,920 y de un bar int (int x) o algo así. 579 00:48:42,920 --> 00:48:52,310 Esto no es una función recursiva perfecta, pero la barra de retorno (x - 1). 580 00:48:52,310 --> 00:48:57,620 Así que, obviamente, esto es erróneo. Necesita casos base y esas cosas. 581 00:48:57,620 --> 00:49:00,360 Pero la idea aquí es que esta es la cola recursiva, 582 00:49:00,360 --> 00:49:06,020 lo que significa que las llamadas barra principal que va a conseguir su marco de pila. 583 00:49:09,550 --> 00:49:12,440 En este marco de pila que va a ser un pequeño bloque de memoria 584 00:49:12,440 --> 00:49:17,490 que corresponde a su argumento x. 585 00:49:17,490 --> 00:49:25,840 Y así digamos principal pasa a llamar bar (100); 586 00:49:25,840 --> 00:49:30,050 Así que x va a comenzar como 100. 587 00:49:30,050 --> 00:49:35,660 Si el compilador reconoce que se trata de una función recursiva cola, 588 00:49:35,660 --> 00:49:38,540 entonces cuando hace su barra llamada recursiva a la barra, 589 00:49:38,540 --> 00:49:45,490 en vez de hacer un nuevo marco de pila, que es donde la pila empieza a crecer en gran medida, 590 00:49:45,490 --> 00:49:48,220 finalmente se ejecutará en el montón y luego te dan segfaults 591 00:49:48,220 --> 00:49:51,590 porque la memoria comienza a chocar. 592 00:49:51,590 --> 00:49:54,830 >> Así que en lugar de hacer su propio marco de pila, se puede realizar, 593 00:49:54,830 --> 00:49:59,080 hey, yo nunca tenga que volver a este marco de pila, 594 00:49:59,080 --> 00:50:08,040 así que en vez que voy a reemplazar este argumento con 99 y luego comenzar bar por todas partes. 595 00:50:08,040 --> 00:50:11,810 Y entonces lo haré otra vez y llegará bar return (x - 1), 596 00:50:11,810 --> 00:50:17,320 y en lugar de hacer un nuevo marco de pila, se acaba de sustituir su actual argumento con el 98 597 00:50:17,320 --> 00:50:20,740 y luego saltar de nuevo al principio de la barra. 598 00:50:23,860 --> 00:50:30,430 Esas operaciones, reemplazando el valor 1 en la pila y salta de nuevo al principio, 599 00:50:30,430 --> 00:50:32,430 son bastante eficientes. 600 00:50:32,430 --> 00:50:41,500 Así que no sólo es el uso de la memoria misma como una función separada que se iterativo 601 00:50:41,500 --> 00:50:45,390 porque sólo está utilizando un marco de pila, pero no está sufriendo los inconvenientes 602 00:50:45,390 --> 00:50:47,240 de tener que llamar a las funciones. 603 00:50:47,240 --> 00:50:50,240 Llamada a funciones puede ser algo caro, ya que tiene que ver todo este montaje 604 00:50:50,240 --> 00:50:52,470 y el desmontaje y todas esas cosas. 605 00:50:52,470 --> 00:50:58,160 Así que esta recursión de cola es bueno. 606 00:50:58,160 --> 00:51:01,170 [Estudiante] ¿Por qué no crear nuevos pasos? 607 00:51:01,170 --> 00:51:02,980 Debido a que se da cuenta de que no necesita. 608 00:51:02,980 --> 00:51:07,800 El llamado a la barra se acaba de devolver la llamada recursiva. 609 00:51:07,800 --> 00:51:12,220 Así que no hay que hacer nada con el valor de retorno. 610 00:51:12,220 --> 00:51:15,120 Es sólo va a devolverlo inmediatamente. 611 00:51:15,120 --> 00:51:20,530 Por lo tanto, sólo va a sustituir su propio argumento y empezar de nuevo. 612 00:51:20,530 --> 00:51:25,780 Y también, si usted no tiene la versión recursiva de cola, 613 00:51:25,780 --> 00:51:31,460 entonces usted consigue todos estos bares donde cuando este bar devuelve 614 00:51:31,460 --> 00:51:36,010 hay que devolver su valor a ésta, luego que la barra vuelve inmediatamente 615 00:51:36,010 --> 00:51:39,620 y devuelve su valor a ésta, entonces sólo va a regresar inmediatamente 616 00:51:39,620 --> 00:51:41,350 y devolver su valor a ésta. 617 00:51:41,350 --> 00:51:45,350 Así que usted está ahorrando esta haciendo estallar todas estas cosas de la pila 618 00:51:45,350 --> 00:51:48,730 ya que el valor de retorno es sólo va a pasar todo el camino de vuelta de todos modos. 619 00:51:48,730 --> 00:51:55,400 Así que ¿por qué no sustituir nuestro argumento con el argumento de actualización y empezar de nuevo? 620 00:51:57,460 --> 00:52:01,150 Si la función no es la cola recursiva, si haces algo como - 621 00:52:01,150 --> 00:52:07,530 [Estudiante] si bar (x + 1). Sí >>. 622 00:52:07,530 --> 00:52:11,770 >> Así que si usted lo pone en condición, entonces usted está haciendo algo con el valor de retorno. 623 00:52:11,770 --> 00:52:16,260 O incluso si usted acaba de hacer cambio de 2 * bar (x - 1). 624 00:52:16,260 --> 00:52:23,560 Así que ahora bar (x - 1) debe volver a fin de que para el cálculo de 2 veces ese valor, 625 00:52:23,560 --> 00:52:26,140 por lo que ahora necesita su propio marco de pila separada, 626 00:52:26,140 --> 00:52:31,180 y ahora, no importa cuánto te esfuerces, vas a tener que - 627 00:52:31,180 --> 00:52:34,410 Esta no es la cola recursiva. 628 00:52:34,410 --> 00:52:37,590 [Estudiante] Lo que trato de llevar una recursividad para aspirar a una recursión de cola - 629 00:52:37,590 --> 00:52:41,450 [Bowden] En un mundo ideal, pero en CS50 usted no tenga que hacerlo. 630 00:52:43,780 --> 00:52:49,280 Con el fin de obtener la recursión de cola, por lo general, se configura un argumento adicional 631 00:52:49,280 --> 00:52:53,550 bar donde se llevará a int x en y 632 00:52:53,550 --> 00:52:56,990 e y corresponde a la última cosa que desea devolver. 633 00:52:56,990 --> 00:53:03,650 Así que esto va a ser regresar bar (x - 1), 2 * y. 634 00:53:03,650 --> 00:53:09,810 Así que eso es sólo un alto nivel de cómo se transforman las cosas sean cola recursiva. 635 00:53:09,810 --> 00:53:13,790 Pero el argumento extra - 636 00:53:13,790 --> 00:53:17,410 Y luego al final cuando llegue a su base, la que acaba de regresar y 637 00:53:17,410 --> 00:53:22,740 porque ha venido acumulando durante todo el tiempo el valor de retorno que desee. 638 00:53:22,740 --> 00:53:27,280 De alguna manera lo han estado haciendo iterativa, pero utilizando las llamadas recursivas. 639 00:53:32,510 --> 00:53:34,900 ¿Preguntas? 640 00:53:34,900 --> 00:53:39,890 [Estudiante] Tal vez sobre la aritmética de punteros, como cuando el uso de cadenas. >> Claro. 641 00:53:39,890 --> 00:53:43,610 Aritmética de punteros. 642 00:53:43,610 --> 00:53:48,440 Cuando el uso de cadenas es fácil porque las cadenas son estrellas char, 643 00:53:48,440 --> 00:53:51,860 chars son para siempre y siempre un solo byte, 644 00:53:51,860 --> 00:53:57,540 por lo que la aritmética de punteros es equivalente a la aritmética normal cuando usted está tratando con cadenas. 645 00:53:57,540 --> 00:54:08,790 Digamos char * s = "hola". 646 00:54:08,790 --> 00:54:11,430 Así que tenemos un bloque en la memoria. 647 00:54:19,490 --> 00:54:22,380 Se necesita de 6 bytes, ya que siempre se necesita el terminador nulo. 648 00:54:22,380 --> 00:54:28,620 Y char * s va a señalar el comienzo de esta matriz. 649 00:54:28,620 --> 00:54:32,830 Así que s apunte allí. 650 00:54:32,830 --> 00:54:36,710 Ahora, esto es básicamente como cualquier matriz funciona, 651 00:54:36,710 --> 00:54:40,780 independientemente de si se trataba de un retorno de malloc o si está en la pila. 652 00:54:40,780 --> 00:54:47,110 Cualquier matriz es básicamente un puntero al comienzo de la matriz, 653 00:54:47,110 --> 00:54:53,640 y después de cualquier operación de matriz, cualquier indexación, es sólo va en esa matriz un cierto desfase. 654 00:54:53,640 --> 00:55:05,360 >> Así que cuando digo algo como s [3], lo que va a s y contar 3 caracteres pulg 655 00:55:05,360 --> 00:55:12,490 Así que s [3], tenemos 0, 1, 2, 3, por lo que s [3] va a hacer referencia a este l. 656 00:55:12,490 --> 00:55:20,460 [Estudiante] Y podríamos alcanzar el mismo valor que al hacer s + 3 estrellas y luego entre paréntesis? 657 00:55:20,460 --> 00:55:22,570 Sí. 658 00:55:22,570 --> 00:55:26,010 Esto es equivalente a * (s + 3); 659 00:55:26,010 --> 00:55:31,240 y que es eterno y para siempre equivalente no importa lo que hagas. 660 00:55:31,240 --> 00:55:34,070 Nunca se deberá utilizar la sintaxis soporte. 661 00:55:34,070 --> 00:55:37,770 Siempre puedes usar el * (s + 3) sintaxis. 662 00:55:37,770 --> 00:55:40,180 La gente tiende a gustar la sintaxis soporte, sin embargo. 663 00:55:40,180 --> 00:55:43,860 [Estudiante] Así que todas las matrices son en realidad punteros. 664 00:55:43,860 --> 00:55:53,630 Hay una diferencia leve cuando digo int x [4] >> [estudiante] ¿Eso cree la memoria? 665 00:55:53,630 --> 00:56:03,320 [Bowden] Eso va a crear 4 enteros en la pila, por lo general de 16 bytes. 666 00:56:03,320 --> 00:56:05,700 Se va a crear 16 bytes en la pila. 667 00:56:05,700 --> 00:56:09,190 x no se almacena en cualquier lugar. 668 00:56:09,190 --> 00:56:13,420 Es sólo un símbolo referente al inicio de la cosa. 669 00:56:13,420 --> 00:56:17,680 Porque declarado la matriz dentro de esta función, 670 00:56:17,680 --> 00:56:22,340 lo que el compilador va a hacer es reemplazar todas las instancias de la variable x 671 00:56:22,340 --> 00:56:26,400 con el lugar donde pasó a optar por poner estos 16 bytes. 672 00:56:26,400 --> 00:56:30,040 No se puede hacer eso con char * s porque s es un puntero real. 673 00:56:30,040 --> 00:56:32,380 Es gratuito para apuntar luego a otras cosas. 674 00:56:32,380 --> 00:56:36,140 x es una constante. No se puede tener que apunte a otra matriz. >> [Estudiante] Bueno. 675 00:56:36,140 --> 00:56:43,420 Pero esta idea, esta indexación, es la misma independientemente de si se trata de un régimen tradicional 676 00:56:43,420 --> 00:56:48,230 o si es un puntero a algo o si es un puntero a un array malloced. 677 00:56:48,230 --> 00:56:59,770 Y, de hecho, es tan equivalente que es también la misma cosa. 678 00:56:59,770 --> 00:57:05,440 En realidad, sólo se traduce lo que hay dentro de los corchetes y lo que queda de los soportes, 679 00:57:05,440 --> 00:57:07,970 los suma, y ​​elimina referencias. 680 00:57:07,970 --> 00:57:14,710 Así que esto es tan válido como * (s + 3) o s [3]. 681 00:57:16,210 --> 00:57:22,090 [Estudiante] ¿Se puede tener punteros que apuntan a 2-dimensionales? 682 00:57:22,090 --> 00:57:27,380 >> Es más difícil. Tradicionalmente, no. 683 00:57:27,380 --> 00:57:34,720 Una matriz de 2 dimensiones es sólo un arreglo 1-dimensional con una sintaxis conveniente 684 00:57:34,720 --> 00:57:54,110 porque cuando digo int x [3] [3], esto es en realidad una matriz con 9 valores. 685 00:57:55,500 --> 00:58:03,000 Y así, cuando yo índice, el compilador sabe a qué me refiero. 686 00:58:03,000 --> 00:58:13,090 Si digo x [1] [2], se sabe que quiero ir a la segunda fila, por lo que va a pasar los primeros 3, 687 00:58:13,090 --> 00:58:17,460 y luego quiere que la segunda cosa en que, por lo que va a conseguir éste. 688 00:58:17,460 --> 00:58:20,480 Pero todavía es sólo una matriz unidimensional. 689 00:58:20,480 --> 00:58:23,660 Y así, si quería asignar un puntero a la matriz, 690 00:58:23,660 --> 00:58:29,770 Yo diría int * p = x; 691 00:58:29,770 --> 00:58:33,220 El tipo de x es justo - 692 00:58:33,220 --> 00:58:38,280 Es decir tipo rudo de x, ya que es sólo un símbolo y no es una variable real, 693 00:58:38,280 --> 00:58:40,140 pero es sólo un * int. 694 00:58:40,140 --> 00:58:44,840 x es sólo un puntero al comienzo de esta. >> [Estudiante] Bueno. 695 00:58:44,840 --> 00:58:52,560 Así que no será capaz de acceder a [1] [2]. 696 00:58:52,560 --> 00:58:58,370 Creo que hay una sintaxis especial para la declaración de un puntero, 697 00:58:58,370 --> 00:59:12,480 algo ridículo como int (* p [-. algo absolutamente ridículo que ni siquiera conozco. 698 00:59:12,480 --> 00:59:17,090 Pero hay una sintaxis para declarar punteros como con paréntesis y las cosas. 699 00:59:17,090 --> 00:59:22,960 Puede incluso no le permiten hacer eso. 700 00:59:22,960 --> 00:59:26,640 Podía mirar hacia atrás en algo que me digas la verdad. 701 00:59:26,640 --> 00:59:34,160 Voy a buscar más tarde, si hay una sintaxis de punto. Pero nunca lo verá. 702 00:59:34,160 --> 00:59:39,670 Y aunque la sintaxis es tan arcaico que si usted lo usa, la gente se desconcierta. 703 00:59:39,670 --> 00:59:43,540 Los arreglos multidimensionales son bastante raros como es. 704 00:59:43,540 --> 00:59:44,630 Te prácticamente - 705 00:59:44,630 --> 00:59:48,490 Bueno, si usted está haciendo las cosas de la matriz que no va a ser raro, 706 00:59:48,490 --> 00:59:56,730 pero en C que está raramente va a utilizar matrices multidimensionales. 707 00:59:57,630 --> 01:00:00,470 Si. >> [Estudiante] Digamos que usted tiene un arsenal muy largo. 708 01:00:00,470 --> 01:00:03,900 >> Así, en la memoria virtual parece ser todos consecutivos, 709 01:00:03,900 --> 01:00:05,640 como los elementos uno al lado del otro, 710 01:00:05,640 --> 01:00:08,770 pero en la memoria física, ¿sería posible que se separaron? Sí >>. 711 01:00:08,770 --> 01:00:16,860 ¿Cómo funciona la memoria virtual es sólo separa - 712 01:00:19,220 --> 01:00:24,860 La unidad de asignación es una página, que tiende a ser 4 kilobytes, 713 01:00:24,860 --> 01:00:29,680 y así, cuando un proceso, dice, hey, quiero utilizar esta memoria, 714 01:00:29,680 --> 01:00:35,970 el sistema operativo se va a asignar 4 kilobytes para que poco bloque de memoria. 715 01:00:35,970 --> 01:00:39,100 Incluso si sólo utiliza un solo byte poco en todo el bloque de memoria, 716 01:00:39,100 --> 01:00:42,850 el sistema operativo se va a dar la totalidad de 4 kilobytes. 717 01:00:42,850 --> 01:00:49,410 Lo que esto significa es que podría tener - vamos a decir que este es mi stack. 718 01:00:49,410 --> 01:00:53,180 Esta pila se podía separar. Mi pila podría ser megabytes y megabytes. 719 01:00:53,180 --> 01:00:55,020 Mi pila podría ser enorme. 720 01:00:55,020 --> 01:01:00,220 Pero la propia pila tiene que ser dividido en páginas individuales, 721 01:01:00,220 --> 01:01:09,010 que si miramos hacia aquí digamos que esta es nuestra RAM, 722 01:01:09,010 --> 01:01:16,600 si tengo 2 GB de RAM, es 0 dirección real como el byte cero de mi memoria RAM, 723 01:01:16,600 --> 01:01:22,210 y esto es de 2 gigabytes todo el camino hasta aquí. 724 01:01:22,210 --> 01:01:27,230 Así que esta página puede corresponder a este bloque por aquí. 725 01:01:27,230 --> 01:01:29,400 Esta página puede corresponder a este bloque por aquí. 726 01:01:29,400 --> 01:01:31,560 Esta podría corresponder a éste por aquí. 727 01:01:31,560 --> 01:01:35,540 Así que el sistema operativo es libre de asignar memoria física 728 01:01:35,540 --> 01:01:39,320 a cualquier página individual arbitrariamente. 729 01:01:39,320 --> 01:01:46,180 Y eso significa que si esto sucede frontera a horcajadas sobre una matriz, 730 01:01:46,180 --> 01:01:50,070 una matriz pasa a ser la izquierda y la derecha de este de este orden de una página, 731 01:01:50,070 --> 01:01:54,460 a continuación, la matriz se va a dividir en la memoria física. 732 01:01:54,460 --> 01:01:59,280 Y luego, cuando usted salga del programa, cuando el proceso termina, 733 01:01:59,280 --> 01:02:05,690 estas asignaciones se borran y entonces es libre de utilizar estos bloques pequeños para otras cosas. 734 01:02:14,730 --> 01:02:17,410 Más preguntas? 735 01:02:17,410 --> 01:02:19,960 [Estudiante] El puntero de la aritmética. >> Oh yeah. 736 01:02:19,960 --> 01:02:28,410 Las cadenas eran fáciles, pero mirando a algo como enteros, 737 01:02:28,410 --> 01:02:35,000 Así que volvemos a int x [4]; 738 01:02:35,000 --> 01:02:41,810 Si se trata de una matriz o si se trata de un puntero a una matriz de 4 enteros malloced, 739 01:02:41,810 --> 01:02:47,060 que va a ser tratado de la misma manera. 740 01:02:50,590 --> 01:02:53,340 [Estudiante] Así matrices están en el montón? 741 01:03:01,400 --> 01:03:05,270 Bowden [] Las matrices no están en el montón. >> [Estudiante] Oh. 742 01:03:05,270 --> 01:03:08,320 >> [Bowden] Este tipo de matriz tiende a ser en la pila 743 01:03:08,320 --> 01:03:12,220 a menos que lo declarado en - haciendo caso omiso de las variables globales. No utilice variables globales. 744 01:03:12,220 --> 01:03:16,280 Dentro de una función digo int x [4]; 745 01:03:16,280 --> 01:03:22,520 Se va a crear un bloque de 4 entero en la pila para esta matriz. 746 01:03:22,520 --> 01:03:26,960 Pero este malloc (4 * sizeof (int)); va a ir en el montón. 747 01:03:26,960 --> 01:03:31,870 Pero después de este punto puedo usar x y p en más o menos de la misma manera, 748 01:03:31,870 --> 01:03:36,140 aparte de las excepciones que dije antes acerca de usted puede reasignar p. 749 01:03:36,140 --> 01:03:40,960 Técnicamente, sus tamaños son un poco diferentes, pero eso es completamente irrelevante. 750 01:03:40,960 --> 01:03:43,310 Usted nunca realmente utilizan sus tamaños. 751 01:03:48,020 --> 01:03:56,810 El p puedo decir p [3] = 2, o x [3] = 2; 752 01:03:56,810 --> 01:03:59,680 Usted las puede utilizar en exactamente la misma manera. 753 01:03:59,680 --> 01:04:01,570 Así que ahora puntero aritmética - Sí. 754 01:04:01,570 --> 01:04:07,390 [Estudiante] No tienes que hacer * p si tiene los brackets? 755 01:04:07,390 --> 01:04:11,720 Los soportes son un dereference implícita. >> Okay. 756 01:04:11,720 --> 01:04:20,200 En realidad, también lo que está diciendo con el se puede obtener matrices multidimensionales 757 01:04:20,200 --> 01:05:02,650 con punteros, lo que puedes hacer es algo como, digamos, int ** pp = malloc (sizeof (int *) * 5); 758 01:05:02,650 --> 01:05:06,900 Voy a escribir todo esto en primer lugar. 759 01:05:37,880 --> 01:05:41,020 Yo no quería eso. 760 01:05:41,020 --> 01:05:42,550 Bien. 761 01:05:42,550 --> 01:05:48,910 Lo que hice aquí es - Eso debe ser pp [i]. 762 01:05:48,910 --> 01:05:53,680 Así pp es un puntero a un puntero. 763 01:05:53,680 --> 01:06:02,420 Estás mallocing pp para apuntar a un arreglo de 5 estrellas int. 764 01:06:02,420 --> 01:06:10,950 Así, en la memoria que tienes en la pila pp 765 01:06:10,950 --> 01:06:20,150 Se va a apuntar a un arreglo de 5 bloques que son ellos solos punteros. 766 01:06:20,150 --> 01:06:28,210 Y luego, cuando malloc aquí abajo, yo malloc que cada uno de los punteros individuales 767 01:06:28,210 --> 01:06:32,080 debería apuntar a un bloque independiente de 4 bytes en la pila. 768 01:06:32,080 --> 01:06:35,870 Así que esto apunta a 4 bytes. 769 01:06:37,940 --> 01:06:40,660 Y éste apunta a un diferente 4 bytes. 770 01:06:40,660 --> 01:06:43,200 >> Y todos ellos apuntan a sus propias 4 bytes. 771 01:06:43,200 --> 01:06:49,080 Esto me da una manera de hacer las cosas multidimensionales. 772 01:06:49,080 --> 01:06:58,030 Podría decir pp [3] [4], pero ahora esto no es lo mismo como matrices multidimensionales 773 01:06:58,030 --> 01:07:05,390 ya que las matrices multidimensionales traducido [3] [4] en una sola Desplazamiento en la matriz x. 774 01:07:05,390 --> 01:07:14,790 Esta p desreferencias, accede al tercer índice, a continuación, elimina referencias que 775 01:07:14,790 --> 01:07:20,790 y accesos - 4 sería inválido - el segundo índice. 776 01:07:24,770 --> 01:07:31,430 Mientras que cuando tuvimos la int x [3] [4] antes como una matriz multidimensional 777 01:07:31,430 --> 01:07:35,740 y al hacer doble soporte es realmente sólo un dereference sola 778 01:07:35,740 --> 01:07:40,490 usted está siguiendo un único puntero y luego un desplazamiento, 779 01:07:40,490 --> 01:07:42,850 esto es realmente referencias 2D. 780 01:07:42,850 --> 01:07:45,840 Sigues 2 punteros separados. 781 01:07:45,840 --> 01:07:50,420 Así que esto también técnicamente le permite tener matrices multidimensionales 782 01:07:50,420 --> 01:07:53,550 donde cada matriz individual es diferentes tamaños. 783 01:07:53,550 --> 01:07:58,000 Así que creo irregulares matrices multidimensionales es lo que se llama 784 01:07:58,000 --> 01:08:01,870 ya que realmente la primera cosa podría apuntar a algo que tiene 10 elementos, 785 01:08:01,870 --> 01:08:05,540 la segunda cosa que podría apuntar a algo que tiene 100 elementos. 786 01:08:05,540 --> 01:08:10,790 [Estudiante] ¿Hay algún límite en el número de punteros que puede tener 787 01:08:10,790 --> 01:08:14,290 apuntando a otros indicadores? No. >> 788 01:08:14,290 --> 01:08:17,010 Usted puede tener int ***** p. 789 01:08:18,050 --> 01:08:23,760 Volver a la aritmética de punteros - >> [estudiante] Oh. Sí >>. 790 01:08:23,760 --> 01:08:35,649 [Estudiante] Si tengo int p *** y luego hago una desreferencia y digo * p es igual a este valor, 791 01:08:35,649 --> 01:08:39,560 ¿Es sólo va a hacer un nivel de eliminación de referencias? Sí >>. 792 01:08:39,560 --> 01:08:43,340 Así que si quiero acceder a lo que el puntero apunta al último - 793 01:08:43,340 --> 01:08:46,210 Luego de hacer p ***. >> Okay. 794 01:08:46,210 --> 01:08:54,080 Así que esto es p apunta a un bloque, apunta a otro bloque, apunta a otro bloque. 795 01:08:54,080 --> 01:09:02,010 Entonces, si usted hace * p = algo más, entonces va a cambiar esta 796 01:09:02,010 --> 01:09:13,640 a punto ahora a un bloque diferente. >> Okay. 797 01:09:13,640 --> 01:09:17,649 >> [Bowden] Y si estos se malloced, entonces usted ahora ha escapado memoria 798 01:09:17,649 --> 01:09:20,430 a menos que le sucede que tiene distintas referencias de estos 799 01:09:20,430 --> 01:09:25,270 ya que no puede volver a aquellos que sólo tiró. 800 01:09:25,270 --> 01:09:29,550 Aritmética de punteros. 801 01:09:29,550 --> 01:09:36,310 int x [4], se va a asignar una matriz de 4 enteros 802 01:09:36,310 --> 01:09:40,670 donde x se va a apuntar a la comienzo de la matriz. 803 01:09:40,670 --> 01:09:50,420 Así que cuando digo algo como x [1], yo quiero que signifique ir al segundo entero en la matriz, 804 01:09:50,420 --> 01:09:53,319 que sería éste. 805 01:09:53,319 --> 01:10:04,190 Pero, en realidad, eso es 4 bytes en la matriz ya que este entero ocupa 4 bytes. 806 01:10:04,190 --> 01:10:08,470 Por lo tanto un desplazamiento de 1 significa realmente un desplazamiento de 1 807 01:10:08,470 --> 01:10:12,030 veces el tamaño de cualquiera que sea el tipo de la matriz es. 808 01:10:12,030 --> 01:10:17,170 Este es un arreglo de enteros, por lo que sabe hacer una veces el tamaño de int cuando se quiere compensar. 809 01:10:17,170 --> 01:10:25,260 El resto de la sintaxis. Recuerda que esto es equivalente a * (x + 1); 810 01:10:25,260 --> 01:10:35,250 Cuando digo puntero + 1, lo que vuelve es la dirección que el puntero está almacenando 811 01:10:35,250 --> 01:10:40,360 más 1 veces el tamaño del tipo del puntero. 812 01:10:40,360 --> 01:10:59,510 Así que si x = ox100, entonces x + 1 = ox104. 813 01:10:59,510 --> 01:11:19,750 Y se puede abusar de esto y decir algo como char * c = (char *) x; 814 01:11:19,750 --> 01:11:23,050 y ahora c va a ser la misma dirección x. 815 01:11:23,050 --> 01:11:26,040 c va a ser igual a ox100, 816 01:11:26,040 --> 01:11:31,490 pero c + 1 va a ser igual a ox101 817 01:11:31,490 --> 01:11:38,030 ya que la aritmética de punteros depende del tipo del puntero que va a agregar a. 818 01:11:38,030 --> 01:11:45,390 Así que c + 1, se ve en c, que es un puntero char, así que va a añadir una veces el tamaño de char, 819 01:11:45,390 --> 01:11:48,110 que siempre va a ser 1, por lo que obtener 101, 820 01:11:48,110 --> 01:11:54,890 mientras que si lo hago x, que también sigue siendo 100, x + 1 va a ser 104. 821 01:11:56,660 --> 01:12:06,340 [Estudiante] ¿Se puede usar c + + para avanzar el puntero por 1? 822 01:12:06,340 --> 01:12:09,810 Sí, se puede. 823 01:12:09,810 --> 01:12:16,180 Usted no puede hacer eso con x porque x es sólo un símbolo, es una constante, no se puede cambiar x. 824 01:12:16,180 --> 01:12:22,610 >> Pero c pasa a ser simplemente un puntero, por lo que c + + es perfectamente válido y que se incrementará en 1. 825 01:12:22,610 --> 01:12:32,440 Si c fuera sólo un int *, entonces c + + sería 104. 826 01:12:32,440 --> 01:12:41,250 + + Hace aritmética de punteros como c + 1 tendría que hacer aritmética de punteros. 827 01:12:43,000 --> 01:12:48,870 Esto es en realidad cómo un montón de cosas como la especie de mezcla - 828 01:12:49,670 --> 01:12:55,710 En lugar de crear copias de las cosas, en su lugar puede pasar - 829 01:12:55,710 --> 01:13:02,400 Al igual que si quería pasar esta mitad de la matriz - Vamos a borrar algo de esto. 830 01:13:04,770 --> 01:13:10,520 Digamos que yo quería pasar a este lado de la matriz en una función. 831 01:13:10,520 --> 01:13:12,700 ¿Qué iba a pasar con esa función? 832 01:13:12,700 --> 01:13:17,050 Si paso x, estoy pasando esta dirección. 833 01:13:17,050 --> 01:13:23,780 Pero quiero pasar esta dirección en particular. Entonces, ¿qué debería pasar? 834 01:13:23,780 --> 01:13:26,590 [Estudiante] Pointer + 2? 835 01:13:26,590 --> 01:13:29,350 [Bowden] Entonces x + 2. Sí. 836 01:13:29,350 --> 01:13:31,620 Eso va a ser esta dirección. 837 01:13:31,620 --> 01:13:42,810 También muy a menudo lo ven como x [2] y luego la dirección de eso. 838 01:13:42,810 --> 01:13:47,850 Así que hay que tomar la dirección de la misma debido a que el soporte es eliminar la referencia implícita. 839 01:13:47,850 --> 01:13:53,250 x [2] se refiere al valor que está en esta caja de texto, a continuación, desea que la dirección de la caja, 840 01:13:53,250 --> 01:13:56,850 por lo que dicen y x [2]. 841 01:13:56,850 --> 01:14:02,880 Así es como algo en especie de combinación en la que desea pasar la mitad de la lista a algo 842 01:14:02,880 --> 01:14:08,790 lo que realmente pasa & x [2], y ahora en cuanto a la llamada recursiva se refiere, 843 01:14:08,790 --> 01:14:12,510 mi nueva matriz comienza allí. 844 01:14:12,510 --> 01:14:15,130 Preguntas de última hora. 845 01:14:15,130 --> 01:14:20,050 [Estudiante] Si no ponemos un signo o un - ¿qué es eso llama? >> Star? 846 01:14:20,050 --> 01:14:23,200 [Estudiante] Estrellas. >> Técnicamente, el operador de indirección, pero - >> [estudiante] eliminación de referencias. 847 01:14:23,200 --> 01:14:29,310 >> Si no ponemos una estrella o un símbolo de unión, ¿qué pasa si acabo de decir y = x y x es un puntero? 848 01:14:29,310 --> 01:14:34,620 ¿Cuál es el tipo de y? >> [Estudiante] sólo voy a decir que es puntero 2. 849 01:14:34,620 --> 01:14:38,270 Así que si usted acaba de decir y = x, x ahora y punto y la misma cosa. >> [Estudiante] apuntan a la misma cosa. 850 01:14:38,270 --> 01:14:45,180 Y si x es un puntero int? Sería >> quejan porque no se puede asignar punteros. 851 01:14:45,180 --> 01:14:46,540 [Estudiante] Bueno. 852 01:14:46,540 --> 01:14:51,860 Recuerde que los punteros, a pesar de que dibujarlos como flechas, 853 01:14:51,860 --> 01:15:02,010 realmente todo lo que tienda - int * x - realmente todo x es el almacenamiento es algo así como ox100, 854 01:15:02,010 --> 01:15:06,490 que nos ha tocado representar como señalar al bloque almacenado a 100. 855 01:15:06,490 --> 01:15:19,660 Así que cuando digo int * y = x; sólo estoy copiando en ox100 y, 856 01:15:19,660 --> 01:15:24,630 que sólo vamos a representar y, también apunta a ox100. 857 01:15:24,630 --> 01:15:39,810 Y si digo int i = (int) x; entonces me va a almacenar cualquiera que sea el valor de ox100 es 858 01:15:39,810 --> 01:15:45,100 dentro de ella, pero ahora que va a ser interpretado como un entero en lugar de un puntero. 859 01:15:45,100 --> 01:15:49,310 Pero es necesario el yeso o de lo contrario se quejará. 860 01:15:49,310 --> 01:15:53,300 [Estudiante] Entonces, ¿te refieres a emitir - 861 01:15:53,300 --> 01:16:00,290 ¿Va a estar echando int x int o fundición de y? 862 01:16:00,290 --> 01:16:03,700 [Bowden] ¿Qué? 863 01:16:03,700 --> 01:16:07,690 [Estudiante] Bueno. Después de estos paréntesis se va a haber una xo ay allí? 864 01:16:07,690 --> 01:16:11,500 >> [Bowden] Cualquiera. x e y son equivalentes. >> [Estudiante] Bueno. 865 01:16:11,500 --> 01:16:14,390 Debido a que ambos son punteros. Sí >>. 866 01:16:14,390 --> 01:16:21,050 [Estudiante] Por lo que sería almacenar el 100 en forma hexadecimal entero? >> [Bowden] Yeah. 867 01:16:21,050 --> 01:16:23,620 Pero no es el valor de lo que apunta. 868 01:16:23,620 --> 01:16:29,940 [Bowden] Yeah. >> [Estudiante] Tan sólo la dirección en forma de número entero. Bien. 869 01:16:29,940 --> 01:16:34,720 [Bowden] Si desea por alguna extraña razón, 870 01:16:34,720 --> 01:16:38,900 usted podría tratar exclusivamente con los punteros y nunca tratar con números enteros 871 01:16:38,900 --> 01:16:49,240 y simplemente ser como int * x = 0. 872 01:16:49,240 --> 01:16:53,000 Luego te vas a quedar muy confundido una vez aritmética de punteros comienza a suceder. 873 01:16:53,000 --> 01:16:56,570 Así que los números que almacenan no tienen sentido. 874 01:16:56,570 --> 01:16:58,940 Sólo es como se llega a interpretarlos. 875 01:16:58,940 --> 01:17:02,920 Así que soy libre de copiar ox100 de un int * a un int, 876 01:17:02,920 --> 01:17:07,790 y yo soy libre de asignar - usted está probablemente va a gritar en fundición para no - 877 01:17:07,790 --> 01:17:18,160 Soy libre para asignar algo como (int *) ox1234 en este * int arbitraria. 878 01:17:18,160 --> 01:17:25,480 Así ox123 es tan válida como una dirección de memoria es & y. 879 01:17:25,480 --> 01:17:32,060 & Y pasa a devolver algo que es más o menos ox123. 880 01:17:32,060 --> 01:17:35,430 [Estudiante] que sería una forma genial de pasar de hexadecimal a formato decimal, 881 01:17:35,430 --> 01:17:39,230 como si usted tiene un puntero y lo echaron como un int? 882 01:17:39,230 --> 01:17:44,860 [Bowden] Puede realmente imprimir utilizando como printf. 883 01:17:44,860 --> 01:17:50,300 Digamos que tengo int y = 100. 884 01:17:50,300 --> 01:18:02,700 Así printf (% d \ n - como usted ya debe saber - que imprime en forma de entero x%. 885 01:18:02,700 --> 01:18:05,190 Vamos a imprimir como hexadecimal. 886 01:18:05,190 --> 01:18:10,760 Así que un puntero no se almacena como hexadecimal, 887 01:18:10,760 --> 01:18:12,960 y un número entero no se almacenan como decimal. 888 01:18:12,960 --> 01:18:14,700 Todo se almacena en forma binaria. 889 01:18:14,700 --> 01:18:17,950 Es sólo que tendemos a mostrar punteros como hexadecimal 890 01:18:17,950 --> 01:18:23,260 porque pensamos en las cosas en estos bloques de 4 bytes, 891 01:18:23,260 --> 01:18:25,390 y las direcciones de memoria tienden a ser familiar. 892 01:18:25,390 --> 01:18:28,890 Somos como, si comienza con bf, a continuación, pasa a ser en la pila. 893 01:18:28,890 --> 01:18:35,560 Así que es sólo nuestra interpretación de punteros como hexadecimal. 894 01:18:35,560 --> 01:18:39,200 Bien. Las últimas preguntas? 895 01:18:39,200 --> 01:18:41,700 >> Voy a estar aquí por un poco después si usted tiene cualquier otra cosa. 896 01:18:41,700 --> 01:18:46,070 Y ese es el final de todo. 897 01:18:46,070 --> 01:18:48,360 >> [Estudiante] Yay! [Aplauso] 898 01:18:51,440 --> 01:18:53,000 >> [CS50.TV]