Начальная программа C

Я работал над некоторыми начальными наборами задач с онлайн-классом Гарварда CS50. Я решил, что проблема работает правильно, но мне было интересно, есть ли более чистый или лучший способ заставить программу работать.

Цель программы — напечатать выровненную по правому краю пирамиду, состоящую из хэш-тегов и пробелов. Любое руководство в отношении стиля или трюков будет очень кстати.

/* Creating the mario program, whose goal is to create a 
*  pyramid by accepting input from the user to get the 
*  height then aligning the pyrimid to the right.
*
*/

#include <stdio.h>
#include <cs50.h>

int main(void)
{

    // get user input and set to variable
    printf("Height: ");
    int height = GetInt();

    int i, j, k;
    for(i = 1 ; i < height; i++)
    {

        // create n-1 spaces
        for(k = (height - 2); k > (i-1); k--)
        {
            printf("%c", ' ');      
        }

        // create n+1 hash tags
        for(j = 0; j < (i+1); j++)
        {
            printf("#");
        }

        printf("\n");
    }
    return 0;
}

person bruin51    schedule 24.11.2013    source источник
comment
Спросите себя, что вы подразумеваете под чище/лучше? Что, по вашему мнению, делает эту программу грязной/плохой.   -  person Preet Sangha    schedule 25.11.2013
comment
В дополнение к комментарию от @PreetSangha, я бы посоветовал не слишком зацикливаться на чистоте/эффективности своего кода, когда вы только начинаете. Ваше стремление к аккуратному коду будет автоматически развиваться по мере того, как вы будете писать более сложные программы, но программирование, в конечном счете, заключается в написании работающих и полезных программ. Оптимизация и эффективность — это то, что нам нужно, поскольку наши программы становятся все более сложными и ресурсоемкими.   -  person hammus    schedule 25.11.2013
comment
@leemo Оптимизация и эффективность есть, но читабельность и основные передовые методы — нет.   -  person    schedule 25.11.2013
comment
Кстати, этот код выглядит просто отлично для меня. Кроме лишних скобок. (А я редко так говорю.)   -  person    schedule 25.11.2013
comment
@ H2CO3 - Согласен, но мой комментарий о том, что не нужно зацикливаться на этом, прежде чем полностью понять концепции, остается в силе.   -  person hammus    schedule 25.11.2013
comment
@PreetSangha Я полностью с вами согласен, код печатает пирамиду и поэтому приемлем. Я просто пытаюсь убедиться, что мой синтаксис и стиль верны.   -  person bruin51    schedule 25.11.2013
comment
@leemo хороший совет, я думаю, чем больше я пишу, тем легче это будет. Ценим обратную связь!   -  person bruin51    schedule 25.11.2013
comment
Долгожданное изменение по сравнению с этим - мой код до сих пор main() { /* to do */ }. Ваш код выглядит хорошо: он удобочитаем, соответствует стилю пробелов и скобок и выполняет свою работу. Не волнуйтесь, стильный код появится позже.   -  person Jongware    schedule 25.11.2013


Ответы (4)


Я предполагаю, что под уборщиком вы подразумеваете "элегантный и модный".

Это выглядит шикарно для меня:

#include <stdio.h>
#include <cs50.h>

int main(void) {
    // get user input and set to variable
    printf("Height: ");
    int height = GetInt();
    int hm2 = height - 2;

    int j, k;
    for(int i = 1 ; i < height; i++) {
        // create n-1 spaces
        for(k = hm2; k > (i-1); k--)
            printf("%c", ' ');      

        // create n+1 hash tags
        for(j = 0; j < (i+1); j++)
            printf("#");

        printf("\n");
    }
    return 0;
}

Тем не менее, не слишком зацикливайтесь на причудливом коде. Хотя хорошо, если вы работаете с другими или сами с собой. Ваш пример выглядел нормально.

Теперь, что касается оптимизации, об этом стоит побеспокоиться. Просто помните, что чрезмерная оптимизация потенциально может сломать вашу программу.

person Radnyx    schedule 24.11.2013
comment
Но это не напечатает чище и лучше пирамиду :) - person haccks; 25.11.2013
comment
Не ЭТО важно, но я думаю, что удаление фигурных скобок в обоих внутренних циклах подвержено ошибкам. - person MByD; 25.11.2013
comment
Мне кажется, мне больше нравится создавать переменную вне цикла for, возможно, это немного улучшит читаемость. Но я думаю, что понимаю аргумент, что есть много способов снять шкуру с этой кошки. - person bruin51; 25.11.2013

На всеобщее обозрение: вот как выглядит «стиль и отсутствие читабельности» :)

i = 0;
while (i++ < height*height)
    printf ("%c%s", (i-1)/height < height-(i-1)%height-1 ? ' ' : '#',
    i % height ? "" : "\n");

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


(позже) Немного более аккуратно поставить i++ в конце, поэтому два раза (i-1) обменивается на немного более сложный тест конца строки:

i = 0;
do
    printf ("%c%s", i/height < height-i%height-1 ? ' ' : '#',
    i % height==height-1 ? "\n" : "");
while (++i < height*height);
person Jongware    schedule 25.11.2013

Я думаю, что под более чистым и лучшим способом вы подразумеваете идеальную форму прямоугольной треугольной пирамиды.
Для этого вы должны сделать следующее
Изменить

printf("Height: ");  

to

printf("Height: \n\n");  

и

for(i = 1 ; i < height; i++)  

to

for(i = 0 ; i < height; i++)   

Посмотрите пример вывода.

person haccks    schedule 24.11.2013
comment
О да! Я думаю, вы правы. меня беспокоило, что мне нужно было иметь как (высота -2), так и (i-1) для создания пространств. показался немного лишним - person bruin51; 25.11.2013

Вот предложение:

#include <stdio.h>
#include <cs50.h>

int main(void) {
    //initialize variables
    int height, hm2, j, k, i;

    printf("Height: \n");
    // Get user input
    height = GetInt();
    hm2 = height - 1;
    for(i = 0; i < height; i++) {
        // create n spaces
        for(k = hm2; k > i; k--)
            printf("%c", ' ');      

        // create n+1 hash tags
        for(j = 0; j < i+1; j++)
            printf("#");

        printf("\n");
    }
    return 0;
}

Результат, если пользователь ввел 5 для высоты:

Height: 
    #
   ##
  ###
 ####
#####

Пара вещей, которые я рассмотрел с этой версией кода:

- В C рекомендуется объявлять все переменные отдельно от присвоения им значения и присваивать значения позже. Некоторые компиляторы могут вызвать эту ошибку, если вы объявляете и присваиваете значение в цикле for: «ошибка: начальные объявления цикла for разрешены только в режиме C99». Эти изменения считаются с тем, что я предоставил.

//initialize variables                                                            
int height, hm2, j, k, i;

-Я добавил новую строку здесь

printf("Height: \n");

-Вместо hm2 = высота - 2 я изменил на:

hm2 = height - 1;

-Первый цикл, теперь мы даем значение i и устанавливаем его на 0, чтобы соответствовать другим изменениям, которые были сделаны:

for(i = 0; i < height; i++) {

-Для цикла создания n пробелов я изменил его на:

for(k = hm2; k > i; k--)

-Наконец удалены скобки (в данном случае не нужны) в последнем цикле for:

for(j = 0; j < i+1; j++)

Ваше здоровье

person spacexengineer    schedule 29.08.2017