>> [REPRODUCCIÓN DE MÚSICA]
>> DOUG LLOYD: Punteros, aquí estamos.
Esta es, probablemente, va a será el tema más difícil
que se habla en el CS50.
Y si has leído nada de apuntadores
antes de que usted puede ser que sea un poco intimidante entrar en este video.
Es cierto los punteros ¿Permite la capacidad
atornillar quizás hasta bastante mal cuando estás
trabajar con variables, y los datos, y haciendo que su programa se bloquee.
Pero en realidad son realmente útiles y nos realmente una gran manera permiten
para pasar los datos hacia atrás y vuelta entre funciones,
que somos de otro modo no puede hacer.
>> Y así lo que realmente quiero hacer aquí es el tren
le permite tener una buena disciplina puntero, por lo que puede utilizar punteros con eficacia
para hacer sus programas que mucho mejor.
Como dije punteros nos dan una diferente manera de pasar los datos entre funciones.
Ahora bien, si usted recuerda de un video anterior, cuando
hablábamos ámbito de variable, mencioné
que todos los datos que se pasa entre funciones en C se pasan por valor.
Y puede que no he usado esa plazo, lo que significaba que
fue que estamos pasando copias de los datos.
Cuando se pasa una variable a una función, no estamos en realidad pasa la variable
a la función, ¿no?
Estamos pasando una copia de que los datos a la función.
La función hace lo que hará y se calcula un valor,
y tal vez usamos ese valor cuando se le da la espalda.
>> Hubo una excepción a esta regla de pasar por valor,
y vamos a volver a lo que es un poco más adelante en este video.
Si utilizamos punteros lugar de utilizar variables,
o en lugar de utilizar las variables ellos mismos o copias de las variables,
ahora podemos pasar a las variables en torno entre las funciones de una manera diferente.
Esto significa que si hacemos un cambio en una función,
que el cambio realmente tomar efectuar en una función diferente.
Una vez más, esto es algo que no podíamos hacer antes,
y si alguna vez has tratado de cambiar la valor de dos variables en una función,
usted ha notado este problema especie de reptil, ¿verdad?
>> Si queremos cambiar X e Y, y pasarlos a una función llamada swap,
dentro de la función de cambiar el variables que hacen los valores de cambio.
Uno se convierte en dos, dos se convierte en uno, pero no lo hacemos realidad
cambiar nada en el original función, en la persona que llama.
Porque no podemos, estamos solamente trabajar con copias de los mismos.
Con punteros embargo, podemos en realidad pasar X e Y a una función.
Esa función puede hacer algo con ellos.
Y los valores de las variables en realidad puede cambiar.
Así que eso es un gran cambio en nuestra capacidad para trabajar con datos.
>> Antes de sumergirse en punteros, creo que vale la pena
tomar un par de minutos a volver a lo básico aquí.
Y echar un vistazo a cómo obras de memoria para computadoras
porque estos dos temas van para ser realmente muy relacionados entre sí.
Como probablemente sabes, en su sistema informático
Tiene un disco duro o tal vez una unidad de estado sólido,
una especie de lugar de almacenamiento de archivos.
Por lo general es un lugar en el vecindad de 250 gigabytes
que tal vez un par de terabytes ahora.
Y es donde todos los de su archivos viven en última instancia,
incluso cuando el ordenador está apagado apagado, puede volver a encenderlo
y usted encontrará los archivos están ahí de nuevo al reiniciar el sistema.
Pero las unidades de disco, como una unidad de disco duro, un disco duro o una unidad de estado sólido, un SSD,
son el espacio de almacenamiento justo.
>> En realidad no podemos hacer nada con los datos que se encuentra en el disco duro,
o en una unidad de estado sólido.
Con el fin de cambiar realmente de datos o moverlo,
tenemos que moverlo a RAM, memoria de acceso aleatorio.
Ahora RAM, usted tiene un montón menos en su ordenador.
Es posible que en algún lugar del barrio de 512 megabytes
si usted tiene un ordenador antiguo, que tal vez dos, cuatro, ocho, 16,
posiblemente incluso un poco más, gigabytes de RAM.
Así que eso es mucho más pequeño, pero eso es donde todos los datos volátiles existe.
Ahí es donde podemos cambiar las cosas.
Pero cuando nos volvemos nuestro ordenador apagado, todos los datos en la RAM se destruye.
>> Así que por eso tenemos que tener el disco duro para la ubicación más permanente de la misma,
de modo que existe- que lo haría ser realmente malo si cada vez que
convertido a nuestro ordenador apagado, cada archivo en nuestro sistema fue borrada.
Así que trabajamos dentro de RAM.
Y cada vez que estamos hablando de memoria, más o menos, en el CS50,
estamos hablando de RAM, no disco duro.
>> Así que cuando nos movemos cosas en la memoria, que ocupa una cierta cantidad de espacio.
Todos los tipos de datos que hemos estado trabajando con
asumir diferentes cantidades de espacio en la RAM.
Así que cada vez que cree un entero variables, cuatro bytes de memoria
se dejan de lado en la memoria RAM para que puede trabajar con ese entero.
Puede declarar el número entero, cambiarlo, asignarlo
a un valor de 10 incrementado por uno, así sucesivamente y así sucesivamente.
Todo lo que tiene que ocurrir en RAM, y se obtiene cuatro bytes
para trabajar con para cada entero que usted cree.
>> Cada carácter que crear consigue un byte.
Eso es sólo la cantidad de espacio necesaria para almacenar un carácter.
Cada flotador, un verdadero número, obtiene cuatro bytes
a menos que sea un doble punto flotante de precisión
número, que le permite tener dígitos más precisas o más
después del punto decimal sin perder precisión,
que tomar hasta ocho bytes de memoria.
Anhela largos, realmente grandes números enteros, También tomar hasta ocho bytes de memoria.
¿Cuántos bytes de memoria Qué cadenas ocupan?
Bueno vamos a poner un alfiler en esa pregunta por ahora, pero vamos a volver a ella.
>> Así que de vuelta a esta idea de la memoria como una gran variedad de células bytes de tamaño.
Eso es realmente todo lo que es, es sólo una enorme variedad de células,
al igual que cualquier otra matriz que usted está familiarizado con y ver,
excepto cada elemento es un byte de ancho.
Y al igual que una matriz, cada elemento tiene una dirección.
Cada elemento de una matriz tiene un índice, y nosotros
puede utilizar ese índice para hacer la llamada acceso aleatorio en la matriz.
No tenemos que empezar por el principio de la matriz,
iterar a través de todos los solo elemento de la misma,
para encontrar lo que estamos buscando.
Sólo podemos decir que quiero llegar al Elemento 15a o el elemento número 100.
Y que sólo puede pasar en ese número y obtener el valor que usted está buscando.
>> Del mismo modo cada localización en la memoria tiene una dirección.
Así que su memoria podría algo como esto.
Aquí hay una muy pequeña parte de memoria, esta es de 20 bytes de memoria.
Los primeros 20 bytes porque mi aborda hay en la parte inferior
son 0, 1, 2, 3, y así en todo el camino hasta el 19.
Y cuando me declaro variables, y cuando empiezo a trabajar con ellos,
el sistema se va a establecer de lado un poco de espacio para mí
en esta memoria para trabajar con mis variables.
Así que podría decir, char c es igual a la capital H. ¿Y qué va a pasar?
Bueno, el sistema va a reservado para mí un byte.
En este caso se eligió el número de bytes cuatro, el byte en la dirección de cuatro,
y que va a almacenar el letra mayúscula H en allí para mí.
Pues si yo digo velocidad int límite es igual a 65, que es
va a dejar de lado las cuatro bytes de memoria para mí.
Y que va a tratar a las personas cuatro bytes como una sola unidad
porque lo que estamos trabajando con un entero aquí.
Y que va a almacenar 65 en ese país.
>> Ahora ya estoy un poco que le dice un poco de una mentira,
derecha, porque sabemos que ordenadores funcionan en binario.
Ellos no entienden necesariamente lo mayúscula es
o lo que es un 65, es decir, que sólo entienden el binario, ceros y unos.
Y lo que en realidad lo que estamos almacenando allí
no es la letra H y el número 65, sino más bien las representaciones binarias
del mismo, que busque un poco algo como esto.
Y, en particular en el contexto de la variable de número entero,
no va a simplemente escupir en, no va a tratarlo como uno de cuatro
trozo byte necesariamente, en realidad está pasando
tratarlo como cuatro trozos de un byte, que podría ser algo como esto.
E incluso esto no es todo cierto tampoco,
debido a algo llamado un endianness, que no estamos
va a entrar en este momento, pero si eres curioso acerca de,
se puede leer en poco y grandes endianness.
Pero por el bien de este argumento, por el bien de este video,
vamos a suponer que es, en De hecho, cómo el número 65 lo haría
estar representados en memoria en todos los sistemas,
aunque no es del todo cierto.
>> Pero seamos en realidad sólo consiguen deshacerse de todos binario completo,
y sólo pensar en como H y el 65, que es mucho más fácil
pensar en ello como que como ser humano.
Muy bien, por lo que también parece tal vez un poco aleatorio que I've- mi sistema
no me dio bytes 5, 6, 7, y 8 para almacenar el número entero.
Hay una razón para eso, también, que no vamos a entrar en este momento, pero suficiente
con decir que lo que el equipo está haciendo aquí
es probablemente una buena jugada de su parte.
Para no darme memoria que es copia necesariamente con espalda.
A pesar de que va a hacerlo ahora si quiero tener otra cadena,
Llamé apellido, y quiero poner Lloyd allí.
Voy a tener que adaptarse a un solo carácter, cada letra que es
va a requerir de un carácter, un byte de memoria.
Así que si podía poner Lloyd en mi arsenal como esto soy bastante bueno para ir, ¿verdad?
¿Lo que falta?
>> Recuerde que cada cadena trabajamos con en C termina con barra invertida cero,
y no podemos omitir que aquí, tampoco.
Tenemos que dejar de lado un byte de memoria para sostener que lo que
saber cuándo nuestra cadena ha terminado.
Así que de nuevo este acuerdo de las cosas
aparecerá en la fuerza de la memoria ser un poco al azar,
pero en realidad es cómo la mayoría de los sistemas están diseñados.
Para alinearlos en múltiplos de cuatro, por razones de nuevo
que no necesitamos entrar en este momento.
Pero esto, por lo que basta con decir que después de estas tres líneas de código,
esto es lo que la memoria podría ser similar.
Si necesito posiciones de memoria 4, 8 y 12 para sujetar mis datos,
esto es lo que mi memoria podría ser similar.
>> Y sólo ser particularmente pedante aquí, cuando
estamos hablando de la memoria direcciones Solemos
hacerlo usando notaciones hexadecimales.
Entonces, ¿por qué no nos convertimos todos estos de decimal a notación hexadecimal
simplemente porque eso es en general cómo nos referimos a la memoria.
Así que en lugar de ser de 0 a 19, lo que tenemos es cero
x cero por cero x1 tres.
Esos son los 20 bytes de memoria que hemos o estamos viendo en esta imagen
aquí.
>> Así que todo lo que se dice, vamos a alejarse de la memoria por un segundo
y de nuevo a los punteros.
Aquí es el más importante cosa para recordar
a medida que comenzamos a trabajar con punteros.
Un puntero es nada más de una dirección.
Lo diré otra vez porque que es tan importante,
un puntero no es nada más de una dirección.
Los punteros son direcciones a lugares en la memoria donde viven variables.
Sabiendo que se hace de esperar un poco más fácil trabajar con ellos.
Otra cosa que me gusta que hacer es tener suerte
de los diagramas de representar visualmente lo que es pasando con varias líneas de código.
Y vamos a hacer esto un par de veces en los punteros,
y cuando hablamos de dinámica asignación de memoria también.
Porque creo que estos diagramas puede ser particularmente útil.
>> Así que si yo digo por ejemplo, int k en mi código, ¿qué está sucediendo?
Bueno lo que está sucediendo es, básicamente, Me estoy poniendo de memoria reservado para mí,
pero ni siquiera me gusta pienso así, yo
gustaría pensar en ello como una caja.
Tengo una caja y es de color verde porque
puede poner números enteros en cajas verdes.
Si se trataba de un personaje que podría tener un cuadro azul.
Pero yo siempre digo, si yo estoy creando una caja que puede contener números enteros
esa caja es de color verde.
Y tomo un marcador permanente y escribo k en el lado de la misma.
Así que tengo una caja llamada k, en la que puedo poner enteros.
Así que cuando digo int k, eso es lo que pasa en mi cabeza.
Si digo k es igual a cinco, ¿qué estoy haciendo?
Bueno, me voy a poner de cinco en el cuadro, la derecha.
Esto es bastante sencillo, si Digo int k, crear un cuadro llamado k.
Si digo k es igual a 5, puso cinco en la caja.
Esperemos que eso no es demasiado de un salto.
Aquí es donde las cosas van un poco interesante.
Si digo int * pk, bien incluso si no lo hago sabe lo que esto significa necesariamente,
Es claramente tiene algo que ver con un entero.
Así que voy a colorear esta caja verde-ish,
Sé que tiene algo que ver con un entero,
pero no es un número entero en sí, porque es un int estrellas.
Hay algo un poco diferente al respecto.
Así involucrados de un entero, pero por lo demás es
no muy diferente de lo que estábamos hablando.
Es una caja, su tiene una etiqueta, que lleva un pk etiqueta,
y es capaz de tenencia estrellas int, lo que son.
Tienen algo que ver con números enteros, con claridad.
Aquí está la última línea sin embargo.
Si digo pk = & k, espera, lo que acaba de suceder, ¿verdad?
Así que este número al azar, aparentemente al azar número, se tira en el cuadro de allí.
Todo lo que es, es pk obtiene la dirección de k.
Así que me quedo donde k vive en la memoria, su dirección, la dirección de sus bytes.
Todo lo que estoy haciendo es lo que digo que el valor es lo que voy
para poner dentro de mi caja llamada pk.
Y porque estas cosas son punteros, y porque busca
en una cadena como cero x ocho cero c siete cuatro y ocho
dos cero es, probablemente, no es muy significativa.
Cuando visualizamos general punteros, que en realidad hacemos como punteros.
Pk nos da la información tenemos que encontrar k en la memoria.
Así que, básicamente pk tiene una flecha en él.
Y si caminamos la longitud de esa flecha, imagínese
es algo que se puede caminar, si caminar a lo largo de la longitud de la flecha,
en la punta de la flecha, que será encontrar la ubicación en la memoria
donde k vive.
Y eso es realmente importante porque una vez que sabemos que k vive,
podemos empezar a trabajar con los datos dentro de esa posición de memoria.
A pesar de que estamos recibiendo un pequeñito poco por delante de nosotros por ahora.
>> Entonces, ¿qué es un puntero?
Un puntero es un elemento de datos cuyo valor es una dirección de memoria.
Esa fue que el cero x ocho cero cosas pasando, que era una dirección de memoria.
Esa fue una ubicación en la memoria.
Y el tipo de un puntero describe el tipo
de los datos que encontrará en esa dirección de memoria.
Así que la parte derecha int estrellas.
Si sigo esa flecha, es me va a llevar a una ubicación.
Y ese lugar, lo que encontrarán allí en mi ejemplo,
es un cuadro de color verde.
Es un entero, eso es lo que encontrarán si voy a esa dirección.
El tipo de datos de un puntero describe lo
se encuentra en esa dirección de memoria.
Así que aquí está la cosa muy fresco sin embargo.
Punteros nos permiten pasar variables entre funciones.
Y en realidad pasar variables y no pasar copias de ellos.
Porque si sabemos exactamente dónde en memoria para encontrar una variable,
no necesitamos hacer una copia de ella, que sólo puede ir a ese lugar
y trabajar con esa variable.
Así que en esencia punteros especie de hacer un entorno informático
mucho más como el mundo real, a la derecha.
>> Así que aquí está una analogía.
Digamos que tengo un cuaderno, derecha, y está lleno de notas.
Y me gustaría que actualizarlo.
Usted es una función que Actualizaciones de notas, derecha.
En la forma en que hemos estado trabajando hasta ahora, lo que
que pasa es que usted tome mi cuaderno, te vas a la tienda de copia,
que va a hacer una copia de Xerox cada página del cuaderno.
Vas a dejar mi libreta de vuelta en mi escritorio cuando haya terminado,
irás y tachar cosas en mi cuaderno que están fuera de fecha o erróneo,
y luego pasará de nuevo a me la pila de páginas Xerox
que es una réplica de mi portátil con los cambios que usted ha hecho a ella.
Y en ese punto, le toca a mí como la función de llamada, ya que la persona que llama,
al decidir tomar sus notas y integrarlos de nuevo en mi cuaderno.
Así que hay un montón de pasos involucrado aquí, a la derecha.
Al igual que ¿no sería mejor si acabo de decir, bueno, ¿verdad
actualizar mi cuaderno para yo, que entrego mi cuaderno,
y se toma las cosas y cruzar literalmente fuera
y actualizar mis notas en mi cuaderno.
Y luego me dan mi cuaderno espalda.
Eso es algo de lo que punteros nos permiten hacer,
que hacen de este entorno mucho más como la forma en que operamos en la realidad.
>> Está bien así que eso es lo que un puntero está, vamos a hablar
acerca de cómo funcionan los punteros en C, y cómo podemos empezar a trabajar con ellos.
Así que hay una muy simple puntero en C llamado el puntero nulo.
Los puntos de puntero nulo a nada.
Esto probablemente parece que es En realidad no es una cosa muy útil,
pero como veremos un poco más adelante, el hecho de
la existencia de este puntero nulo realmente realmente puede ser útil.
Y cada vez que se crea un puntero y no establece su valor de inmediato-
un ejemplo de configuración su valor inmediatamente
será un par de diapositivas de regreso donde dije pk es igual a & k,
pk obtiene la dirección de k, como vamos a ver lo que eso significa,
vamos a ver cómo el código que shortly- si no establecemos su valor a algo
inmediatamente significativo, siempre debe
establecer el puntero para apuntar a null.
Usted debe configurarlo para que apunte a nada.
>> Eso es muy diferente a simplemente dejando el valor ya que es
y luego declarar una puntero y acaba asumiendo
es nula porque es rara vez es cierto.
Así que siempre se debe establecer el valor de un puntero
null si no se establece su valor a algo significativo inmediatamente.
Puede comprobar si el valor de un puntero es nulo utilizando el operador de igualdad
(==), Al igual que se compara cualquier entero valores o valores de caracteres utilizando (==)
así como.
Es un tipo especial de constante valor que se puede utilizar para probar.
Así que fue una muy simple puntero, el puntero nulo.
Otra forma de crear un puntero es extraer
la dirección de una variable ya ha creado,
y lo hace utilizando la Y extracción dirección del operador.
Que ya hemos visto con anterioridad en el primer ejemplo diagrama mostré.
Así que si x es una variable que hemos ya creado de tipo entero,
a continuación, y x es un puntero a un entero.
y x es- recuerdan, y se va a extraer la dirección de la cosa a la derecha.
Y puesto que un puntero es sólo una dirección, que y x es un puntero a un entero
cuyo valor es donde en la memoria x vidas.
Es la dirección de x.
Así y x es la dirección de x.
Echemos un paso más allá y conectar a algo
He aludido en un video anterior.
Si arr es una matriz de dobles, a continuación, y corchete arr i es un puntero
a una doble.
OK.
arr corchete i, si arr es una matriz de dobles,
luego arr corchete i es el elemento i de esa matriz,
y Y arr corchete i es donde en existe el elemento i de arr memoria.
>> ¿Cuál es la implicación aquí?
Un nombre de matrices, la implicación de todo este asunto,
es que el nombre de una matriz es en realidad sí mismo un puntero.
Usted ha estado trabajando con punteros a lo largo
cada vez que usted ha utilizado una matriz.
Recuerde el ejemplo el ámbito de las variables,
cerca del final del video que presento un ejemplo en el que tenemos una función
llamada int set y un función llamada matriz de conjuntos.
Y su reto para determinar si o no, o lo que el
valores que imprime el final de la función,
al final del programa principal.
>> Si usted recuerda de ese ejemplo o si has visto el video,
usted sabe que cuando Tú- la llamada a conjunto int hace efectivamente nada.
Pero la llamada para establecer matriz hace.
Y en cierto modo me pasó por alto por qué ese fue el caso en el momento.
Que acabo de decir, así que es una matriz, que es especial, ya sabes, hay una razón.
La razón es que una matriz de nombre es en realidad sólo un puntero,
y hay este especial sintaxis de corchete que
hacer las cosas mucho más agradable para trabajar.
Y hacen la idea de un puntero mucho menos intimidante,
y es por eso que son una especie de presentado de esa manera.
Pero en realidad las matrices son punteros.
Y por eso cuando nos hecho un cambio en la matriz,
cuando pasamos una matriz como un parámetro a una función o como un argumento
a una función, el contenido de la matriz en realidad cambiado tanto en el destinatario de la llamada
y en la persona que llama.
Lo que para cualquier otro tipo de variables que vimos no fue el caso.
Así que eso es algo a tener en mente cuando se trabaja con punteros,
es que el nombre de un array en realidad un puntero
al primer elemento de la matriz.
>> Aceptar lo que ahora tenemos todos estos hechos, vamos a seguir adelante, a la derecha.
¿Por qué nos preocupamos donde algo vive.
Bueno, como he dicho, es bastante útil saber donde algo vive
por lo que puede ir allí y cambiarlo.
Trabajar con él y, de hecho tener la cosa que usted
quiere hacer en este sentido toma variables, y no tomar efecto en alguna copia de la misma.
Esto se llama eliminación de referencias.
Nos vamos a la referencia y cambiamos el valor allí.
Así que si tenemos un puntero y se llama pc, y apunta a un personaje,
entonces podemos decir * * PC y PC es el nombre de lo que encontraremos si vamos
a la dirección de PC.
¿Qué vamos a encontrar que hay un personaje y * PC es como nos referimos a los datos en ese
localización.
Así que podríamos decir algo como * pc = D o algo por el estilo,
y eso significa que todo lo que fue en memoria de direcciones de la PC,
cualquier carácter era previamente allí, ahora es D, si decimos * pc = D.
>> Así que aquí vamos de nuevo con algunas cosas raras C, derecha.
Así que hemos visto anteriormente como * de alguna manera parte del tipo de datos,
y ahora se está utilizando en un contexto ligeramente diferente
para acceder a los datos en una ubicación.
Sé que es un poco confuso y eso es en realidad parte de este todo
al igual que, ¿por qué punteros tienen esta mitología alrededor de ellos por ser tan complejo,
es una especie de problema de sintaxis, la verdad.
Pero * se utiliza en ambos contextos, tanto como parte del nombre de tipo,
y vamos a ver un poco algo más tarde lo demás, también.
Y ahora mismo es el operador de eliminar la referencia.
Así que va a la referencia, se accede a los datos
en la ubicación del puntero, y le permite manipular a voluntad.
>> Ahora bien, esto es muy similar a visitar a su vecino, a la derecha.
Si usted sabe lo que su vecino vive, usted es
no salir con su vecino.
Usted sabe usted sucede saber dónde viven,
pero eso no quiere decir que por virtud de tener ese conocimiento
está interactuando con ellos.
Si desea interactuar con ellos, usted tiene que ir a su casa,
tienes que ir a donde viven.
Y una vez que lo haces, entonces usted puede interactuar
con ellos al igual que querrías.
Y de manera similar con las variables, tienes que ir a su domicilio
si quieres interactuar ellos, uno no puede saber la dirección.
Y la manera de ir a la dirección es de usar *, el operador eliminar la referencia.
¿Qué crees que sucede si tratamos de eliminar la referencia
un puntero cuyo valor es nulo?
Recordemos que la hipótesis nula puntero apunta a nada.
Así que si usted trata de eliminar la referencia nada o ir a una dirección de nada,
¿qué crees que sucede?
Segmentación Bueno, si usted lo adivinó culpa, estaríamos en lo cierto.
Si tratas de eliminar la referencia un puntero nulo,
usted sufre una segmentación culpa. Pero espera,
No te digo, que si no vas
para establecer su valor de su Puntero a algo significativo,
debe establecer en nulo?
Lo hice y realmente la segmentación culpa es una especie de buen comportamiento.
>> ¿Alguna vez ha declarado una variable y No asignado su valor de inmediato?
Así que usted acaba de decir int x; no lo hace realidad asignarla a nada
y más tarde en su código, imprima el valor de x,
Todavía no tener es asignado a nada.
Frecuentes que obtendrá cero, pero a veces
podría conseguir algo de números aleatorios, y usted no tiene idea de dónde vino.
Del mismo modo puede cosas pasar con punteros.
Cuando se declara un puntero int * pk por ejemplo,
y no se asigna a un valor, usted consigue cuatro bytes para la memoria.
Cualesquiera que sean cuatro bytes de la memoria del sistema puede
encontrar que tienen algún valor significativo.
Y podría haber habido algo que ya existe que
ya no es necesaria por otro función, por lo que sólo tiene
todos los datos que estaba allí.
>> Lo que si se trató de hacer dereference alguna dirección que no- había
ya bytes e información en allí, eso es ahora en el puntero.
Si tratas de eliminar la referencia de ese puntero, usted podría estar metiendo con algo de memoria
que no tenía intención meterse con todo.
Y, de hecho, usted podría hacer algo realmente devastador,
como romper otro programa, o romper otra función,
o hacer algo malicioso que que no tiene la intención de hacerlo en absoluto.
Y por eso es realmente una buena idea
para establecer sus punteros a null si no les establece en algo significativo.
Es probablemente mejor en el final del día para su programa
a estrellarse a continuación para que lo haga algo que mete la pata
otro programa u otra función.
Ese comportamiento es probablemente aún menos ideal que sólo estrellarse.
Y por eso es en realidad un buen hábito
para entrar en establecer sus punteros null si no se establece que
a un valor significativo de inmediato, un valor que usted sabe
y que usted puede de manera segura al eliminar la referencia.
>> Así que volvamos ahora y echar un vistazo en la sintaxis general de la situación.
Si digo int * p ;, lo que he acabo de hacer?
Lo que he hecho es esto.
Sé que el valor de p es una dirección porque todos los indicadores son sólo
direcciones.
Puedo eliminar la referencia p usando el operador *.
En este contexto aquí, en el muy superior recordar la * forma parte del tipo.
Int * es el tipo de datos.
Pero no puedo eliminar la referencia p usando el operador *,
y si lo hago, si me voy a esa dirección, lo que voy a encontrar en esa dirección?
Voy a encontrar un entero.
Así int * p es básicamente diciendo: p es una dirección.
Puedo eliminar la referencia p y si Lo hago, voy a encontrar un entero
en esa ubicación de memoria.
>> OK, así que dijo que había otro cosa molesta con las estrellas
y aquí es donde que cosa molesta con las estrellas es.
¿Alguna vez ha tratado de declarar múltiples variables del mismo tipo
en la misma línea de código?
Así que por un segundo, pretender que la línea, el código realidad tengo allí en verde
No está ahí y sólo dice int x, y, z ;.
Lo que haría es en realidad crear tres variables enteras para usted,
uno llamado x, uno llamado y, y uno llamado z.
Es una manera de hacerlo sin tener que dividir en tres líneas.
>> Aquí es donde las estrellas obtienen molesto otra vez sin embargo,
porque el * es en realidad parte tanto el nombre del tipo y parte
del nombre de la variable.
Y por lo que si te digo int * px, py, pz, lo que conseguir realmente es un puntero a un entero
llamado px y dos números enteros, py y pz.
Y eso probablemente no lo es que queremos, eso no es bueno.
>> Así que si quiero crear múltiples punteros en la misma línea, del mismo tipo,
y las estrellas, lo que realmente necesita que hacer es decir int * pa, * pb, * pc.
Ahora que acaba de decir que y ahora usted esta diciendo,
usted probablemente nunca va a hacer esto.
Y es probablemente una buena cosa, sinceramente, porque es posible que inadvertidamente
omitir una estrella, algo así.
Es probablemente el mejor para declarar tal vez indicaciones sobre las líneas individuales,
pero es sólo otro de los sintaxis molesto
cosas con las estrellas que hacen punteros tan difícil de trabajar.
Porque es precisamente esta sintáctica lío que tiene que trabajar a través.
Con la práctica lo hace realmente convertido en una segunda naturaleza.
Todavía cometo errores con él todavía después de la programación durante 10 años,
así que no se preocupe si pasa algo a usted, que es bastante común con honestidad.
Es muy amable de un defecto de la sintaxis.
>> Aceptar así que tipo de prometí que íbamos a volver
el concepto de qué tan grande es una cadena.
Bueno si te dijera que un cadena, tenemos muy amable de
estado mintiendo todo el tiempo.
No hay ningún tipo de datos llamado cadena, y de hecho
mencionado esto en una de nuestras primeros videos sobre tipos de datos,
esa cadena era un tipo de datos que fue creado por usted en CS50.h.
Tienes que #include CS50.h con el fin de usarlo.
>> Bueno cadena es realmente sólo un alias para algo
llamado el char *, un Puntero a un personaje.
Bueno punteros, el recuerdo, son sólo aborda.
Entonces, ¿cuál es el tamaño en bytes de una cadena?
Bueno, es de cuatro u ocho.
Y la razón por la que decir cuatro o ocho es porque en realidad
depende del sistema, Si está utilizando Ide CS50, char * es el tamaño de un char
* Es de ocho, que es un sistema de 64 bits.
Cada dirección en la memoria es de 64 bits de longitud.
Si utilizas aparato CS50 o el uso de cualquier máquina de 32 bits,
y usted ha oído ese término de 32 bits máquina, lo que es una máquina de 32 bits?
Bueno, sólo significa que cada dirección en la memoria es de 32 bits de longitud.
Y así 32 bits es de cuatro bytes.
Así que un char * es de cuatro u ocho bytes en función del sistema.
Y de hecho cualquier tipo de datos, y un puntero a los datos
escriba, ya que todos los punteros son sólo direcciones, cuatro u ocho bytes.
Así que vamos a revisar este Diagrama y vamos a llegar a la conclusión
este video con un poco de ejercicio aquí.
Así que aquí está el diagrama lo dejamos con en el comienzo del vídeo.
Entonces, ¿qué pasa ahora si digo * pk = 35?
Así que, ¿qué significa cuando digo, * pk = 35?
Tome un segundo.
* pk.
En el contexto aquí, * es operador de eliminar la referencia.
Así que cuando el dereference se utiliza operador,
vamos a la dirección apuntada por pk y cambiamos lo que encontramos.
Así * pk = 35 con eficacia Hace esto a la imagen.
Así que es básicamente sintácticamente idéntico al de haber dicho k = 35.
>> Uno mas.
Si digo int m, creo una nueva variable llamada m.
Una nueva caja, que es una caja verde porque que va a contener un número entero,
y está etiquetada m.
Si digo m = 4, puse un entero en esa caja.
Si por ejemplo pk = & m, ¿cómo lo hace este cambio diagrama?
Pk = & m, ¿recuerda lo que el Y el operador hace o se llama?
Recuerde que y algún nombre de variable es la dirección de un nombre de variable.
Así que lo que estamos diciendo es pk obtiene la dirección del m.
Y así efectivamente lo que sucede el diagrama es que ya no pk puntos
ak, pero apunta a m.
>> Una vez más punteros son muy difícil de trabajar con
y toman una gran cantidad de práctica, sino porque
de su capacidad de permitir que para pasar los datos entre las funciones
y en realidad tienen los los cambios surtan efecto,
conseguir su cabeza alrededor que es realmente importante.
Es probablemente el más complicado tema se discute en el CS50,
pero el valor que llegar desde el uso de punteros
es mucho mayor que las complicaciones que provienen de aprenderlas.
Así que le deseo la mejor de suerte aprendiendo sobre punteros.
Soy Doug Lloyd, esto es CS50.