Форум программистов, компьютерный форум CyberForum.ru

Сравнение двух строк оператором == - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.67
Trydorg
1 / 1 / 0
Регистрация: 23.03.2011
Сообщений: 25
03.09.2011, 21:01     Сравнение двух строк оператором == #1
Мое почтение, уважаемые форумчане!
Делаю шаблонный класс и случайно столкнулся с аномалией в моем понимании сравнения строк: две строки (char*) безошибочно сравниваются оператором == в операторе if.
Подскажите, пожалуйста, как в данном случае происходит сравнение и почему работает == без перегрузки такового?
Спасибо.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.09.2011, 21:01     Сравнение двух строк оператором ==
Посмотрите здесь:

Сравнение двух строк C++
Сравнение двух строк C++
C++ Сравнение двух символьных строк
Осуществить сравнение первых n символов двух строк C++
C++ Сравнение двух строк без учета пробелов
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Сыроежка
Заблокирован
03.09.2011, 21:05     Сравнение двух строк оператором == #2
Цитата Сообщение от Trydorg Посмотреть сообщение
Мое почтение, уважаемые форумчане!
Делаю шаблонный класс и случайно столкнулся с аномалией в моем понимании сравнения строк: две строки (char*) безошибочно сравниваются оператором == в операторе if.
Подскажите, пожалуйста, как в данном случае происходит сравнение и почему работает == без перегрузки такового?
Спасибо.
char * - это не строка, а указатель на символьный массив ( или даже пролсто один символ). Поэтому когда вы сравниваете две переменные, объявленные как char * , вы сравниваете адреса этих символьных массивов, а не сами символьные массивы.

Чтобы сравнить сами символьные массивы, используйте стандартную функцию strcmp из библиотеки <cstring>, если работаете на С++, или <string.h>, если работаете на С.
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
03.09.2011, 21:08     Сравнение двух строк оператором == #3
Trydorg, код в студию.


Если вы делаете так:

C
1
2
3
4
5
6
7
8
9
10
11
char *a = "hello";
char *b = "goodbye";
 
if( a == b )
{
   puts( "equal" );
}
else
{
   puts( "different" );
}
То тогда происходит сравнение указателей. Но тут и строки, и указатели разные - "equal" выводить не должно в принципе:
Trydorg
1 / 1 / 0
Регистрация: 23.03.2011
Сообщений: 25
03.09.2011, 21:14  [ТС]     Сравнение двух строк оператором == #4
Ок!

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
using namespace std;
int main()
{
    char* a = "hello";
    char* b = "helli";
 
    if( a == b )
    {
        puts( "equal" );
    }
    else
    {
        puts( "different" );
    }
    return 0;
}
Почему different?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
using namespace std;
int main()
{
    char* a = "hello";
    char* b = "hello";
 
    if( a == b )
    {
        puts( "equal" );
    }
    else
    {
        puts( "different" );
    }
    return 0;
}
Почему equal?
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
03.09.2011, 21:18     Сравнение двух строк оператором == #5
Код
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
 
int main()
{
    char* a = "hello";
    char* b = "helli";
 
    printf( "a: 0x%x\nb: 0x%x\n", a, b );
 
    if( a == b )
    {
        puts( "equal" );
    }
    else
    {
        puts( "different" );
    }
    return 0;
}


Вывод
a: 0x403024
b: 0x40302a
different
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
03.09.2011, 21:20     Сравнение двух строк оператором == #6
Цитата Сообщение от Trydorg Посмотреть сообщение
Почему different?
Цитата Сообщение от Trydorg Посмотреть сообщение
Почему equal?
А почему один и тот же код у Вас даёт разные результаты? В обоих случаях different должно быть. (О, отредактировано уже). Но не потому, что строки разные, а потому, что компилятор расположил их по разным адресам. Одинаковые же строки компилятор может разместить как в одном месте (чаще всего так, но совсем не обязательно), так и в разных.

Добавлено через 58 секунд
Как уже сказано выше, null-terminated строки надо сравнивать с помощью функций вроде strcmp()
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
03.09.2011, 21:20     Сравнение двух строк оператором == #7
Trydorg, как уже говорил Сыроежка, сравнивайте строки при помощи strcmp
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
03.09.2011, 21:22     Сравнение двух строк оператором == #8
Цитата Сообщение от Trydorg Посмотреть сообщение
Почему different?
Потому что char * это никакая не строка, а всего лишь указатель на char. И сравниваем мы не строки, а указатели на них. Естественно, что указатели разные.

Цитата Сообщение от Trydorg Посмотреть сообщение
Почему equal?
Потому что компилятор оптимизирующий и хранит дублирующиеся строковые значения в одном месте. Но он не обязан этого делать. Например, gcc
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
diagon@shadeware:~$ cat 11.cpp && gcc 11.cpp && ./a.out
#include <stdio.h>
int main()
{
    char * a = "abc";
    char * b = "abс";
    printf("a == b is %s\n", a == b ? "true" : "false");
}
11.cpp: In function ‘int main()’:
11.cpp:4:13: warning: deprecated conversion from string constant to ‘char*11.cpp:5:13: warning: deprecated conversion from string constant to ‘char*’
a == b is false
diagon@shadeware:~$
Сыроежка
Заблокирован
03.09.2011, 21:26     Сравнение двух строк оператором == #9
Цитата Сообщение от Trydorg Посмотреть сообщение
Ок!

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
using namespace std;
int main()
{
    char* a = "hello";
    char* b = "helli";
 
    if( a == b )
    {
        puts( "equal" );
    }
    else
    {
        puts( "different" );
    }
    return 0;
}
Почему different?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
using namespace std;
int main()
{
    char* a = "hello";
    char* b = "hello";
 
    if( a == b )
    {
        puts( "equal" );
    }
    else
    {
        puts( "different" );
    }
    return 0;
}
Почему equal?
В первом случае у вас не равенство, потому что строковые литералы различны, а поэтому компилятор их размещает в разных частях памяти.
Во-втором случае код на самом деле зависит от реализации компилятора или от опции компилирования. То есть стандарт оставляет на усмотрение разработчиков компиляторов, как размещать в памяти строковые литералы, если они совпадают. Разработчики их могут помещать в одном месте, чтобы не транжировать память, а могут для каждого равного строкового литерала выделять отдельную память.
В вашем случае компилятор для совпадающих строковых литералов выделил память для хранения одного экземпляра, чтобы их не дублировать.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.09.2011, 21:31     Сравнение двух строк оператором ==
Еще ссылки по теме:

C++ Сравнение двух строк функцией strcmp
C++ Сравнение двух строк string
C++ Сравнение двумерного массива созданного из двух строк

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Trydorg
1 / 1 / 0
Регистрация: 23.03.2011
Сообщений: 25
03.09.2011, 21:31  [ТС]     Сравнение двух строк оператором == #10
Спасибо, господа!
Открыли глаза на хранение одинаковых строк по одному адресу, зачастую.
А то я уже было думал, что незыблемые постулаты дают трещину.
Yandex
Объявления
03.09.2011, 21:31     Сравнение двух строк оператором ==
Ответ Создать тему
Опции темы

Текущее время: 16:50. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru