void main() {
if("a" == "a")
printf("Yes, equal");
else
printf("No, not equal");
}
Dlaczego jest wyjście No, not equal?
void main() {
if("a" == "a")
printf("Yes, equal");
else
printf("No, not equal");
}
Dlaczego jest wyjście No, not equal?
Odpowiedzi:
Porównujesz dwa adresy pamięci dla różnych ciągów, które są przechowywane w różnych lokalizacjach. Zasadniczo wygląda to następująco:
if(0x00403064 == 0x002D316A) // Two memory locations
{
printf("Yes, equal");
}
Użyj poniższego kodu, aby porównać dwie wartości ciągów:
#include <string.h>
...
if(strcmp("a", "a") == 0)
{
// Equal
}
Ponadto "a" == "a"może rzeczywiście zwrócić wartość true, w zależności od kompilatora, który może łączyć równe ciągi w czasie kompilacji w jeden, aby zaoszczędzić miejsce.
Kiedy porównujesz dwie wartości znakowe (które nie są wskaźnikami), jest to porównanie liczbowe. Na przykład:
'a' == 'a' // always true
-fmerge-constantsi -fno-merge-constantswłączyć / wyłączyć ciąg i zmiennoprzecinkowej stałej łączących w poprzek jednostek tłumaczeniowych, choć na niektórych GCCs wydaje się, że stała łączenie jest zawsze włączony, niezależnie od wybranej opcji.
inttyp. :-) Ponadto wskaźniki nie muszą być wartościami liczbowymi.
intjest też numeryczny, prawda? Ale myślałem, że znaki to bajty. Int to 4 bajty. Same wskaźniki również są liczbami całkowitymi. Zawierają adres zbioru danych (danych, które rzeczywiście nie muszą być numeryczne).
'a' == 'A' // not true... MySQL ma inne zdanie.
Trochę spóźniłem się na przyjęcie, ale i tak odpowiem; technicznie te same bity, ale z nieco innej perspektywy (język C poniżej):
W języku C wyrażenie "a"oznacza literał łańcuchowy , który jest statyczną nienazwaną tablicą o const chardługości dwóch - tablica składa się ze znaków 'a'i'\0' - kończący znak null sygnalizuje koniec ciągu.
Jednak w C w ten sam sposób nie można przekazywać tablic do funkcji według wartości - ani przypisywać do nich wartości ( po inicjalizacji ) - nie ma przeciążonego operatora ==dla tablic, więc nie jest możliwe ich bezpośrednie porównanie. Rozważać
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
Jeśli narzędzie ==nie porównuje tablic, to co właściwie robi? W C prawie we wszystkich kontekstach - w tym w tym - tablice rozpadają się na wskaźniki (które wskazują na pierwszy element tablicy) - a porównywanie wskaźników równości robi to, czego można się spodziewać. Tak skutecznie, kiedy to robisz
"a" == "a"
faktycznie porównujesz adresy pierwszych znaków w dwóch nienazwanych tablicach . Zgodnie ze standardem C, porównanie może dać prawdę lub fałsz (tj. 1 lub 0) - "a"s mogą w rzeczywistości oznaczać tę samą tablicę lub dwie zupełnie niepowiązane tablice. Z technicznego punktu widzenia wynikowa wartość jest nieokreślona , co oznacza, że porównanie jest dozwolone (tj. Nie jest to niezdefiniowane zachowanie ani błąd składniowy), ale żadna z wartości jest prawidłowa, a implementacja (Twój kompilator) nie jest wymagana do udokumentowania tego, co faktycznie się wydarzy.
Jak zauważyli inni, aby porównać „łańcuchy c” (tj. Łańcuchy zakończone znakiem null), należy skorzystać z wygodnej funkcji strcmpznajdującej się w standardowym pliku nagłówkowym string.h. Funkcja zwraca wartość 0równych ciągów; za dobrą praktykę uważa się jawne porównywanie zwracanej wartości 0zamiast używania operatora `! ´, tj
strcmp(str1, str2) == 0 // instead of !strcmp(str1, str2)
Zgodnie z C99 (sekcja 6.4.5 / 6)
Literały strunowe
Nie jest określone, czy te tablice są różne, pod warunkiem, że ich elementy mają odpowiednie wartości .
W tym przypadku nie jest określone, czy oba "a"są różne. Zoptymalizowany kompilator może przechowywać pojedynczy plik "a"w lokalizacji tylko do odczytu i oba odwołania mogą się do tego odnosić.
Sprawdź wyjście na gcc tutaj
Ponieważ są to 2 oddzielne const char*wskaźniki, brak rzeczywistych wartości. Mówisz coś takiego, 0x019181217 == 0x0089178216co oczywiście zwraca NIE
Użyj strcmp()zamiast==
Mówiąc najprościej, C nie ma wbudowanego operatora porównania ciągów. W ten sposób nie może porównywać łańcuchów.
Zamiast tego, łańcuchy są porównywane przy użyciu standardowych procedur bibliotecznych, takich jak strcmp (), lub przez pisanie kodu w celu wykonania pętli przez każdy znak w ciągu.
W języku C ciąg tekstu w cudzysłowach zwraca wskaźnik do ciągu. Twój przykład to porównanie wskaźników i najwyraźniej twoje dwie wersje ciągu istnieją pod różnymi adresami.
Ale nie jest to porównywanie samych strun, jak można się spodziewać.
Wskaźniki.
Pierwsza "a"to wskaźnik do łańcucha ASCII zakończonego znakiem null.
Drugi "a"to wskaźnik do innego łańcucha ASCII zakończonego znakiem null.
Jeśli używasz kompilatora 32-bitowego, spodziewałbym się "a"=="a"-4. Jednak właśnie wypróbowałem to z tcc / Win32 i otrzymałem "a"=="a"-2. No cóż...
strcmpna uruchamianie kilku bajtów jednocześnie. Niektórzy kompilatorzy to robią, niektórzy nie, niektórzy robią to tylko dla stringów dłuższych niż jakieś minimum ...
to pytanie wyznacza bardzo dobrą ścieżkę wyjaśnień dla wszystkich początkujących ...
pozwólcie, że się do tego przyczynię .....
jak wszyscy powyżej wyjaśniali, dlaczego otrzymujesz takie wyjście.
teraz, jeśli chcesz swojego prog. Aby wydrukować „tak równe”
albo użyj
if(strcmp("a", "a") == 0)
{
}
lub
nie używaj „a” jako łańcuchów, użyj ich jako znaków ....
if('a'=='a')
{
printf ("yes Equal");
}
w znakach C to 1-bajtowa krótka liczba całkowita .......
'a', są w rzeczywistości liczbami całkowitymi.
Niektóre kompilatory mają opcję „merge strings”, której można użyć do wymuszenia, aby wszystkie stałe ciągi miały ten sam adres. Gdybyś tego użył, "a" == "a"byłby true.
jeśli porównanie między znakami jest zawsze w pojedynczym cudzysłowie, np
if('a' == 'a')
a C nie obsługuje porównywania ciągów, takich jak "abc" == "abc"
Zrobione strcmp("abc","abc")
Ten facet nie używa zmiennych. Zamiast tego używa tymczasowo tablic tekstowych: ai a. Powód dlaczego
void main()
{
if("a" == "a")
printf("Yes, equal");
else
printf("No, not equal");
}
oczywiście nie działa, to że nie porównujesz zmiennych.
Jeśli tworzysz zmienne takie jak:
char * text = "a";
char * text2 = "a";
następnie można porównać textz text2, i powinno to być prawdą
Może nie powinieneś zapomnieć o użyciu {i }=)
void main() {
if("a" == "a")
{
printf("Yes, equal");
}
else
{
printf("No, not equal");
}
}
void main??? Ew ...