¿Por qué "a"! = "a" en C?
void main() {
if("a" == "a")
printf("Yes, equal");
else
printf("No, not equal");
}
¿Por qué es la salida No, not equal
?
Lo que estás comparando son las dos direcciones de memoria para las diferentes cadenas, que están almacenadas en diferentes ubicaciones. Básicamente, hacerlo se ve así:
if(0x00403064 == 0x002D316A) // Two memory locations
{
printf("Yes, equal");
}
Utilice el siguiente código para comparar dos valores de cadena:
#include <string.h>
...
if(strcmp("a", "a") == 0)
{
// Equal
}
Además, "a" == "a"
es posible que devuelva verdadero, dependiendo de su compilador, que puede combinar cadenas iguales en el momento de la compilación en una para ahorrar espacio.
Cuando comparas valores de dos caracteres (que no son punteros), es una comparación numérica. Por ejemplo:
'a' == 'a' // always true
Llegué un poco tarde a la fiesta, pero voy a contestar de todos modos; Técnicamente los mismos bits, pero desde una perspectiva un poco diferente (lenguaje C a continuación):
En C, la expresión "a"
denota un literal de cadena , que es una matriz estática sin nombre de const char
, con una longitud de dos (la matriz consta de caracteres 'a'
y '\0'
) el carácter nulo final señala el final de la cadena.
Sin embargo, en C, de la misma manera que no se pueden pasar matrices a funciones por valor, ni asignarles valores ( después de la inicialización ), no hay ningún operador sobrecargado ==
para las matrices, por lo que no es posible compararlas directamente. Considerar
int a1[] = {1, 2, 3};
int a2[] = {3, 4, 5};
a1 == a2 // is this meaningful? Yes and no; it *does* compare the arrays for
// "identity", but not for their values. In this case the result
// is always false, because the arrays (a1 and a2) are distinct objects
Si ==
no compara matrices, ¿qué hace realmente? En C, en casi todos los contextos, incluido este, las matrices se descomponen en punteros (que apuntan al primer elemento de la matriz), y comparar punteros para determinar la igualdad hace lo que cabría esperar. De manera tan efectiva, al hacer esto
"a" == "a"
en realidad estás comparando las direcciones de los primeros caracteres en dos matrices sin nombre . Según el estándar C, la comparación puede dar como resultado verdadero o falso (es decir, 1 o 0); "a"
en realidad, s puede denotar la misma matriz o dos matrices completamente no relacionadas. En términos técnicos, el valor resultante no está especificado , lo que significa que la comparación está permitida (es decir, no es un comportamiento indefinido ni un error de sintaxis), pero cualquiera de los valores es válido y no se requiere que la implementación (su compilador) documente lo que realmente sucederá.
Como otros han señalado, para comparar "cadenas c" (es decir, cadenas terminadas con un carácter nulo), se utiliza la función de conveniencia strcmp
que se encuentra en el archivo de encabezado estándar string.h
. La función tiene un valor de retorno de 0
para cadenas iguales; se considera una buena práctica comparar explícitamente el valor de retorno 0
en lugar de utilizar el operador `!´, es decir
strcmp(str1, str2) == 0 // instead of !strcmp(str1, str2)
Según C99 (Sección 6.4.5/6)
Literales de cadena
No se especifica si estas matrices son distintas siempre que sus elementos tengan los valores apropiados .
Entonces, en este caso no se especifica si ambas "a"
s son distintas. Un compilador optimizado podría mantener uno "a"
en la ubicación de solo lectura y ambas referencias podrían hacer referencia a eso.
Consulte el resultado en gcc aquí
Porque son 2 const char*
punteros separados, sin valores reales. Estás diciendo algo así 0x019181217 == 0x0089178216
que por supuesto devuelve NO.
Usar strcmp()
en lugar de==