онлайн-версия стандарта языка C имеет то, что вам нужно (и именно на это я буду ссылаться в этом ответе); просто имейте в виду, что это определение языка , а не учебное пособие, и, как таковое, его может быть нелегко прочитать тому, кто еще не имеет большого опыта.
Сказав это, ваш учитель бросает вам несколько грязных мячей. Например:
j=d[i++][++i][++i];
Это утверждение приводит к неопределенному поведению по нескольким причинам. Первые несколько абзацев раздела 6.5 связанного выше документа объясняют проблему, но в двух словах:
За исключением нескольких ситуаций, C не гарантирует оценку выражений слева направо; это также не гарантирует, что побочные эффекты будут применены сразу после оценки;
Попытка изменить значение объекта более одного раза между точками последовательности 1 или изменение, а затем попытка использования значения объекта без промежуточной точки последовательности приводит к неопределенному поведению .
По сути, не пишите ничего в форме:
x = x++;
x++ * x++;
a[i] = i++;
a[i++] = i;
C не гарантирует, что каждые ++i
и i++
оцениваются слева направо, и не гарантирует, что побочный эффект каждой оценки применяется немедленно. Таким образом, результат j[i++][++i][++i]
не является четко определенным, и результат не будет одинаковым для разных программ или даже для разных сборок одной и той же программы 2 .
И , кроме того, i++
соответствует значению current i
; так ясно, что ваш учитель хотел, чтобы j[i++][++i][++i]
оценил j[-1][1][2]
, что также приведет к неопределенному поведению, так как вы пытаетесь индексировать за пределами границ массива.
Вот почему я ненавижу, ненавижу, ненавижу это когда учителя бросают такой код в своих учеников - он не только бесполезно сбивает с толку, он не только поощряет плохую практику, но и чаще, чем нет это просто неправильно .
Что касается других вопросов:
for(q=-2;q=-5;q+=3) { //assignment in condition part??
См. Разделы 6.5.16 и 6.8.5.3. Короче говоря, выражение присваивания имеет значение (значение левого операнда после любых преобразований типов) и может появляться как часть управляющего выражения в цикле for
. Пока результат присваивания не равен нулю (как в случае выше), цикл будет выполняться.
printf("%o",a); //prints 12
См. Раздел 7.21.6.1. Спецификатор преобразования o
указывает printf
форматировать целочисленное значение как восьмеричное: 10<sub>10</sub> == 12<sub>8</sub>
Точка последовательности - это точка выполнения программы, в которой выражение полностью оценено и применены любые побочные эффекты. Точки последовательности появляются в конце операторов, между оценкой параметров функции и вызовом функции, после вычисления левого операнда операторов &&
, ||
и ?:
и нескольких других мест. См. Приложение C для полного списка.
Или даже разные прогоны одной и той же сборки, хотя на практике вы не увидите, как значения меняются от прогона к прогону, если вы не делаете что-то действительно странное.