in

Puntero NULO en C – GeeksforGeeks

gfg 200x200 min

En un nivel muy alto, podemos pensar en NULL como un puntero nulo que se usa en C para varios propósitos. Algunos de los casos de uso más comunes de NULL son
a) Para inicializar una variable de puntero cuando esa variable de puntero aún no tiene asignada ninguna dirección de memoria válida.
b) Para comprobar si hay un puntero nulo antes de acceder a cualquier variable de puntero. Al hacerlo, podemos realizar el manejo de errores en el código relacionado con el puntero, por ejemplo, eliminar la referencia de la variable del puntero solo si no es NULL.
c) Pasar un puntero nulo a un argumento de función cuando no queremos pasar ninguna dirección de memoria válida.

El ejemplo de a es

El ejemplo de b es

if(pInt != NULL)

{ }

else

{ }

El ejemplo de c es

int fun(int *ptr)

{

 

 return 10;

}

fun(NULL);

Cabe señalar que el puntero NULL es diferente de un puntero colgante y sin inicializar. En un contexto de programa específico, todos los punteros no inicializados o colgantes o NULL no son válidos, pero NULL es un puntero no válido específico que se menciona en el estándar C y tiene propósitos específicos. Lo que queremos decir es que los punteros colgantes y sin inicializar no son válidos, pero pueden apuntar a alguna dirección de memoria que puede ser accesible a través del acceso a la memoria no intencionado.

#include <stdio.h>

int main()

{

 int *i, *j;

 int *ii = NULL, *jj = NULL;

 if(i == j)

 {

  printf("This might get printed if both i and j are same by chance.");

 }

 if(ii == jj)

 {

  printf("This is always printed coz ii and jj are same.");

 }

 return 0;

}

Al mencionar específicamente el puntero NULL, el estándar C proporciona un mecanismo mediante el cual un programador de C puede usar y verificar si un puntero dado es legítimo o no. Pero, ¿qué es exactamente NULL y cómo se define? Estrictamente hablando, NULL se expande a una constante de puntero nulo definida por la implementación que se define en muchos archivos de encabezado como «stdio.h«,»stddef.h«,»stdlib.h”Etc. Veamos qué dicen los estándares de C sobre el puntero nulo. De la cláusula 6.3.2.3 de la norma C11,

«Una expresión constante entera con el valor 0, o una expresión convertida en tipo void *, se denomina constante de puntero nulo. Si una constante de puntero nulo se convierte en un tipo de puntero, se garantiza que el puntero resultante, llamado puntero nulo, se comparará de forma desigual con un puntero a cualquier objeto o función.«

Antes de continuar con esta discusión NULL :), mencionemos algunas líneas sobre el estándar C en caso de que desee remitirlo para un estudio más detallado. Tenga en cuenta que ISO / IEC 9899: 2011 es el último estándar del lenguaje C que se publicó en diciembre de 2011. También se denomina estándar C11. Para completar, mencionemos que los estándares anteriores para C eran C99, C90 (también conocido como ISO C) y C89 (también conocido como ANSI C). Aunque el estándar C11 real se puede comprar en ISO, hay un documento preliminar que está disponible en el dominio público de forma gratuita.

Al llegar a nuestra discusión, la macro NULL se define como ((anulado *) 0) en los archivos de encabezado de la mayoría de las implementaciones del compilador de C. Pero el estándar C dice que 0 también es una constante de puntero nulo. Significa que lo siguiente también es perfectamente legal según el estándar.

Tenga en cuenta que 0 en la declaración C anterior se usa en el contexto del puntero y es diferente de 0 como número entero. Esta es una de las razones por las que se prefiere el uso de NULL porque hace explícito en el código que el programador está usando un puntero nulo, no un entero 0. Otro concepto importante sobre NULL es que “NULL se expande a una constante de puntero nulo definida por la implementación”. Esta declaración también es de la cláusula 7.19 de C11. Significa que la representación interna del puntero nulo podría ser un patrón de bits distinto de cero para transmitir el puntero NULL. Es por eso que NULL no siempre necesita representarse internamente como un patrón de bits todos ceros. Una implementación de compilador puede elegir representar una «constante de puntero nulo» como un patrón de bits para todos los 1 o cualquier otra cosa. Pero nuevamente, como programador en C, no debemos preocuparnos mucho por el valor interno del puntero nulo a menos que estemos involucrados en la codificación del compilador o incluso por debajo del nivel de codificación. Habiendo dicho esto, normalmente NULL se representa como todos los bits puestos a 0 solamente. Para saber esto en una plataforma específica, se puede utilizar lo siguiente

#include<stdio.h>

int main()

{

 printf("%d",NULL);

 return 0;

}

Lo más probable es que imprima 0, que es el valor de puntero nulo interno típico, pero nuevamente puede variar según el compilador / plataforma de C. Puede probar algunas otras cosas en el programa anterior, como printf («‘% c», NULL) o printf («% s», NULL) e incluso printf («% f», NULL). Los resultados de estos serán diferentes dependiendo de la plataforma utilizada, pero sería interesante especialmente el uso de %F con NULL!

Podemos usar tamaño de() operador en NULL en C? Bueno, el uso de sizeof (NULO) está permitido, pero el tamaño exacto dependerá de la plataforma.

#include<stdio.h>

int main()

{

 printf("%lu",sizeof(NULL));

 return 0;

}

Dado que NULL se define como ((anulado *) 0), podemos pensar en NULL como un puntero especial y su tamaño sería igual al de cualquier puntero. Si el tamaño del puntero de una plataforma es 4 bytes, la salida del programa anterior sería 4. Pero si el tamaño del puntero en una plataforma es 8 bytes, la salida del programa anterior sería 8.

¿Qué pasa con la desreferenciación de NULL? ¿Qué va a pasar si usamos el siguiente código C?

#include<stdio.h>

int main()

{

 int * ptr = NULL;

 printf("%d",*ptr);

 return 0;

}

En algunas máquinas, lo anterior se compilaría correctamente, pero se bloquea cuando se ejecuta el programa, no es necesario que muestre el mismo comportamiento en todas las máquinas. Nuevamente, depende de muchos factores. Pero la idea de mencionar el fragmento anterior es que siempre debemos verificar NULL antes de acceder a él.

Dado que NULL se define normalmente como ((anulado *) 0), hablemos un poco sobre vacío escriba también. Según la cláusula 6.2.5 del estándar C11, «El tipo vacío comprende un conjunto vacío de valores; es un tipo de objeto incompleto que no se puede completar”. Incluso la cláusula 6.5.3.4 del C11 menciona que “El operador sizeof no se aplicará a una expresión que tenga un tipo de función o un tipo incompleto, al nombre entre paréntesis de dicho tipo, ni a una expresión que designe un miembro de campo de bits.«Básicamente, significa que vacío es un tipo incompleto cuyo tamaño no tiene ningún sentido en los programas C, pero las implementaciones (como gcc) pueden elegir sizeof (vacío) como 1 para que la memoria plana apuntada por el puntero vacío pueda verse como una memoria sin tipo, es decir, una secuencia de bytes. Pero la salida de lo siguiente no tiene por qué ser la misma en todas las plataformas.

#include<stdio.h>

int main()

{

 printf("%lu",sizeof(void));

 return 0;

}

En gcc, lo anterior daría como resultado 1. ¿Qué pasa con sizeof (vacío *)? Aquí C11 ha mencionado pautas. De la cláusula 6.2.5, «Un puntero a void debe tener los mismos requisitos de representación y alineación que un puntero a un tipo de carácter.”. Es por eso que la salida de lo siguiente sería la misma que cualquier tamaño de puntero en una máquina.

#include<stdio.h>

int main()

{

 printf("%lu",sizeof(void *));

 return 0;

}

A pesar de mencionar cosas que dependen de la máquina como se indicó anteriormente, nosotros, como programadores de C, siempre debemos esforzarnos por hacer que nuestro código sea lo más portátil posible. Entonces podemos concluir en NULL de la siguiente manera:

1. Siempre inicialice las variables de puntero como NULL.
2. Realice siempre una comprobación NULL antes de acceder a cualquier puntero.

Por favor, haga Me gusta / Tweet / G + 1 si encuentra útil lo anterior. Además, déjenos un comentario para obtener más aclaraciones o información. Nos encantaría ayudar y aprender 🙂

Si desea aprender de los mejores videos seleccionados y problemas de práctica, consulte el Curso básico de C de Básico a Avanzado C.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

apple touch icon@2

python – ¿Cómo escribir una declaración if en línea para imprimir?

200px Lamborghini Aventador

Ferrari vs Lamborghini: diferencia y comparación