Форум программистов, компьютерный форум, киберфорум
ZaMaZaN4iK
Войти
Регистрация
Восстановить пароль
Этот блог посвящён олимпиадному программированию.Если вы хотите узнать, что это такое и с чем его едят - милости просим.Если вы хотите чему-то научиться, что-то дополнить - добро пожаловать!

В данном блоге я буду стараться рассказать про особенности спортивного программирования.Также расскажу о различных типах задач и, конечно, алгоритмах.
Рейтинг: 4.00. Голосов: 1.

Структура программы, ввод\вывод и много чего ещё

Запись от ZaMaZaN4iK размещена 26.05.2013 в 22:45

Ну, надо начинать что-либо более близкое к практике.Для начала я хотел бы рассказать про построение программы, ввод\вывод данных, перенаправление ввода и выода в файлы, типы используемых переменных и отладку программ.

Сделаю ещё раз оговорку - все исходники будут только на С++.

Что ж, как надо структурировать программу? В спортивном программировании принято делать так: В начале исходника подключаются все необходимые библиотеки(стандартный набор и опциональные), обьявляют пространство имен std,потом все переменные и массивы обьявляют глобально, затем пишут функции-заготовки, и в конце-концов пишут main().

Как всё это выглядит:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <utility>
#include <cmath>
#include <vector>
 
using namespace std;
 
const long long n=10;
 
long long arr[n];
 
void prepare()
{
}
 
void input()
{
}
 
void ans()
{
}
 
void output()
{
}
 
int main()
{
    prepare();
    input();
    ans();
    output();
    return 0;
}
У меня все заготовки выглядят примерно так.Почему так много библиотек подключаю сначала? А просто так привык уже.И они не мешаются.

using namespace std используется для удобства, чтобы каждый раз не писать std::

Всё разбито на функции для лучшего понимания кода(а то бывает, напишешь, а потом сидишь, думаешь - где и что)
В функции prepare() я задаю всем переменным какие либо значения.В input() ввожу все необходимые данные. Ans() это функция решения задачи, ну а output() выводит ответ.А потом всё это вызывается поочередно в main() и всё.

Такое структурирование исходника очень удобно.Рекомендую к нему привыкнуть.


Теперь поговорим про ввод\вывод.

В С++ принято использовать cin и cout.Но в спортивном программировании их использование нежелательно, так как они работают довольно медленно.А вместо них используют функции ввода\вывода языка Си - scanf и printf и иже с ними.С этими функциями немного труднее работать, но они работают значительно быстрее, чем функции потокового ввода\вывода.Давайте с ними познакомимся.

Функции ввода.
scanf() - функция ввода.Читает значения из стандартного потока и записывает их в переменные.Если ввод невозможен, возвращает EOF(end of file).Функцию следует использовать так:
C++
1
2
3
scanf("%d",&n);// читает 1 число типа int
scanf("%f %d %c",&x,&n,&let);//читает 2 числа и 1 символ и сохраняет их в переменные типа float,int и char
scanf("%s",arr);//читает строку
Эта функция в основном используется при вводе.Обратите внимание, что вы должны передавать адрес, а не имя переменной.Но при вводе строки, надо передавать имя переменной, так как имя массива - это указатель на 1-ый элемент.При чтении строки, в массив после всех символов записывается '\0'.

Для каждого типа существует свой идентификатор для переменной.Вот таблица для этих типов:
%c Читает один символ
%d Читает десятичное целое
%i Читает целое в любом формате (десятичное, восьмеричное или шестнадцатеричное)
%e Читает число с плавающей точкой
%f Читает число с плавающей точкой
%lf Читает число с плавающей точкой(сохраняет в double)
%o Читает восьмеричное число
%s Читает строку
%x Читает шестнадцатеричное число
%p Читает указатель
%n Принимает целое значение, равное количеству прочитанных до сих пор символов
%u Читает десятичное целое без знака
%% Читает знак процента
%I64d Читает 64-битное число

Эту таблицу надо выучить.
С этой функцией надо быть очень аккуратными.Если что -то забудете написать, то весь ввод пойдет насмарку.

getchar() - функция, возвращающая код прочитанного символа, если ввод неудачен, до возвращает EOF. Ввод заканчивается при получении функцией символа '\n'(Enter).
Тоже очень удобная функция.Рекомендую её запомнить.



С выводом всё очень просто, если вы усвоили ввод.вывод осуществляется при помощи функций printf() и putchar().
printf() используется также, как и scanf(), только передавать аргументы нужно без &, иначе он напечатает не то, что вы хотели.А putchar() используйте как getchar().



С вводом и выводом разобрались.А как же вводить и выводить данные из и в файлы?Можно конечно использовать файловый ввод\вывод, открывать файловый поток, потом его закрывать,но это всё немного дольше писать, да и работает оно всё медленно.А используется для наших целей замечательная функция freopen().

Пример использования:
C++
1
2
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
Эти команды как бы подменяют стандартный поток ввода\вывода на файловый.А после того, как мы это применили, можно спокойно использовать scanf\printf.И всё будет работать.


Что касается типа переменных.Рекомендуется везде использовать long long(он же int64).Не будем боятся всяких переполнений.Место под массив лучше сразу резервировать+ ещё пару элементов, чтобы случайно не вышли за границу массива.И только в случаях крайней нехватки памяти используйте типы меньшего размера.



Ну вот, по плану только осталась отладка.На олимпиадах пишут во многих средах - MSVS 2010, CodeBlocks, Dev-C++.В студии обычно писать не дают, а отладчик там очень хороший.Codeblocks чаще появляется, но в нем компилятор настроить немного сложновато, поэтому я выбрал для себя и постоянно на олимпиадах пишу в Dev-C++.Но хочу огорчить Вас - в Дэве нет отладчика.Поэтому всё приходится делать ручками.

И вот тут нам пригодится структура нашей программы.Если программа не работает, то комментим все функции, кроме одной, и проверяем её.Не нашли ошибок - проверяем следующую, и так далее.да, в Дэве отладка программ - это сущий ад, но ничего не поделаешь - зато IDE мало весит, не требовательна к ресурсам машинки(а иногда на таких корчах пишут олимпиаду, что удивляешься, как он работает вообще).Точки останова - system("pause"), вывод переменных сами пишем, и вот так продолжаем до победного конца.


Надеюсь, информация Вам пригодится.И удачи!
Размещено в Без категории
Просмотров 1810 Комментарии 5
Всего комментариев 5
Комментарии
  1. Старый комментарий
    и тут остапа понесло
    Запись от Jupiter размещена 26.05.2013 в 23:15 Jupiter вне форума
  2. Старый комментарий
    Аватар для ZaMaZaN4iK
    Да нет, просто несколько дней уже всё это понемногу писал.А постил вот так всё в 1 день
    Запись от ZaMaZaN4iK размещена 27.05.2013 в 02:07 ZaMaZaN4iK вне форума
  3. Старый комментарий
    Аватар для dr.curse
    Цитата:
    В С++ принято использовать cin и cout.Но в спортивном программировании их использование нежелательно, так как они работают довольно медленно.А вместо них используют функции ввода\вывода языка Си - scanf и printf и иже с ними.
    если причина только скорость и привычнее писать с cin/cout то можно писать изпользую их просто в начале программы вызвать ios_base::sync_with_stdio(0) и будет хороший прирост скорости
    Запись от dr.curse размещена 05.06.2013 в 18:51 dr.curse вне форума
  4. Старый комментарий
    Аватар для ZaMaZaN4iK
    aram_gyumri, спасибо большое! Не знал про этот способ.Протестировал только что - производительность такая же, как и у scanf и printf.Но cin and cout IMHO удобнее использовать
    Запись от ZaMaZaN4iK размещена 08.06.2013 в 19:59 ZaMaZaN4iK вне форума
  5. Старый комментарий
    Аватар для dr.curse
    ну кому как мне scanf/printf удобнее поскольку я больше на Си пиши + форматирование
    Запись от dr.curse размещена 08.06.2013 в 20:09 dr.curse вне форума
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.