2013-06-24 3 views
0

Я просто сделал простую функцию, которая возвращает длиннее введенных символов и печатает их на консоли. Я ожидал некоторую форму ошибки сегментации, когда оба символа равны, но каждый раз он печатает второй символ *. Является ли это формой оптимизации компилятора или я что-то упускаю?Оптимизация компилятора для возвращаемого значения?

Пример ввода: ./longer test test выдает второй «тест» (argv [2]).

Пробовал как clang, так и gcc из любопытства, тот же результат.

#include<stdio.h> 

char* longer(char *, char *); 

int main(int argc, char *argv[]) { 
    printf("%s", longer(argv[1], argv[2])); 
    return 0; 
} 

char* longer(char* s1, char* s2) { 
    char *first, *second; 
    for(first = s1, second = s2; *s1 && *s2; s1++, s2++); 
    return *s1 > *s2 ? first : second; 
} 

Для получения разъяснений, тем дольше функция сравнения значений ASCII текущей позиции, в связи с петлей на нарушения нулевого байта. По сути, сравнение было бы 0> 0, правильно?

+0

поведение вы видите это хорошо, но ваше предположение не является правильным. '0> 0' является ложным, поэтому' second' сохраняется – VoidPointer

+0

Ahh, ничего себе, я вижу свет, я не знаю, почему я был раздутым в течение последних 20 минут. Спасибо, глупый вопрос. –

+0

'return * s1? second: first; 'обеспечивает более простое сравнение. – kfsone

ответ

0

Он должен что-то вернуть. Поэтому он будет возвращаться на основе «истинного» или «ложного». Если s1 не больше s2, он возвращает false. В этом случае это строка «вторая».

0

0 > 0 не соответствует действительности. (Это имеет смысл, ноль не больше нуля).

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

0

Условный return *s1 > *s2 ? first : second; также может выйти из строя, если ваша система использует подписанный символ, и вы вводите строку с символами за пределами 0x7F. Лучше и проще это:

return *s1 ? first : second; 
+0

Я думал о том, чтобы явно отличать char * s до неподписанного при сравнении, но это намного более элегантно. Спасибо. –

0

Если по какой-то причине вам нужно принести в жертву удобочитаемость для уменьшения условий ветвления:

char* longer(char* first, char* second) { 
    char *s1 = first, *s2 = second; 
    for (; ; ++s1, ++s2) 
     if(!*s2) 
      return first; 
     if(!*s1) 
      return second; 
    } 
}