Comparando as matrizes de caracteres com um operador em C ==
-
05-07-2019 - |
Pergunta
Eu sei que a maneira correta de comparar "strings" em C está usando strcmp
, mas agora eu tentei comparar alguns arrays de caracteres com o operador ==
, e conseguiu alguns resultados estranhos.
Dê uma olhada no seguinte 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
}
O primeiro printf
imprime corretamente uma 1
, o que sinaliza que eles não são iguais. Mas alguém pode me explicar por que, quando comparados os arrays de caracteres, o ==
está retornando um 0
?
Alguém por favor pode me explicar por que o primeiro printf
está retornando um 1
(ou seja, eles são iguais) e as matrizes de caracteres são retornando um 0
?
Solução
O == é comparar o endereço de memória.
É provável que o seu compilador está fazendo S1 e S2 ponto aos mesmos dados estáticos para economizar espaço.
ie. Os "Andreas" nas duas primeiras linhas de código é armazenado em seus dados executáveis. O padrão C diz que essas cordas são constantes e por isso tem optomized os dois ponteiros para apontar para o mesmo armazenamento.
O char [] linhas criar uma variável copiando os dados para a variável e, assim, são armazenados no endereço diferente na pilha durante a execução.
Outras dicas
Uh ... quando ==
imprime a 1, isso significa que eles são iguais. É diferente de strcmp, que retorna a ordem relativa das cordas.
Você está comparando os endereços e não as cordas. Os dois primeiros são constantes e só será criado uma 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);
}
Saída no meu computador, mas você começa a idéia:
1
0x1fd8 == 0x1fd8
0
0xbffff8fc != 0xbffff8f4
0
0x1fd8 != 0x1fe0
Espere um pouco ... 1 significa verdadeiro, 0 significa falso. Portanto, sua explicação é parcialmente para trás. Quanto ao porquê das duas primeiras cordas parecem ser iguais: O compilador construído constante cadeia de caracteres (S1 / 2) apenas uma vez
. meios s1 == s2
"(char*) == (char*)
" ou que os endereços são os mesmos.
A mesma coisa para s3 == s4
. Essa é a " matrizes decadência em ponteiros " no trabalho .
E você tem o significado do resultado da errada comparação:
0 == 0; /* true; 1 */
42 == 0; /* false; 0 */
"foo" == "bar"; /* false (the addresses are different); 0 */
Todos os valores de S1 até S5 não são caractere próprios, eles são ponteiros para caractere . Então, o que você está comparando são os endereços de memória de cada corda, em vez das próprias cordas.
Se você exibir os endereços assim, você pode ver o que os operadores de comparação estão realmente trabalhando em:
#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
}
Exatamente onde as cordas são alocados na memória é a aplicação específica. Neste caso, o S1 e S2 estão apontando para o mesmo bloco de memória estática, mas eu não esperaria que o comportamento a ser portátil.
Você não pode comparar strings, mas você pode comparar ponteiros.