martes, 12 de febrero de 2013

Localidad De Memoria/Palabras Reservadas


INTRODUCCIÓN


Este es un lenguaje orientado en la implementación de sistemas operativos como Unix. El lenguaje C es apreciado por la eficiencia del código que produce y es el lenguaje de programación más popular para crear software de sistemas, aunque también puede ser utilizado para crear nuevas aplicaciones.
Un manejador de memoria es un componente que te permite administrar de manera sencilla y fiel los recursos que maneja tu programa (software), específicamente el recurso de la memoria.
Todos los objetos tienen un tiempo de vida, es decir, el tiempo durante el cual se garantiza que el objeto exista. En C, existen 3 tipos de duración: estática, automática y asignada
En los lenguajes informáticos, una palabra reservada es una palabra que tiene un significado gramatical especial para ese lenguaje y no puede ser utilizada como un identificador en ese lenguaje.








Manejo de memoria en el lenguaje C

Un manejador de memoria es un componente que te permite administrar de manera sencilla y fiel los recursos que maneja tu programa (software), específicamente el recurso de la memoria.
Todos los objetos tienen un tiempo de vida, es decir, el tiempo durante el cual se garantiza que el objeto exista. En C, existen 3 tipos de duración: estática, automática y asignada. Las variables globales y las variables locales declaradas con el especificador static tienen duración estática. Se crean antes de que el programa inicie su ejecución y se destruyen cuando el programa termina. Las variables locales no static tienen duración automática. Se crean al entrar al bloque en el que fueron declaradas y se destruyen al salir de ese bloque. Duración asignada se refiere a los objetos cuya memoria se reserva de forma dinámica. Como se explicó anteriormente, esta memoria se crea y se debe liberar de forma explícita. Los arreglos de longitud variable de C99 son un caso especial. Tienen duración automática, con la particularidad de que son creados a partir de su declaración.
Como sabemos, en lenguaje C/C++ , &x es la dirección donde se almacena en memoria la variable x. Si p es un apuntador en C/C++ , *p es el contenido de la localidad de memoria p. Si usamos C/C++ para implementar listas ligadas, podemos usar estos apuntadores. Sin embargo, primero analizaremos cómo asignar y liberar el almacenamiento en forma dinámica y cómo se accesa al almacenamiento dinámico en C/C++ .

Malloc

En C/C++ , una variable que debe contener la dirección en la memoria que almacena un número entero se crea mediante la declaración
int *p;
Recordemos que esta declaración se divide en dos partes: la parte de tipo int *, que indica que se trata de un apuntador a un entero; y la parte de identificador, en este caso p. Una vez declarada la variable p como un apuntador a un tipo específico de dato, debe ser posible crear dinámicamente un objeto de este tipo específico y asignar su dirección a p. Esto se hace en C/C++ mediante la función de la biblioteca estándar malloc (size). La función malloc asigna de manera dinámica una parte de memoria de tamaño especificado en size y devuelve un apuntador a un elemento de tipo char. Consideremos las siguientes declaraciones:
extern char *malloc();
int *pi; float *pr;
La palabra clave extern especifica que una variable o función tiene un enlace externo. Esto significa que la variable o función a la que nos referimos está definida en algún otro archivo fuente, o más adelante en el mismo archivo. Sin embargo, en
C/C++ podemos usar esta palabra clave extern con una cadena. La cadena indica que se está usando el convenio de enlace de otro lenguaje para los identificadores que se están definiendo. Para los programas C++ la cadena por defecto es ``C++''.
Los enunciados:
pi = (int *) malloc(sizeof(int));
pr = (float *) malloc(sizeof(float));
Crean directamente la variable entera *pi y la variable real *pr. Estas se denominan variables dinámicas. Al ejecutar estos enunciados, el operador sizeof devuelve el tamaño en bytes de su operando. Esto se usa para conservar la independencia de máquina. Después, malloc crea un objeto de este tamaño. Por tanto, malloc(sizeof(int)) asigna almacenamiento para un entero, en tanto que malloc(sizeof(float)) asigna espacio necesario para un real. De igual manera, malloc devuelve un apuntados al almacenamiento que asigna. Este apuntador es al primer byte de este almacenamiento y es de tipo char *. Para obligar al apuntador a que señale a un entero, usamos el operador de cálculo (int *) ó (float *).
El operador sizeof, devuelve un valor de tipo int, en tanto que la función malloc espera un parámetro de tipo unsigned. Para hacer que correspondan, debemos escribir
pi=(int *)malloc((unsigned)(sizeof(int)));
Como ejemplo, vamos a considerar este breve código:
#include <iostream>

int main (int argc, char * const argv[]) {
( 1)  int *p, *q;
( 2)  int x;
( 3)  p = (int *)malloc(sizeof(int));
( 4)  *p = 3;
( 5)  q = p;
( 6)  std::cout<< *p << "  " << *q << "\n";
( 7)  x = 7;
( 8)  *q = x;
( 9)  std::cout<< *p << "  " << *q << "\n";
(10)  p = (int *)malloc(sizeof(int));
(11)  *p = 5;
(12)  std::cout<< *p << "  " << *q << "\n";
return 0;}
En la línea (3), se crea una variable de tipo entero y su dirección se coloca en p. La línea (4) establece el valor de esa variable en 3. La línea (5) hace que la dirección q sea la misma dirección que p. El enunciado de la línea (5) es perfectamente válido, pues se asigna a una variable de tipo apuntador (q) el valor de otra variable del mismo tipo (p). En este momento *p y *q hacen referencia a la misma variable. Por tanto, la línea (6) imprime el contenido de esa variable (que ahora es 3) dos veces.
En la línea (7), se almacena el valor 7 en la variable entera x. La línea (8) cambia el valor de *q al valor de x. sin embargo, dado que p y q apuntan a la misma variable, *p y *q tienen el valor 7. Por tanto la línea (9) imprime el número 7 dos veces.
La línea (10) crea una nueva variable entera y coloca su dirección en p. Ahora *p hace referencia a la variable entera recién creada que todavía no ha recibido un valor. q no ha cambiado; por lo que el valor de *q sigue siendo 7. Observemos que *p no hace referencia a una variable específica única. Su valor cambia conforme se modifica el valor de p. La línea (11) establece el valor de esta variable recién creada en 5 y la línea 12 imprime los valores 5 y 7. Y así la salida del programa es:
3  3
7  7
5  7

Malloc; Ejemplo has exited with status 0.
La función free se usa en C para liberar almacenamiento de una variable asignada dinámicamente.
 La orden free(p);
invalida cualquier referencia futura a la variable *p (a menos que se asigne nuevo espacio de memoraia a esa variable). Llamar free(p) hace que quede disponible para reúso el almacenamiento ocupado por *p, si es necesario.
La función free espera un parámetro apuntador del tipo char *, para que no tengamos problemas de tipos, debemos hacer
free((char *)p);
Consideremos el siguiente ejemplo para ilustrar el uso de free:
#include <iostream>

int main (int argc, char * const argv[]) {
    int *p, *q;
              
( 1) p=(int *)malloc(sizeof(int));
( 2) *p=5;
( 3) q=(int *)malloc(sizeof(int));
( 4) *q=8;
( 5) free(p);
( 6) p=q;
( 7) q=(int *)malloc(sizeof(int));
( 8) *q=6;
( 9) std::cout<<*p<<" "<<*q<<"\n";
        return 0;}

Punteros void

La función malloc devuelve un puntero inespecífico, que no apunta a un tipo de datos determinado. En C, estos punteros sin tipo se declaran como void*
 Muchas funciones que devuelven direcciones de memoria utilizan los punteros void*. Un puntero void* puede convertirse a cualquier otra clase de puntero:
char* ptr = (char*)malloc(1000);
El problema de malloc es conocer cuántos bytes se quieren reservar. Si se quiere reservar una zona para diez enteros, habrá que multiplicar diez por el tamaño de un entero.
El tamaño en bytes de un elemento de tipo T se obtiene con
la expresión sizeof (T)

Función free

Cuando una zona de memoria reservada con malloc ya no se necesita, puede ser liberada mediante la función free.
void free (void* ptr);
 ptr es un puntero de cualquier tipo que apunta a un área de memoria reservada previamente con malloc.
Si ptr apunta a una zona de memoria indebida, los efectos pueden ser desastrosos, igual que si se libera dos veces la misma zona.

CALLOC

La función CALLOC sirve para obtener un bloque de memoria especificado en términos del número de elementos y el tamaño de estos elementos
#include <stdlib.h>
void *calloc(size_t nelem, size_t elsize);
La función calloc inicializa todos los elementos del bloque de memoria a cero
Ejemplo:
int *p = (int *)calloc(100,sizeof(int))

REALLOC

La función REALLOC puede cambiar el tamaño del bloque apuntado por un apuntador especifico
#include <stdlib.h>
void *realloc(void *ptr, size_t size);
El apuntador *ptr debe estar apuntando hacia algún bloque de memoria. En caso de que el apuntador sea nulo la función trabaja igual que malloc

Ejemplo
void leer(int *A, int n)
{
for(int i=0; i < n; i++ )
{
printf("A[%d] = ", i);
scanf("%d",&A[i]);
}
}
void imprime(int *A, int n)
{
for(int i=0; i < n; i++ )
printf("A[%d] = %d \n", i,A[i]);
}Ejemplo 5
void leer(int *A, int n)
{
for(int i=0; i < n; i++ )
{
printf("A[%d] = ", i);
scanf("%d",&A[i]);
}
}
void imprime(int *A, int n)
{
for(int i=0; i < n; i++ )
printf("A[%d] = %d \n", i,A[i]);
}
Método de Ordenamiento
void burbuja(int *A, int n)
{
int i,j,temp;
for(i = 0; i < (n-1); i++)
for(j = i+1; j < n; j++)
if (A[i] > A[j])
{
temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}
Programa Principal
#include <stdio.h>
#include <stdlib.h>
void burbuja(int *A, int n);
void leer(int *A, int n);
void imprime(int *A, int n);
main()
{
int n, *A;
printf("Proporciona el numero de datos a leer: ");
scanf("%d",&n);
A = (int *)malloc(n*sizeof(int));
leer(A,n);
burbuja(A,n);
imprime(A,n);
system("pause");
return 0;
}

Palabras reservadas


En los lenguajes informáticos, una palabra reservada es una palabra que tiene un significado gramatical especial para ese lenguaje y no puede ser utilizada como un identificador en ese lenguaje.
Por ejemplo, en SQL, un usuario no puede ser llamado "group", porque la palabra group es usada para indicar que un identificador se refiere a un grupo, no a un usuario. Al tratarse de una palabra clave su uso queda restringido.
Ocasionalmente la especificación de un lenguaje de programación puede tener palabras reservadas que están previstas para un posible uso en futuras versiones. En Java const y goto son palabras reservadas — no tienen significado en Java, pero tampoco pueden ser usadas como identificadores. Al reservar los términos pueden ser implementados en futuras versiones de Java, si se desea, sin que el código fuente más antiguo escrito en Java deje de funcionar.
En la CLI de .NET, todos los lenguajes tienen que proporcionar un mecanismo para utilizar los identificadores públicos que son palabras reservadas en ese lenguaje. Para ver por qué es necesario, supongamos que se define una clase en VB.NET como sigue:
Public Class this
End Class

Entonces, se compila esta clase en un ensamblado de .NET y se distribuye como parte de un conjunto de herramientas. Un programador de C#, que quiere definir una variable de tipo “this” encontraría un problema: “this” es una palabra reservada en C#. El siguiente fragmento en C# no compilará:
This × = new this () ;

Un tema similar aparece cuando se accede a miembros, sobrescribiendo métodos virtuales e identificando espacios de nombres. En C#, colocando la arroba (@) antes del identificador, se forzará a ser considerado como un identificador en vez de una palabra reservada por el compilador. El signo arroba no es considerado parte del identificador.
@this × = new @this () ;
Por consistencia, esta utilización también se permite en configuraciones no-públicas como variables locales, nombres de parámetros y miembros privados.


CONCLUSIONES


Todos los objetos tienen un tiempo de vida, es decir, el tiempo durante el cual se garantiza que el objeto exista. En C, existen 3 tipos de duración: estática, automática y asignada. Las variables globales y las variables locales declaradas con el especificador static tienen duración estática. Se crean antes de que el programa inicie su ejecución y se destruyen cuando el programa termina

En los lenguajes informáticos, una palabra reservada es una palabra que tiene un significado gramatical especial para ese lenguaje y no puede ser utilizada como un identificador en ese lenguaje.

Ocasionalmente la especificación de un lenguaje de programación puede tener palabras reservadas que están previstas para un posible uso en futuras versiones.


No hay comentarios:

Publicar un comentario