Проверьте все пакеты, которые вы установили для php, используя:
yum list installed | grep remi
Установите все соответствующие пакеты php, особенно php-devel на вашем компьютере.
Это упрощает создание исходного кода, а также для написания кода, который может быть легко продлен позднее. Рассмотрим, что требуется для добавления дополнительной записи:
int a[] = {
1,
2,
3
};
... вам нужно добавить запятую в существующую строку и добавить новую строку. Сравните это с тем случаем, когда три уже имеют запятую после него, где вам просто нужно добавить строку. Аналогично, если вы хотите удалить строку, вы можете сделать это, не заботясь о том, является ли она последней строкой или нет, и вы можете переупорядочивать строки, не перебирая запятыми. В основном это означает, что существует единообразие в том, как вы относитесь к линиям.
Теперь подумайте о генерации кода. Что-то вроде (псевдокод):
output("int a[] = {");
for (int i = 0; i < items.length; i++) {
output("%s, ", items[i]);
}
output("};");
Не нужно беспокоиться о том, является ли текущий элемент, который вы пишете, первым или последним. Гораздо проще.
Все, что все говорят о простоте добавления / удаления / генерации строк, верны, но реальное место синтаксиса сияет при объединении исходных файлов. Представьте, что у вас есть этот массив:
int ints[] = {
3,
9
};
И предположим, что вы проверили этот код в репозитории.
Затем ваш приятель редактирует его, добавляя в конец:
int ints[] = {
3,
9,
12
};
И вы одновременно редактируете его, добавляя в начало:
int ints[] = {
1,
3,
9
};
Семантически эти виды операций (добавление к началу, добавление в конец) должны быть полностью безопасными для слияния и ваше программное обеспечение для управления версиями (надеюсь, git) должно быть способно авторизоваться. К сожалению, это не так, потому что ваша версия не имеет запятой после 9 и ваших приятелей. Принимая во внимание, что если исходная версия имела конечный 9, они бы автоматизировались.
Итак, мое эмпирическое правило: используйте конечную запятую, если список охватывает несколько строк, не используйте его, если список находится на одной строке.
Единственный язык, на котором он - на практике * - не разрешен, - это Javascript, и это вызывает бесчисленное количество проблем. Например, если вы скопируете & amp; вставьте строку из середины массива, вставьте ее в конец и забудьте удалить запятую, тогда ваш сайт будет полностью разбит для ваших посетителей IE.
* Теоретически это разрешено, но Internet Explorer не соответствует стандарту и рассматривает его как ошибку
var x = [,,,]
является законным (за исключением IE & lt; 9, но спецификация говорит, что это законно)
– Peter C
12 August 2011 в 22:12
Одна из причин, по которой мне известно, что это должно быть просто автоматически генерировать код; вам не нужна специальная обработка для последнего элемента.
Трейлинг-запятая, я считаю, допускается для соображений обратной совместимости. Существует много существующего кода, в основном автогенератора, который помещает конечную запятую. Это облегчает запись цикла без специального условия в конце. например,
for_each(my_inits.begin(), my_inits.end(),
[](const std::string& value) { std::cout << value << ",\n"; });
Для программиста нет никакого преимущества.
P.S. Хотя легче автогенерировать код таким образом, я на самом деле всегда старался не ставить конечную запятую, усилия минимальны, читаемость улучшается, и это более важно. Вы пишете код один раз, вы читаете его много раз.
int a = b + c +;
или if(a && b &&);
будет проще просто копировать и вставлять что-нибудь в конце и проще писать генераторы кода , Эта проблема является тривиальной и субъективной, и в таких случаях всегда полезно делать то, что лучше всего подходит для чтения кода.
– Gene Bushuyev
12 August 2011 в 23:06
&&
, иногда я выполняю такие условия, как if (true \n && b1 \n && b2)
, чтобы я мог добавлять и удалять строки, как мне нужно.
– Christian Mann
4 June 2016 в 14:12
В дополнение к генерации кода и редактированию, если вы хотите реализовать парсер, этот тип грамматики проще и проще реализовать. C # следует за этим правилом в нескольких местах, где есть список разделенных запятыми элементов, таких как элементы в определении enum
.
Это позволяет защитить от ошибок, вызванных перемещением элементов в длинном списке.
Например, предположим, что у нас есть код, похожий на этот.
#include <iostream>
#include <string>
#include <cstddef>
#define ARRAY_SIZE(array) (sizeof(array) / sizeof *(array))
int main() {
std::string messages[] = {
"Stack Overflow",
"Super User",
"Server Fault"
};
size_t i;
for (i = 0; i < ARRAY_SIZE(messages); i++) {
std::cout << messages[i] << std::endl;
}
}
И это здорово, поскольку это показывает оригинальную трилогию сайтов Stack Exchange.
Stack Overflow
Super User
Server Fault
Но есть одна проблема с этим. Как видите, нижний колонтитул на этом веб-сайте показывает «Ошибка сервера перед суперпользователем». Лучше исправить это, прежде чем кто-нибудь заметит.
#include <iostream>
#include <string>
#include <cstddef>
#define ARRAY_SIZE(array) (sizeof(array) / sizeof *(array))
int main() {
std::string messages[] = {
"Stack Overflow",
"Server Fault"
"Super User",
};
size_t i;
for (i = 0; i < ARRAY_SIZE(messages); i++) {
std::cout << messages[i] << std::endl;
}
}
В конце концов, движущиеся линии вокруг не могут быть такими трудными, не так ли?
Stack Overflow
Server FaultSuper User
Я знаю, нет сайт под названием «Server FaultSuper User», но наш компилятор утверждает, что он существует. Теперь проблема заключается в том, что C имеет функцию конкатенации строк, которая позволяет вам писать две строки с двойными кавычками и конкатенировать их, используя ничего (аналогичная проблема также может возникать с целыми числами, поскольку знак -
имеет несколько значений).
Теперь, что, если исходный массив имел бесполезную запятую в конце? Ну, линии будут перемещены, но такой ошибки не произошло бы. Легко пропустить что-то столь же маленькое, как запятая. Если вы запомните запятую после каждого элемента массива, такой ошибки просто не может быть. Вы не хотели бы тратить четыре часа на отладку, пока вы не найдете запятую, что является причиной ваших проблем .
Это проще для машин, т. е. разбора и генерации кода.
Предполагая, что C, вы могли бы написать следующее?
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
puts("Line 1");
puts("Line 2");
puts("Line 3");
return EXIT_SUCCESS
}
No. Не только потому, что конечный оператор является ошибкой, но и потому, что он непоследовательный. Итак, зачем делать то же самое с коллекциями? Даже на языках, которые позволяют пропустить последние точки с запятой и запятыми, сообществу обычно это не нравится. Сообщество Perl, например, похоже, не хочет пропускать точки с запятой, выровнять однострочные. Они также применяют это к запятым.
Не пропускайте запятые в многострочных коллекциях по той же причине, что и вы не опускаете точки с запятой для многострочных блоков кода. Я имею в виду, вы бы этого не сделали, даже если язык позволил это, не так ли? Правильно?
Он позволяет каждой строке следовать одной и той же форме. Во-первых, это упрощает добавление новых строк и система управления версиями отслеживает изменение значимо, а также позволяет легче анализировать код. Я не могу придумать техническую причину.
Он генерирует генераторы кода, которые легче выделяют массивы или перечисления.
Представьте себе:
std::cout << "enum Items {\n";
for(Items::iterator i(items.begin()), j(items.end); i != j; ++i)
std::cout << *i << ",\n";
std::cout << "};\n";
Т.е. нет необходимости выполнять специальную обработку первого или последнего элемента, чтобы избежать
Если генератор кода написан на Python, например, легко избежать плющения конечной запятой с помощью функции str.join()
:
print("enum Items {")
print(",\n".join(items))
print("}")
Как и многие другие, конечная запятая в инициализаторе массива является одной из вещей, которые C ++ унаследовал от C (и им придется поддерживать навсегда). В книге «Deep C secrets» упоминается вид, совершенно отличный от тех, что указаны здесь.
В этом случае после примера с более чем одним «парамодическим знаком»:
char *available_resources[] = {
"color monitor" ,
"big disk" ,
"Cray" /* whoa! no comma! */
"on-line drawing routines",
"mouse" ,
"keyboard" ,
"power cables" , /* and what's this extra comma? */
};
мы читаем:
... что конечная запятая после конечный инициализатор не является опечаткой, но является следствием синтаксиса, перенесенного с аборигенного C. Его присутствие или отсутствие разрешено, но не имеет никакого значения. Обоснование, заявленное в обосновании ANSI C, заключается в том, что упрощает автоматическую генерацию C. Претензия была бы более надежной, если бы конечные запятые разрешались в каждом списке с разделителями-запятыми, например, в объявлениях перечислений или нескольких деклараторах переменных в одной декларации. Это не так.
blockquote>... для меня это имеет смысл
enum
несколько интересен, так как это тот случай, когда недостающая запятая представляла наименьшую двусмысленность. Учитывая struct foo arr[] = {{1,2,3,4,5}, {3,4,5,6,7}, }
; существует два разумных значения, которые может присвоить язык: создать двухэлементный массив или создать трехэлементный массив, в котором последний элемент имеет значения по умолчанию. Если бы C принял более позднюю интерпретацию, я мог видеть, что запрещать enum foo {moe, larry, curly, };
по принципу, что должен быть только один способ написать заявление (без запятой), но ...
– supercat
1 August 2015 в 19:40
enum foo {moe,,larry,curly,};
как пропуск числа между moe
и larry
, обычно не имеет значения, обрабатывалась ли конечная запятая или игнорировалась , Единственный случай, когда это могло бы иметь значение, было бы, если последний элемент был максимальным значением для его объявленного типа, и что ...
– supercat
1 August 2015 в 19:44
Я всегда предполагал, что это облегчает добавление дополнительных элементов:
int a[] = {
5,
6,
};
просто становится:
int a[] = {
5,
6,
7,
};
в более позднюю дату.
[1,2,3,]
в порядке, но {a:1, b:2, c:3,}
- нет).
– Dereleased
12 August 2011 в 22:51
Это упрощает создание кода, поскольку вам нужно только добавить одну строку и не нужно обрабатывать добавление последней записи, как если бы это был особый случай. Это особенно актуально при использовании макросов для генерации кода. Есть толчок, чтобы попытаться устранить необходимость в макросах на языке, но многие языки развивались рука об руку с доступными макросами. Дополнительная запятая позволяет определять и использовать макросы, такие как следующее:
#define LIST_BEGIN int a[] = {
#define LIST_ENTRY(x) x,
#define LIST_END };
Использование:
LIST_BEGIN
LIST_ENTRY(1)
LIST_ENTRY(2)
LIST_END
Это очень упрощенный пример, но часто этот шаблон используется макросы для определения таких вещей, как отправка, сообщения, события или переводы карт и таблиц. Если запятая не была разрешена в конце, нам понадобится специальный:
#define LIST_LAST_ENTRY(x) x
, и это будет очень неудобно использовать.
Я удивлен, что все это время никто не цитировал Аннотированное справочное руководство C ++ ( ARM ), он говорит следующее о [dcl.init] с акцентом my:
Очевидно, слишком много обозначений для инициализаций, но каждый, кажется, хорошо подходит к определенному стилю использования. Обозначение = {initializer_list, opt} было унаследовано от C и хорошо служит для инициализации структур данных и массивов. [...]
blockquote>, хотя грамматика развилась с тех пор, как было написано ARM , происхождение остается.
, и мы можем перейти к Обоснование C99 , чтобы понять, почему это было разрешено в C, и он говорит:
K & amp; R допускает конечную запятую в инициализаторе в конце списка инициализаторов. Стандарт сохранил этот синтаксис, поскольку он обеспечивает гибкость при добавлении или удалении членов из списка инициализаторов и упрощает создание таких списков.
blockquote>
Полезно, если вы делаете что-то вроде этого:
int a[] = {
1,
2,
3, //You can delete this line and it's still valid
};
var a = [1, 2,];
, поэтому большинство других языков я знаю ... ActionScript, Python, PHP.
– Sean Fujiwara
14 August 2011 в 04:43
undefined
.
– Skilldrick
16 August 2011 в 10:57
Простота использования для разработчика, я думаю.
int a[] = {
1,
2,
2,
2,
2,
2, /*line I could comment out easily without having to remove the previous comma*/
}
Кроме того, если по какой-либо причине у вас есть инструмент, который сгенерировал код для вас; инструмент не должен заботиться о том, является ли это последним элементом в инициализации или нет.
Причина тривиальна: простота добавления / удаления строк.
Представьте следующий код:
int a[] = {
1,
2,
//3, // - not needed any more
};
Теперь вы можете легко добавлять / удалять элементы в список без иногда добавлять / удалять конечную запятую.
В отличие от других ответов, я действительно не считаю, что легкость генерации списка является веской причиной: в конце концов, для кода тривиально вставьте последнюю (или первую) строку. Генераторы кода записываются один раз и используются много раз.
Я вижу один случай использования, который не упоминался в других ответах, наши любимые макросы:
int a [] = {
#ifdef A
1, //this can be last if B and C is undefined
#endif
#ifdef B
2,
#endif
#ifdef C
3,
#endif
};
Добавление макросов для обработки последнего ,
было бы большой болью. С этим небольшим изменением синтаксиса это тривиально для управления. И это более важно, чем машинный код, потому что, как правило, это намного проще сделать в полной версии Turing, чем очень ограниченный препроцессор.
Если вы используете массив без указанной длины, VC ++ 6.0 может автоматически идентифицировать его длину, поэтому, если вы используете «int a [] = {1,2,};» длина a равна 3 , но последний не был инициализирован, вы можете использовать «cout & lt;