¿Por qué "a"! = "a" en C?

Resuelto Javed Akram asked hace 13 años • 11 respuestas
void main() {
    if("a" == "a")
      printf("Yes, equal");  
    else
      printf("No, not equal");
}

¿Por qué es la salida No, not equal?

Javed Akram avatar Jan 30 '11 22:01 Javed Akram
Aceptado

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
 avatar Jan 30 '2011 15:01

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 strcmpque se encuentra en el archivo de encabezado estándar string.h. La función tiene un valor de retorno de 0para cadenas iguales; se considera una buena práctica comparar explícitamente el valor de retorno 0en lugar de utilizar el operador `!´, es decir

strcmp(str1, str2) == 0 // instead of !strcmp(str1, str2)
eq- avatar Jan 30 '2011 20:01 eq-

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í

Prasoon Saurav avatar Jan 30 '2011 15:01 Prasoon Saurav

Porque son 2 const char*punteros separados, sin valores reales. Estás diciendo algo así 0x019181217 == 0x0089178216que por supuesto devuelve NO.

Usar strcmp()en lugar de==

Antwan van Houdt avatar Jan 30 '2011 15:01 Antwan van Houdt