[C con Clase] Más punteros

Steven Davidson steven en conclase.net
Mar Feb 27 23:13:07 CET 2007


Hola Alejandro,

El pasado 2007-02-27 19:45:35, Alejandro escribió:

A> Muchas gracias por vuestra ayuda con los punteros. A ver si consigo verles la utilidad, pero, por ahora tengo otras dos dudas:
A> Si en un programa yo hago "p* ++" no me incrementa el número que tiene la variable a la que apunto, si no que muestra números sin sentido. Sin embargo, si hago "++ *p" si que me funciona. ¿Por qué?

Esto tiene que ver con la evaluación de la expresión que implica el orden en que los operadores son aplicados. A esto se llama precedencia de operadores. En tu caso, los operadores ++ y * (unitario) pertenecen al mismo nivel de precedencia. Por lo tanto, tenemos que aplicar el criterio de asociatividad para determinar cuál operador se realiza antes. En tu caso, estos operadores se asocian de derecha a izquierda.

Dicho lo anterior, '*p++' se evalúa así (*(p++)). Esto es, hacemos el incremento al puntero y luego accedemos al valor apuntado. En el caso de '++*p', hacemos lo siguiente, (++(*p)); o sea, accedemos al valor apuntado y luego incrementamos.

Tratamos este tema en el capítulo 14: http://c.conclase.net/curso/index.php?cap=014

A> Existe otra comparación que se realiza muy frecuente con los punteros. Para averiguar si
A> estamos usando un puntero es corriente hacer la comparación:
A> if(NULL != p)
A> o simplemente
A> if(p)
A> Y también:
A> if(NULL == p)
A> O simplemente
A> if(!p)
A> Pero en esta parte no entiendo la utilidad de los 'if' ni para qué los usáis. ¿Me lo podéis explicar?

Primeramente, 'NULL' es una constante simbólica definida en las bibliotecas estándares de ANSI C. Bajo C++, un puntero nulo es 0 (cero), y así no dependemos de los ficheros de cabecera para este asunto.

En cuanto a las condiciones, esto nos viene bien para comprobar si un puntero es válido o no. Por ejemplo,

void incremento( float *ptr, unsigned int nCant )
{
  while( nCant-- )  ++*ptr++;
}

Esto puede funcionar, con tal de que 'ptr' apunte a una lista existente. Sin embargo, tendremos problemas si 'ptr' es un puntero nulo. Por ejemplo, tenemos lo siguiente en 'main()':

float *pLista=0;
unsigned int nElem=10;

crearLista( pLista, nElem );

incremento( pLista, nElem );

Si no se pudo crear la lista, entonces 'pLista' permanecerá nulo. Cuando lleguemos al incremento, tendremos un problema, ya que no tenemos una lista. Para resolver el problema, comprobamos su validez:

if( !pLista )  incremento( pLista, nElem );

Típicamente, hacemos esta comprobación al usar memoria dinámica, ya que no está garantizado que el sistema operativo te dé tal memoria; es más bien una petición. Por lo tanto, puede ocurrir que el S.O. nos niegue tal petición y por tanto el puntero es nulo.


Espero haber aclarado las dudas.

Steven


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