Compiladores C incorporados permitem void main () porque pode não haver nenhum sistema operacional ao qual fornecer um código de retorno.
Jeanne Pindar
26
Como uma pergunta como essa pode ser votada com tanta frequência? Realmente não é tão interessante ... Quero dizer, que strings são arrays e arrays são ponteiros é realmente um velho chapéu em C, não é?
Felix Dombek
64
@Felix, é uma pergunta escrita concisamente que aborda um ponto comum de confusão para os iniciantes na linguagem. O SO não é apenas para especialistas - é também para iniciantes, e perguntas direcionadas como esta são boas para indicar iniciantes no futuro.
bdonlan
37
@Felix: Você está errado. matrizes não são ponteiros
John Dibling
Respostas:
209
O que você está comparando são os dois endereços de memória para as diferentes strings, que são armazenadas em locais diferentes. Isso basicamente se parece com isto:
if(0x00403064==0x002D316A)// Two memory locations{
printf("Yes, equal");}
Use o seguinte código para comparar dois valores de string:
Além disso, "a" == "a"pode realmente retornar true, dependendo do seu compilador, que pode combinar strings iguais em tempo de compilação em uma para economizar espaço.
Quando você está comparando dois valores de caracteres (que não são ponteiros), é uma comparação numérica. Por exemplo:
GCC também tem as opções -fmerge-constantse -fno-merge-constantspara ativar / desativar corda e constante de ponto flutuante fusão entre as unidades de tradução, embora em alguns GCCs parece que fusão constante é sempre ativada, independentemente de essa opção.
Adam Rosenfield
2
Funcionaria se você usar 'a' em vez de "a". O primeiro é um char, que na verdade é um valor numérico.
GolezTrol
@GolezTrol: em C, o literal 'a' realmente tem inttipo. :-) Além disso, os ponteiros não precisam ser valores numéricos.
Bastien Léonard
inttambém é numérico, não é? Mas eu pensei que chars fossem Byte. Int tem 4 bytes. Os ponteiros em si também são inteiros. Eles contêm o endereço de um monte de dados (dados que de fato não precisam ser numéricos).
GolezTrol
'a' == 'A' // not true... O MySQL discorda.
Steven
52
Estou um pouco atrasado para a festa, mas vou atender mesmo assim; tecnicamente os mesmos bits, mas de uma perspectiva um pouco diferente (linguagem C abaixo):
Em C, a expressão "a"denota um literal de string , que é uma matriz estática não nomeada de const char, com um comprimento de dois - a matriz consiste em caracteres 'a'e '\0'- o caractere nulo de terminação sinaliza o fim da string.
Porém, em C, da mesma forma que você não pode passar arrays para funções por valor - ou atribuir valores a eles ( após a inicialização ) - não há operador sobrecarregado ==para arrays, então não é possível compará-los diretamente. 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
Se o ==não estiver comparando matrizes, o que ele realmente fará? Em C, em quase todos os contextos - incluindo este - os arrays decaem em ponteiros (que apontam para o primeiro elemento do array) - e a comparação de ponteiros para igualdade faz o que você esperaria. Tão eficazmente, ao fazer isso
"a"=="a"
na verdade, você está comparando os endereços dos primeiros caracteres em duas matrizes sem nome . De acordo com o padrão C, a comparação pode resultar em verdadeiro ou falso (ou seja, 1 ou 0) - "a"s pode na verdade denotar o mesmo array ou dois arrays completamente não relacionados. Em termos técnicos, o valor resultante não é especificado , o que significa que a comparação é permitida (ou seja, não é um comportamento indefinido ou um erro de sintaxe), mas qualquer um dos valores é válido e a implementação (seu compilador) não é necessária para documentar o que realmente acontecerá.
Como outros apontaram, para comparar "strings c" (ou seja, strings terminadas com um caractere nulo), você usa a função de conveniência strcmpencontrada no arquivo de cabeçalho padrão string.h. A função tem um valor de retorno de 0para strings iguais; é considerado uma boa prática comparar explicitamente o valor de retorno ao em 0vez de usar o operador `! ´, ou seja,
strcmp(str1, str2)==0// instead of !strcmp(str1, str2)
Não é especificado se essas matrizes são distintas, desde que seus elementos tenham os valores apropriados .
Portanto, neste caso, não é especificado se os dois "a"s são distintos. Um compilador otimizado pode manter um único "a"local somente leitura e ambas as referências podem se referir a ele.
Literais de string não são ponteiros, são matrizes. Eles decaem para indicadores de comparação, no entanto.
GManNickG
@Gman verdade, desculpe por não ter sido muito claro sobre isso, tende a esquecer :)
Antwan van Houdt
9
Simplificando, C não tem nenhum operador de comparação de string embutido. Ele não pode comparar strings dessa maneira.
Em vez disso, as strings são comparadas usando rotinas de biblioteca padrão, como strcmp () ou escrevendo código para percorrer cada caractere na string.
Em C, uma string de texto entre aspas duplas retorna um ponteiro para a string. Seu exemplo está comparando os ponteiros e, aparentemente, suas duas versões da string existem em endereços diferentes.
Mas não é comparar as próprias cordas, como você parece esperar.
O primeiro "a"é um ponteiro para uma string ASCII terminada em nulo.
O segundo "a"é um ponteiro para outra string ASCII terminada em nulo.
Se você estiver usando um compilador de 32 bits, eu esperaria "a"=="a"-4. Acabei de experimentar com tcc / Win32, no entanto, e entendi "a"=="a"-2. Ah bem...
Por que você esperaria que as strings fossem alinhadas ao limite de 4 bytes? Eles não são intentos. 2 é o que eu esperaria (se o compilador não os fundir), já que cada string tem dois bytes de comprimento, incluindo o terminador nulo.
Sergei Tachenov
Algum grau de alinhamento pode, por exemplo, permitir strcmpa execução de vários bytes de uma vez. Alguns compiladores fazem isso, outros não, alguns fazem isso apenas para strings maiores do que o mínimo ...
zwol
@Zack: como eles saberiam o comprimento da string antes de realmente compará-los?
Joachim Sauer
Quero dizer, alguns compiladores alinham strings mais longas do que o mínimo.
zwol
1
Você está comparando dois endereços de memória, então o resultado nem sempre será verdadeiro. Você tentou if('a' == 'a'){...}?
Os caracteres ocupam apenas 1 byte, mas os literais de caracteres, como 'a', na verdade, são inteiros.
Spidey de
0
Alguns compiladores têm a opção 'merge strings' que você pode usar para forçar todas as strings constantes a terem o mesmo endereço. Se você usasse isso, "a" == "a"seria true.
void main
??? Ew ...Respostas:
O que você está comparando são os dois endereços de memória para as diferentes strings, que são armazenadas em locais diferentes. Isso basicamente se parece com isto:
Use o seguinte código para comparar dois valores de string:
Além disso,
"a" == "a"
pode realmente retornar true, dependendo do seu compilador, que pode combinar strings iguais em tempo de compilação em uma para economizar espaço.Quando você está comparando dois valores de caracteres (que não são ponteiros), é uma comparação numérica. Por exemplo:
fonte
-fmerge-constants
e-fno-merge-constants
para ativar / desativar corda e constante de ponto flutuante fusão entre as unidades de tradução, embora em alguns GCCs parece que fusão constante é sempre ativada, independentemente de essa opção.int
tipo. :-) Além disso, os ponteiros não precisam ser valores numéricos.int
também é numérico, não é? Mas eu pensei que chars fossem Byte. Int tem 4 bytes. Os ponteiros em si também são inteiros. Eles contêm o endereço de um monte de dados (dados que de fato não precisam ser numéricos).'a' == 'A' // not true
... O MySQL discorda.Estou um pouco atrasado para a festa, mas vou atender mesmo assim; tecnicamente os mesmos bits, mas de uma perspectiva um pouco diferente (linguagem C abaixo):
Em C, a expressão
"a"
denota um literal de string , que é uma matriz estática não nomeada deconst char
, com um comprimento de dois - a matriz consiste em caracteres'a'
e'\0'
- o caractere nulo de terminação sinaliza o fim da string.Porém, em C, da mesma forma que você não pode passar arrays para funções por valor - ou atribuir valores a eles ( após a inicialização ) - não há operador sobrecarregado
==
para arrays, então não é possível compará-los diretamente. ConsiderarSe o
==
não estiver comparando matrizes, o que ele realmente fará? Em C, em quase todos os contextos - incluindo este - os arrays decaem em ponteiros (que apontam para o primeiro elemento do array) - e a comparação de ponteiros para igualdade faz o que você esperaria. Tão eficazmente, ao fazer issona verdade, você está comparando os endereços dos primeiros caracteres em duas matrizes sem nome . De acordo com o padrão C, a comparação pode resultar em verdadeiro ou falso (ou seja, 1 ou 0) -
"a"
s pode na verdade denotar o mesmo array ou dois arrays completamente não relacionados. Em termos técnicos, o valor resultante não é especificado , o que significa que a comparação é permitida (ou seja, não é um comportamento indefinido ou um erro de sintaxe), mas qualquer um dos valores é válido e a implementação (seu compilador) não é necessária para documentar o que realmente acontecerá.Como outros apontaram, para comparar "strings c" (ou seja, strings terminadas com um caractere nulo), você usa a função de conveniência
strcmp
encontrada no arquivo de cabeçalho padrãostring.h
. A função tem um valor de retorno de0
para strings iguais; é considerado uma boa prática comparar explicitamente o valor de retorno ao em0
vez de usar o operador `! ´, ou seja,fonte
De acordo com C99 (Seção 6.4.5 / 6)
Portanto, neste caso, não é especificado se os dois
"a"
s são distintos. Um compilador otimizado pode manter um único"a"
local somente leitura e ambas as referências podem se referir a ele.Verifique a saída do gcc aqui
fonte
Porque são 2
const char*
ponteiros separados , sem valores reais. Você está dizendo algo como o0x019181217 == 0x0089178216
que obviamente retorna NÃOUse em
strcmp()
vez de==
fonte
Simplificando, C não tem nenhum operador de comparação de string embutido. Ele não pode comparar strings dessa maneira.
Em vez disso, as strings são comparadas usando rotinas de biblioteca padrão, como strcmp () ou escrevendo código para percorrer cada caractere na string.
Em C, uma string de texto entre aspas duplas retorna um ponteiro para a string. Seu exemplo está comparando os ponteiros e, aparentemente, suas duas versões da string existem em endereços diferentes.
Mas não é comparar as próprias cordas, como você parece esperar.
fonte
Ponteiros.
O primeiro
"a"
é um ponteiro para uma string ASCII terminada em nulo.O segundo
"a"
é um ponteiro para outra string ASCII terminada em nulo.Se você estiver usando um compilador de 32 bits, eu esperaria
"a"=="a"-4
. Acabei de experimentar com tcc / Win32, no entanto, e entendi"a"=="a"-2
. Ah bem...fonte
strcmp
a execução de vários bytes de uma vez. Alguns compiladores fazem isso, outros não, alguns fazem isso apenas para strings maiores do que o mínimo ...Você está comparando dois endereços de memória, então o resultado nem sempre será verdadeiro. Você tentou
if('a' == 'a'){...}
?fonte
esta questão estabelece um caminho de explicação muito bom para todos os iniciantes ....
deixe-me também contribuir com isso .....
como todos explicaram acima, por que você está obtendo tal saída.
agora se você quiser seu prog. Para imprimir "sim igual" então
ou use
ou
não use "a" como strings, use-os como caracteres ....
em C os caracteres são um inteiro curto de 1 byte .......
fonte
'a'
, na verdade, são inteiros.Alguns compiladores têm a opção 'merge strings' que você pode usar para forçar todas as strings constantes a terem o mesmo endereço. Se você usasse isso,
"a" == "a"
seriatrue
.fonte
se a comparação entre os caracteres estiver sempre em aspas simples, por exemplo
e C não pode suportar comparação de strings como
"abc" == "abc"
Acabou com
strcmp("abc","abc")
fonte
Esse cara não usa variáveis. Em vez disso, ele usa matrizes de texto temporariamente:
a
ea
. A razão porquenão funciona é claro, é que você não compara variáveis.
Se você criar variáveis como:
então você pode comparar
text
comtext2
, e deve ser verdadeTalvez você não deva se esquecer de usar
{
e}
=)fonte