Форум русскоязычного сообщества Ubuntu


Увидели сообщение с непонятной ссылкой, спам, непристойность или оскорбление?
Воспользуйтесь ссылкой «Сообщить модератору» рядом с сообщением!

Автор Тема: Программа на Си. Помогите сократить код и увеличить быстродействие.  (Прочитано 2573 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Sеr

  • Автор темы
  • Любитель
  • *
  • Сообщений: 60
  • Познаю мир, пока не в вузе...
    • Просмотр профиля
Ну, собственно, я написал интересную программку..обработки ошибок почти нет, но мне важно другое.
Как на ваш взгляд должен выглядеть этот код? Достаточно короткий, достаточно производительный?
Оцените, пожалуйста, и если сможете покажите как будет лучше, проще и быстрее.
PS: программа перевода в n-систему счисления из 10-ричной.


#include <stdio.h>
int div(int *x,int n)
{
int y=*x;
*x=y/n;
y%=n;
return y;
}
int system(int x, int n)
{
int y,i=0,m[100];
if(n<=10){
for(;;i++){
y = div(&x,n);
if(x<n) {
m[i]=y;
m[++i]=x;
break; }
else m[i]=y; }
for(i;i>=0;i--) printf("%d",m[i]); }
else if(n>10){
for(;;i++){
y = div(&x,n);
if(x<n) {
if(y<10)m[i]=y+'0';
else m[i]=y+'A'-10;
if(x<10)m[++i]=x+'0';
else m[++i]=x+'A'-10;
break; }
else {
if(y<10)m[i]=y+'0';
else m[i]=y+'A'-10; }
}
for(i;i>=0;i--) printf("%c",m[i]); }
}
int main()
{
int x,y;
printf("Добро пожаловать!\nЭта программа переводит числа в формате ввода:");
printf(" \"Число\",\"Основание системы\" в заданную систему счисления.\nМаксимально возможное основание системы - 36.\n");
while(1){
while(scanf("%d, %d", &x, &y),y>36)printf("Максимально возможное основание системы - 36!\n");
system(x,y);
putchar('\n');}
return 0;
}
 


46 строк.

Оффлайн SergeyIT

  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 5708
  • Все по палатам!
    • Просмотр профиля
Никогда не используйте имена функций из стандартных библиотек
man div
man system
Извините, я все еще учусь

andrey_p

  • Гость
1. Ты сам то пробовал запустить свою программу?

2. Всегда компилируй программу с флагом -Wall.

3. За одну конструкцию (нерабочую и уродливо написанную) - шалбан. Два раза. На все остальное даже смотреть не хочется.
while(1){
while(scanf("%d, %d", &x, &y),y>36)printf("Максимально возможное основание системы - 36!\n");
system(x,y);
putchar('\n');}

ЗЫ Заимей замечательную книгу "Практика программирования" - и от корки до корки.

ЗЫЫ То all. На русском знаю только одну хорошую книгу для начинающих - Программирование в тональности С#, но она маленько не в тему. Может что-то еще есть? На английском знаю несколько, а вот на русском что-то не попадалось. К&R все-таки сложноват для совсем зеленых. Ну и tpop тоже только в качестве дополнительной может идти.
« Последнее редактирование: 20 Мая 2011, 17:40:13 от andrey_p »

Оффлайн Not eXist

  • Активист
  • *
  • Сообщений: 916
    • Просмотр профиля
Цитировать
while(1)
На такие вещи компилятор должен бросать варнинги вида "Constant value in conditional expression", как и на while(true).
Бесконечные циклы лучше оформлять через for(;;).

andrey_p

  • Гость
gcc не жалуется, он распознает эту идиому. И это было бы самая маленькая проблема. Фактически его main сводится:

int main()
{
    int x, y;
    while(1)
    {
        while(scanf("%d %d", &x, &y), y > 36)
        {
            printf("y > 36\n");
        }
        printf("%d, %d\n", x, y);
    }
    return 0;
}

Жуть. Как из этого предполагается выйти? А как это еще и написано... Жуть в квадрате.
« Последнее редактирование: 20 Мая 2011, 19:34:17 от andrey_p »

Оффлайн inkblack

  • Старожил
  • *
  • Сообщений: 1216
    • Просмотр профиля
«Помогите сократить код и увеличить быстродействие» — Тут быстродействие, мне кажется, далеко не первая задача. Что будет, если программе ввести в качестве числа и основания 1 и 1? Вот так:
Добро пожаловать!
Эта программа переводит числа в формате ввода: "Число","Основание системы" в заданную систему счисления.
Максимально возможное основание системы - 36.
1,1
А если просто запятую? — еще интереснее.

И почему-то приветственное сообщение не влезает в 80 колонок консоли (я уж не говорю про терминалы произвольной ширины).

А зачем здесь 100?
int y,i=0,m[100];
Вообще, разбираться в программе гораздо проще, если известно, какие требования к ней предъявляются.
ИМХО, для такой программы компактность и быстродействие нахрен не нужны.
Гораздо важнее удобство пользования (см. примеры выше) и понятность кода (ни одного комментария).

Ну и ко всему вышесказанному присоединяюсь.

====================================================================================

Ser, вы не бойтесь, здесь ребята хорошие. Подскажут, если надо, но вы и сами думайте, что делаете и зачем.
Делюсь знаниями, но их у меня мало!

Оффлайн Sеr

  • Автор темы
  • Любитель
  • *
  • Сообщений: 60
  • Познаю мир, пока не в вузе...
    • Просмотр профиля
Никогда не используйте имена функций из стандартных библиотек
man div
man system

Спасибо, я это знаю, но здесь решил использовать..просто не подключены. Учту :)

2. Всегда компилируй программу с флагом -Wall.
>>не расскажете, что это за флаг? я им не пользовался.

3. За одну конструкцию (нерабочую и уродливо написанную) - шалбан. Два раза. На все остальное даже смотреть не хочется.
>>Рабочая.
это обработчик ошибок, он включается только если я ввел второе значение превышающее 36. в другом случае цикл просто опускается и программа продолжает выполнятся, не выполняя тело цикла.

ЗЫ Заимей замечательную книгу "Практика программирования" - и от корки до корки.
>>Спасибо :)

Жуть. Как из этого предполагается выйти? А как это еще и написано... Жуть в квадрате
>>Ну, собственно, я и не рассчитывал делать выход из цикла =)
из программы можно выйти нажав CTRL+C

Цитировать
Что будет, если программе ввести в качестве числа и основания 1 и 1? Вот так:
Код:
Добро пожаловать!
Эта программа переводит числа в формате ввода: "Число","Основание системы" в заданную систему счисления.
Максимально возможное основание системы - 36.
1,1
А если просто запятую? — еще интереснее.

здесь полностью согласен =(
программа не имеет нормальный обработчик ошибок и имеется порядочный баг - она не хочет выводить числа в единичной системе счисления, непонятно почему. по идее она должна вывести на экран т-количество нулей, то есть если задать  5,1 она по идее должна вывести 00000, но этого почему то не происходит и она продолжает работать, при
этом загружая систему(

И почему-то приветственное сообщение не влезает в 80 колонок консоли (я уж не говорю про терминалы произвольной ширины).
>> не совсем понял, что вы имеете в виду.

А зачем здесь 100?
>>Честно говоря, нужен массив из n-элементов, причем я не могу знать, сколько их. ну я и указал 100, предположительно -_- только эта строка мне очень не нравится, а как сделать по-другому не знаю . =((

Гораздо важнее удобство пользования (см. примеры выше) и понятность кода (ни одного комментария).
>>Согласен =)
только удобство использования я здесь с самого начала не предусматривал, а комментарии просто решил не использовать =_=

Спасибо!
сейчас попробую немного подправить =)

andrey_p

  • Гость
Цитировать
>>Рабочая.
это обработчик ошибок, он включается только если я ввел второе значение превышающее 36. в другом случае цикл просто опускается и программа продолжает выполнятся, не выполняя тело цикла.

Ну-ну. Рабочая. Обработчик ошибок...  А если ввести "0" и "A" ? А если 10 и -1000000000? Навскидку, в первом случае будет бесконечный цикл, во втором бессмысленное значение. И программа, которая не предусматривает выхода, а только ее "убийство" подойдет разве что для автономного управления полетом баллистической ракеты. ;)

Оффлайн es1840

  • Активист
  • *
  • Сообщений: 328
    • Просмотр профиля
Еще хорошо проверяет код на соответствие стандартам программка splint.
Она есть в стандартном репозитории.
Вот, к примеру прогон вашего кода:
$ splint programm.c
(Нажмите, чтобы показать/скрыть)

Оффлайн inkblack

  • Старожил
  • *
  • Сообщений: 1216
    • Просмотр профиля

...

2. Всегда компилируй программу с флагом -Wall.
>>не расскажете, что это за флаг? я им не пользовался.


Warnings=all

Цитировать

...
И почему-то приветственное сообщение не влезает в 80 колонок консоли (я уж не говорю про терминалы произвольной ширины).
>> не совсем понял, что вы имеете в виду.
...


Ну, получается как-то так:

Добро пожаловать!
Эта программа переводит числа в формате ввода: "Число","Основание системы" в зад
анную систему счисления.
Максимально возможное основание системы - 36.
— в зад — некрасиво...

Цитировать


... не хочет выводить числа в единичной системе счисления, непонятно почему. по идее она должна вывести на экран т-количество нулей, то есть если задать  5,1 она по идее должна вывести 00000, ...


... а комментарии просто решил не использовать =_=


Были бы комментарии, было бы понятно, что она должна переводить и в единичную систему. А так непонятно ничего, в чужих 46 строчках так сразу трудно разбираться. Надо догадаться, что этот код должен делать (и что на самом деле делает) в случае тех или иных входных данных, а ни намёка на это нет. Да вы и сами в своём коде через две недели не разберётесь...
Делюсь знаниями, но их у меня мало!

Оффлайн Sеr

  • Автор темы
  • Любитель
  • *
  • Сообщений: 60
  • Познаю мир, пока не в вузе...
    • Просмотр профиля
#include <stdio.h>
int divisionResidue(int *x,int n) //Возвращает остаток от деления x на n и передает x результат деления.
{
int y=*x;
*x=y/n;
y%=n;
return y;
}
int functionConvertNumberSystem(int x, int n)
{
int y,i=0,m[100];
if(n<=10){ //Выполняется, если система счисления не включается в себя буквенных обозначений цифр(n<10).
for(;;i++){
y = divisionResidue(&x,n); //X делится на основание системы и остаток присваивается переменной у
if(x<n) { //Инициализация элементов массива значением остатка от деления(y)
m[i]=y;
m[++i]=x;
break; }
else m[i]=y; }
for(i;i>=0;i--) printf("%d",m[i]); }
else if(n>10){ //Выполняется, если система счисления предусматривает "буквенные цифры"(A,B,...,X,Z)
for(;;i++){
y = divisionResidue(&x,n);
if(x<n) { //Пользуемся кодировкой символов ('A' = 65; допустим y == 11 =>
if(y<10)m[i]=y+'0'; //=> x[i] == 11 - 10 + 'A' ==  'A' + 1 => x[n] == 'B')
else m[i]=y+'A'-10;
if(x<10)m[++i]=x+'0';
else m[++i]=x+'A'-10;
break; }
else {
if(y<10)m[i]=y+'0';
else m[i]=y+'A'-10; }
}
for(i;i>=0;i--) printf("%c",m[i]); }
else { printf("Not a Number!\n"); //Обработчик ошибки ввода.
main(); }
}
int main()
{
int x,y;
printf("Добро пожаловать!\nЭта программа переводит числа в формате ввода:");
printf(" \"Число\",\"Основание системы\" в указанную систему счисления.\nМаксимально возможное основание системы - 36.\n");
while(scanf("%d, %d", &x, &y),y>36)printf("Максимально возможное основание системы - 36!\n");
functionConvertNumberSystem(x,y);
putchar('\n');
return 0;
}
нет обработчика ошибок и я убрал лишний бесконечный цикл.
добавил несколько комментариев.

Оффлайн фирэфохэ

  • Старожил
  • *
  • Сообщений: 2169
  • straightedge
    • Просмотр профиля
Кто тебя так учил фигурные скобки расставлять :idiot2:?
http://i18.ЗАПРЕЩЁННЫЙ РЕСУРС/big/2011/0325/6d/19eaa72dd24048a6fb0587832c4b096d.gif КДЕ - УГ. Дебиан - недоось.

andrey_p

  • Гость
Заставил вспомнить молодость.
(Нажмите, чтобы показать/скрыть)

Это неполноценная программа - scanf вообще не подходит для универсальных и интерактивных программ, только для пакетной обработки. Правильно - надо считывать строку и парсить ее. Но, по-крайней мере, эта программа работает как фильтр и делает что-то вменяемое в случае неправильного ввода (перебор или отрицательное число - пустая строка, нечисло - выход).

Ну и алгоритм проще, и, надеюсь, стиль получше.

ЗЫ Тщательно не тестировал, но вроде должно работать. Комментарии на английском, поскольку так привык, и вообще считаю, что в программировании английский - lingua franca, и его знать обязательно.
« Последнее редактирование: 22 Мая 2011, 07:23:03 от andrey_p »

Оффлайн inkblack

  • Старожил
  • *
  • Сообщений: 1216
    • Просмотр профиля
Не критикую, но:
#define MAXLENINT 10*8 + 1
— этакая мина замедленного действия. Потом вдруг кто-нибудь где-нибудь решит использовать
MAXLENINT * 2
Делюсь знаниями, но их у меня мало!

andrey_p

  • Гость
Согласен (с чего я решил, что компилятор вычислит  :idiot2:. Он это, конечно, сделает, но после препроцессора). Поправил.

 

Страница сгенерирована за 0.051 секунд. Запросов: 26.