punteros
Diferencias
Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anteriorRevisión previaPróxima revisión | Revisión previa | ||
| punteros [2014/03/27 13:12] – [Cast de punteros] lmateu | punteros [2021/09/22 20:07] (actual) – [Big endian vs. Little endian] lmateu | ||
|---|---|---|---|
| Línea 1: | Línea 1: | ||
| - | ===== Punteros ===== | + | ====== Punteros |
| Además del identificador de las variables globales o automáticas, | Además del identificador de las variables globales o automáticas, | ||
| Línea 16: | Línea 16: | ||
| Para no entrar a usar valores numéricos de la direcciones en memoria graficaremos una dirección simplemente como una flecha hacia la variable de destino. | Para no entrar a usar valores numéricos de la direcciones en memoria graficaremos una dirección simplemente como una flecha hacia la variable de destino. | ||
| - | ==== Desreferencia ==== | + | ===== Desreferencia |
| El operador unario de prefijo ' | El operador unario de prefijo ' | ||
| Línea 44: | Línea 44: | ||
| {{ : | {{ : | ||
| - | ==== Declaración de punteros con valor inicial ==== | + | ===== Declaración de punteros con valor inicial |
| Al igual que con cualquier variable, al declarar un puntero es posible darle un valor inicial. | Al igual que con cualquier variable, al declarar un puntero es posible darle un valor inicial. | ||
| Línea 59: | Línea 59: | ||
| Por otra parte, en la asignación //*p= 2//, el asterisco sí es el operador de desreferencia y por lo tanto se está cambiando //a//, no //p//. | Por otra parte, en la asignación //*p= 2//, el asterisco sí es el operador de desreferencia y por lo tanto se está cambiando //a//, no //p//. | ||
| - | ==== Ejemplo: función que intercambia los valores de 2 variables ==== | + | ===== Ejemplo: función que intercambia los valores de 2 variables |
| Al igual que en los métodos de Java, los parámetros de las funciones de C se pasan por valor. | Al igual que en los métodos de Java, los parámetros de las funciones de C se pasan por valor. | ||
| Línea 103: | Línea 103: | ||
| Escriba la función swap_double que intercambia valores de variables de tipo double. | Escriba la función swap_double que intercambia valores de variables de tipo double. | ||
| - | === Función que intercambia las direcciones de 2 punteros === | + | ===== Función que intercambia las direcciones de 2 punteros |
| Suponga que ahora tiene este código: | Suponga que ahora tiene este código: | ||
| Línea 110: | Línea 110: | ||
| int main() { | int main() { | ||
| int a= 1, b= 2; | int a= 1, b= 2; | ||
| - | int *px= &a, *py= &b; | + | int *pa= &a, *pb= &b; |
| swap_ptr(& | swap_ptr(& | ||
| } | } | ||
| </ | </ | ||
| - | Ahora se busca que después de invocar swap_ptr, //px// apunte a //b// y //py// apunte a // | + | Ahora se busca que después de invocar swap_ptr, //pa// apunte a //b// y //pb// apunte a // |
| < | < | ||
| Línea 132: | Línea 132: | ||
| Por lo tanto al asignar //*p= *q// se está cambiando el valor de px en el llamador (main). | Por lo tanto al asignar //*p= *q// se está cambiando el valor de px en el llamador (main). | ||
| - | === Como entender la declaración de punteros === | + | ===== Como entender la declaración de punteros |
| Hay que confesar que la declaración de un puntero simple //int *p// o uno doble //int %%**%%q// no suena natural. | Hay que confesar que la declaración de un puntero simple //int *p// o uno doble //int %%**%%q// no suena natural. | ||
| Línea 149: | Línea 149: | ||
| * Escriba la función swap_ptr_ptr que intercambia 2 variables de tipo // | * Escriba la función swap_ptr_ptr que intercambia 2 variables de tipo // | ||
| - | ==== Comparación de punteros ==== | + | ===== Comparación de punteros |
| Se puede determinar si 2 punteros apuntan a la misma variable comparando ambos punteros con los operadores binarios == y !=. Vea este ejemplo: | Se puede determinar si 2 punteros apuntan a la misma variable comparando ambos punteros con los operadores binarios == y !=. Vea este ejemplo: | ||
| Línea 183: | Línea 183: | ||
| Aun cuando p!=r, sí se cumple que *p == *r porque en el segundo caso se comparan los valores almacenados en las variables. | Aun cuando p!=r, sí se cumple que *p == *r porque en el segundo caso se comparan los valores almacenados en las variables. | ||
| - | ==== El puntero nulo ==== | + | ===== El puntero nulo ===== |
| Al declarar variables automáticas sin inicialización, | Al declarar variables automáticas sin inicialización, | ||
| Línea 207: | Línea 207: | ||
| No es válido acceder a la dirección NULL en un proceso y por lo tanto si se desreferencia un puntero nulo se produce el error // | No es válido acceder a la dirección NULL en un proceso y por lo tanto si se desreferencia un puntero nulo se produce el error // | ||
| - | ==== Punteros locos ==== | + | ===== Punteros locos ===== |
| El tipo del valor retornado por la siguiente función es un puntero. | El tipo del valor retornado por la siguiente función es un puntero. | ||
| Línea 246: | Línea 246: | ||
| } | } | ||
| </ | </ | ||
| - | ==== Variables dinámicas ==== | + | ===== Variables dinámicas: malloc/free ===== |
| Una variable dinámica se crea explícitamente llamando a la función malloc. | Una variable dinámica se crea explícitamente llamando a la función malloc. | ||
| Línea 263: | Línea 263: | ||
| printf(" | printf(" | ||
| free(p); | free(p); | ||
| + | return 0; | ||
| } | } | ||
| </ | </ | ||
| Línea 274: | Línea 275: | ||
| Las variables dinámicas se crean en una zona especial de la memoria de un proceso denominada el // | Las variables dinámicas se crean en una zona especial de la memoria de un proceso denominada el // | ||
| - | === No hay recolector de basuras === | + | ==== No hay recolector de basuras ==== |
| En Java no es necesario liberar la memoria porque posee un recolector de basuras que recicla automáticamente los objetos que ya no son accesibles por el programa. | En Java no es necesario liberar la memoria porque posee un recolector de basuras que recicla automáticamente los objetos que ya no son accesibles por el programa. | ||
| - | ==== Aritmética de punteros ==== | + | ===== Aritmética de punteros |
| La característica más importante de C es su flexibilidad con el manejo de memoria, la que se ve reflejada en la // | La característica más importante de C es su flexibilidad con el manejo de memoria, la que se ve reflejada en la // | ||
| Línea 289: | Línea 290: | ||
| </ | </ | ||
| - | ¿De que sirve pedir espacio para 10 enteros consecutivos en la memoria? | + | ¿De qué sirve pedir espacio para 10 enteros consecutivos en la memoria? |
| {{ : | {{ : | ||
| Línea 304: | Línea 305: | ||
| </ | </ | ||
| - | === Azucar sintáctico === | + | ==== Azucar sintáctico |
| El problema es que escribir *(p+i) es pesado sintácticamente, | El problema es que escribir *(p+i) es pesado sintácticamente, | ||
| Línea 343: | Línea 344: | ||
| ... | ... | ||
| r=p; | r=p; | ||
| + | ... | ||
| free(p); | free(p); | ||
| + | ... | ||
| x= *r; /* r es dangling reference */ | x= *r; /* r es dangling reference */ | ||
| </ | </ | ||
| - | Aquí r y p apuntan a la misma dirección de memoria. | + | Aquí r y p apuntan a la misma dirección de memoria. |
| - | === Restricciones === | + | ==== Restricciones |
| - | Solo está permitido sumar o restar un entero a un puntero. | + | Solo está permitido sumar o restar un entero a un puntero. |
| < | < | ||
| Línea 371: | Línea 374: | ||
| En el caso de la resta de punteros, se cumple esta propiedad: %%(p + i) - p ≡ i%% | En el caso de la resta de punteros, se cumple esta propiedad: %%(p + i) - p ≡ i%% | ||
| - | === Arreglos de C vs. arreglos en Java === | + | ==== Arreglos de C vs. arreglos en Java ==== |
| Dado que en Java los arreglos corresponden a un objeto bien definido con índices que parten en 0 y terminan en el tamaño del arreglo menos 1, Java puede validar cada acceso y arrojar una excepción cuando el índice está fuera del rango permitido. | Dado que en Java los arreglos corresponden a un objeto bien definido con índices que parten en 0 y terminan en el tamaño del arreglo menos 1, Java puede validar cada acceso y arrojar una excepción cuando el índice está fuera del rango permitido. | ||
| Línea 379: | Línea 382: | ||
| Gracias a la aritmética de punteros es posible programar en C sistemas operativos, malloc/free o el recolector de basuras de Java. En contrapartida esta aritmética conduce a todo tipo de errores que son muy difíciles de diagnosticar. | Gracias a la aritmética de punteros es posible programar en C sistemas operativos, malloc/free o el recolector de basuras de Java. En contrapartida esta aritmética conduce a todo tipo de errores que son muy difíciles de diagnosticar. | ||
| - | ==== Cast de punteros ==== | + | ===== Cast de punteros |
| El significado de un cast de un dato primitivo es distinto del de un cast de un puntero. | El significado de un cast de un dato primitivo es distinto del de un cast de un puntero. | ||
| Línea 413: | Línea 416: | ||
| - | ==== Big endian vs. Little endian ==== | + | ===== Big endian vs. Little endian |
| ¿Qué valor retorna la siguiente función? | ¿Qué valor retorna la siguiente función? | ||
| Línea 429: | Línea 432: | ||
| {{ : | {{ : | ||
| - | El valor retornado por esta función depende de una propiedad del hardware. | + | El valor retornado por esta función depende de una propiedad del hardware. |
| Los únicos casos en donde esta distinción arquitectural es importante es cuando se graban archivos binarios o se transmiten datos binarios por la red. Es decir en vez de escribir los enteros en formato ascii en notación decimal, se escriben directamente los 4 bytes del entero. | Los únicos casos en donde esta distinción arquitectural es importante es cuando se graban archivos binarios o se transmiten datos binarios por la red. Es decir en vez de escribir los enteros en formato ascii en notación decimal, se escriben directamente los 4 bytes del entero. | ||
| Línea 438: | Línea 441: | ||
| Programe la función int '' | Programe la función int '' | ||
| - | ==== Resumen ==== | + | ===== Resumen |
| La siguiente tabla resume las operaciones con punteros: | La siguiente tabla resume las operaciones con punteros: | ||
punteros.1395925935.txt.gz · Última modificación: por lmateu
