Сравнение строк в одной строке
В качестве упражнения я хочу реализовать сравнение строк как можно более короткое. Код ниже:
#include <stdio.h>
int strcmp(const char* a, const char* b)
{
for(;a && b && *a && *b && *a++==*b++;);return *a==*b;
}
int main ()
{
const char* s1 = "this is line";
const char* s2 = "this is line2";
const char* s3 = "this is";
const char* s4 = "this is line";
printf("Test 1: %d\n", strcmp(s1, s2));
printf("Test 2: %d\n", strcmp(s1, s3));
printf("Test 3: %d\n", strcmp(s1, s4));
printf("Test 4: %d\n", strcmp(s1, s1));
printf("Test 5: %d\n", strcmp(s2, s2));
return 0;
}
Результат:
Test 1: 0
Test 2: 0
Test 3: 1
Test 4: 0
Test 5: 0
Что не так в случае сравнения строки с самой собой?
ПРИМЕЧАНИЕ: я знаю, что есть более короткое решение, но я хочу найти его сам.
РЕДАКТИРОВАТЬ: компилятор gcc
под Ubuntu.
4 ответа
Пожалуйста, не называйте ваши функции так же, как функции в стандартной библиотеке, если они не предоставляют такую же функциональность. Когда вы это сделаете, вы будете тонко разбивать многие вещи. Видимо, это была ошибка здесь.
Чтобы добавить еще несколько полезных комментариев здесь. Вместо этого используйте цикл while. Не проверяйте, чтобы аргументы были NULL, это плохой стиль, и даже если цикл for завершается из-за этого, оператор return все равно завершится сбоем, потому что будет разыменовываться NULL.
Я проверил ваш код с GCC-4.4.7, и он получил тот же результат. Страница GCC описывает оптимизацию для strcmp
http://gcc.gnu.org/projects/optimize.html
GCC может оптимизировать strcmp (и memcmp), где одна строка является константой для сравнения последовательных байтов с известными постоянными байтами.
Переименуйте свою функцию, и вы получите ожидаемый результат, как показано ниже:
$ cc yourcode.c
$ ./a.out
Test 1: 0
Test 2: 0
Test 3: 1
Test 4: 0
Test 5: 0
$ cc -D strcmp=strcmp1 yourcode.c
$ ./a.out
Test 1: 0
Test 2: 0
Test 3: 1
Test 4: 1
Test 5: 1
Если вы найдете два символа, которые не равны, вы увеличиваете указатели a
а также b
тем не менее, а затем вы вернетесь *a==*b
поэтому вы возвращаете результат сравнения символов за местом, где строки различаются. Лучше сделай это так:
for(;*a && *b && *a==*b; a++, b++) ;
return *a==*b;
И пожалуйста, пожалуйста, переименуйте вашу функцию. это все, кроме strcmp.
РЕДАКТИРОВАТЬ, что не объясняет тестовый пример 4, но это объясняется использованием имени функции strcmp()
как говорят другие ответы.
Вот правильный strcmp
int my_strcmp(char *str1, char *str2)
{
int i;
i = 0;
while (str1[i] || str2[i])
{
if (str1[i] != str2[i])
return (str1[i] - str2[i]);
i++;
}
return (0);
}