# include < stdio.h > /* <- тут ЖЖ что-то пытается подгрузить автоматом. Поставил пробел после колодца и ><*/ main () { /*Логика программы следующая: * Всего 60 позиций на циферблате. * Каждые 12 минут часовая стрелка смещается на 1 позицию. 60 раз за оборот. * Каждые 60 секунд минутная стрелка смещается на 1 позицию. * Когда разница по модулю между этими двумя значениями достигает 15-ти, то образуется прямой угол. */ int hour, counter_1, counter_min, counter_hour, otvet; otvet=0; counter_hour = 0; hour = 0; printf("Start\n"); for (counter_1=0; counter_1<12; counter_1++) /*делаем оборот часовой стрелки*/ { for (counter_min=0; counter_min<60; counter_min++) /*делаем один оборот минутной стрелки*/ { if ((counter_min % 12) == 0) /*часовой стрелке пора сдвинуться на одну позицию*/ { if (counter_min == 0 && counter_1 == 0) /*но не надо двигаться сразу в полночь*/ {} else counter_hour = counter_hour + 1; if ((counter_hour % 5) == 0) printf("Hour - %2d\n", counter_hour/5); } if ((counter_hour - counter_min == 15) || (15 + counter_hour == counter_min + 60)) { hour = (counter_hour - (counter_hour%5))/5; printf("%2d : %2d\n", hour, counter_min); otvet++; } if ((counter_min - counter_hour == 15) || (15 + counter_min == counter_hour + 60)) { hour = (counter_hour - (counter_hour%5))/5; printf("%2d : %2d\n", hour, counter_min); otvet++; } } }
тут материала не на один ответ, это как минимум двухчасовая лекция или недельный курс нужен ) Вкратце - современный С++ (не то что мы видели на компах и книжках 90-х годов) это совершенно другой язык, который хоть отчасти и сохраняет частичную совместимость с С (я бы сказал скорее "к сожалению") имеет очень и очень мало с ним общего.
"С" задумывался как "переносимый ассемблер" и "язык написания операционных систем", отсюда его минималистичность/лаконичность и практически полное отсутствие высокоуровневым конструкций. Современный С++ это такой монстр которого полностью никто не знает :)
Спасибо. Я не нарочно писал строго на "С". Просто задача/программа тривиальна и не требовала сложных конструкций. Я правильно понял, что современные высокоуровневые языки больше полагаются на набор внешних библиотек, которые вполне свободно кушаются всякими современными IDE? И современный программист приложений должен больше внимания обращать на вот эти сами библиотеки, чем на создание своих собственных?
> Я правильно понял, что современные высокоуровневые языки больше полагаются на набор внешних библиотек,
Если под "внешней библиотекой" понимать "библиотека, не входящая в сам язык но всегда поставляющаяся с языком" то и Си так же использует стандартные библиотеки Си. Ты включил "stdio.h" и можешь пользоваться функцией "printf" которая не является частью языка Си, но всегда идет с ним в стандартной библиотеке.
Если под внешними библиотеками ты понимаешь что то "совсем другое", не составляющееся с инструментом разработки - то, скорее, нет.
> которые вполне свободно кушаются всякими современными IDE
IDE это всего навсего "удобная обертка" над компилятором/линкером/отладчиком. Она позволяет тебе не тарабанить команды в консоли, а тыкать мышкой в кнопки или нажимать командные сокращения. IDE сама переведет их в нужные параметры для компилятора/отладчика/итд, сама их запустит, распарсит вывод и расцветит красивыми цветами в своих окошках. Но ничего сверх того, формально, IDE не делает. "Кушать" и "переваривать" библиотеки должны компилятор/отладчик/прочие тузлзы.
> И современный программист приложений должен больше внимания обращать на вот эти сами библиотеки, чем на создание своих собственных?
Это довольно давно было так. На Си cтандартная библиотека была довольно ограниченная и часто приходилось дописывать "что то свое". Языки более высоких уровней много "более высокой" функциональности внесено в сам язык (и даже не в стандартные библиотеки). Это делает исходный код более "выразительным" (не самый лучший перевод слова "expressive"), то есть позволяет программисту получить результат написав меньше исходного текста. Поскольку чаще всего слабое звено это человек, то с развитием вычислительных мощностей/компиляторов становится все более и более выгодным переложить как можно больше работы на компилятор, чтобы меньше требовать от человека. Это, конечно, стоит оптимальности и эффективности генерируемого кода, но развитие железа в целом делает такой подход более чем оправданным.
С++ далеко не самых хороший пример высокоуровневого языка, но даже в нем появляются забавные вещи позволяющие делать интересные трюки. Например, классическая функция факториала если мы запишем ее так: (чувствую убьет ЖЖ форматирование но прочитать можно будет)
int fact(int n) { if (n <= 0) { return 1; } else { return n * fact(n-1); } }
int fact5() { int result = fact(5); return result; }
Вроде все просто и понятно, будет сгенерирован код и выполнены куча условий во время исполнения. Но если мы перепишем это используя новый модификатор С++ (кажется из стандарта 2011 года) "constexpress" то мы даем компилятору подсказку "эта вся мутотень может быть вычислена во время компиляции:
constexpr int fact(int n) { if (n <= 0) { return 1; } else { return n * fact(n-1); } }
int fact5() { constexpr int result = fact(5); return result; }
В результате, откомпилировав второй вариант мы увидем что компилятор утоптал этот исходник в смешные две инструкции на arm64 процессоре:
0000000000000000 mov w0, #0x78 0000000000000004 ret
Вот именно так: "вернуть 0x78" или "120". Весь сгенеренный код.
Для x86_64 кодогенерация будет подлиннее из за пролога/эпилога функции но все равно банальные:
# include < stdio.h > /* <- тут ЖЖ что-то пытается подгрузить автоматом. Поставил пробел после колодца и ><*/
main ()
{
/*Логика программы следующая:
* Всего 60 позиций на циферблате.
* Каждые 12 минут часовая стрелка смещается на 1 позицию. 60 раз за оборот.
* Каждые 60 секунд минутная стрелка смещается на 1 позицию.
* Когда разница по модулю между этими двумя значениями достигает 15-ти, то образуется прямой угол.
*/
int hour, counter_1, counter_min, counter_hour, otvet;
otvet=0;
counter_hour = 0;
hour = 0;
printf("Start\n");
for (counter_1=0; counter_1<12; counter_1++) /*делаем оборот часовой стрелки*/
{
for (counter_min=0; counter_min<60; counter_min++) /*делаем один оборот минутной стрелки*/
{
if ((counter_min % 12) == 0) /*часовой стрелке пора сдвинуться на одну позицию*/
{
if (counter_min == 0 && counter_1 == 0) /*но не надо двигаться сразу в полночь*/
{}
else counter_hour = counter_hour + 1;
if ((counter_hour % 5) == 0) printf("Hour - %2d\n", counter_hour/5);
}
if ((counter_hour - counter_min == 15) || (15 + counter_hour == counter_min + 60))
{
hour = (counter_hour - (counter_hour%5))/5;
printf("%2d : %2d\n", hour, counter_min);
otvet++;
}
if ((counter_min - counter_hour == 15) || (15 + counter_min == counter_hour + 60))
{
hour = (counter_hour - (counter_hour%5))/5;
printf("%2d : %2d\n", hour, counter_min);
otvet++;
}
}
}
printf ("Otvet %d\n", otvet);
return 0;
}
Reply
Reply
Reply
Вкратце - современный С++ (не то что мы видели на компах и книжках 90-х годов) это совершенно другой язык, который хоть отчасти и сохраняет частичную совместимость с С (я бы сказал скорее "к сожалению") имеет очень и очень мало с ним общего.
"С" задумывался как "переносимый ассемблер" и "язык написания операционных систем", отсюда его минималистичность/лаконичность и практически полное отсутствие высокоуровневым конструкций. Современный С++ это такой монстр которого полностью никто не знает :)
Reply
Я правильно понял, что современные высокоуровневые языки больше полагаются на набор внешних библиотек, которые вполне свободно кушаются всякими современными IDE? И современный программист приложений должен больше внимания обращать на вот эти сами библиотеки, чем на создание своих собственных?
Reply
> Я правильно понял, что современные высокоуровневые языки больше полагаются на набор внешних библиотек,
Если под "внешней библиотекой" понимать "библиотека, не входящая в сам язык но всегда поставляющаяся с языком" то и Си так же использует стандартные библиотеки Си. Ты включил "stdio.h" и можешь пользоваться функцией "printf" которая не является частью языка Си, но всегда идет с ним в стандартной библиотеке.
Если под внешними библиотеками ты понимаешь что то "совсем другое", не составляющееся с инструментом разработки - то, скорее, нет.
> которые вполне свободно кушаются всякими современными IDE
IDE это всего навсего "удобная обертка" над компилятором/линкером/отладчиком. Она позволяет тебе не тарабанить команды в консоли, а тыкать мышкой в кнопки или нажимать командные сокращения. IDE сама переведет их в нужные параметры для компилятора/отладчика/итд, сама их запустит, распарсит вывод и расцветит красивыми цветами в своих окошках. Но ничего сверх того, формально, IDE не делает. "Кушать" и "переваривать" библиотеки должны компилятор/отладчик/прочие тузлзы.
> И современный программист приложений должен больше внимания обращать на вот эти сами библиотеки, чем на создание своих собственных?
Это довольно давно было так. На Си cтандартная библиотека была довольно ограниченная и часто приходилось дописывать "что то свое". Языки более высоких уровней много "более высокой" функциональности внесено в сам язык (и даже не в стандартные библиотеки). Это делает исходный код более "выразительным" (не самый лучший перевод слова "expressive"), то есть позволяет программисту получить результат написав меньше исходного текста.
Поскольку чаще всего слабое звено это человек, то с развитием вычислительных мощностей/компиляторов становится все более и более выгодным переложить как можно больше работы на компилятор, чтобы меньше требовать от человека. Это, конечно, стоит оптимальности и эффективности генерируемого кода, но развитие железа в целом делает такой подход более чем оправданным.
С++ далеко не самых хороший пример высокоуровневого языка, но даже в нем появляются забавные вещи позволяющие делать интересные трюки.
Например, классическая функция факториала если мы запишем ее так: (чувствую убьет ЖЖ форматирование но прочитать можно будет)
int fact(int n) {
if (n <= 0) {
return 1;
} else {
return n * fact(n-1);
}
}
int fact5() {
int result = fact(5);
return result;
}
Вроде все просто и понятно, будет сгенерирован код и выполнены куча условий во время исполнения.
Но если мы перепишем это используя новый модификатор С++ (кажется из стандарта 2011 года) "constexpress" то мы даем компилятору подсказку "эта вся мутотень может быть вычислена во время компиляции:
constexpr int fact(int n) {
if (n <= 0) {
return 1;
} else {
return n * fact(n-1);
}
}
int fact5() {
constexpr int result = fact(5);
return result;
}
В результате, откомпилировав второй вариант мы увидем что компилятор утоптал этот исходник в смешные две инструкции на arm64 процессоре:
0000000000000000 mov w0, #0x78
0000000000000004 ret
Вот именно так: "вернуть 0x78" или "120". Весь сгенеренный код.
Для x86_64 кодогенерация будет подлиннее из за пролога/эпилога функции но все равно банальные:
0000000000000000 pushq %rbp
0000000000000001 movq %rsp, %rbp
0000000000000004 movl $0x78, %eax
0000000000000009 popq %rbp
000000000000000a retq
в принципе те же самые "вернуть 0x78".
Вот такой совсем маленький тизер-демонстрация новых (относительно) возможностей.
Reply
Leave a comment