2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 Функция, которая удаляет нужный символ из строки [C ]
Сообщение01.08.2012, 09:25 
Аватара пользователя


26/02/11
332
Вновь из Кернигана-Ритчи не могу понять устройство следующей функции.
Цитата: "Для примера рассмотрим функцию squeeze (s, с), которая удаляет все вхождения
символа с из строки s.
Используется синтаксис C
/* squeeze: удаляет все символы с из строки s */
void squeeze(char s [] , int c)
{
    int i, j ;
    for (i = j = 0; s[i] != '\0'; i++)
    if (s[i] != c)
        s [j+ + ] = s [i] ;
    s[j] = '\0';
}

Всякий раз, когда встречается символ, отличный от с, он копируется в текущую
позицию j, и только затем j инкрементируется, чтобы подготовиться к приему
следующего символа. Эта форма в точности эквивалентна следующей":
Используется синтаксис C
if (s[i] != с) {
    s[j] = s[i] ;
    j++;
}

Вопрос:
Почему после первого, отличного от 'с' символа цикл продолжает выполняться? Допустим s[0] отличен от с, тогда s[1] = '\0', но ведь в заголовке for s[i] != '\0'. Объясните пожалуйста.

 Профиль  
                  
 
 Re: Функция, которая удаляет нужный символ из строки
Сообщение01.08.2012, 10:10 
Заслуженный участник
Аватара пользователя


11/03/08
9540
Москва
Dosaev в сообщении #601751 писал(а):
Допустим s[0] отличен от с, тогда s[1] = '\0',


Почему? С чего Вы это взяли?

 Профиль  
                  
 
 Re: Функция, которая удаляет нужный символ из строки
Сообщение01.08.2012, 10:16 
Заслуженный участник


11/05/08
32166
Dosaev в сообщении #601751 писал(а):
Допустим s[0] отличен от с, тогда s[1] = '\0',

Нолик ведь присваивается после цикла, а не внутри.

 Профиль  
                  
 
 Re: Функция, которая удаляет нужный символ из строки
Сообщение01.08.2012, 10:49 
Аватара пользователя


26/02/11
332
ewert в сообщении #601762 писал(а):
Нолик ведь присваивается после цикла, а не внутри.

Аа, вон оно как. Тут просто без { } написано, поэтому показалось, что в цикле. Спасибо.

 Профиль  
                  
 
 Re: Функция, которая удаляет нужный символ из строки
Сообщение01.08.2012, 14:42 
Заслуженный участник
Аватара пользователя


30/01/06
72407
Принято указывать вложенность отступами. Если вы смотрите в книге на пример, обращайте внимание на отступы, и потом аккуратно их воспроизводите (здесь вы неправильно воспроизвели даже оператор + +, с пробелом - так не скомпилируется). Обратите внимание:
Используется синтаксис C
/* squeeze: удаляет все символы с из строки s */
void squeeze(char s [] , int c)
{
    int i, j;
    for (i = j = 0; s[i] != '\0'; i++)
        if (s[i] != c)
            s [j++] = s [i] ;
    s[j] = '\0';
}

"читается взглядом" как:
Используется синтаксис C
/* squeeze: удаляет все символы с из строки s */  <-- 0-й уровень вложенности - текст на уровне файла
void squeeze(char s [] , int c)
{
|   int i, j;                                     <-- 1-й уровень вложенности - текст на уровне функции,
|   for (i = j = 0; s[i] != '\0'; i++)                  то есть 0-й уровень вложенности в функции
|   |   if (s[i] != c)                            <-- 1-й уровень вложенности в функции, вложено в for
|   |   |   s [j++] = s [i] ;                     <-- 2-й уровень вложенности в функции, вложено в for - if
|   s[j] = '\0';                                  <-- снова 0-й уровень вложенности в функции
}


Разумеется, по правилам языка так делать не обязательно (компилятор всё "скушает"), но для читаемости текста другим человеком - обязательно. Это абсолютно общепринятая традиция, и нарушается, только если надо специально читателя запутать.

Ещё полезно раздельные смысловые части функции зрительно отделять одну от другой пустыми строками, и/или комментариями. Но это уже дело вкуса. То есть, тот же текст можно написать так:
Используется синтаксис C
/* squeeze: удаляет все символы с из строки s */
void squeeze(char s [], int c)
{
    int i, j;

    for (i = j = 0; s [i] != '\0'; i++)
        if (s [i] != c)
            s [j++] = s [i];

    s [j] = '\0';
}

 Профиль  
                  
 
 Re: Функция, которая удаляет нужный символ из строки
Сообщение01.08.2012, 16:55 
Аватара пользователя


26/02/11
332
Munin в сообщении #601864 писал(а):
(здесь вы неправильно воспроизвели даже оператор + +, с пробелом - так не скомпилируется)

Это я понимаю, просто скопировал код прямо из книги, и поэтому так вышло. Извините, не обратил внимание.
Munin в сообщении #601864 писал(а):
обращайте внимание на отступы

Да, спасибо, вы очень щепетильны :-) Но дело в том, что мне показалось, что оператор присваивания s[j++] = s[i] не относится к циклу. Да, он относится к условию if, а if в свою очередь лежит в цикле, это понятно. Но для меня это не означало, что он принадлежит for. Короче говоря, оператор присваивания лежал в for-е через if, и для меня это не показалось очевидным.

 Профиль  
                  
 
 Re: Функция, которая удаляет нужный символ из строки
Сообщение01.08.2012, 17:29 
Заслуженный участник


11/05/08
32166
Dosaev в сообщении #601914 писал(а):
и для меня это не показалось очевидным.

Так ведь именно из-за недисциплинированности отступов и показалось, так всегда бывает.

 Профиль  
                  
 
 Re: Функция, которая удаляет нужный символ из строки
Сообщение01.08.2012, 17:56 
Заслуженный участник
Аватара пользователя


30/01/06
72407
Ну, значит, привыкайте, у вас ещё большая дорога впереди.

 Профиль  
                  
 
 Re: Функция, которая удаляет нужный символ из строки
Сообщение01.08.2012, 20:22 
Заслуженный участник


09/09/10
3729
Еще можно всегда-всегда брать тела циклов/ветвлений в фигурные скобки, даже если там всего одна строчка. Здорово ускоряет момент, когда ты понимаешь, что функцию пора резать на пять маленьких :-)

 Профиль  
                  
 
 Re: Функция, которая удаляет нужный символ из строки
Сообщение01.08.2012, 20:53 
Заслуженный участник
Аватара пользователя


30/01/06
72407

(Оффтоп)

Joker_vD в сообщении #602014 писал(а):
Еще можно всегда-всегда брать тела циклов/ветвлений в фигурные скобки, даже если там всего одна строчка. Здорово ускоряет момент, когда ты понимаешь, что функцию пора резать на пять маленьких

Тут бывает в обратную сторону причинно-следственная связь. Функцию пора резать, когда она не умещается в голове и на экране. А добавляя почти пустых строк, вы её текстуально увеличиваете и зрительно усложняете.

 Профиль  
                  
 
 Re: Функция, которая удаляет нужный символ из строки
Сообщение01.08.2012, 21:19 
Заслуженный участник


11/05/08
32166

(Оффтоп)

Joker_vD в сообщении #602014 писал(а):
Еще можно всегда-всегда брать тела циклов/ветвлений в фигурные скобки, даже если там всего одна строчка.

Я их в фигурные скобки никогда не беру попросту потому, что в Сях не программирую. Зато, напротив, коротенькие тела циклов стараюсь уместить в одну строчку даже при нескольких командах в теле -- просто для пущей читабельности (хотя бы для себя самого потом), и пусть меня потом пуристы травят, мне интереснее результат. С третьей стороны, иногда и однооператорные тела беру в операторные скобки, но это уже лишь с прицелом на возможные дальнейшие модификации, а так нет. С четвёртой: независимо от всего предыдущего, отступы -- это святое, и за отступление от них следует сжигать на костре.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 11 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group