Во-первых, в аргументах функций они в точности эквивалентны:
void foo(char *x);
void foo(char x[]); // exactly the same in all respects
В других контекстах char *
выделяет указатель, а char []
выделяет массив. Где строка идет в первом случае, спросите вы? Компилятор тайно выделяет статический анонимный массив для хранения строкового литерала. Итак:
char *x = "Foo";
// is approximately equivalent to:
static const char __secret_anonymous_array[] = "Foo";
char *x = (char *) __secret_anonymous_array;
Обратите внимание, что вы не должны пытаться модифицировать содержимое этого анонимного массива с помощью этого указателя; эффекты не определены (часто это означает сбой):
x[1] = 'O'; // BAD. DON'T DO THIS.
Использование синтаксиса массива напрямую выделяет его в новую память. Таким образом, модификация безопасна:
char x[] = "Foo";
x[1] = 'O'; // No problem.
Однако массив работает только до тех пор, пока его область охвата, поэтому, если вы делаете это в функции, не возвращайте и не пропадаете указатель на этот массив - сделайте скопируйте вместо этого strdup()
или аналогичный. Если массив выделен в глобальной области, конечно, не проблема.
Jayan упоминает checkstyle, который отлично подходит для проверки стандартов кодирования.
Я помню, что с помощью Jalopy лет назад для автоматического форматирования кода это могло бы также удовлетворить ваши потребности.
Однако, честно говоря, я бы не переформатировал код автоматически. Использование таких инструментов, как checkstyle для повышения предупреждений, - это одно. Взять под контроль исходный код разработчика - совсем другое, и большинство людей находят это ужасно навязчивым и неприятным. Кроме того, ошибка в проверке кода в худшем случае порождает неверные предупреждения. Ошибка в расшифровке кода может привести к повреждению и разрушению часов работы.