C program to print a triangle of stars

This C code is to print a triangle of stars.

#include <stdio.h>
int main(){
for(int i=0;i<3;i++) {
for(int j=0;j<i*2+1;j++){
printf("*");
}
printf("\n");
}
}


which works well though, I'd like to know if there is a better way to do the job, as it's said 2 layers of loop is inefficient, compared to vectorization.

I use a string to avoid the inner loop. The problem here is the printf() inside. A 3000-row triangle redirected to /dev/null takes 50ms, but now only 4ms.

I reformatted the output. And I left dots as fillers to see what is going on.

$./a.out ...*... ..***.. .*****. *******  It starts with one * in the so-called middle, and every row-iteration only sets two more bytes to * before it prints. The complicated part is preparing the string i.e. array of chars. You can use calloc() to clear the right side, but it still takes a step to put blanks on the left side. #include <stdio.h> #include <string.h> int trihi = 4; char PIX = '*'; int main(void){ int width = trihi * 2 - 1; char s[width + 1]; memset(s, '.', width); s[width] = '\0'; int mid = trihi - 1; s[mid] = PIX; printf("%s\n", s); for (int i = 1; i < trihi; i++) { s[mid - i] = s[mid + i] = PIX; printf("%s\n", s); } }  This should add up. s[mid + i] runs up to 2*mid = 2*(trihi-1). The '\0' sits at width = 2*trihi - 1 which is one higher, and is the highest legal index for s. It is very easy to make a small mistake and not have the \0 at the correct place. It also works with a triangle height of 1: $ ./a.out
*


And by setting ... = --PIX; in the loop:

$./a.out .....*..... ....)*).... ...()*)(... ..'()*)('.. .&'()*)('&. %&'()*)('&%  The So-Called Middle This is how a triangle of height 4 is laid out. Size is 8. The middle is s[3]; there are 3 spaces to the left. 01234567 --- "offset", "index" ...*...0 | | | | | +-- s[width] (width = 2*trihi - 1) | +------ s[mid] (mid = trihi - 1) +--------- s[0]  You start with trihi=4, but what you need is mostly 3 and 7...the geometrical base width is also 7. Just any Triangle If this is enough (with original height = 3): $ ./a.out
*
**
***


then the code gets much simpler:

#include <stdio.h>
#include <stdlib.h>

int trihi = 3;
char PIX = '*';

int main(void){

char *s = calloc(trihi+1, 1);

for (int i = 0; i < trihi; i++) {
s[i] = PIX;
printf("%s\n", s);
}
}


I kicked everything out except the basic idea: re-using a prepared string/array. Here the calloc-zeroes are only after the PIXes. No need for a filler like space or dots via memset() anymore. But it is also not the same user experience...and the triangle is half the size.

Overiq.com has a double-loop version of a C Program to print Half Pyramid pattern using *. It takes much longer than the above (tri2.c below).

$gcc -O2 over.c$ time ./a.out |wc -l
3001

real    0m0.029s
user    0m0.020s
sys     0m0.014s
$gcc -O2 tri2.c$ time ./a.out |wc -l
3000

real    0m0.006s
user    0m0.000s
sys     0m0.011s

• Your answer is almost a good one. Currently your observation about the performance of the program is implied, if you actually mention it in the answer it would be better. – pacmaninbw Nov 1 '20 at 16:44
• With redir to a tmpfs file it is 54ms vs. 11ms. I don't know what you mean with "imply" or "mention". I tested and mentioned it. – user232636 Nov 1 '20 at 17:02
• It is the OP who mentioned efficiency, and I think he is right to ask. His way would work well with curses, I guess, where you "refresh" when done modifying. – user232636 Nov 1 '20 at 17:20

Due to the size of the program, I have only a few things to suggest

• Since you aren't returning anything from main(), use int main(void).
• Use don't have to perform any arithmetic in the inner nested-loop, you only need to do j <= i
• 3 in the outer-loop is a magic number or, an unnamed numeric constant. I suggest you assign it to const int rows, to make it clear
#include <stdio.h>

int main(void)
{
const int rows = 3;

for(int i = 0;i < rows; i++)
{
for(int j = 0; j <= i; j++)
printf("*")

printf("\n");
}
}


I believe this will be the best, and easiest way to perform this task!