C Hollow Diamond Star Pattern (Inside Square)

Intermediate
8 min read
Updated: Sep 2026
3 programs
Live preview

What Is This Pattern?

A hollow diamond inside a square frame sits in a fixed grid: width 2 * rows, height 2 * rows - 1. Solid star bars close the top and bottom; every other line is left stars, a hollow gap, then right stars.

Remember
Rule: bars on ends; else left stars + gap spaces + left stars
      (width = 2*rows, height = 2*rows-1)

**********
****  ****
***    ***
**      **
*        *
**      **
***    ***
****  ****
**********     ← rows = 5 (10 wide, 9 tall)

Unlike Program 9 (standalone hollow diamond) or Program 10 (filled diamond), every line here is exactly 2 * rows characters. Middle rows use a mirrored index i so the gap opens to the waist and closes again.

How to Solve It

Two ways to emit the same shape — start with nested loops, then optionally shorten with a print_chars helper.

MethodIdeaBest for
Nested loopsBar vs left / gap / right via printfLearning, interviews, exams
print_chars helperReuse one loop for each segmentCleaner demos once formulas click

Pseudocode

Pseudocode
height = 2 * rows - 1
width  = 2 * rows

for line from 1 to height:
    if line is 1 or height:
        print width stars
    else:
        i = line if line <= rows else (2 * rows - line)
        left = rows - i + 1
        gap  = 2 * (i - 1)
        print left stars, gap spaces, left stars
    print newline

Cheat sheet

GoalPattern
Grid sizeheight = 2 * rows - 1, width = 2 * rows
Solid barsline == 1 || line == height → print width stars
Mirror indexi = (line <= rows) ? line : (2 * rows - line)
Side starsleft = rows - i + 1
Hollow gapgap = 2 * (i - 1)
Width check2 * left + gap == width
End the rowprintf("\n");

Printing Stars vs Starting a New Line

APIEffectUse for
printf("*") / printf(" ")Stays on the same lineEach star or space
printf("\n")Ends the current lineAfter the bar or left/gap/right

Live Preview

Change the size and the framed hollow diamond updates instantly — including height and width.

Whole numbers from 1 to 12. Width is 2 * rows; height is 2 * rows - 1.

Live result 5 rows · 9 × 10
**********
****  ****
***    ***
**      **
*        *
**      **
***    ***
****  ****
**********

Worked Walkthrough — rows = 4

Trace each line: solid bar vs inner row, and the values of i, left, and gap. Grid is 7 × 8.

lineKindileftgapPrinted row
1Bar———********
2Inner232*** ***
3Inner324** **
4Inner416* *
5Inner324** **
6Inner232*** ***
7Bar———********

On every inner row, 2 * left + gap = 8 = width. Lines 3 and 5 share the same i because of mirroring — that is why time is still O(n²).

C Programs

Three complete programs: fixed size, console input, and a print_chars helper. Use View Output to reveal sample results.

Example 1 — Fixed rows = 5

Hard-coded size — solid bars on the ends; left / gap / right elsewhere.

c
#include <stdio.h>

int main(void) {
    int rows = 5;
    int line, j;
    int height = 2 * rows - 1;
    int width = 2 * rows;

    for (line = 1; line <= height; ++line) {
        if (line == 1 || line == height) {
            for (j = 1; j <= width; ++j) {
                printf("*");
            }
        } else {
            int i = (line <= rows) ? line : (2 * rows - line);
            int left = rows - i + 1;
            int gap = 2 * (i - 1);

            for (j = 1; j <= left; ++j) {
                printf("*");
            }
            for (j = 1; j <= gap; ++j) {
                printf(" ");
            }
            for (j = 1; j <= left; ++j) {
                printf("*");
            }
        }
        printf("\n");
    }

    return 0;
}

How It Works

1. Set the grid. height = 9 and width = 10 for rows = 5.

2. Outer loop walks each line. line runs from 1 to height.

3. Top and bottom are solid bars. When line == 1 or line == height, print width stars with no gap.

4. Inner rows use left / gap / right. Map line to mirrored i, then print left stars, gap spaces, and left stars again.

5. Break the line. printf("\n") after the bar or the three segments.

At the waist (line = 5), i = 5, so left = 1 and gap = 8 — one star on each side with a wide hollow center.

Example 2 — User Input Version

Read the size at runtime. Prefer checking scanf’s return value (shown in the tip below).

c
#include <stdio.h>

int main(void) {
    int rows;
    int line, j;
    int height, width;

    printf("Enter the number of rows: ");
    scanf("%d", &rows);

    height = 2 * rows - 1;
    width = 2 * rows;

    for (line = 1; line <= height; ++line) {
        if (line == 1 || line == height) {
            for (j = 1; j <= width; ++j) {
                printf("*");
            }
        } else {
            int i = (line <= rows) ? line : (2 * rows - line);
            int left = rows - i + 1;
            int gap = 2 * (i - 1);

            for (j = 1; j <= left; ++j) {
                printf("*");
            }
            for (j = 1; j <= gap; ++j) {
                printf(" ");
            }
            for (j = 1; j <= left; ++j) {
                printf("*");
            }
        }
        printf("\n");
    }

    return 0;
}

How It Works

1. Prompt and read. Ask for a size, then fill rows with scanf.

2. Same frame core. Only the source of rows changes — the print logic matches Example 1.

3. Safer input tip. Ignoring scanf’s return leaves rows unset on bad input. Prefer:

Safer input
if (scanf("%d", &rows) != 1 || rows < 1) {
    printf("Enter a positive whole number.\n");
    return 1;
}

Example 3 — print_chars Helper

Encode each segment once; the outer loop only picks counts.

c
#include <stdio.h>

void print_chars(char ch, int n) {
    int j;
    for (j = 1; j <= n; ++j) {
        putchar(ch);
    }
}

int main(void) {
    int rows = 5;
    int line;
    int height = 2 * rows - 1;
    int width = 2 * rows;

    for (line = 1; line <= height; ++line) {
        if (line == 1 || line == height) {
            print_chars('*', width);
        } else {
            int i = (line <= rows) ? line : (2 * rows - line);
            int left = rows - i + 1;
            int gap = 2 * (i - 1);

            print_chars('*', left);
            print_chars(' ', gap);
            print_chars('*', left);
        }
        putchar('\n');
    }

    return 0;
}

How It Works

1. One helper for runs. print_chars(ch, n) prints n copies of ch with putchar.

2. Same formulas. Bars still use width; inner rows still use left and gap.

3. Cleaner main loop. The outer loop only chooses which segments to call — useful once you can explain the math out loud.

Learn the nested-loop version first (Examples 1–2) so both bounds stay visible in an interview; treat the helper as a polish shortcut afterward.

Edge Cases & Pitfalls

Check these before calling the solution done.

Wrong width

Use 2 * rows

Program 9 uses width 2 * rows - 1. Mixing that here breaks the solid bars and side closure.

No mirror

Only half a diamond

Forget i = 2 * rows - line on the lower half and the gap never closes again.

Swapped formulas

Broken sides

Keep left = rows - i + 1 and gap = 2 * (i - 1). Swapping them misaligns the hollow diamond.

Newline early

Broken rows

Call printf("\n") only after the full bar or all three segments — never inside the character loops.

rows = 1

Two identical bars

Height is 1, width is 2 — a single line of ** (top and bottom are the same line).

rows ≤ 0

Empty or invalid

Validate and re-prompt for interactive programs.

Bad scanf

Check the return

If scanf fails, rows is uninitialized — always test != 1.

Time and Space Complexity

ProgramTimeExtra space
Nested loops (Examples 1–2)O(rows²)O(1)
print_chars helper (Example 3)O(rows²)O(1)

About 2n - 1 lines, each up to 2n characters — still quadratic in n = rows.

Key Takeaways

  • Grid: width 2 * rows, height 2 * rows - 1.
  • Bars: first and last lines are solid runs of width stars.
  • Inner rows: left stars, gap spaces, left stars — with mirrored i.
  • Check: 2 * left + gap == width; time is O(n²).

One line: solid bars on the ends; elsewhere print left, gap, left with a mirrored i.

Frequently Asked Questions

Use height 2*rows-1 and width 2*rows. Print a full bar of stars on the first and last lines. For every other line, map line to i with symmetry, then print (rows-i+1) stars, a gap of 2*(i-1) spaces, and the same number of stars again.
Width is 2*rows and height is 2*rows-1 so the top and bottom are full horizontal bars while the sides close on the leftmost and rightmost columns of the inner rows.
Program 9 prints a hollow diamond alone with constant width 2*rows-1 and diagonal j/k tests. Program 11 adds solid top and bottom bars of length 2*rows and builds each inner line from left stars, gap, and right stars.
left = rows - i + 1 is how many stars sit on each side. gap = 2 * (i - 1) is the hollow space between them. Together they always equal the line width.
If line <= rows, i = line. Otherwise i = 2 * rows - line. That mirrors distance from the nearest end so the gap is widest at the waist.
printf("*") (or printf(" ")) stays on the same line. printf("\n") ends the current line. Characters use printf without a newline; the row break comes after the bar or the three segments.
O(n²) for n = rows. There are about 2n lines and each prints about 2n characters.
Check scanf's return value: if (scanf("%d", &rows) != 1) handle bad input, and require rows >= 1. Unchecked scanf leaves rows uninitialized on failure.

Did you know?

Every line is exactly 2 * rows characters wide. Inner rows always satisfy 2 * left + gap == 2 * rows — so the frame closes cleanly on both sides.

Back to the Star Patterns Hub

You finished the C star pattern series — revisit any shape or jump to number and alphabet patterns.

Star Patterns hub →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

12 people found this page helpful