Имеет ли смысл кто-то вызывать вашу функцию с NULL
аргументами?Если нет, вам следует запретить NULL
аргументы в контракте вашей функции, например, добавив комментарий над объявлением, в котором говорится, что он работает только с действительными, не NULL
аргументами.Другими словами, любой, кто использует вашу функцию, соглашается не давать NULL
аргументов;тогда их обязанность проверять это, а не ваше.
Если имеет смысл, чтобы один или оба аргумента были NULL
, тогда вам нужно решить, какФункция ведет себя в таком случае и реализует это таким образом.В этом случае вы соглашаетесь поддерживать NULL
аргументы и делать что-то разумное с ними, и поэтому становится вашей обязанностью проверить это и действовать соответственно (например, if (s1 == NULL)
).
Если вы не можете придумать какое-либо разумное поведение для NULL
аргументов, то выберите первый вариант и полностью запретите их.Если вы сделаете это, то ваш пример вызова LCS(0,0);
нарушает контракт (т. Е. Передает NULL
указатели, когда функция не соглашается их принимать) и должен быть удален.В более сложном сценарии, если вы передаете аргументы из переменных, и есть вероятность, что эти переменные указывают на NULL
, то вы должны проверить перед вызовом LCS
, например, if (v1 && v2) { LCS(v1,v2); } else { … }
.
To track возможные ошибки, связанные с этим, вы можете использовать assert
для проверки, например:
#include <assert.h>
char **LCS (char *s1, char *s2) {
assert(s1);
assert(s2);
…
}
Это приведет к выходу из вашей программы, если s1
или s2
равно NULL
, если NDEBUG
не было определено до включения assert.h
(в этом случае утверждения ничего не делают ).Таким образом, утверждения являются способом проверки в процессе разработки, что вызывающий не дает вам NULL
аргументов, но это все равно ошибка, если они это делают.
Что касается других недействительных указателей,Вы не можете даже проверить достоверно, например, нет способа узнать, есть ли у вызывающей стороны действительно странная строка или они просто передали неправильный адрес.Это также их обязанность избегать, и LCS
должен просто предполагать, что вызывающий абонент предоставляет вам действительные данные.Конечно, если у вас есть дополнительные ограничения, например, максимальная длина строк аргумента, вы должны сделать эти ограничения понятными для вызывающей стороны (т. Е. Указать контракт для функции, «эта функция выполняет X [ваша ответственность как разработчика LCS] при условии»).что… [их обязанности как пользователя LCS] »).Это относится к всему программированию, например, стандарт C определяет, как должен использоваться сам язык и стандартные библиотечные функции (например, нельзя делить на ноль, строки аргументов для strcpy
не могут перекрываться и т. Д.).