• Empleos
  • Sobre nosotros
  • profesionales
    • Inicio
    • Empleos
    • Cursos y retos
  • empresas
    • Inicio
    • Publicar vacante
    • Nuestro proceso
    • Precios
    • Evaluaciones
    • Nómina
    • Blog
    • Comercial
    • Calculadora de salario

0

241
Vistas
¿Puedo usar NULL como sustitución del valor de 0?

¿Puedo usar el puntero NULL como reemplazo del valor de 0 ?

¿O hay algo de malo en eso?


Como por ejemplo:

 int i = NULL;

como reemplazo de:

 int i = 0;

Como experimento compilé el siguiente código:

 #include <stdio.h> int main(void) { int i = NULL; printf("%d",i); return 0; }

Producción:

 0

De hecho, me da esta advertencia, que es completamente correcta por sí sola:

 warning: initialization makes integer from pointer without a cast [-Wint-conversion]

pero el resultado sigue siendo equivalente.


  • ¿Estoy cruzando a "Comportamiento indefinido" con esto?
  • ¿Está permitido utilizar NULL de esta manera?
  • ¿Hay algo de malo en usar NULL como valor numérico en expresiones aritméticas?
  • ¿Y cuál es el resultado y el comportamiento en C++ para este caso?

He leído las respuestas de ¿Cuál es la diferencia entre NULL, '\0' y 0 sobre cuál es la diferencia entre NULL , \0 y 0 , pero no obtuve la información concisa de allí, si es bastante permisible y también derecho a usar NULL como valor para operar en asignaciones y otras operaciones aritméticas.

over 3 years ago · Santiago Trujillo
7 Respuestas
Responde la pregunta

0

Descargo de responsabilidad: no sé C ++. Mi respuesta no debe aplicarse en el contexto de C++

'\0' es un int con valor cero, solo 100% exactamente como 0 .

 for (int k = 10; k > '\0'; k--) /* void */; for (int k = 10; k > 0; k--) /* void */;

En el contexto de punteros , 0 y NULL son 100% equivalentes:

 if (ptr) /* ... */; if (ptr != NULL) /* ... */; if (ptr != '\0') /* ... */; if (ptr != 0) /* ... */;

son todos 100% equivalentes.


Nota sobre ptr + NULL

El contexto de ptr + NULL no es el de punteros. No existe una definición para la adición de punteros en el lenguaje C; se pueden sumar (o restar) punteros y números enteros. En ptr + NULL si ptr o NULL es un puntero, el otro debe ser un número entero, por lo que ptr + NULL es efectivamente (int)ptr + NULL o ptr + (int)NULL y dependiendo de las definiciones de ptr y NULL varios comportamientos se puede esperar: todo funcionando, advertencia de conversión entre puntero y entero, falla al compilar, ...

over 3 years ago · Santiago Trujillo Denunciar

0

NULL es una constante de puntero nulo. En C, podría ser una expresión constante de entero con valor 0 o una expresión de este tipo convertida en void* , siendo lo último más probable. Lo que significa que no puede asumir que usará NULL indistintamente con cero. Por ejemplo, en este ejemplo de código

 char const* foo = "bar"; foo + 0;

No se garantiza que reemplazar 0 con NULL sea un programa C válido, porque la suma entre dos punteros (y mucho menos de diferentes tipos de punteros) no está definida. Hará que se emita un diagnóstico debido a una violación de restricción. Los operandos para la suma no serán válidos .


En cuanto a C++, las cosas son algo diferentes. La falta de una conversión implícita de void* a otros tipos de objetos significó que NULL se definió históricamente como 0 en el código C++. En C ++ 03, probablemente podría salirse con la suya. Pero desde C++11 se puede definir legalmente como la palabra clave nullptr . Ahora nuevamente se produce un error, ya que std::nullptr_t no se puede agregar a los tipos de puntero.

Si NULL se define como nullptr , incluso su experimento se vuelve inválido. No hay conversión de std::nullptr_t a un número entero. Es por eso que se considera una constante de puntero nulo más segura.

over 3 years ago · Santiago Trujillo Denunciar

0

¿Puedo usar el puntero NULL como reemplazo del valor 0?

No , no es seguro hacerlo. NULL es una constante de puntero nulo, que podría tener el tipo int , pero que normalmente tiene el tipo void * (en C) o, de lo contrario, no se puede asignar directamente a un int (en C++ >= 11). Ambos lenguajes permiten que los punteros se conviertan en números enteros, pero no permiten que dichas conversiones se realicen implícitamente (aunque algunos compiladores lo proporcionan como una extensión). Además, aunque es común convertir un puntero nulo en un número entero para obtener el valor 0, el estándar no lo garantiza. Si desea una constante con tipo int y valor 0, deletréelo 0 .

  • ¿Puedo cruzarme con un Comportamiento indefinido con esto?

Sí, en cualquier implementación en la que NULL se expanda a un valor de tipo void * o cualquier otro que no se pueda asignar directamente a int . El estándar no define el comportamiento de su asignación en dicha implementación, ergo, su comportamiento no está definido.

  • ¿Está permitido operar con NULL de esa manera?

Tiene un estilo pobre y se romperá en algunos sistemas y bajo algunas circunstancias. Dado que parece estar usando GCC, se rompería en su propio ejemplo si compilara con la opción -Werror .

  • ¿Hay algo de malo en usar NULL como valor numérico en expresiones aritméticas?

Si. No se garantiza que tenga un valor numérico en absoluto. Si quiere decir 0, escriba 0, que no solo está bien definido, sino que es más breve y claro.

  • ¿Y cómo es el resultado en C++ para ese caso?

El lenguaje C++ es más estricto con respecto a las conversiones que C y tiene reglas diferentes para NULL , pero allí también las implementaciones pueden proporcionar extensiones. Nuevamente, si quiere decir 0, entonces eso es lo que debe escribir.

over 3 years ago · Santiago Trujillo Denunciar

0

De las preguntas frecuentes de C:

P: Si NULL y 0 son equivalentes como constantes de puntero nulo, ¿cuál debo usar?

R: Solo en contextos de puntero NULL y 0 son equivalentes. NULL no debe usarse cuando se requiere otro tipo de 0, aunque podría funcionar, porque hacerlo envía un mensaje de estilo incorrecto. (Además, ANSI permite que la definición de NULL sea ((void *)0) , lo que no funcionará en contextos que no sean de puntero). En particular, no use NULL cuando se desee el carácter nulo ASCII (NUL). Proporcione su propia definición

http://c-faq.com/null/nullor0.html

over 3 years ago · Santiago Trujillo Denunciar

0

¿Puedo usar el puntero NULL como reemplazo del valor 0?

 int i = NULL;

Las reglas varían entre los idiomas y sus versiones. En algunos casos se puede y en otros no. De todos modos, no deberías . Si tiene suerte, su compilador le advertirá cuando lo intente o, mejor aún, no pueda compilar.

En C++, antes de C++11 (cita de C++03):

[lib.soporte.tipos]

NULL es una constante de puntero nulo de C++ definida por la implementación en esta Norma Internacional.

Tiene poco sentido usar una constante de puntero nulo como un número entero. Sin embargo...

[conv.ptr]

Una constante de puntero nulo es una expresión constante integral (5.19) rvalue de tipo entero que se evalúa como cero.

Entonces, técnicamente funcionaría incluso si no tiene sentido. Debido a este tecnicismo, es posible que encuentre programas mal escritos que abusen de NULL .

Desde C++ 11 (cita del último borrador):

[conv.ptr]

Una constante de puntero nulo es un literal entero ([lex.icon]) con valor cero o un prvalue de tipo std​::​nullptr_t .

Un std​::​nullptr_t no se puede convertir a un número entero, por lo que usar NULL como número entero solo funcionaría de forma condicional, dependiendo de las elecciones realizadas por la implementación del lenguaje.

PS nullptr es un prvalue de tipo std​::​nullptr_t . A menos que necesite que su programa se compile en una versión anterior a C++ 11, siempre debe usar nullptr en lugar de NULL .


C es un poco diferente (citas del borrador C11 N1548):

6.3.2.3 Idioma / Conversiones / Otros operandos / Punteros

3 Una expresión constante de entero con el valor 0, o una expresión de este tipo convertida al tipo void * , se denomina constante de puntero nulo. ...

Entonces, el caso es similar a la publicación C++ 11, es decir, el abuso de NULL funciona condicionalmente según las elecciones realizadas por la implementación del lenguaje.

over 3 years ago · Santiago Trujillo Denunciar

0

Sí , aunque dependiendo de la implementación, es posible que necesite un molde. Pero sí, es 100% legítimo, por lo demás.

Aunque es muy, muy, muy mal estilo (¿no hace falta decirlo?).

NULL no es, o era, en realidad C++, es C. Sin embargo, el estándar, como para muchos legados de C, tiene dos cláusulas ([diff.null] y [support.types.nullptr]) que técnicamente hacen NULL C++. Es una constante de puntero nulo definida por la implementación . Por lo tanto, incluso si tiene un mal estilo, técnicamente es tan C++ como puede ser.
Como se señaló en la nota al pie, las posibles implementaciones podrían ser 0 o 0L , pero no (void*)0 .

NULL podría, por supuesto (el estándar no lo dice explícitamente, pero es prácticamente la única opción que queda después de 0 o 0L ) ser nullptr . Ese casi nunca es el caso, pero es una posibilidad legal.

La advertencia que le mostró el compilador demuestra que, de hecho, el compilador no cumple (a menos que haya compilado en modo C). Porque, bueno, según la advertencia, convirtió un puntero nulo (no nullptr que sería de nullptr_t , que sería distinto), por lo que aparentemente la definición de NULL es (void*)0 , que puede no serlo.

De cualquier manera, tiene dos posibles casos legítimos (es decir, el compilador no está roto). Cualquiera de los dos (el caso realista), NULL es algo así como 0 o 0L , entonces tiene conversiones de "cero o uno" a enteros, y está listo para comenzar.

O NULL es de hecho nullptr . En ese caso, tiene un valor distinto que tiene garantías sobre la comparación, así como conversiones claramente definidas de números enteros, pero desafortunadamente no a números enteros. Sin embargo, tiene una conversión claramente definida a bool (que da como resultado false ), y bool tiene una conversión claramente definida a entero (que da como resultado 0 ).

Desafortunadamente, son dos conversiones, por lo que no está dentro de "cero o uno" como se indica en [conv]. Por lo tanto, si su implementación define NULL como nullptr , deberá agregar una conversión explícita para que su código sea correcto.

over 3 years ago · Santiago Trujillo Denunciar

0

No, ya no se prefiere usar NULL (antigua forma de inicialización del puntero).

Desde C++11:

La palabra clave nullptr denota el puntero literal. Es un prvalue de tipo std::nullptr_t. Existen conversiones implícitas de nullptr a valor de puntero nulo de cualquier tipo de puntero y cualquier puntero a tipo de miembro. Existen conversiones similares para cualquier constante de puntero nulo, que incluye valores de tipo std::nullptr_t , así como la macro NULL .

https://en.cppreference.com/w/cpp/language/nullptr

En realidad, std::nullptr_t es el tipo del literal de puntero nulo, nullptr . Es un tipo diferenciado que no es en sí mismo un tipo de puntero o un puntero a un tipo de miembro.

 #include <cstddef> #include <iostream> void f(int* pi) { std::cout << "Pointer to integer overload\n"; } void f(double* pd) { std::cout << "Pointer to double overload\n"; } void f(std::nullptr_t nullp) { std::cout << "null pointer overload\n"; } int main() { int* pi; double* pd; f(pi); f(pd); f(nullptr); // would be ambiguous without void f(nullptr_t) // f(0); // ambiguous call: all three functions are candidates // f(NULL); // ambiguous if NULL is an integral null pointer constant // (as is the case in most implementations) }

Producción:

 Pointer to integer overload Pointer to double overload null pointer overload
over 3 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Nuestro proceso Comercial
Legal
Términos y condiciones Política de privacidad
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recomiéndame algunas ofertas
Necesito ayuda