Форум программистов
 
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

Вернуться   Форум программистов > C++ > Общие вопросы C/C++
Регистрация

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

Ответ
 
Опции темы
Старый 12.09.2018, 17:06   #1
Sinli
Пользователь
 
Регистрация: 10.09.2018
Сообщений: 43
Репутация: 10
Радость Оцените, пожалуйста, данный код.

Добрый день, программисты.
Только что выполнил одно упражнение из книги Стивена Прата (глава 6, упр.5).
упр 5.png

Код работает, но, так как я совсем недавно начал заниматься изучением программирования, подозреваю, что выполнил задание через пень колоду. Оцените, пожалуйста, наверняка найдете какие-нибудь лишние телодвижения в коде.

Код:

#include <stdio.h>

int main(void)
{
        char ch;
        int i, j;
        int number_of_word, key_of_word;
        printf("Введите прописную букву: ");
        scanf("%c", &ch);
        number_of_word = (int)ch - 64;
        key_of_word = number_of_word;
        for (i = 1; i <= key_of_word; i++)
        {

                for (j = 1; j + i - 1 < key_of_word; j++)
                        printf(" ");
                for ( ; j <= key_of_word; j++)
                        printf("%c", ch + 1 - (number_of_word--));
                number_of_word - (int)ch - 64;
                for ( ; j + i - 1 > key_of_word + 1; j--)
                        printf("%c", ch - 1 - (number_of_word++) );
                printf("\n");
                number_of_word = (int)ch - 64;
        }
        return 0;
}

Премного благодарен.
Sinli вне форума   Ответить с цитированием
Старый 12.09.2018, 17:31   #2
Alex11223
Модератор
Заслуженный модератор
 
Регистрация: 12.01.2011
Сообщений: 17,111
Репутация: 3316

icq: 512-765
skype: alexp.frl
По умолчанию

У переменных странные имена, "номер слова"? Если это число слов, то лучше wordsCount (или wordCount) и т.п., я правда не увидел в задании ничего про слова, и про ключи.

И обычно используют camelCase вместо _, это ж как минимум удобнее писать. Так тоже норм, главное в одном стиле, просто не помню когда последний раз видел _ в именах переменных (кроме констант капсом). В некоторых языках есть общепринятый стиль кода, но С не из их числа, у всех свой.
https://ru.hexlet.io/blog/posts/naming-in-programming

И в современных стандартах С (с С99) можно объявлять переменные в любом месте, например
Код:

for (int i = 0; ........)

Вместo (a++) есть ++a.

Вместо 64 лучше писать 'A' или что там это. Ну и вообще магические числа зло, лучше заводить константы и т.п.

Последний раз редактировалось Alex11223; 12.09.2018 в 18:25.
Alex11223 вне форума   Ответить с цитированием
Старый 13.09.2018, 12:16   #3
Sinli
Пользователь
 
Регистрация: 10.09.2018
Сообщений: 43
Репутация: 10
По умолчанию

Добрый день. Внес изменения в код согласно рекомендациям.

Код:

#include <stdio.h>

int main(void)
{
        char ch;
        int i, j;
        int letterCount, letterOrder;
        int const START = 64; /*В ASCII код символа 'A' - 65, 'B' - 66 и т.д.*/
        printf("Введите прописную букву: ");
        scanf("%c", &ch);
        letterCount = (int)ch - START;
        letterOrder = letterCount;
        for (i = 1; i <= letterOrder; i++)
        {

                for (j = 1; j + i - 1 < letterOrder; j++)
                        printf(" ");
                for ( ; j <= letterOrder; j++)
                        printf("%c", ch + 1 - (letterCount--));
                for ( ; j + i - 1 > letterOrder + 1; j--)
                        printf("%c", ch - 1 - (letterCount++) );
                printf("\n");
                letterCount = (int)ch - START;
        }
        return 0;
}

"номер слова" - это меня подвел мой английский, хотел написать "номер буквы".
Почитал статью, теперь "_" в переменных использовать не буду.
Когда попытался объявить переменные "i" и "j" компилятор заругался, так что оставил как есть. К тому же вроде в этом нет ничего криминального?
Насчет постпрефиксного и препрефиксного (ин-)декрементирования: я читал, что в них есть разница, когда они являются частью какого-либо выражения. Они означают одно и то же, когда стоят обособленно. Или все же в данном случае разница есть?
На магическое число "64" завел константу.

Благодарю за советы.

Последний раз редактировалось Sinli; 13.09.2018 в 12:19.
Sinli вне форума   Ответить с цитированием
Старый 13.09.2018, 12:31   #4
Alex11223
Модератор
Заслуженный модератор
 
Регистрация: 12.01.2011
Сообщений: 17,111
Репутация: 3316

icq: 512-765
skype: alexp.frl
По умолчанию

Зачем 64 вообще писать? В С символы это просто числа, можно просто 'A' - 1.


Цитата:
Сообщение от Sinli Посмотреть сообщение
Когда попытался объявить переменные "i" и "j" компилятор заругался
По умолчанию может быть включен С89 стандарт.
В gcc/MinGW изменяется флагом --std=c99
Цитата:
Сообщение от Sinli Посмотреть сообщение
я читал, что в них есть разница, когда они являются частью какого-либо выражения
Ну так тут же так и есть если убрать скобки.
++а изменяет и возвращает новое, а++ возвращает старое и изменяет.
Alex11223 вне форума   Ответить с цитированием
Старый 13.09.2018, 13:23   #5
Sinli
Пользователь
 
Регистрация: 10.09.2018
Сообщений: 43
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alex11223 Посмотреть сообщение

Ну так тут же так и есть если убрать скобки.
++а изменяет и возвращает новое, а++ возвращает старое и изменяет.
поменял на все на префиксную форму. Правда, мне не понятно, почему это имеет значение.

Если сравнить эту часть кода:
Код:

 printf("%c", ch - 1 - (letterCount++) );
printf("%c", ch - (++letterCount) );

мне пришлось тут помимо изменения формы инкрементирования удалить "-1". И это логично.

НО если сравнить, скажем, это:
Код:

for (j = 1; j + i - 1 < letterOrder; j++)
                        printf(" ");
for (j = 1; j + i - 1 < letterOrder; ++j)
                        printf(" ");

то тут код работает как и прежде, и изменение формы инкрементирования никак не повлияло на результат. И мне не пришлось делать какие-то дополнительные корректировки.

Вот последний вариант программы:

Код:

#include <stdio.h>

int main(void)
{
        char ch;
        int i, j;
        int letterCount, letterOrder;
        int const START = 'A' - 1; /*В ASCII код символа 'A' - 65, 'B' - 66 и т.д.*/
        printf("Введите прописную букву: ");
        scanf("%c", &ch);
        letterCount = (int)ch - START;
        letterOrder = letterCount;
        for (i = 1; i <= letterOrder; ++i)
        {

                for (j = 1; j + i - 1 < letterOrder; ++j)
                        printf(" ");
                for ( ; j <= letterOrder; ++j)
                        printf("%c", ch - (--letterCount));
                for ( ; j + i - 1 > letterOrder + 1; --j)
                        printf("%c", ch - (++letterCount) );
                printf("\n");
                letterCount = (int)ch - START;
        }
        return 0;
}

Sinli вне форума   Ответить с цитированием
Старый 13.09.2018, 13:28   #6
Alex11223
Модератор
Заслуженный модератор
 
Регистрация: 12.01.2011
Сообщений: 17,111
Репутация: 3316

icq: 512-765
skype: alexp.frl
По умолчанию

Я бы letterCount++ делал просто в отдельной строке без лишних скобок и +-1.
Alex11223 вне форума   Ответить с цитированием
Старый 13.09.2018, 13:29   #7
p51x
Профессионал
 
Регистрация: 15.02.2010
Сообщений: 12,480
Репутация: 2073
По умолчанию

Для современных компиляторов в релизе с оптимизациями и для "простых" типов пре или пост не имеет значение, компилятор это способен оптимизировать. Обычно все равно стараются их разделять, чтобы лишний раз не напрягать читающего ваш код и было сразу понятен замысел.
__________________
Запомните раз и навсегда: помочь != "решите за меня"!
p51x вне форума   Ответить с цитированием
Старый 13.09.2018, 14:24   #8
_Bers
Профессионал
 
Регистрация: 16.12.2011
Адрес: Москва
Сообщений: 2,167
Репутация: 929
По умолчанию

Цитата:
Сообщение от Sinli Посмотреть сообщение
Вот последний вариант программы:

Код:

#include <stdio.h>

int main(void)
{
        char ch;
        int i, j;
        int letterCount, letterOrder;
        int const START = 'A' - 1; /*В ASCII код символа 'A' - 65, 'B' - 66 и т.д.*/
        printf("Введите прописную букву: ");
        scanf("%c", &ch);
        letterCount = (int)ch - START;
        letterOrder = letterCount;
        for (i = 1; i <= letterOrder; ++i)
        {

                for (j = 1; j + i - 1 < letterOrder; ++j)
                        printf(" ");
                for ( ; j <= letterOrder; ++j)
                        printf("%c", ch - (--letterCount));
                for ( ; j + i - 1 > letterOrder + 1; --j)
                        printf("%c", ch - (++letterCount) );
                printf("\n");
                letterCount = (int)ch - START;
        }
        return 0;
}

код не делает то, что должен.
и даже не предупреждает программистов о возможных проблеммах.
а почему? потому что год - говно.

кстати, об это же сказал компилятор:
Код:

warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result [-Wunused-result]
         scanf("%c", &ch);

в результате, если вбить русскую буковку 'Ф' - лососнет тунца.
_Bers вне форума   Ответить с цитированием
Старый 13.09.2018, 16:13   #9
Sinli
Пользователь
 
Регистрация: 10.09.2018
Сообщений: 43
Репутация: 10
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
Для современных компиляторов в релизе с оптимизациями и для "простых" типов пре или пост не имеет значение, компилятор это способен оптимизировать. Обычно все равно стараются их разделять, чтобы лишний раз не напрягать читающего ваш код и было сразу понятен замысел.
Понятно, спасибо за информацию.

Цитата:
Сообщение от _Bers Посмотреть сообщение
код не делает то, что должен.
и даже не предупреждает программистов о возможных проблеммах.
а почему? потому что год - говно.

кстати, об это же сказал компилятор:
Код:

warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result [-Wunused-result]
         scanf("%c", &ch);

в результате, если вбить русскую буковку 'Ф' - лососнет тунца.
Странно, но у меня компилятор молчит. да и с выполнением все в порядке.
А насчет букв из кириллицы, то код писался для латинских букв, а русскую локаль я даже не подключал.
Sinli вне форума   Ответить с цитированием
Старый 13.09.2018, 17:14   #10
Alex11223
Модератор
Заслуженный модератор
 
Регистрация: 12.01.2011
Сообщений: 17,111
Репутация: 3316

icq: 512-765
skype: alexp.frl
По умолчанию

Цитата:
Сообщение от Sinli Посмотреть сообщение
А насчет букв из кириллицы, то код писался для латинских букв, а русскую локаль я даже не подключал.
Ну наверно имелось в виду, что надо было хотя бы уточнить это в описании при вводе.
Alex11223 вне форума   Ответить с цитированием
Ответ

Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Подскажите, что делает данный код rogge Помощь студентам 1 03.12.2016 17:53
Как понять данный код? SkyWay Microsoft Office Excel 1 12.02.2015 03:36
как правильно разбить данный код на 3 класса? neomax38 Общие вопросы по Java, Java SE, Kotlin 1 25.11.2011 22:17
адаптировать данный код 555shiro Помощь студентам 0 09.01.2010 18:50
Почему не работает данный код? C# byte916 Помощь студентам 4 11.12.2009 22:19


00:45.


Powered by vBulletin® Version 3.8.8 Beta 2
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.

RusProfile.ru


Справочник российских юридических лиц и организаций.
Проекты отопления, пеллетные котлы, бойлеры, радиаторы
интернет магазин respective.ru