La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Una variable en un programa es algo con un nombre, cuyo valor puede variar. La manera en que el compilador y enlazador maneja esto es asignando un bloque.

Presentaciones similares


Presentación del tema: "Una variable en un programa es algo con un nombre, cuyo valor puede variar. La manera en que el compilador y enlazador maneja esto es asignando un bloque."— Transcripción de la presentación:

1

2 Una variable en un programa es algo con un nombre, cuyo valor puede variar. La manera en que el compilador y enlazador maneja esto es asignando un bloque de memoria específico en la computadora para almacenar el valor de esa variable.

3 El tamaño de dicho bloque depende del rango sobre el cual se permite variar a la variable.

4 Para saber el tamaño de diferentes tipos de datos, p.ej enteros en su sistema particular, puede escribirse el sig. código: #include int main() { printf("el tamaño de un short es %d\n", sizeof(short)); printf("el tamaño de un entero es %d\n", sizeof(int)); printf("el tamaño de un long es %d\n", sizeof(long)); }

5 Cuando declaramos una variable le informamos al compilador dos cosas: el nombre de la variable y el tipo de la variable. Por ejemplo, declaramos una variable de tipo entero con el nombre k así: int k;

6 Al ver la parte "int" de esta sentencia el compilador aparta 2 bytes de memoria (en una PC) para almacenar el valor del entero. También establece una tabla de símbolos. En esa table añade el símbolo k y la dirección relativa de memoria donde esos 2 bytes fueron apartados.

7 Más tarde si escribimos: k = 2; En tiempo de ejecución cuando esta sentencia se ejecute el valor 2 será colocado en esa ubicación de memoria reservada para el almacenamiento del valor de k. En C nos referimos a una variable como el entero k como un "objeto". DirecciónValor 00AA 00AB 00AC 2 00AD 00AE

8 En un sentido, hay 2 valores asociados con el objeto k. Uno es el valor del entero almacenado ahí (2 en el ejemplo anterior) y el otro es el valor de la ubicación de memoria; es decir la dirección de k. Algunos textos se refieren a estos 2 valores con la nomenclatura rvalue (right value) y lvalue (left value) respectivamente. DirecciónValor 00AA 00AB 00AC 2 00AD 00AE lvalue rvalue

9 En algunos lenguajes,lvalue es el valor permitido del lado izquierdo del operador de asignación '=' (la dirección donde el resultado de la evaluación del lado derecho terminará). Rvalue es el que está en el lado derecho de la asignación, el 2 anterior. Los Rvalues no pueden ser usados del lado izquierdo de la sentencia de asignación, de este modo : 2 = k; es inválido.

10 Consideremos : int j, k; k = 2; j = 7; <-- línea 1 k = j; <-- línea 2 En este ejemplo, el compilador interpreta la j en la línea 1 como la dirección de la variable j (su lvalue) y crea código para copiar el valor 7 a esa dirección. En la línea 2, sin embargo, la j es interpretada como su rvalue (dado que está en el lado derecho del operador de asignación '='). Esto es, aquí la j se refiere al valor almacenado en la ubicación de memoria establecida para j, en este caso 7. Así, el 7 es copiado a la dirección designada por el lvalue de k.

11 Ahora, digamos que por alguna razón deseamos tener una variable diseñada para almacenar un lvalue (una dirección). El tamaño requerido para almacenar tal valor depende del sistema.

12 Tal variable es llamada una variable apuntador o puntero. En C cuando definimos un apuntador lo hacemos precediendo su nombre con un asterisco. Además en C le damos al apuntador un tipo, el cual, en este caso, hace referencia al tipo de dato almacenado en la dirección que estamos almacenando en nuestro apuntador.

13 Por ejemplo considere la declaración de variable: int *ptr; ptr es el nombre de nuestra variable. El '*' informa al compilador que deseamos una variable apuntador, para que aparte tantos bytes se requieran para almacenar una dirección en memoria. El int le dice que deseamos utilizar nuestra variable apuntador para almacenar la dirección de un entero. Dicho apuntador se dice que "apunta a " un entero.

14 En este caso, si la declaración está fuera de cualquier función, la variable se inicializa a un valor garantizado de tal forma que no apunte a ningún objeto o función de C. Un puntero inicializado de essta manera se llama un puntero "nulo" o "null".

15 Establecer el valor de puntero usando la macro NULL, como en la sentencia de asignación ptr = NULL, gurantiza que el puntero se ha vuelto un puntero nulo. De manera similar que probamos que un valor entero es igual a 0 como en if(k == 0), podemos revisar un puntero nulo usando if (ptr == NULL).

16 Supongamos ahora que deseamos almacenar la dirección de nuestra variable entera k. Para ello usamos el operador unitario & y escribimos: ptr = &k;

17 Lo que hace el operador & es recuperar el valor lvalue (dirección) de k, aún cuando k está del lado derecho del operador de asignación '=', y lo copia al contenido de nuestro puntero ptr. Ahora se dice que ptr apunta a k.

18 Tenemos al operador de "dereferencia" que es el asterisco y se usa de la sig. manera: *ptr = 7; Esto copiará 7 a la dirección apuntada por ptr. De este modo si ptr apunta a (contiene la dirección de) k, la sentencia anterior establecerá el valor de k en 7. Esto es, cuando usamos el '*' estamos haciendo referencia al valor al cual ptr está apuntando, no el valor del puntero en sí mismo.

19 De un modo similar, podemos escribir: printf("%d\n",*ptr); para imprimir a pantalla el valor entero almacenado en la dirección a la cual apunta ptr.

20 #include int j, k; int *ptr; int main(void) { j = 1; k = 2; ptr = &k; printf("\n"); printf("j tiene el valor %d y es almacenado en %p\n", j, (void *)&j); printf("k tiene el valor %d y es almacenado en %p\n", k, (void *)&k); printf("ptr tiene el valor %p y es almacenado en %p\n", ptr, (void *)&ptr); printf(El valor del entero apuntado por ptr es %d\n", *ptr); return 0; }

21 Una variable se declara dándole un tipo y un nombre (p.ej. int k;) Una variable puntero se declara dándole un tipo y un nombre (p.ej. int *ptr) donde el asterisco le indica al compilador que la variable llamada ptr es una variable puntero y el tipo le dice al compilador que tipo de dato está apuntando el puntero (entero en este caso). Una vez que una variable se declara, podemos obtener su dirección precediendo su nombre con el operador unitario &, como en &k Podemos desreferenciar un puntero, es decir referirnos al valor al cual apunta el puntero usando el operador unitario '*' como en *ptr. Un valor lvalue de una variable es el valor de su dirección, esto es donde está almacenada en memoria. El valor rvalue de la variable es el valor almacenado en esa variable (en esa dirección).

22

23 int *ptr; *ptr = 2; En las declaraciones anteriores el compilador sabe cuantos bytes copiar en la ubicación de memoria apuntada por ptr. Si ptr fue declarada como un apuntador a un entero, se copiaran 2 bytes. De este mismo modo en el caso de flotantes y dobles el número apropiado de bytes se copiará.

24 Pero el definir el tipo al que apunta el puntero permite otras maneras para que el compilador interprete el código. Por ejemplo, considere un bloque en memoria que consiste de 10 enteros en una fila. Esto es, se reservan 20 bytes para almacenar los 10 enteros. Ahora, digamos que apuntamos nuestro puntero entero al primero de estos enteros. Más allá, digamos que el entero se ubica en la dirección de memoria 100 (decimal).

25 Lo que sucede cuando escribimos: ptr + 1; Como el compilador sabe que esto es un puntero (su valor es una dirección) y que apunta a un entero (su dirección actual, 100, es la dirección de un entero), le agrega 2 a ptr en vez de, de manera que el puntero apunta al entero siguiente, en la ubicación de memoria 102. Lo mismo aplica para otros tipos de datos tales como floats, doubles, o incluso usando tipos de datos definidos por el usuario tales como estructuras. Esto obviamente no es el mismo tipo de suma que normalmente pensamos. En C esto se conoce como aritmética de punteros.

26 #include int my_array[] = {1,23,17,4,-5,100}; int *ptr; int main(void) { int i; ptr = &my_array[0]; /* apunta nuestro puntero al 1er elemento del arreglo*/ printf("\n\n"); for (i = 0; i < 6; i++) { printf("my_array[%d] = %d ",i,my_array[i]); /*<-- A */ printf("ptr + %d = %d\n",i, *(ptr + i)); /*<-- B */ } return 0; }

27

28 En C, las cadenas son arreglos de caracteres terminados con un caracter cero binario (escrito como '\0'). Considérese: char my_string[40]; my_string[0] = 'T'; my_string[1] = 'e'; my_string[2] = 'd; my_string[3] = '\0';

29 Dado que escribir lo anterior tomaría mucho tiempo, C permite 2 maneras alternas para escribir lo mismo. Primero, podríamos escribir: char my_string[40] = {'T', 'e', 'd', '\0',}; O bien char my_string[40] = "Ted";

30 Cuando se usan las comillas dobles, en vez de las comillas sencillas, el caracter nulo ( '\0' ) se añade automáticamente al final de la cadena. El compilador aparta un bloque contiguo de memoria de 40 bytes para almacenar los caracteres y lo inicializa de manera que los primeros 4 caracteres son Ted\0.

31 #include char strA[80] = Una cadena como demostracion"; char strB[80]; int main(void) { char *pA; /* un apuntador de tipo caracter */ char *pB; /* otro apuntador de tipo caracter */ puts(strA); /* muestra cadena A */ pA = strA; /* apunta pA a la cadena A */ puts(pA); /* muestra a que está apuntando pA */ pB = strB; /* apunta pB a la cadena B */ putchar('\n'); /* mueve hacia abajo una línea en la pantalla */ while(*pA != '\0') /* línea A */ { *pB++ = *pA++; /* línea B */ } *pB = '\0'; /* línea C */ puts(strB); /* muestra strB en pantalla */ return 0; }

32 Empezamos definiendo 2 arreglos de 80 caracteres cada uno. Como están definidos globalmente están inicializados con '\0's al principio. strA tiene sus primeros caracteres inicializados a la cadena entre comillas. Declaramos 2 punteros de caracteres y mostramos la cadena en pantalla. Entonces apuntamos el puntero pA a strA. Esto es, copiamos la dirección de strA[0] en nuestra variable pA. Usamos puts() para mostrar lo que está apuntando pA en pantalla En la línea se define que mientras el caracter apuntado por pA (*pA) no sea un caracter nulo (la teminación '\0'), haga lo siguiente: En la línea B: se copia el caracter apuntando por pA al espaio apuntado por pB, entonces incrementamos pA de manera que apunta al siguiente caracter y pB de manera que apunte al siguiente espacio. Cuando copiamos el último caracter, pA ahora apunta al caracter nulo y el ciclo termina. Sin embago el caracter nulo no se copió por eso lo añadimos en la línea C.


Descargar ppt "Una variable en un programa es algo con un nombre, cuyo valor puede variar. La manera en que el compilador y enlazador maneja esto es asignando un bloque."

Presentaciones similares


Anuncios Google