2013-08-30 3 views
1
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

int main() 
{ 
    static char s1[]="Good"; 
    static char s2[20]; 
    static char s3[20]="Day"; 

    int i = strcmp(strcat(s3,strcpy(s2,s1)),strcat(s3,"good")); 

    printf("%d\n",i); 

    return 0; 
} 

Здесь вывод равен 0, что означает, что две строки, переданные как аргументы в strcmp, равны. Но для strcmp первый аргумент - "DaygoodGood", а второй - "Daygood" ...Неожиданный вывод при выполнении строковых методов

Почему это происходит?

+0

@WhozCraig, вы правы, но это не имеет никакого отношения к причине, по которой он не получает ожидаемого результата. – nickie

+0

strcat (s3, «good») ..... справа налево ассоциативный – user2712068

ответ

4

Вы сравниваете s3 с s3, независимо от того, как вы на это смотрите. Вы всегда будете равны в этом. Просто разбейте его - изменение:

i=strcmp(strcat(s3,strcpy(s2,s1)),strcat(s3,"good")); 

в:

char *s4 = strcpy(s2,s1);  // s4 == s2 -> "Good" 
    char *s5 = strcat(s3,s4);  // s5 == s3 -> "DayGood" 
    char *s6 = strcat(s3,"good"); // s6 == s3 -> "DayGoodgood" 

    i = strcmp(s5, s6);   // same as strcmp(s3, s3) 

Теперь это действительно происходит ли так, или если это:

char *s4 = strcpy(s2,s1);  // s4 == s4 -> "Good" 
    char *s6 = strcat(s3,"good"); // s6 == s3 -> "Daygood" 
    char *s5 = strcat(s3,s4);  // s5 == s3 -> "DaygoodGood" 

    i = strcmp(s5, s6);   // same as strcmp(s3, s3) 

Вместо этого, не определен в стандарт. Независимо от того, вы сравниваете одинаковые строки, в зависимости от того, в каком порядке выполняются конкатенации. Вы либо сравниваете "DayGoodgood", либо "DayGoodgood", либо "DaygoodGood" - "DaygoodGood", но в любом случае вы должны ожидать 0 в любом случае.

+0

+1 комментарии после звонков, вероятно, помогут OP, по крайней мере, увидеть, что он не сравнивает только «идентичные строки», он сравнивает * то же самое * строка в * сама *. – WhozCraig

+0

Спасибо - я пытался придумать хороший способ объяснить это. –

+0

«printf («% p,% p \ n, (void *) s5, (void *) s6); 'или некоторые из них, вероятно, будут приводить последний гвоздь в гроб = P – WhozCraig

3

из strcat(t, s) всегда равен t. Если вы считаете это запутанным, помните, что строки в C являются символами указателей, поэтому мы говорим о том, что оба указателя равны, а не о (предыдущем или текущем) содержимом строки t.

Таким образом, две приведенные строки соответствуют s3 и s3, независимо от того, что содержит s3. Конечно, они равны.

1

Это потому, что первые strcat возвращает s3, как и второй. Первый вызов добавляет что-то к содержимому s3, второе добавляет больше, но оба возвращают один и тот же указатель.

1

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

Первым понятием является «побочные эффекты». То есть, когда параметр вызывает функцию, тогда эта функция может изменять данные так, чтобы как оценивался параметр.

Например, при оценке strcmp(A,B) этот параметр сначала оценивается, A или B? Если A и B являются просто переменными, то это делает NOT вопрос. Однако, если они сами являются функциями, это может иметь значение: strcmp(A(1), B(2)) может быть, может быть, иметь значение, если сначала оценивается A (1), или B(2).

Давайте посмотрим конкретно на ваш код:

strcmp(strcat(s3,strcpy(s2,s1)),strcat(s3,"good")); 

Он может быть оценен внутренне компилятором как:

A) 
    strcat(s3,strcpy(s2,s1)); //s3 = "DayGood' 
    strcat(s3,"good");   //s3 = "DayGoodgood" 
    strcmp(s3, s3); 

или она может быть оценена как:

B) 
    strcat(s3,"good");   // s3 = "Daygood" 
    strcat(s3,strcpy(s2,s1)); // s3 = "DaygoodGood" 
    strcmp(s3, s3); 

Так , s3 имеет два возможных значения, в зависимости от того, как компилятор оценивает параметры, а разница свидетельствует о " побочные эффекты".

Наконец, чтобы увидеть, как ваш компилятор работает, измените PRINTF заявление:

printf("\n%d, %s\n\n", i, s3); 

Надеется, что это помогает.

+0

спасибо ... я получил его ... но если мы рассмотрим любое решение, как вы упомянули (рассмотрим B) ... второй аргумент - «Daygood», а сначала «DaygoodGood» ... так что окончательное выражение становится strcmp («DaygoodGood», «Daygood»)) .... это не ??? ... – user2712068

+0

@ user2712068, нет, они оба «DaygoodGood». Они оба 's3', поэтому они оба являются одной и той же строкой. –

+0

поэтому, сравнивая только базовый адрес s3 возвращается .... следовательно, при сравнении, s3 изменен на DaygoodGood по его адресу ... это правильно ???? – user2712068

Смежные вопросы