Saltar al contenido principal
LibreTexts Español

5.1: Introducción

  • Page ID
    83069
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    Todas las variables y funciones tienen una dirección (ubicación de memoria) asociada a ellas. Aquí es donde “viven”. Para entidades de múltiples bytes, esta es la dirección de inicio del bloque de memoria que ocupa el elemento. La dirección de cualquier variable (con la excepción de la clase de registro) se puede encontrar con el operador &. Dependiendo del sistema operativo, la dirección generalmente estará contenida dentro de 2 bytes o 4 bytes de longitud (8 bytes para un SO de 64 bits). Es decir, así se pueden describir todas las direcciones posibles en el sistema. Si se coloca una dirección en otra variable, se dice que esta otra variable es un puntero (es decir, almacena la dirección de, o “apunta a”, la primera variable). Para aprovechar la comprobación de tipos y la matemática de puntero, los punteros se declaran por el tipo de ítem al que apuntan, aunque todos los punteros son ellos mismos del mismo tamaño. Así, un puntero se declara correctamente como un puntero a un tipo char o un puntero a un tipo float, por ejemplo. El operador * se utiliza para indicar que la declaración es de un puntero. Por ejemplo:

    int *pc;
    

    declara un puntero a un int.

    int c, *pc;
    
    c = 12;
    pc = &c;
    

    Este trozo de código declara un int y un puntero a un int, asigna 12 al int (c), y luego coloca la dirección del int (c) en el puntero (pc). El valor del ítem apuntado puede ser recuperado a través del operador de indirección *. Considera la siguiente adición a lo anterior:

    printf("The value of c = %d, the address of c = %d\n", c, &c );
    printf("The value of pc = %d, the value pc points to = %d\n", pc, *pc );
    

    Tenga en cuenta que c y *pc tienen el mismo valor (12). Además, tenga en cuenta que si se cambia el valor de c, *pc refleja este cambio. Por lo tanto, agregando

    c = 36;
    printf("New value of c = %d, the address of c = %d\n", c, &c );
    printf("The value of pc = %d, the value pc points to = %d\n", pc, *pc );
    

    mostrará 36 para *pc así como c, y las direcciones no habrán cambiado.

    Ejercicio\(\PageIndex{1}\)

    Crea un pequeño programa basado en el código anterior y ejecútalo. Compara tus resultados con los de tus compañeros de laboratorio. ¿Qué notas?

    ¿Y si la dirección del puntero se almacena en otro puntero? A esto se le llama asa. Considere el siguiente fragmento de código:

    int c, *pc, **ppc;
    
    c = 12;
    pc = &c;
    ppc = &pc;
    
    printf("pc = %d, the value pc points to = %d\n", pc, *pc );
    printf("ppc = %d, the value ppc points to = %d\n", ppc, *ppc );
    

    Ejercicio\(\PageIndex{2}\)

    Altere su programa para reflejar lo anterior. Ejecutarlo y comparar sus resultados. ¿Cuál crees que es el valor **ppc? (Pruébalo).

    Las direcciones se pueden enviar como argumentos a las funciones. Es así como una función puede devolver más de un valor y es un concepto importante para recordar. Considera lo siguiente:

    int main( void )
    {
          int a, b, c, *pc;
    
          pc = &c;
    
          assign_it( &a, &b, pc );
    
          printf(“The values in main are: %d %d %d\n”, a, b, c );
    }
    
    void  assign_it( int *x, int *y, int *z )
    {
          *x = 1;
          *y = 20;
          *z = 300;
    }
    

    Tenga en cuenta que se puede llamar a Assign_it () usando la dirección del operador (&) en una variable existente, o pasando un puntero a una variable (como en el caso de &c o pc). Además, la declaración de asign_it () s establece que está aceptando punteros a int, no simple int antiguo.

    Ejercicio\(\PageIndex{3}\)

    Usando lo anterior como guía, cree un programa para probar que devuelva múltiples valores de una función.

    Ejercicio\(\PageIndex{4}\)

    Modifique lo anterior para imprimir las direcciones de las variables recibidas por sign_it (), así como &a, &b y pc de nuevo en main (). ¿Qué muestra esto?

    Nota: Si no está seguro del tamaño de los punteros en un sistema operativo dado, simplemente use el operador sizeof (). Esto devolverá el tamaño del elemento dado en bytes. Por ejemplo, el fragmento de código,

    int x, *pc;
    
    x = sizeof( pc );
    printf(“Pointers are %d bytes\n”, x );
    

    may print 2 (Windows 3.1, Eeek!) , 4 (Windows 95/XP, algunos sistemas UNIX) u 8 (verdaderos sistemas operativos de 64 bits). Tenga en cuenta que pc podría ser un puntero a un float, double, char o cualquier cosa, y seguirá siendo del mismo tamaño. Este es un punto muy importante a entender. Intente usar sizeof () para verificar esto.


    This page titled 5.1: Introducción is shared under a CC BY-NC-SA 4.0 license and was authored, remixed, and/or curated by James M. Fiore via source content that was edited to the style and standards of the LibreTexts platform; a detailed edit history is available upon request.