Код раздела 1.9 K&R для сохранения самой длинной строки ввода имеет функцию:
int getline(char s[], int lim)
{
int c, i;
for(i = 0; i < lim -1 && (c =getchar()) != EOF && c != '\n'; ++i)
s[i] = c;
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = c;
return i;
}
Тем не менее, для лучшей практики я узнал, что функция выполняет только одно действие. Я считаю, что эта функция копирует строку из своего ввода в массив символов s И возвращает длину. Разве это не считается двумя вещами? Прав ли я в своем предположении, что это плохая практика?
Чтобы уточнить, мы действительно используем ввод от функции getLine, но очень неинтуитивно.
main()
{
int len; /*current line length*/
int max; /*Current max line length seen so far*/
char line[MAXLINE]; /*Current input line */
char longest[MAXLINE]; /*Longest line saved here*/
max = 0;
while ((len = getline(line, MAXLINE)) > 0)
if (len > max) {
max = len;
copy(longest, line);
}
if (max > 0) /* there was a line */
printf("%s", longest);
return 0;
}
/*FUNCTION GETLINE TAKEN OUT */
/*copy: copy 'from' into 'to'; assume to is big enough */
void copy(char to[], char from[])
{
int i;
i = 0;
while ((to[i] = from[i]) != '\0')
++i;
}
3 ответа
Нет, по двум причинам.
Во-первых, можно утверждать, что цель getline
(как следует из названия) - прочитать строку из ввода. Тот факт, что он также возвращает количество прочитанных символов, можно объяснить тем, как работают C-строки, и что в противном случае функция не могла бы использоваться для чтения данных, содержащих нулевые байты.
Во-вторых, функция не содержит дополнительного кода для вычисления длины. Это побочный продукт чтения строки. В противном случае функция имела бы тип void
, поэтому на самом деле нет никаких недостатков в возврате длины строки.
Кроме того, рекомендации по кодированию не являются самоцелью, но должны помочь в создании хорошего кода. Я не вижу, как этот код можно улучшить, опустив оператор return и написав отдельную функцию O (n) для получения длины.
Функция getline()
не выполняет двух разных действий. Он выполняет две очень тесно связанные вещи, и это определенно неплохая практика, когда он возвращает длину строки.
Не пытайтесь слепо вписывать функции, алгоритмы и другие подобные вещи в схемы. То, что делает getline()
, концептуально правильно, поскольку строка является объектом. Она имеет буфер содержимого и длины. Оба «свойства» принадлежат строковому объекту, и на самом деле я считаю плохой практикой разделять их.
Кроме того, было бы излишне сложно (и неэффективно) иметь еще одну функцию, вычисляющую длину строки. В C строки заканчиваются нулем, и поэтому такая функция должна пройти всю строку, чтобы найти ее длину.
(Не говоря уже о том, что такая функция уже есть в стандартной библиотеке C, она называется strlen()
.)
Часто для строк и массивов в целом это не исключение, а на самом деле очень полезное поведение. В некотором смысле массивы обладают неявным свойством длины. Иногда это известно во время компиляции, иногда это известно во время выполнения и сохраняется в переменной, а иногда это может быть определено только на основании того, что это массив с завершающим нулем.
В любом случае, поскольку нельзя вернуть массив по значению, возвращение длины массива (которое часто очень удобно знать) является очень полезным свойством функций, которые записывают массив в буфер. Я могу даже утверждать, что это идиоматично в C, когда длина записанного массива не может быть известна вызывающему.
ДОБАВЛЕНИЕ: Вышеупомянутый ответ относится к функциям, которые не выделяют память, а только записывают в предоставленный буфер. Иногда бывает полезно вернуть простую структуру struct { size_t size; valtype* vals; }
, если знание размера выделенного массива всегда полезно для вызывающей стороны и вы не хотите позже перебирать массив. Проведя параллели с вашим вопросом, вы поймете, почему в некотором смысле он на самом деле не делает двух вещей; это просто дает вам более полный результат.
Похожие вопросы
Новые вопросы
c
C - это язык программирования общего назначения, используемый для системного программирования (ОС и встраиваемых), библиотек, игр и кроссплатформенности. Этот тег следует использовать с общими вопросами, касающимися языка C, как это определено в стандарте ISO 9899 (последняя версия 9899: 2018, если не указано иное, а также для запросов, специфичных для версии, с c89, c99, c11 и т. Д.). C отличается от C ++ и не должен сочетаться с тэгом C ++ без разумной причины.
printf
печатает строку и возвращает количество записанных ею символов. Пока этотgetline
уже ведет подсчет длины строки, почему бы не вернуть его в результате? Он даже возвращает0
для "нет ввода".> 80
?max
никогда не обновляется; конечно, отступif
вводит в заблуждение или ему нужны фигурные скобки?