[C con Clase] Dudas con las variables char

Salvador Pozo salvador en conclase.net
Mie Mar 19 11:12:18 CET 2014


El pasado 2014-03-19 08:40:51, Lazarus escribió:
 
L> Hola :-) , soy nuevo en esta lista, y sigo desde hace poco el curso de programacion c++, espero escribir en el sitio correcto, si no, mis disculpas.

Hola:

Primero, bienvenido. Y sí, es el lugar correcto.

L> Mis preguntas son:
L>  - ¿Buscando el ahorro de memoria, en el ejemplo 1 y 2, la variable "n" seguiria ocupando un 1 byte?

Bueno, lo cierto es que según las declaraciones que haces, n es un array en ambos ejemplos, así que es imposible que ocupe un byte en ninguno de los dos casos.

En ambos ejemplos, está declarada como "char n[2]", de modo que ocupará, como mínimo, dos bytes.

Y digo como mínimo, porque el espacio ocupado realmente dependerá de otros factores, como las optimizaciones del compilador o el alineamiento de memoria. 

Otra cosa que quiero aclarar es que la conversión de tipos se aplica cuando en una expresión están involucrados valores de tipos diferentes. Por ejemplo:

char a='x';
int i=100;

if(a < i) {...

En este caso, en la expresión del if se compara un char con un int. Antes de evaluar la expresión, el compilador necesita que los dos operandos sean del mismo tipo, por lo tanto, hará las conversiones necesarias. Concretamenete, converitá el valor a de char a int.

En tus ejemplos no se da el caso, ya que en todas las expresiones, los operandos son del mismo tipo.

De todos modos, esto no es algo que el compilador hace internamente. Si se quiere controlar ese mecanismo se puede usar una conversión explícita:

if((int)a < i) {...

Antiguamente, cuando los procesadores tenían mucha menos potencia, y la memoria era un recurso realmente escaso, preocuparse por estos problemas podía ser muy importante, hasta el punto que los programas podían o no caber en memoria o disponer de recursos para funcionar.

Actualmente, salvo que estemos programando para dispositivos con poca capacidad, como algunos microcontroladores, estas cosas no nos preocupan demasiado. No parece que tenga sentido preocuparse por si una variable ocupa uno, dos o cuatro bytes, cuando los registros del procesador son de 64 bits, y trabajarán siempre con cuatro.

Hasta cierto punto, trabajar con bytes podría ser incluso más costoso en términos de tiempo de procesador que trabajar con enteros, ya que tendremos que extraer una palabra de 64 bits desde memoria, y de esa palabra, extraer los ocho bits que nos interesan.

Por eso los procesadores pueden usar alineamiento de memoria, es decir, acceden sólo a direcciones de memoria que sean múltiplos de 2, de 4 o de más bytes, así que declarar una variable de tipo char puede requerir dos o cuatro bytes de memoria, de los que sólo uno es accesible.

En otros casos, el compilador puede optimizar el código para usar un registro, en lugar de acceder a memoria. Por ejemplo, en tu primer programa, la variable n puede almancenarse en un registro del procesador, y en ningún momento de la ejecución se almacenaría en memoria. Por lo tanto, carecería de sentido preocuparse por cuanta memoria usa.

Volviendo a tus ejemplos, lo cierto es que estás desperdiciando un byte, ya que jamás accedes a n[1]. El primer ejemplo se podría reescribir así:

     #include <iostream>
     using namespace std;
     int main(){
	
        for (char n = '0'; n < ':'; n++){ // utilizando la tabla Ascii.
            cout << "El valor de n es " << n << "." << endl;
        }
     }

Y se podría hacer algo análogo en el segundo.

También puedes usar el operador sizeof() para averiguar el tamaño de una variable, y salir de dudas.

L> ¿Merece la pena, o al final con Short int, o int y ya esta?

Esto, como cometé antes, dependerá de cada caso. Si estás programando en un entorno con pocos recursos, el tiempo empleado en optimizar el tamaño de las variables se verá recompensado.

También es importante elegir bien los tipos cuando los datos se van a almacenar de forma externa, y su volumen es grande. Por ejemplo, si necesitamos almacenar un millon de datos de determinado tipo, un byte de diferencia significaría un giga de almacenamiento.

Otro caso en que es interesante optimizar el tamaño es cuando hay que tranferir los datos por un canal con poco ancho de banda, por ejemplo, por una línea serie. En este caso, el ahorro de espacio se traduce en ahorro de tiempo de transmisión. Lo mismo es aplica para canales en el que el ancho de banda es caro, o se debe compartir con muchos usuarios.

Hasta pronto.

-- 
Salvador Pozo (Administrador)
mailto:salvador en conclase.net
Blog con Clase: http://blogconclase.wordpress.com
Con Clase: http://conclase.net


Más información sobre la lista de distribución Cconclase