Los compiladores de C integrados permiten void main () porque puede que no haya ningún sistema operativo al que dar un código de retorno.
Jeanne Pindar
26
¿Cómo se puede votar a favor una pregunta como esta con tanta frecuencia? Realmente no es tan interesante ... quiero decir, que las cadenas son matrices y las matrices son punteros es realmente un viejo sombrero en C, ¿no?
Felix Dombek
64
@Felix, es una pregunta escrita de manera concisa que aborda un punto común de confusión para los recién llegados al idioma. SO no es solo para expertos, también es para principiantes, y preguntas específicas como esta son buenas para recomendar a los principiantes en el futuro.
bdonlan
37
@Felix: Estás equivocado. las matrices no son punteros
John Dibling
Respuestas:
209
Lo que está comparando son las dos direcciones de memoria para las diferentes cadenas, que se almacenan en diferentes ubicaciones. Hacerlo esencialmente se ve así:
if(0x00403064==0x002D316A)// Two memory locations{
printf("Yes, equal");}
Utilice el siguiente código para comparar dos valores de cadena:
Adicionalmente, "a" == "a" puede devolver verdadero, dependiendo de su compilador, que puede combinar cadenas iguales en tiempo de compilación en una para ahorrar espacio.
Cuando está comparando dos valores de caracteres (que no son punteros), es una comparación numérica. Por ejemplo:
GCC también tiene las opciones -fmerge-constantsy -fno-merge-constantspara habilitar / deshabilitar la fusión constante de cadena y punto flotante entre unidades de traducción, aunque en algunas GCC parece que la fusión constante siempre está habilitada independientemente de esa opción.
Adam Rosenfield
2
Funcionaría si usa 'a' en lugar de "a". El primero es un char, que en realidad es un valor numérico.
GolezTrol
@GolezTrol: en C, el literal 'a' en realidad tiene inttipo. :-) Además, los punteros no tienen que ser valores numéricos.
Bastien Léonard
inttambién es numérico, ¿no? Pero pensé que los caracteres eran Byte. Int es 4 bytes. Los punteros en sí mismos también son números enteros. Contienen la dirección de un montón de datos (datos que de hecho no tienen que ser numéricos).
GolezTrol
'a' == 'A' // not true... MySQL pide diferir.
Steven
52
Llego un poco tarde a la fiesta, pero voy a responder 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 de terminación señala el final de la cadena.
Sin embargo, en C, de la misma manera que no puede pasar matrices a funciones por valor, o asignarles valores ( después de la inicialización ), no hay un operador sobrecargado ==para 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 está comparando matrices, ¿qué hace realmente, entonces? 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 la igualdad hace lo que cabría esperar. Tan efectivamente, al hacer esto
"a"=="a"
en realidad, está comparando las direcciones de los primeros caracteres en dos matrices sin nombre . De acuerdo con el estándar C, la comparación puede dar como resultado verdadero o falso (es decir, 1 o 0); "a"s en realidad 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 o un error de sintaxis), pero cualquiera de los valores es válido y la implementación (su compilador) no es necesaria para documentar lo que realmente sucederá.
Como han señalado otros, para comparar "cadenas c" (es decir, cadenas terminadas con un carácter nulo) se utiliza la función de conveniencia que se strcmpencuentra 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 en 0lugar de usar el operador `! ´, es decir
strcmp(str1, str2)==0// instead of !strcmp(str1, str2)
No se especifica si estas matrices son distintas siempre que sus elementos tengan los valores adecuados .
Entonces, en este caso, no se especifica si ambos "a"son distintos. Un compilador optimizado podría mantener un solo"a" en la ubicación de solo lectura y ambas referencias podrían hacer referencia a eso.
Los literales de cadena no son punteros, son matrices. Sin embargo, se convierten en indicadores en comparación.
GManNickG
@Gman es cierto, lo siento por no ser muy claro en eso, tienden a olvidarlo :)
Antwan van Houdt
9
En pocas palabras, C no tiene un operador de comparación de cadenas incorporado. No puede comparar cadenas de esta manera.
En su lugar, las cadenas se comparan usando rutinas de biblioteca estándar como strcmp () o escribiendo código para recorrer cada carácter de la cadena.
En C, una cadena de texto entre comillas dobles devuelve un puntero a la cadena. Su ejemplo es comparar los punteros y, aparentemente, sus dos versiones de la cadena existen en diferentes direcciones.
Pero no se trata de comparar las cadenas en sí, como parece esperar.
¿Por qué esperaría que las cadenas se alineen con el límite de 4 bytes? No son ints. 2 es lo que esperaría (si el compilador no los combina), ya que cada cadena tiene dos bytes de longitud, incluido el terminador nulo.
Sergei Tachenov
Algún grado de alineación puede permitir, por ejemplo, strcmpejecutar varios bytes a la vez. Algunos compiladores lo hacen, otros no, algunos lo hacen solo para cadenas más largas que un mínimo ...
zwol
@Zack: ¿cómo sabrían la longitud de la cadena antes de compararlos?
Joachim Sauer
Quiero decir, algunos compiladores alinean cadenas más largas que un mínimo.
zwol
1
Estás comparando dos direcciones de memoria, por lo que el resultado no siempre será cierto. Lo intentaste if('a' == 'a'){...}?
Los caracteres ocupan solo 1 byte, pero los literales de caracteres, como 'a', son en realidad números enteros.
Spidey
0
Algunos compiladores tienen la opción 'fusionar cadenas' que puede usar para forzar que todas las cadenas constantes tengan la misma dirección. Si usaras eso, "a" == "a"lo sería true.
" y debería ser verdadero " - No. No se especifica si los literales de cadena se almacenarán en la misma ubicación de memoria. Lea las otras respuestas.
void main
??? Ew ...Respuestas:
Lo que está comparando son las dos direcciones de memoria para las diferentes cadenas, que se almacenan en diferentes ubicaciones. Hacerlo esencialmente se ve así:
Utilice el siguiente código para comparar dos valores de cadena:
Adicionalmente,
"a" == "a"
puede devolver verdadero, dependiendo de su compilador, que puede combinar cadenas iguales en tiempo de compilación en una para ahorrar espacio.Cuando está comparando dos valores de caracteres (que no son punteros), es una comparación numérica. Por ejemplo:
fuente
-fmerge-constants
y-fno-merge-constants
para habilitar / deshabilitar la fusión constante de cadena y punto flotante entre unidades de traducción, aunque en algunas GCC parece que la fusión constante siempre está habilitada independientemente de esa opción.int
tipo. :-) Además, los punteros no tienen que ser valores numéricos.int
también es numérico, ¿no? Pero pensé que los caracteres eran Byte. Int es 4 bytes. Los punteros en sí mismos también son números enteros. Contienen la dirección de un montón de datos (datos que de hecho no tienen que ser numéricos).'a' == 'A' // not true
... MySQL pide diferir.Llego un poco tarde a la fiesta, pero voy a responder 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 deconst char
, con una longitud de dos: la matriz consta de caracteres'a'
y'\0'
- el carácter nulo de terminación señala el final de la cadena.Sin embargo, en C, de la misma manera que no puede pasar matrices a funciones por valor, o asignarles valores ( después de la inicialización ), no hay un operador sobrecargado
==
para matrices, por lo que no es posible compararlas directamente. ConsiderarSi
==
no está comparando matrices, ¿qué hace realmente, entonces? 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 la igualdad hace lo que cabría esperar. Tan efectivamente, al hacer estoen realidad, está comparando las direcciones de los primeros caracteres en dos matrices sin nombre . De acuerdo con el estándar C, la comparación puede dar como resultado verdadero o falso (es decir, 1 o 0);
"a"
s en realidad 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 o un error de sintaxis), pero cualquiera de los valores es válido y la implementación (su compilador) no es necesaria para documentar lo que realmente sucederá.Como han señalado otros, para comparar "cadenas c" (es decir, cadenas terminadas con un carácter nulo) se utiliza la función de conveniencia que se
strcmp
encuentra en el archivo de encabezado estándarstring.h
. La función tiene un valor de retorno de0
para cadenas iguales; se considera una buena práctica comparar explícitamente el valor de retorno en0
lugar de usar el operador `! ´, es decirfuente
Según C99 (Sección 6.4.5 / 6)
Entonces, en este caso, no se especifica si ambos
"a"
son distintos. Un compilador optimizado podría mantener un solo"a"
en la ubicación de solo lectura y ambas referencias podrían hacer referencia a eso.Mira el resultado en gcc aquí
fuente
Porque son 2
const char*
punteros separados , sin valores reales. Estás diciendo algo como0x019181217 == 0x0089178216
que por supuesto devuelve NOUsar en
strcmp()
lugar de==
fuente
En pocas palabras, C no tiene un operador de comparación de cadenas incorporado. No puede comparar cadenas de esta manera.
En su lugar, las cadenas se comparan usando rutinas de biblioteca estándar como strcmp () o escribiendo código para recorrer cada carácter de la cadena.
En C, una cadena de texto entre comillas dobles devuelve un puntero a la cadena. Su ejemplo es comparar los punteros y, aparentemente, sus dos versiones de la cadena existen en diferentes direcciones.
Pero no se trata de comparar las cadenas en sí, como parece esperar.
fuente
Punteros.
El primero
"a"
es un puntero a una cadena ASCII terminada en nulo.El segundo
"a"
es un puntero a otra cadena ASCII terminada en nulo.Si está utilizando un compilador de 32 bits, lo esperaría
"a"=="a"-4
. Sin embargo, acabo de probarlo con tcc / Win32 y lo tengo"a"=="a"-2
. Oh bien...fuente
strcmp
ejecutar varios bytes a la vez. Algunos compiladores lo hacen, otros no, algunos lo hacen solo para cadenas más largas que un mínimo ...Estás comparando dos direcciones de memoria, por lo que el resultado no siempre será cierto. Lo intentaste
if('a' == 'a'){...}
?fuente
esta pregunta establece un muy buen rastro de explicación para todos los principiantes ...
permítanme contribuir también .....
como explicaron todos los anteriores, por qué obtiene tal salida.
ahora si quieres tu prog. Para imprimir "sí igual" entonces
o use
o
no use "a" como cadenas, úselas como caracteres ....
en C los caracteres son un entero corto de 1 byte .......
fuente
'a'
, son en realidad números enteros.Algunos compiladores tienen la opción 'fusionar cadenas' que puede usar para forzar que todas las cadenas constantes tengan la misma dirección. Si usaras eso,
"a" == "a"
lo seríatrue
.fuente
si la comparación entre caracteres está siempre entre comillas simples, p. ej.
y C no puede soportar la comparación de cadenas como
"abc" == "abc"
Esta hecho con
strcmp("abc","abc")
fuente
Este tipo no usa variables. En su lugar, usa matrices de texto temporalmente:
a
ya
. La razón por la cualPor supuesto que no funciona, es que no se comparan variables.
Si crea variables como:
entonces podrías comparar
text
context2
, y debería ser ciertoQuizás no deberías olvidarte de usar
{
y}
=)fuente