[Архив!] Чистая математика, физика, химия и т.п.: задачки для тренировки мозгов, никак не связанные с торговлей - страница 234

 
Mathemat >>:

А вот дальше непонятка. В первой шапке (внешнем цикле) условие d=0 как-то напрягает. Это ж всегда true?

Да в С наверняка (и d тому свидетель) в for проверяется истинность ПОСЛЕДНЕГО выражения.

 
Декомпиляция 2х циклов :)
 
int a=10000,b,c=2800,d,e,f[2801],g;
int main(void){
 for(;b-c;)f[b++]=a/5;
 for(;d=0,g=c*2;c-=14,printf("%.4d",e+d/a),e=d%a)
 for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b);
}

Цикл выполняется до тех пор, пока выражение b - c оценивается как true. Что такое true в Си? Кажись, любой не нуль. Значит, цикл увеличения b от нуля и заполнения массива f[] выполняется до тех пор, пока b не сравняется с с, т.е. до 2800. Массив f[] заполняется одинаковыми числами 10000/5 = 2000.

Пока не сильно ошибся?

при первом цикле b = с = 2800. (цикл будет такой "for(;0;)") Но цикл все равно выполниться один раз. Затем в ячейку f[2800] (b=2800) запишется число a/5 или 2000. После b увеличиться на единицу b станет 2801.
 

http://www.languagec.info/oper_for.php:

for ( выражение 1 ; выражение 2 ; выражение 3 ) тело

Выражение 1 обычно используется для установления начального значения переменных, управляющих циклом. Выражение 2 - это выражение, определяющее условие, при котором тело цикла будет выполняться. Выражение 3 определяет изменение переменных, управляющих циклом после каждого выполнения тела цикла.

Схема выполнения оператора for:

1. Вычисляется выражение 1.

2. Вычисляется выражение 2.

3. Если значения выражения 2 отлично от нуля (истина), выполняется тело цикла, вычисляется выражение 3 и осуществляется переход к пункту 2, если выражение 2 равно нулю (ложь), то управление передается на оператор, следующий за оператором for.

Существенно то, что проверка условия всегда выполняется в начале цикла. Это значит, что тело цикла может ни разу не выполниться, если условие выполнения сразу будет ложным.

Давай лучше на внутреннем цикле сосредоточимся. Итак:

for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b);

Начиная с b=c,

при условиях

d+=f[b]*a,f[b]=d%--g,d/=g--,--b

выполняется

d*=b

Особо надо понять условия, т.к. это все операторы присваивания.

 

MetaDriver писал(а) >>

// собсно говоря for( ; g=c*2; ) гораздо лучше будет смотреться в такой редакции: for(g=c*2; g!=0; )

Не, так не пойдёт. g=c*2 - должно пересчитываться в каждом цикле.

Следующаяя версия:

while(g!=0)
{
d=0;
b=c-1;
   while(b!=0)
{
b--;
d += f[b] * a;
g
--;
 f[b] = d % g;
 d /= g;
g--;
d*=b;
}
c-=14;
g=c*2:
 
printf("%.4d", e+d/a);
e=d%a;

}

 

У тебя нет ни одного if, так не пойдет.

Еще раз, нужно разобраться в условиях, это главное. Я никак не пойму, где это найти в учебнике.

 
Mathemat >>:

http://www.languagec.info/oper_for.php:

Давай лучше на внутреннем цикле сосредоточимся. Итак:

Начиная с b=c,

при условиях

d+=f[b]*a,f[b]=d%--g,d/=g--,--b
выполняется

Особо надо понять условия, т.к. это все операторы присваивания.

Условие одно, все остальное переписываем наружу.

 
Mathemat >>:

У тебя нет ни одного if, так не пойдет.

Еще раз, нужно разобраться в условиях, это главное. Я никак не пойму, где это найти в учебнике.

Читай "оператор запятая". :)

 

Операция последовательного вычисления обозначается запятой (,) и используется для вычисления двух и более выражений там, где по синтаксису допустимо только одно выражение. Эта операция вычисляет два операнда слева направо. При выполнении операции последовательного вычисления, преобразование типов не производится. Операнды могут быть любых типов. Результат операции имеет значения и тип второго операнда. Отметим, что запятая может использоваться также как символ разделитель, поэтому необходимо по контексту различать, запятую, используемую в качестве разделителя или знака операции.

И где ж там отбрасывание всех окромя последнего?

Еще:

В языке СИ присваивание также является выражением, и значением такого выражения является величина, которая присваивается.

Вот я шо и говорю, шо куча присваиваний - это выражения, оцениваемые в соответствии с местом, где стоят, т.е. true/false.

2 C-4: Твоя интерпретация операнда b-c в самом первом цикле как присваивания мне не понятна.

 
Mathemat >>:
Операция последовательного вычисления обозначается запятой (,) и используется для вычисления двух и более выражений там, где по синтаксису допустимо только одно выражение. Эта операция вычисляет два операнда слева направо. При выполнении операции последовательного вычисления, преобразование типов не производится. Операнды могут быть любых типов. Результат операции имеет значения и тип второго операнда. Отметим, что запятая может использоваться также как символ разделитель, поэтому необходимо по контексту различать, запятую, используемую в качестве разделителя или знака операции.

В данном контексте второй = последний. Формальное определение рекурсивно, т.е. второй оператор может быть составной (и содержать опять же запятую).