Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.08.2011, 10:03   #1
wandererindreams
Пользователь
 
Регистрация: 19.07.2011
Сообщений: 12
По умолчанию Метки, для упрощения структуры программы

Меня научили, что метки - зло и их нужно избегать любыми способами (с оговоркой про очень исключительные случаи). Я согласен, и метки не люблю, но вот код программы, который которая по моему от меток не страдает, а так же если не использовать метки ее читаемость будет гораздо хуже.
Код:
#include <stdio.h>
#include <conio.h>
int read_number(int &number);                            //считывает максимальное число для составления рядов Лэнгфорда
int make_series(const FILE* f_series, const int number, const int &number_of_series = 3);  //находит ряды Лэнгфорда

int output_series(const FILE* f_series);                 //выводит на экран ряды Лэнгфорда, записанные в файле f_series
void erors(const &error);                                //обрабатывает ошибки (угаданные заранее), возникающие в программе
//---------------------------------------------------------------
/*
 error    - номер ошибки (0 - ошибок нет, работаем дальше)
 number   - максимальное число для составления ряда Лэнгфорд (его вводит пользователь)
 char0    - вспомогатеьная переменная
 f_series - файл, куда записываются найденные ряды Лэнгфорда
*/
main()
{
 int error = 0,
     number = 0,
     number_of_series = 2;
 char char0 = 'n';
 FILE* f_series = NULL;

 clrscr();
 printf("Данная программа находит последовательности Ленгфорда для любого целого числа\n");
 printf("от 3 до 12 с условием, что последовательность должна начинаться с наибольшего\nчисла.\n");

 f_series = fopen("\\series", "w");

 do                                              //цикл, пока не будет ошибки или пользователь не захочет закончить работу
 {
  error = read_number(number);                   //пользователь вводит максимальное число Лэнгфорда
  if(error) goto m_error;
  error = make_series(f_series, number); //находятся ряды Лэнгфорда, начинающиеся с масимального числа number
  if(error) goto m_error;
  error = output_series(f_series);
  if(error) goto m_error;
  printf("Завершить работу программы? (y/)n: ");
  char0 = getchar();
  while(getchar() != '\n');
 }
 while(char0 != 'y');

 m_error:                                        //выход сюда, если возникла ошибка
 if (error) erors(error);
 getch();
}
//---------------------------------------------------------------
Смысл в том, что я хочу знать нормально ли выполнила функция свою работу, или нет, и если нет, то прекратить выполнение программы. Но если убрать метки, то такое можно сделать только вложенными условиями, которые выглядят не очень читабельно даже в такой небольшой программе. Вопрос: может такой вариант использования меток вполне приемлем? Если нет, то почему и как получше переписать программу.

Последний раз редактировалось wandererindreams; 12.08.2011 в 10:09.
wandererindreams вне форума Ответить с цитированием
Старый 12.08.2011, 11:13   #2
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

> ее читаемость будет гораздо хуже

куда уж хуже )
У вас же есть уже цикл, чем break не устраивает?

Код:
do                                              //цикл, пока не будет ошибки или пользователь не захочет закончить работу
{
    if (error = read_number(number)) break;                   //пользователь вводит максимальное число Лэнгфорда
    //
    if (error = make_series(f_series, number)) break; //находятся ряды Лэнгфорда, начинающиеся с масимального числа number
    //
    if (error = output_series(f_series)) break;
    //
    printf("Завершить работу программы? (y/n): ");
    char0 = getchar();
    //
    while (getchar() != '\n') ;
}
while(char0 != 'y');

if (error) erors(error);
Код:
 m_error:                                        //выход сюда, если возникла ошибка
сюда он попадёт и при обычном выходе из цикла (по нажатию 'y'). Видите, уже сами запутались с этими метками. Фтопку их )
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 12.08.2011, 11:37   #3
wandererindreams
Пользователь
 
Регистрация: 19.07.2011
Сообщений: 12
По умолчанию

Цитата:
У вас же есть уже цикл, чем break не устраивает?
Согласен, если это законченная программа, то да, но стоит мне хоть что-то добавить после цикла do/while и break передаст управление НЕ в конец программы.
Цитата:
сюда он попадёт и при обычном выходе из цикла (по нажатию 'y'). Видите, уже сами запутались с этими метками.
Я не запутался. До обычного нажатия 'y' будут выполнены все функции цикла, а я хочу выйти досрочно, без выполнения, если например чтение данных вызвало ошибку.

Последний раз редактировалось wandererindreams; 12.08.2011 в 11:40.
wandererindreams вне форума Ответить с цитированием
Старый 12.08.2011, 11:52   #4
G-Kyller
Пользователь
 
Регистрация: 11.03.2011
Сообщений: 67
По умолчанию

Есть специальные операторы try-catch которые отлавливают ошибки, т.е. пока все хорошо выполняется TRY{}, как только появляется ошибка(в блоке try), программа переходит в CATCH{}.
Таким образом можно отлавливать все ошибки, либо создать свои типы ошибок и отлавливать их, добавляя разные действия на разные ошибки.
P.S. Читабельность при этом никак не ухудшается, а наоборот.
Если помог, жми спасибо

Последний раз редактировалось G-Kyller; 12.08.2011 в 11:55.
G-Kyller вне форума Ответить с цитированием
Старый 12.08.2011, 12:04   #5
wandererindreams
Пользователь
 
Регистрация: 19.07.2011
Сообщений: 12
По умолчанию

Цитата:
Сообщение от G-Kyller Посмотреть сообщение
Есть специальные операторы try-catch которые отлавливают ошибки, т.е. пока все хорошо выполняется TRY{}, как только появляется ошибка(в блоке try), программа переходит в CATCH{}.
Поискал в интернете. Если правильно понял, то операторы try-catch введены в С++, мне же нужно написать именно на С.
wandererindreams вне форума Ответить с цитированием
Старый 12.08.2011, 12:35   #6
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

> break передаст управление НЕ в конец программы

ну и что? у вас же там error всё-равно проверяется:

Код:
if (error) {
  // всё, приплыли
}
else {
  // кажется, пронесло
}
> Я не запутался

я имел в виду, что вот этот комментарий:

Цитата:
//выход сюда, если возникла ошибка
не соответсвует действительности.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 12.08.2011, 14:07   #7
wandererindreams
Пользователь
 
Регистрация: 19.07.2011
Сообщений: 12
По умолчанию

Цитата:
Сообщение от veniside Посмотреть сообщение
> break передаст управление НЕ в конец программы

ну и что? у вас же там error всё-равно проверяется:

Код:
if (error) {
  // всё, приплыли
}
else {
  // кажется, пронесло
}
Вы предлагаете после цикла написать if-else от которого я и пытаюсь избавиться, но в любом случае я могу после цикла написать переход по метке в случае ошибки, так что от меток в цикле в любом случае вы меня избавили =).
У меня правда опыта мало, может получиться избежать глубокого вложения условий, буду пытаться. А на основной вопрос пока никто не ответил: использование меток, как переход в конец программы при возникновении ошибки, является плохим, плохо модифицируемым способом или нет? Вроде нет, тут они работают вроде оператора break. Можно и сам break использовать, но тогда будет полный выход из main, без захода в функцию errors(), которая подскажет где именно произошла ошибка.
wandererindreams вне форума Ответить с цитированием
Старый 12.08.2011, 14:11   #8
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

А почему Вы пытаетесь уйти от if-then-else? Как раз в сравнении с метками это основной и вполне логичный механизм управления логикой вычислений.
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 12.08.2011, 14:45   #9
wandererindreams
Пользователь
 
Регистрация: 19.07.2011
Сообщений: 12
По умолчанию

Цитата:
Сообщение от Utkin Посмотреть сообщение
А почему Вы пытаетесь уйти от if-then-else? Как раз в сравнении с метками это основной и вполне логичный механизм управления логикой вычислений.
Потому, что первый вариант читается лучше, чем второй.
Код:
 {
  if(error = read_number(number)) goto m_error;
  if(error = make_series(f_series, number)) goto m_error;
  if(error = output_series(f_series)) goto m_error;
  ......
  m_error: errors();
 }

 {
  if( !(error = read_number(number)) ) {
   if( !(error = make_series(f_series, number)) )  {
    if( !(error = output_series(f_series)) ) {
    } else errors(); break;
   } else errors(); break;
  } else errors(); break;
 }
Я как-то написал не очень большую программу (в турбо паскале), где тело условия занимало больше одного экрана, а учитывая что условий несколько, было не удобно высчитывать к какому if относится else (конечно комментарии в помощь, но все же). А в первом варианте та же линейная структура, более компактная и без лишнего нагромождения скобок.
Может конечно я плохо продумал программу, но в любом случае первый вариант смотрится удобнее второго.
wandererindreams вне форума Ответить с цитированием
Старый 12.08.2011, 15:04   #10
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Есть еще swith-case...
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Упрощения парсинга текста Lauri Общие вопросы Delphi 11 16.07.2011 14:09
Программы разветвленной структуры в С++ Draips Общие вопросы C/C++ 1 11.05.2010 19:15
Программы разветвленной структуры в С++ Draips Помощь студентам 0 11.05.2010 17:58
ПРОГРАММЫ ЦИКЛИЧЕСКОЙ СТРУКТУРЫ В VISUAL BASIC 6 uradik2 Помощь студентам 5 23.03.2010 23:55
Разработка программы блочной структуры xxSINxx Помощь студентам 2 05.03.2009 15:50