Printing pyramids in C (CS50) I'm taking the CS50 course, and we're asked to create a program which takes an input (the total height of the pyramid) and outputs a pyramid of that height.
i.e Here’s how the program might work if the user inputs 8 when prompted:
$ ./mario
Height: 8
       #  #
      ##  ##
     ###  ###
    ####  ####
   #####  #####
  ######  ######
 #######  #######
########  ########

Here is my code:
#include &lt;cs50.h&gt;
#include &lt;stdio.h&gt;

void print_hashes(int width, int empty_space);

int main(void)
{
    // Get height input between ranges 1 to 8 inclusive
    int height;
    do
    {
        height = get_int(&quot;Height: &quot;);
    } 
    while (height &lt; 1 || height &gt; 8);
    // Loops through each row
    for (int row = 1; row &lt;= height; row++)
    {
        // Prints the left part of the pyramid, we need to print empty spaces before printing the hashes, so
        // the width is equal to the height, amount of hashes printed is equal to the row, so amount of empty spaces is the width - row
        print_hashes(height, height - row);
        printf(&quot;  &quot;);
        // Prints the right part of the pyramid, we don't need to print empty spaces before printing hashes, so
        // the width is equal to the amount of hashes, i.e the row and the amount of empty space is just 0
        print_hashes(row, 0);
        printf(&quot;\n&quot;);
    }
}

void print_hashes(int width, int empty_space)
{
    // Loops through the column in the row
    for (int column = 0; column &lt; width; column++)
    {
        // Checks if there needs to be an empty space within that column, if so print a space and if not print a hash
        if (column &lt; empty_space)
        {
            printf(&quot; &quot;);
        } 
        else
        {
            printf(&quot;#&quot;);
        }
    }
}

I would like some feedback on my code and how I could improve it; things like readability, efficiency, etc.
Is my code easily understandable? Am I overdoing the comments? The reason I put a lot of comments is because in my experience, when looking at code days/weeks after writing it, I tend to forget what it does. So I wrote explanations so that I can easily understand the code in the future.
How do I improve the style, and are there any code conventions I'm not following? Can I optimize this to make it a faster process? Or maybe there's a better way to do the same thing? Basically, how do I improve my code?
The code can be structured better, so the code is more self-documenting.
Self-documenting code doesn't need as many comments, which makes it easier on everyone. Comments that aren't there can't be obsolete either.

Take input (height)
Output pyramid

Those are the only lines I want to see in main. The rest should be in functions.
You started out nicely by creating a print_hashes function, but we can do better. For example, the entire do ... while can be in a function.
int ask_height(void)
{
    // Get height input between ranges 1 to 8 inclusive
    int height;
    do
    {
        height = get_int(&quot;Height: &quot;);
    } 
    while (height &lt; 1 || height &gt; 8);
    return height;
}

Now, we can start the main program like this instead:
int main(void)
{
    int height = ask_height();

That turns 7 lines in main into 1 line in main. And since the function name is descriptive, the comments are almost obsolete.
We can do the same thing with the rest of the program.
void print_pyramid(int height)
{
    // Loops through each row
    for (int row = 1; row &lt;= height; row++)
    {
        // Prints the left part of the pyramid, we need to print empty spaces before printing the hashes, so
        // the width is equal to the height, amount of hashes printed is equal to the row, so amount of empty spaces is the width - row
        print_hashes(height, height - row);
        printf(&quot;  &quot;);
        // Prints the right part of the pyramid, we don't need to print empty spaces before printing hashes, so
        // the width is equal to the amount of hashes, i.e the row and the amount of empty space is just 0
        print_hashes(row, 0);
        printf(&quot;\n&quot;);
    }
}

And all of a sudden, we have nicely split-out code, each function has one and only 1 thing to do (you may want to read up on the SRP, the Single-responsibility principle).
Now your file starts like this:
#include &lt;cs50.h&gt;
#include &lt;stdio.h&gt;

int ask_height(void);
void print_hashes(int width, int empty_space);
void print_pyramid(int height);

int main(void)
{
    int height = ask_height();
    print_pyramid(height);
}

That's it. The rest is in functions. The function names can probably be further improved, but I'm quite awful at that myself. If you want to go a step further, you don't even need a height variable in main. This works too:
int main(void)
{
    print_pyramid(ask_height());
}

The rest is in functions, and functions can be re-used. Besides, should you ever want to call your program from an outside location, that's a lot easier now too.