Almacenamiento en memoria
La memoria puede verse como un conjunto de celdas numeradas y ordenadas, cada una de las cuales puede almacenar un byte de información. El número correspondiente a cada celda se conoce como su dirección.
Cuando se crea una variable, el compilador reserva el número suficiente de celdas de memoria (bytes) requeridos para almacenar la variable, y se encarga de que los espacios reservados no se traslapen.
Direcciones de memoria
En C/C++ es posible obtener la dirección de memoria donde se encuentra almacenada una variable mediante el operador de referencia &
Ejemplo:int main() { int a = 10, b = 20; cout << &a << endl; cout << &b << endl; return 0;}
Tamaño de una variable
Podemos también obtener la cantidad de memoria que ocupa una variable (en bytes) mediante el operador sizeof:int main() { int a = 10; cout << “Valor de a: “ << a << endl; cout << “Dirección de a: “ << &a << endl; cout << “Tamaño de a: “ << sizeof(a) << endl; return 0;}
Apuntadores
Un apuntador es una variable que contiene una dirección de memoria (donde posiblemente se almacene el valor de otra variable).
Para crear apuntadores, se utiliza el operador * como se muestra a continuación:int main() { int a = 10; int *p; p = &a; cout << “Valor de p: “ << p << endl; cout << “Valor en p: “ << *p << endl; cout << “Dirección de p: “ << &p << endl;}
Apuntadores
Un apuntador es una variable que contiene una dirección de memoria (donde posiblemente se almacene el valor de otra variable).
Para crear apuntadores, se utiliza el operador * como se muestra a continuación:int main() { int a = 10; int *p; p = &a; cout << “Valor de p: “ << p << endl; cout << “Valor en p: “ << *p << endl; cout << “Dirección de p: “ << &p << endl;}
La variable p es de tipo “apuntador a int”
Almacenamiento de arreglos
Cuando se declara un arreglo, se reserva un solo bloque contiguo de memoria para almacenar todos sus elementos, y éstos se almacenan en la memoria en el mismo orden que ocupan en el arreglo:
int main() {
int i, a[10];
for (i = 0; i < 10; i++) {
cout << &a[i] << endl;
}
return 0;
}
Almacenamiento de arreglos
Cuando se declara un arreglo, se reserva un solo bloque contiguo de memoria para almacenar todos sus elementos, y éstos se almacenan en la memoria en el mismo orden que ocupan en el arreglo:
int main() {
int i, a[10];
for (i = 0; i < 10; i++) {
cout << &a[i] << endl;
}
return 0;
}
Verificar que &a[i] es igual a &a[0] + i * sizeof(int)
Arreglos y apuntadores
En C/C++, el nombre de un arreglo es también un apuntador al primer elemento del arreglo.
De hecho, el lenguaje C no puede distinguir entre un arreglo y un apuntador: ambos son completamente intercambiables.
int main() {
int i, a[10], *p;
for (i = 0; i < 10; i++) { a[i] = i; };
p = a;
for (i = 0; i < 10; i++) {
cout << p[i] << endl;
}
return 0;
}
Aritmética de apuntadores
Recuerde que un apuntador siempre está asociado con el tipo de dato al que apunta (e.g., apuntador a int, apuntador a float, etc).
Esto hace posible definir la operación p+k donde p es un apuntador y k es un entero. El resultado de esta operación es
p + k * sizeof(tipo)
donde tipo es el tipo de datos asociado a p.
Notar entonces que, si p es un arreglo
&p[k] es equivalente a p+k y p[k] equivale a *(p+k)
Ejemplo: operaciones elementales
void MulRen(float *m, int n, int r, float k) {
float *p = m + r * n;
for (int j = 0; j < n; j++) { p[j] *= k; }
}
void SumRen(float *m, int n, int r1, int r2, float k) {
float *p1 = m + r1 * n;
float *p2 = m + r2 * n;
for (int j = 0; j < n; j++) { p1[j] += p2[j] * k; }
}
void InterRen(float *m, int n, int r1, int r2) {
float t;
float *p1 = m + r1 * n;
float *p2 = m + r2 * n;
for (int j = 0; j < n; j++) {
t = p1[j]; p1[j] = p2[j]; p2[j] = t;
}
}
Página siguiente |