Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Объясните работу 6 строк кода


Автор: Black 26.4.2007, 23:40
Недавно начал учить C

Не могу понять код:

Код

void main()
{
    char s[] = "Удалить пробелы и табуляции из строки";
    char *ss, *sd;

    printf("было: %s\n", s);

    for(ss=sd=s; *sd=*ss; ss++)
        if(!(*ss==' ' || *ss=='\t')) sd++;

    printf("стало: %s\n", s);
}


Все, впринципе, понятно, но то как работает цикл for() с указателями ставит меня в тупик  smile 
Объясните, пожалуйста.

Автор: archimed7592 26.4.2007, 23:48
ss=sd=s
эквивалентно
sd = s;
ss = sd;
т. е. инициализируешь ss и sd значением s
*sd=*ss - копируешь символ на кот. указывает ss по адресу на кот. указывает sd
ss++ - сдвигаешь этот указатель на след символ
если *ss не пробел и не табуляция, то сдвигаешь и sd...
другими словами, destination(sd) сдвигаешь ток тогда, когда скопирован был не пробел и не табуляция
ну а source(ss) сдвигаешь всегда...
поскольку строки кончаются нулём - *sd=*ss когда-нибудь вернёт 0 (скопирован 0) и тогда цикл завершится smile

зы. да уж... жестячок получился...

Автор: Black 26.4.2007, 23:59
А как получается, что потом выводят в экран переменную s и она уже без пробелов и знаков табуляции.. хотя в for нет упоминаний о переменной s?

Автор: Xenon 27.4.2007, 00:23
Black, Почему нет? Мы ею иницилизируем ss и sd.

Автор: BigHeart 27.4.2007, 01:33
просто и s и ss и sd это указатели, котоые указывают на одну и ту же область памяти

Автор: Rockie 28.4.2007, 17:07
Black, есть переменная, которая содержит какое-то значение:
Код

int x = 3;

У каждой переменной есть адрес, его можно получить с помощью &:
Код

cout<<&x;

Указатель - это переменная, содержащая такие адреса. Объявим указатель, содержащий в себе адрес переменной x:
Код

int* y = &x;

У нас есть указатель, содержащий в себе адрес перемнной x. Мы хотим через этот указатель получить значение переменной x. Для этого применяется *(разыменование указателя):
Код

cout<<*x;


Ну и в конце концов, у указателя тоже есть адрес:
Код

cout<<&y;


Тогда получаем:
Код

#include<cstdio>

int main()
{
    // массив s[] содержит строку символов, так как есть кавчки,
    // компилятор добавит в конец строки ноль (символ '\0', окончание строки )
    char s[] = "Delete spaces and tabulations";    
    printf("was: %s\n", s);    

    // объявим 2 указателя на сомволы, пока они не инициализированы, в них мусор вместо адресов
    char *ss, *sd;    
    
    //запись s обозначает адрес начала массива, его первого элемента.
    // cout<<s; это то же самое что cout<<&s[0];
    for(ss=sd=s;  // приравниваем оба указателя к s, все теперь указывают на начало массива
        *sd=*ss;  // пока можно приравнять значение по адресу ss значению по адресу sd
                  // (на первой итерации это будет s[0]=s[0];)
        ss++)      // перемещаем указатель ss
        // В общем ss постоянно бежит по массиву и каждый раз меняется с sd, а sd увеличивается
        // только в случае, когда обмен произошел с символом, а не с пробелом
         if(!(*ss==' ' || *ss=='\t')) sd++;
    // поэтому табуляция и пробелы в обменах участвуют, но в массив не попадают
    printf("becomes: %s\n", s);

    return 0;
}



Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)