Что именно возвращает strcmp() в C?

Я написал этот код на C:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

int main()
{
    char string1[20];
    char string2[20];
    strcpy(string1, "Heloooo");
    strcpy(string2, "Helloo");
    printf("%d", strcmp(string1, string2));
    return(0);
}

Должна ли консоль печатать значение 1 или разницу между ASCII значениями o и \0 символа, т.е. 111? На этом сайте написано, что это должно выдавать put 111, но когда я запускаю это на моем ноутбуке, он показывает 1. Почему?


person Akhil Raj    schedule 16.01.2016    source источник
comment
strcmp возвращает -1 (меньше 0), 0 (равно) или 1 (больше чем 0). Один из способов узнать это — поискать в Google man strcmp. ПРИМЕЧАНИЯ: 1) ваш сайт неправильный. 2) strcmp() ожидает строку C (массив символов с нулевым завершением); не индивидуальное значение char.   -  person paulsm4    schedule 16.01.2016
comment
На каком сайте написано, что должно выдавать 111?   -  person tkausl    schedule 16.01.2016
comment
Это зависит от реализации.   -  person BLUEPIXY    schedule 16.01.2016
comment
@paulsm твой ответ неверен. это зависит от реализации, если это дает -1, это также может дать разницу в ascii-значениях   -  person Peter Miehle    schedule 16.01.2016
comment
@tkausl tutorialspoint.com/ansi_c/c_strcmp.htm   -  person Akhil Raj    schedule 16.01.2016
comment
@ Питер Миль3. Я никогда не видел и не слышал о реализации, которая дает что-либо кроме 0, ‹ 0 или › 0. Я не верю вам, но... Q: Вы можете привести ссылку на одну из них?   -  person paulsm4    schedule 16.01.2016
comment
@ paulsm4 на самом деле большинство оптимизированных библиотек возвращают разницу между символами вместо 1 и -1. Например, Google bionic, glibc и BSD,   -  person phuclv    schedule 19.05.2018
comment
Версия FreeBSD   -  person phuclv    schedule 19.05.2018


Ответы (6)


Из документации cppreference.com.

int strcmp( const char *lhs, const char *rhs );

Возвращаемое значение

  • Отрицательное значение, если левая стоит перед правой в лексикографическом порядке.

  • Ноль, если левая и правая стороны равны.

  • Положительное значение, если левая следует после правой в лексикографическом порядке.

Как вы можете видеть, он просто говорит «отрицательный», «ноль» или «положительный». Вы не можете рассчитывать ни на что другое.

Сайт, на который вы ссылаетесь, не является неверным. Он сообщает вам, что возвращаемое значение равно < 0, == 0 или > 0, и дает пример и показывает его вывод. Он не говорит, что вывод должен быть 111.

person bolov    schedule 16.01.2016
comment
Итак, возвращаемое значение будет -1, 0, 1? или это могут быть другие значения? - person c-an; 10.06.2020
comment
@c-an любое отрицательное значение, нуль и любое положительное значение соответственно - person bolov; 10.06.2020
comment
Итак, какова ценность? Как он определяет стоимость? - person c-an; 11.06.2020
comment
@c-an не имеет значения, какое значение. Стандарт не навязывает определенное значение намеренно. Это до реализации. Некоторые просто возвращают -1 0 и 1, некоторые могут оптимизировать и возвращать разницу. В комментариях к вопросу у вас есть ссылки на некоторые реализации, которые возвращают разницу между первой несовпадающей парой символов. - person bolov; 11.06.2020

Чтобы процитировать справочную страницу:

Функции strcmp() и strncmp() возвращают целое число, меньшее, равное или большее нуля, если найдено, что s1 (или его первые n байтов) соответственно меньше, соответствует или больше s2. .

Другими словами, вы никогда не должны полагаться на точное возвращаемое значение strcmp (конечно, кроме 0). Единственная гарантия состоит в том, что возвращаемое значение будет отрицательным, если первая строка «меньше», положительным, если первая строка «больше», или 0, если они равны. Одни и те же входные данные могут генерировать разные результаты на разных платформах с разными реализациями strcmp.

person Mureinik    schedule 16.01.2016

strcmp возвращает 'значение меньше 0', если строка1 в алфавитном порядке меньше строки2; zero, если они равны; и 'значение больше 0', если строка 1 в алфавитном порядке больше строки 2.

person Peter Miehle    schedule 16.01.2016

Результат зависит от реализации. Достойной реализацией функции strcmp будет:

int strcmp (const char * s1, const char * s2)
{
    for(; *s1 == *s2; ++s1, ++s2)
        if(*s1 == 0)
            return 0;
    return *(unsigned char *)s1 < *(unsigned char *)s2 ? -1 : 1;
}

Приведенная выше реализация возвращает -1, если s1 ‹ s2, 1, если s1 > s2, и 0, если s1 = s2.
Но обычно существует более быстрая версия, реализованная для реального использования:

int strcmp (const char * s1, const char * s2)
{
    for(; *s1 == *s2; ++s1, ++s2)
        if(*s1 == 0)
            return 0;
    return *(const unsigned char *)s1 - *(const unsigned char *)s2;
}

Обратите внимание, что это быстрее, потому что пропускает ветвление, которое выполнялось ранее. Поэтому обычно принято соглашение, согласно которому отрицательное возвращаемое значение означает, что s1 лексикографически меньше, чем s2, а положительное значение означает, что наоборот.

person Aseem Baranwal    schedule 16.01.2016
comment
Исторически это могло быть причиной, но оптимизирующий компилятор обычно может избежать дополнительной ветки в первой версии. Первая версия может быть еще на пару циклов быстрее, но эта разница будет незначительна. Фактическая strcmp в библиотеке будет оптимизирована гораздо сильнее, см. эта версия strcmp медленнее"> stackoverflow.com/questions/44874690/ - person Carsten S; 08.07.2017

int strcmp(const char *str1, const char *str2)

вернет значение меньше, равное или больше 0. Если он возвращает 0, это означает, что две строки равны, если он возвращает значение младше 0, это указывает, что str1 меньше, чем str2. Если он возвращает значение > 0, это означает, что str2 меньше, чем str1.

Ваше возвращаемое значение равно 1, потому что "Heloooo" на один символ больше, чем "Hellooo". На самом деле в слове Helloo 6 символов, а в Heloooo 7 символов. Ровно еще один символ.

person Claudio Cortese    schedule 16.01.2016

По сути, strcmp() может вернуть следующее:

  • > 0, если вторая строка меньше первой первой строки.

    char s1, s2;
    strcpy (s1, "helloworld");
    strcpy (s2, "world");
    int check = strcmp (s1, s2);
    
  • 0, если переданные строки совпадают.

    char s1, s2;
    strcpy (s1, "hello");
    strcpy (s2, "hello");
    int check = strcmp (s1, s2);
    

    В этом случае, поскольку строки равны, проверка будет иметь 0.

  • < 0, если первая строка меньше второй строки.

    char s1, s2;
    strcpy (s1, "hello");
    strcpy (s2, "worldhello");
    int check = strcmp (s1, s2);
    

Итак, в вашем случае strcmp () вернет 1, поскольку строки не равны.

Ознакомьтесь с этим и это руководство по strcmp ().

person Ashish Ahuja    schedule 16.01.2016