Pregunta

Sé que la forma correcta de comparar " cadenas " en C es usando strcmp , pero ahora intenté comparar algunas matrices de caracteres con el operador == , y obtuve algunos resultados extraños.

Eche un vistazo al siguiente código:

int main()
{
    char *s1 = "Andreas";
    char *s2 = "Andreas";

    char s3[] = "Andreas";
    char s4[] = "Andreas";

    char *s5 = "Hello";

    printf("%d\n", s1 == s2); //1
    printf("%d\n", s3 == s4); //0
    printf("%d\n", s1 == s5); //0
}

La primera printf imprime correctamente un 1 , lo que indica que no son iguales. Pero, ¿alguien puede explicarme por qué, al comparar las matrices de caracteres, el == devuelve un 0 ?

¿Puede alguien explicarme por qué la primera printf devuelve un 1 (es decir, son iguales) y las matrices de caracteres devuelven un 0 ?

¿Fue útil?

Solución

El == está comparando la dirección de memoria.
Es probable que su compilador haga que s1 y s2 apunten a los mismos datos estáticos para ahorrar espacio.

es decir. El " Andreas " en las dos primeras líneas de código se almacena en sus datos ejecutables. El estándar C dice que estas cadenas son constantes y, por lo tanto, ha optimizado los dos punteros para apuntar al mismo almacenamiento.

Las líneas char [] crean una variable al copiar los datos en la variable y, por lo tanto, se almacenan en una dirección diferente en la pila durante la ejecución.

Otros consejos

Uh ... cuando == imprime un 1, significa que son iguales. Es diferente de strcmp, que devuelve el orden relativo de las cadenas.

Estás comparando direcciones y no las cadenas. Los dos primeros son constantes y solo se crearán una vez.

int main()
{
    char *s1 = "Andreas";
    char *s2 = "Andreas";

    char s3[] = "Andreas";
    char s4[] = "Andreas";

    char *s5 = "Hello";

    printf("%d\n", s1 == s2); //1
    printf("%p == %p\n", s1, s2);
    printf("%d\n", s3 == s4); //0
    printf("%p != %p\n", s3, s4);
    printf("%d\n", s1 == s5); //0
    printf("%p != %p\n", s1, s5);
}

Salida en mi computadora, pero tienes la idea:

1
0x1fd8 == 0x1fd8
0
0xbffff8fc != 0xbffff8f4
0
0x1fd8 != 0x1fe0

Espere un segundo ... 1 significa verdadero, 0 significa falso. Entonces su explicación es parcialmente al revés. En cuanto a por qué las dos primeras cadenas parecen ser iguales: el compilador construyó esa cadena constante (s1 / 2) solo una vez.

s1 == s2 significa " (char *) == (char *) " o que las direcciones son las mismas.

Lo mismo para s3 == s4 . Esa es la " las matrices decaen en punteros " en el trabajo.

Y tiene el significado del resultado de la comparación incorrecto:

0 == 0; /* true; 1 */
42 == 0; /* false; 0 */
"foo" == "bar"; /* false (the addresses are different); 0 */

Todos los valores de s1 a s5 no son char , son punteros a char . Entonces, lo que está comparando son las direcciones de memoria de cada cadena, en lugar de las cadenas en sí.

Si muestra las direcciones de este modo, puede ver en qué están trabajando realmente los operadores de comparación:

#include <stdio.h>

int main() {
  char *s1 = "Andreas";
  char *s2 = "Andreas";

  char s3[] = "Andreas";
  char s4[] = "Andreas";

  char *s5 = "Hello";

  printf("%p\n", s1); // 0x80484d0
  printf("%p\n", s2); // 0x80484d0
  printf("%p\n", s3); // 0xbfef9280
  printf("%p\n", s4); // 0xbfef9278
  printf("%p\n", s5); // 0x80484d8
}

Exactamente dónde se asignan las cadenas en la memoria es específico de la implementación. En este caso, el s1 y el s2 apuntan al mismo bloque de memoria estática, pero no esperaría que ese comportamiento sea portátil.

No puede comparar cadenas, pero puede comparar punteros.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top