Я не понимаю эту C программу, созданную с помощью указателей - PullRequest
0 голосов
/ 12 января 2020

Я видел эту C программу, которая копирует первую строку во вторую, используя указатели.

void copy(char const *s1, char *s2)
{ 
    for(;(*s2=*s1);++s1,++s2){};
}

Я понимаю, почему это работает, но я не могу понять, как для l oop знает, когда остановиться, потому что я мог написать (*s2=*s1)!='\0', и это работает, но если я не пишу! = '\ 0', это тоже работает. Как для l oop узнать, когда остановиться?

Ответы [ 3 ]

2 голосов
/ 12 января 2020

Скобки указывают, что критерий проверки является результатом присвоения местоположению, указанному s1 (левый операнд). Другими словами, l oop работает до тех пор, пока значение *s2 не станет ложным.

(*s2=*s1)!='\0' эквивалентно (*s2=*s1)!=0, что эквивалентно (*s2=*s1); или (*s2=*s1)==true, если вы предпочитаете. Очевидно, ненулевое значение оценивается как истина, поэтому l oop выполняется до тех пор, пока вторая строка не будет иметь нулевой терминатор.

2 голосов
/ 12 января 2020

Символ между одинарными кавычками является символом. Символ \0 имеет значение 0, поэтому

char a = '\0`;

равно

char a = 0;

И, таким образом, if (x != '\0') равно if (x != 0), что равно if (x) похоже в состоянии как часть for.

1 голос
/ 12 января 2020

Это становится основой того, как C различает истину и ложь.

True - любое ненулевое значение (любой бит в целом числе). В то время как тесты условий, такие как == и >, выдают значение 1, любое ненулевое значение работает на true.

False - это значение нуля (все биты выключены) в целое число), который включает NULL в указателях.

Значение '\0', конечно, является двоичным нулем, поэтому (*s2++=*s1++) в части условия for выполняет неявный тест для ненулевой, так что это работает, и до тех пор, пока \0 не будет скопирован. \0 возвращает false и выходит из l oop. Добавление собственного !='\0' добавляет явный тест для того же самого.

Осторожно: Если вы просто использовали неправильный *s1++ = *s2++ != '\0' без скобок, он будет рассматриваться как очень глючный *s1++ = (*s2++ != '\0'), который назначит серию из 1 для * s1, за которой следует '\0' для завершения «строки». К сожалению.

...