¿Es seguro marcar un puntero para no estar NULL
escribiendo simplemente if(pointer)
o tengo que usarlo if(pointer != NULL)
?
c++
pointers
if-statement
null
null-pointer
danijar
fuente
fuente
0
onullptr
. (NULL
Es un C'ism, y requiere que incluye un archivo de cabecera.)NULL
en C ++ a partir de aquí porqueNULL
es una macro dependiente de la implementación que puede darte comportamientos ambiguos.Respuestas:
Usted puede; el puntero nulo se convierte implícitamente en falso booleano, mientras que los punteros no nulos se convierten en verdadero. Desde el estándar C ++ 11, sección sobre conversiones booleanas:
fuente
Si, podrías.
Esto es parte de la conversión estándar de C ++, que se incluye en la cláusula de conversión booleana :
§ 4.12 Conversiones booleanas
fuente
Sí tu puedes. De hecho, prefiero usarlo
if(pointer)
porque es más fácil de leer y escribir una vez que te acostumbras.También tenga en cuenta que C ++ 11 introdujo
nullptr
que se prefiere sobreNULL
.fuente
if(som_integer)
vsif(some_integer != 0)
porque los enteros tampoco son booleanos, ¿verdad? Prefiero evitar0
oNULL
en una declaración if.if (pointer)
mí mismo, pero meif (ptr != nullptr)
parece perfectamente legítimo. Por otro lado, si veía a alguien en mi equipo que escribieraif (some_integer)
, les haría cambiarloif (some_integer != 0)
. Sin embargo, no voy a fingir que no es una preferencia relativamente arbitraria de mi parte, simplemente prefiero no tratar los punteros y los enteros de la misma manera.if(isReady)
if(filePtr)
if(serviceNo)
? Hacer nombres de variables incorrectos a propósito no significa mucho en este caso. De todos modos, ya entendí tu punto y lo entendí, pero puedo insistir en usar mi propio estilo de codificación, ¿de acuerdo?La pregunta está respondida, pero me gustaría agregar mis puntos.
Siempre preferiré en
if(pointer)
lugar deif(pointer != NULL)
y enif(!pointer)
lugar deif(pointer == NULL)
:Menos posibilidades de escribir un código erróneo, supongo que si lo escribo mal operador de comprobación de igualdad
==
con=
if(pointer == NULL)
pueden estar mal escritasif(pointer = NULL)
Así que voy a evitarlo, lo mejor es simplementeif(pointer)
.(También sugerí alguna condición de Yoda en una respuesta , pero esa es una cuestión diferente)
Del mismo modo
while (node != NULL && node->data == key)
, simplemente escribiré lowhile (node && node->data == key)
que es más obvio para mí (lo demuestra usando cortocircuito).fuente
(boolean expression)? true : false
Es completamente inútil. La expresión evalúa totrue
to tofalse
; lo que dices es "si es verdad, dame verdad, si es falso, dame falso". En resumen: es completamente equivalente a la expresión booleana misma. Tenga en cuenta quenode == NULL
es una expresión booleana. Por cierto, sus dos implementaciones devuelven exactamente lo opuesto entre sí. O quieres!=
en el primero, o solo uno!
en el segundo.=
lugar de==
es hacer sus variablesconst
siempre que sea posible. Por ejemplo, podría definir su función comoisEmnpy(node* const head) { ... }
, y luego el compilador se negaría a compilarla si escribió accidentalmente ennode = NULL
lugar denode == NULL
. Por supuesto, eso solo funciona para variables que realmente no necesita cambiar.T* get() const
lugar deoperator T*() const
evitar conversiones implícitas. Sin embargo, tienen unoperator bool() const
.La comprobación explícita de NULL podría proporcionar una pista al compilador sobre lo que está tratando de hacer, por lo que puede ser menos propenso a errores.
fuente
Sí tu puedes. La capacidad de comparar valores con ceros implícitamente se ha heredado de C, y existe en todas las versiones de C ++. También puede usar
if (!pointer)
para verificar los punteros para NULL.fuente
Los casos de uso relevantes para punteros nulos son
Moldes dinámicos. Lanzar un puntero de clase base a uno particular de clase derivada (algo que debería intentar evitar de nuevo, pero que a veces puede ser necesario) siempre tiene éxito, pero da como resultado un puntero nulo si la clase derivada no coincide. Una forma de verificar esto es
(o, preferiblemente
auto derived_ptr = ...
) Ahora, esto es malo, porque deja el puntero derivado (posiblemente inválido, es decir, nulo) fuera delif
alcance del bloque de protección de seguridad . Esto no es necesario, ya que C ++ le permite introducir variables booleanas convertibles dentro de unaif
condición :que no solo es más corto y seguro para el alcance, también es mucho más claro en su intención: cuando verifica nulo en una condición if separada, el lector se pregunta "ok, entonces
derived_ptr
no debe ser nulo aquí ... bueno, ¿por qué será nulo? Mientras que la versión de una sola línea dice muy claramente "si se puede transmitir de forma segurabase_ptr
aDerived*
, y luego usarlo para ...".Lo mismo funciona igual de bien para cualquier otra operación de posible falla que devuelva un puntero, aunque IMO generalmente debería evitar esto: es mejor usar algo
boost::optional
como el "contenedor" para obtener resultados de posibles operaciones fallidas, en lugar de punteros.Entonces, si el caso de uso principal para punteros nulos siempre se debe escribir en una variación del estilo implícito, diría que es bueno, por razones de coherencia, usar siempre este estilo, es decir, abogaría por
if(ptr)
másif(ptr!=nullptr)
.Me temo que tengo que terminar con un anuncio: la
if(auto bla = ...)
sintaxis es en realidad una aproximación un poco engorrosa a la solución real a tales problemas: la coincidencia de patrones . ¿Por qué forzarías primero alguna acción (como lanzar un puntero) y luego considerarías que podría haber una falla ... Quiero decir, es ridículo, ¿no? Es como si tuvieras algo de comida y quieres hacer sopa. Se lo entrega a su asistente con la tarea de extraer el jugo, si resulta ser un vegetal blando. No lo miras primero. Cuando tienes una papa, todavía se la das a tu asistente, pero te la devuelven en la cara con una nota de falla. ¡Ah, programación imprescindible!Mucho mejor: considere de inmediato todos los casos que pueda encontrar. Entonces actúa en consecuencia. Haskell
Haskell también tiene herramientas especiales para cuando realmente existe una posibilidad seria de falla (así como para un montón de otras cosas): mónadas. Pero este no es el lugar para explicarlos.
⟨/Propaganda⟩
fuente
if(ptr)
lugar de hacerloif(ptr != nullptr)
, para lo cual hay mucho más que decir.¡sí, por supuesto! de hecho, escribir if (puntero) es una forma más conveniente de escribir que if (puntero! = NULL) porque: 1. es fácil de depurar 2. fácil de entender 3. si accidentalmente, se define el valor de NULL, entonces también el código no se bloqueará
fuente
Si. De hecho deberías. Si se pregunta si crea una falla de segmentación , no lo hace.
fuente
Como otros ya respondieron bien, ambos son intercambiables.
Sin embargo, vale la pena mencionar que podría haber un caso en el que desee utilizar la declaración explícita, es decir
pointer != NULL
.Ver también https://stackoverflow.com/a/60891279/2463963
fuente
Sí, siempre puede hacer esto ya que la condición 'SI' se evalúa solo cuando la condición dentro de ella se cumple. C no tiene un tipo de retorno booleano y, por lo tanto, devuelve un valor distinto de cero cuando la condición es verdadera, mientras que devuelve 0 siempre que la condición en 'IF' sea falsa. El valor distinto de cero devuelto por defecto es 1. Por lo tanto, ambas formas de escribir el código son correctas, mientras que siempre preferiré el segundo.
fuente
Creo que, como regla general, si su expresión if puede reescribirse como
de modo que NO provoque ADVERTENCIAS, entonces ESE debería ser el estilo preferido para la expresión if . (Sé que recibo advertencias cuando asigno un C
BOOL
(#define BOOL int
) antiguo a un C ++bool
, por no hablar de punteros).fuente
"Es seguro..?" es una pregunta sobre el estándar de idioma y el código generado.
"¿Es una buena práctica?" es una pregunta sobre qué tan bien la declaración es entendida por cualquier lector humano arbitrario de la declaración. Si hace esta pregunta, sugiere que la versión "segura" es menos clara para futuros lectores y escritores.
fuente