Программирование методом подбора, которое иногда называют «случайным программированием», — это подход к разработке программного обеспечения, при котором программист решает проблему итеративно, делая небольшие изменения (перестановки) и тестирование каждого изменения, чтобы увидеть, ведёт ли оно себя, как хотелось бы. Такой подход иногда кажется привлекательным, когда программист не в полной мере понимает код и считает, что одно или несколько небольших изменений может привести к коду, который является правильным.
Пример
правитьНапример, следующий пример кода C (предназначен для поиска и копирования последовательности цифр из большой строки) имеет несколько проблем:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
const char* buffer = "123abc";
char destination[10];
int i = 0;
int j = 0;
int l = strlen(buffer);
while (i < l) {
if (isdigit(buffer[i])) {
destination[j++] = buffer[i++];
}
++i;
}
destination[j] = '\0';
printf("%s\n", destination);
}
Во-первых, он не даёт правильного результата. Для заданной начальной строки он печатает «13», в то время как правильным результатом является «123». Программист, не видящий структурной проблемы, может ухватиться за одну команду, сказав: «Ага, здесь лишнее увеличение на единицу». Он удаляет строку «++i», но при тестировании программа попадает в бесконечный цикл. «Ой, неправильный инкремент». Предыдущее выражение возвращается на место, а строкой выше удаляется постфиксный инкремент переменной i:
if (isdigit(buffer[i])) {
destination[j++] = buffer[i];
}
В ходе тестирования код теперь выдаёт правильный ответ, «123». Программист удовлетворённо вздыхает: «Вот, вот и всё. Теперь всё готово». Дополнительное тестирование с другими входными строками подтверждает этот вывод.
Однако, поскольку программист не утруждает себя полным пониманием кода, остаются следующие проблемы:
- Если ввод содержит несколько чисел, разделённых нецифровыми символами, например «123аб456», в целевой буфер попадут все цифры подряд.
- Если ввод длиннее целевого буфера, то целевой буфер переполнится.
- Если ввод длиннее
INT_MAX
, то поведение становится неопределённым, посколькуstrlen()
возвращает беззнаковое целочисленное значение типаsize_t
, в котором может храниться значение, большее максимума для знакового целочисленного (int
). - Если на используемой платформе тип
char
— знаковый и ввод содержит символы не из диапазона от0
доUCHAR_MAX
после приведения к int, то вызовisdigit()
приводит к неопределённому поведению.
Хотя решение окажется подходящим для определённого набора вводимых данных, оно не является корректным для всех таких наборов, и замечания к такому коду будут возникать в течение долгого времени.
Примечания
правитьЭто заготовка статьи о программировании. Помогите Википедии, дополнив её. |
В статье не хватает ссылок на источники (см. рекомендации по поиску). |