Консультация № 179388
04.07.2010, 13:46
0.00 руб.
0 6 1
1) Даны натуральные числа а, b, с, которые обозначают число, месяц и год, например 1, 4, 1901 - 1 апреля 1901 года. Получить тройку чисел, соответствующих следующему дню.
При решении задачи принять во внимание, что в современном (григорианском) календаре каждый год, номер которого делится на 4, является високосным, за исключением тех номеров, которые делятся на 100 и не делятся на 400.
2) Дано действитёльное число х. Получить целую часть *) числа х; затем — число х, округленное до ближайшего целого; затем — число х без дробных цифр.
Целой частью числа х, обозначаемой [х], называется наибольшее целое, не превосходящее х; так, [3.14] = 3, [3] = 3, [- 3.14] = 4, [- 3] = 3.


Вроде бы не сложные программы, но СИ не владею вообще а нужно именно на нём...помогите если не сложно!

Обсуждение

давно
Профессор
401888
1232
04.07.2010, 14:57
общий
И нафига тогда в Паскаль писать?
Неизвестный
04.07.2010, 17:28
общий
Уточню, что можно перенести вопрос в соответствующую рассылку, но С и мы владеем.. В каком надо то?
Неизвестный
05.07.2010, 18:36
общий
это ответ
Здравствуйте, Филипов Олег Вичеславович.

Привожу решение первой задачи на Паскале (поскольку раздел по программированию на Паскале) и на Си (поскольку в вопросе написано: "СИ не владею вообще а нужно именно на нём". Обратите внимание, что в версии на Паскале числа должны вводиться через пробел, а в версии на C — через точку (измените форматную строку scanf, если нужен другой разделитель).

Прокомментирую небольшой трюк, используемый при проверке корректности ввода в версии на C:
Код:
if( (unsigned)month > 11 || ... ) {
printf( "Недопустимая дата.\n" );
...
}

Значение month ранее было уменьшено на 1, т.е. допустимый диапазон стал 0..11.
Если безо всяких хитростей, то следует писать:
Код:
if( month < 0 || month > 11 || ... ) {
printf( "Недопустимая дата.\n" );
...
}

Выражение (month < 0 || month > 11) можно заменить на одно: ((unsigned)month > 11), поскольку, если число отрицательное, то при приведении его к беззнаковому типу оно будет больше 11. Это справедливо, если отрицательные числа записываются в дополнительном коде (а именно он используется в CPU 80x86).
Для проверки day (и в версии на Паскале) этот прием не используется, поскольку надо также исключить значение 0.

179388.PAS:
Код:
{
Даны натуральные числа а, b, с, которые обозначают число, месяц и год,
например 1, 4, 1901 - 1 апреля 1901 года.
Получить тройку чисел, соответствующих следующему дню.
При решении задачи принять во внимание, что в современном (григорианском)
календаре каждый год, номер которого делится на 4, является високосным,
за исключением тех номеров, которые делятся на 100 и не делятся на 400.
}

program q179388;

const days_in_month : array [1..12] of word =
(
31, { январь }
28, { февраль (невисокосный) }
31, { март }
30, { апрель }
31, { май }
30, { июнь }
31, { июль }
31, { август }
30, { сентябрь }
31, { октябрь }
30, { ноябрь }
31 { декабрь }
);

{ Возвращает true, если год високосный }
function is_leap_year( year : integer ) : boolean;
begin
if (year and 3) <> 0 then
is_leap_year := false { год не делится на 4 - невисокосный }
else { год делится на 4 }
if (year mod 100) <> 0 then
is_leap_year := true { год не делится на 100 - високосный }
else { год делится на 100, проверяем, делится ли он на 400 }
is_leap_year := (year mod 400) = 0;
end;

var day, month, year : integer;

begin
write( 'Введите дату (число, месяц, год) цифрами через пробел: ' );
readln( day, month, year );

if month = 2 then { февраль - особая обработка }
if is_leap_year(year) then
days_in_month[2] := 29
else
days_in_month[2] := 28;

if (month <= 0) or (month > 12) or
(day <= 0) or (day > days_in_month[month]) or
(year <= 0 )
then
writeln( 'Недопустимая дата.' )
else begin
if day < days_in_month[month] then { следующий день того же месяца }
inc( day )
else begin { последний день месяца }
day := 1;
inc( month );
if month = 13 then begin { следующий год }
month := 1;
inc( year );
end;
end;
writeln( 'Следующий день: ', day, '.', month, '.', year );
end;
writeln( 'Нажмите [Enter] для выхода...' );
readln;
end.
Проверено в Borland Pascal 7.0.

179388.c:
Код:
/*
Даны натуральные числа а, b, с, которые обозначают число, месяц и год,
например 1, 4, 1901 - 1 апреля 1901 года.
Получить тройку чисел, соответствующих следующему дню.
При решении задачи принять во внимание, что в современном (григорианском)
календаре каждый год, номер которого делится на 4, является високосным,
за исключением тех номеров, которые делятся на 100 и не делятся на 400.
*/

#include <stdio.h>

int days_in_month[] =
{
31, // январь
28, // февраль (невисокосный)
31, // март
30, // апрель
31, // май
30, // июнь
31, // июль
31, // август
30, // сентябрь
31, // октябрь
30, // ноябрь
31 // декабрь
};

/* Возвращает ненулевое значение, если год високосный */
int is_leap_year( int year )
{
return (year & 3) ? 0 : (year % 100) ? 1 : year % 400 == 0;

/* предыдущий оператор делает то же самое, что и следующий код:
if( year & 3 ) return 0; // год не делится на 4 - невисокосный
// год делится на 4
if( year % 100 ) return 1; // год не делится на 100 - високосный
// год делится на 100, проверяем, делится ли он на 400
return year % 400 == 0;
*/
}

int main()
{
int day, month, year;
printf( "Введите дату (число, месяц, год) цифрами через точку: " );
scanf( "%d . %d . %d", &day, &month, &year );

if( --month == 1 ) /* февраль - особая обработка */
days_in_month[1] = is_leap_year(year) ? 29 : 28;

// значение month должно быть в диапазоне 0..11
if( (unsigned)month > 11 || day <= 0 || day > days_in_month[month] || year <= 0 ) {
printf( "Недопустимая дата.\n" );
system( "pause" );
return 1;
}

if( day < days_in_month[month] ) /* следующий день того же месяца */
++day;
else { /* последний день месяца */
day = 1;
if( ++month == 12 ) { /* следующий год */
month = 0;
++year;
}
}
printf( "Следующий день: %d.%02d.%d\n", day, month+1, year );
system( "pause" );
return 0;
}
Проверено в Code::Blocks 10.05 (gcc) и MSVC++ 6.0.

Успехов!
давно
Академик
320937
2216
05.07.2010, 20:15
общий
Филипов Олег Вичеславович:
Добрый день! Вы пишете.
Целой частью числа х, обозначаемой [х], называется наибольшее целое, не превосходящее х;

После чего приводите примеры:
...[- 3.14] = 4, [- 3] = 3.

Получаем противоречие. Исходя из Вашего определения, должно быть
Код:
[- 3.14] = -4, [- 3] = -3
Неизвестный
05.07.2010, 21:46
общий
Исправил свой код в ответе — была ошибка в проверке корректности введенных данных.
Неизвестный
05.07.2010, 22:30
общий
Филипов Олег Вичеславович:
Решение второй задачи:

Код:
/*
Дано действитёльное число х. Получить:
- целую часть числа х;
- число х, округленное до ближайшего целого;
- число х без дробных цифр.

Целой частью числа х, обозначаемой [х], называется наибольшее целое, не превосходящее х
*/


#include <stdio.h>
#include <math.h>


int main()
{
float f, w, r, h;
while(1) {
printf( "\nВведите действительное число (0 - выход): " );
scanf( "%f", &f );
if( f == 0.0 ) break; // сравнение с 0 - точное
w = floor( f ); // целая часть
r = floor( f+0.5 ); // округление
h = f < 0 ? ceil(f) : w;

printf(
"Целая часть : %g\n"
"Округление : %g\n"
"Без дробных цифр: %g\n",
w, r, h );
}
return 0;
}
Форма ответа