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

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

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

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

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

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

Добрый день, программисты.
Только что выполнил одно упражнение из книги Стивена Прата (глава 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, 16:31   #2
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

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

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

И в современных стандартах С (с С99) можно объявлять переменные в любом месте, например
Код:
for (int i = 0; ........)
Вместo (a++) есть ++a.

Вместо 64 лучше писать 'A' или что там это. Ну и вообще магические числа зло, лучше заводить константы и т.п.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.

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

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

Код:
#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 в 11:19.
Sinli вне форума Ответить с цитированием
Старый 13.09.2018, 11:31   #4
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

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


Цитата:
Сообщение от Sinli Посмотреть сообщение
Когда попытался объявить переменные "i" и "j" компилятор заругался
По умолчанию может быть включен С89 стандарт.
В gcc/MinGW изменяется флагом --std=c99
Цитата:
Сообщение от Sinli Посмотреть сообщение
я читал, что в них есть разница, когда они являются частью какого-либо выражения
Ну так тут же так и есть если убрать скобки.
++а изменяет и возвращает новое, а++ возвращает старое и изменяет.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 13.09.2018, 12:23   #5
Sinli
Пользователь
 
Регистрация: 10.09.2018
Сообщений: 43
По умолчанию

Цитата:
Сообщение от 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, 12:28   #6
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Я бы letterCount++ делал просто в отдельной строке без лишних скобок и +-1.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 13.09.2018, 12:29   #7
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Для современных компиляторов в релизе с оптимизациями и для "простых" типов пре или пост не имеет значение, компилятор это способен оптимизировать. Обычно все равно стараются их разделять, чтобы лишний раз не напрягать читающего ваш код и было сразу понятен замысел.
p51x на форуме Ответить с цитированием
Старый 13.09.2018, 13:24   #8
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от 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, 15:13   #9
Sinli
Пользователь
 
Регистрация: 10.09.2018
Сообщений: 43
По умолчанию

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

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

кстати, об это же сказал компилятор:
Код:
warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result [-Wunused-result]
         scanf("%c", &ch);
в результате, если вбить русскую буковку 'Ф' - лососнет тунца.
Странно, но у меня компилятор молчит. да и с выполнением все в порядке.
А насчет букв из кириллицы, то код писался для латинских букв, а русскую локаль я даже не подключал.
Sinli вне форума Ответить с цитированием
Старый 13.09.2018, 16:14   #10
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Цитата:
Сообщение от Sinli Посмотреть сообщение
А насчет букв из кириллицы, то код писался для латинских букв, а русскую локаль я даже не подключал.
Ну наверно имелось в виду, что надо было хотя бы уточнить это в описании при вводе.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Ответ


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

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


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