Code1:
#include<stdio.h>
int main()
{
unsigned short i, j, k;
for (i = 0; i < 2; i++)
{
k = i * 4 + 4;
for (j = k - 4; j < k; j++)
printf("%hu ", j);
putchar('\n');
}
return 0;
}
Output of Code1:
0 1 2 3
4 5 6 7
Remarks of Code1:
Space after 3 and 7
Newline after 7 (Stackoverflow has removed it)
Code2:
#include<stdio.h>
int main()
{
unsigned short i, j, k;
for (i = 0; i < 2; i++)
{
k = i * 4 + 4;
for (j = k - 4; j < k; j++)
{
printf("%hu", j);
if (j + 1 != k) putchar(' ');
}
if (i + 1 != 2) putchar('\n');
}
return 0;
}
Output of Code2:
0 1 2 3
4 5 6 7
Remarks of Code2:
No space after 3 and 7
No newline after 7
Additional remark of Code2:
The problem of Code2 is that the algorithm always compares two values in the if blocks and so Code2 is not efficient. I want to use Code1 and change these:
Code3
#include<stdio.h>
int main()
{
unsigned short i, j, k;
for (i = 0; i < 2; i++)
{
k = i * 4 + 4;
for (j = k - 4; j < k; j++)
printf("%hu ", j);
printf("\b\n");
}
putchar('\b');
return 0;
}
These do not show the same output of Code2 because \b does not erase anything.
My question:
Is there any standard way to do so what I've tried in Code3?
Remark of my question:
I have searched the internet but have not determined the solution.
Edit the question if it is not clear.
Edit: I don't know why my question is not useful or constructive. Though the above is an arbitrary small example, but performance might be an issue when processing very large amount of data. I thought that the way of removing character from console output might improve performance and there might be a specific way to do so. That's why I've asked the question. I could write the following codes in the answers. Now I've known via comments that removing character from console output is not possible because it is implementation dependent.
The usual approach to this is to treat either the first or the last printf as a special case (outside of the loop):
for(ii=0; ii<2; ii++) {
jj = 0;
printf("%d", jj); // first number printed without space.
for(jj=1; jj<4; jj++) {
printf(" %d", jj); // include the space before the number printed
}
if(ii<2-1) printf("\n");
}
Obviously I simplified how the loops are constructed and what is printed - for simplicity. You could make the first printf statement
printf("\n%d", jj);
then you have a newline at the start of your output (often a good thing) and then you don't need the if statement later - you just don't have a newline printed at the end of the line (because it will be printed at the start...)
There are marginally more efficient ways of doing this that would involve no if statements at all - but these all come at the expense of less readable code. For example, here is a "no loop unrolling and no additional if statements" version of the code:
http://codepad.org/01qPPtee
#include <stdio.h>
int main(void) {
int ii, jj;
ii = 0;
while(1) {
jj = 0;
while(1) {
printf("%d", jj); // include the space before the number printed
jj++;
if(jj<4) printf("."); else break;
}
ii++;
if(ii<2) printf("*\n"); else break;
}
return 0;
}
Output:
0.1.2.3*
0.1.2.3
Basically I have taken the functionality of the for loop and made it explicit; I also use a . rather than a and "*\n" rather than "\n" to show in the printout that things behave as expected.
It does what you asked without extra evaluation of the condition. Is it more readable? Not really...
If it really bothers you, you can unroll your loops a little so that you treat the last item as a special case:
#include<stdio.h>
int main()
{
unsigned short i, j, k;
for (i = 0; i < 1; i++)
{
k = i * 4 + 4;
for (j = k - 4; j < k - 1; j++)
{
printf("%hu ", j);
}
printf("%hu\n", j);
}
k = i * 4 + 4;
for (j = k - 4; j < k - 1; j++)
{
printf("%hu ", j);
}
printf("%hu", j);
return 0;
}
#include <stdio.h>
int main(){
unsigned short num = 0, to=8;
while(num < to){
printf("%hu", num++);
if(num < to)
putchar(num % 4 == 0 ? '\n' : ' ');
}
#if 0
do{
printf("%hu", num++);
}while(num < to && putchar(num % 4 == 0 ? '\n' : ' '));
#endif
return 0 ;
}
Well, to try to answer your question, here's how I would do it:
for (i = k = 0; i < 2; i++){
if (i > 0) printf("\n");
for (j = 0; j < 4; j++, k++){
if (j > 0) printf(" ");
printf("%d", k);
}
}
I do it this way because I want to be sure every line but the first starts with a \n, and every item is separated by a space from the one before it.
Also, I do not want the row and column position to be intimately tied to the content of what is being printed.
In terms of performance, keep in mind that these if statements cost about 1 cycle, while each character printed costs at least hundreds if not thousands. printf goes through many layers of system calls to interpret its format string, build a buffer, send the buffer to the system I/O routines, which then cause repainting and scrolling of the console window. Get the idea?
DO NOT WORRY about performance unless you know you have a problem.
Then, don't guess. Use a diagnostic. Here's what I do.
Related
So here is the problem: Write a program that accept an integer n, print out the largest number but smaller or equal n that is the product of two consecutive even number. Example: Input: 12, Output: 8 ( 2x4 )
Here is my code :
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n);
for (int i = n; i >= 0; i--)
{
for (int j = 0; j <= n; j = j + 2)
{
if ( i == j * (j+2) )
{
printf("%d ", i);
break;
}
}
}
return 0;
}
So if i input 20, it will print out 8 and 0 instead of 8, if i input 30, it will print out 24,8 and 0 instead of just 24. How do i make it stop after printing out the first number that appropriate ?
You need to stop an outer loop from processing, for example by using a boolean flag (meaning "solution found, we finish work") or a goto statement.
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
int solutionFound = 0;
for (int i = n; i >= 0; i--) {
// this could also be put into for's condition i.e. "i >= 0 && !solutionFound"
if (solutionFound) {
break;
}
for (int j = 0; j <= n; j = j + 2) {
if ( i == j * (j+2) ) {
printf("%d ", i);
solutionFound = 1;
break;
}
}
}
return 0;
}
EDIT: immediate return as noted in the comments is also a nice idea, if you don't need to do anything later.
Your problem is that you are nested - in a for loop which is inside another for loop - when you want to stop processing.
Some languages would let you code break 2; to indicate that you want to break out of 2 loops. Alas, C i snot such a language.
I would recommend that you code a function. That would serve a few porpoises: 1) your main should be "lean & mean" 2) as your programs get larger, you will learn the benefits of putting individual coding tasks into functions 3) you can use return; instead of break; and it will exit the function immediately.
Something like this:
#include <stdio.h>
void FindNeighbouringDivisors(int n)
{
for (int i = n; i >= 0; i--)
{
for (int j = 0; j <= n; j = j + 2)
{
if ( i == j * (j+2) )
{
printf("%d times %d = %d", j, j + 2, i);
return;
}
}
}
printf("There are no two adjacent even numbers which can be multiplied to give %d", n);
}
int main()
{
int n;
scanf("%d", &n); /* could get from comamnd line */
FindNeighbouringDivisors(n);
return 0; /* should be EXIT_SUCCESS */
}
Btw, when you have a problem with your code, ask a question here. When you have it working, consider posting it at our code review site where more experienced programmers can give you advice on how to improve it. It's a great way to learn
Break only breaks you out of immediate loop, so either use flags or just use return to terminate the execution. Or you can even use following code:
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n);
for (int j = 0; j <= n; j = j + 2)
{
if ( n < j * (j+2) )
{
printf("%d ", j*(j-2));
break;
}
}
return 0;
}
I wanted to print a rhombus shape with only 1 loop. The furthest I have gone is using 2 for loops.
The result shape is as follows:
rhombus shape
*
* *
* *
* *
* *
* *
* *
* *
*
The code for using 3 loops is as follows:
#include <iostream>
int main() {
int i, j;
int columns = 4;
for(i = 0; i < columns; i++){
for(j = 0; j <= (columns-1) - i;j++){
printf(" ");
}
for(j = 0;j<=2*i;j++){
if(i == 0||j == 0||j == 2*i){
printf("*");
}else{
printf(" ");
}
}
printf("\n");
}
for(i = columns; i >= 0; i--){
for(j = 0; j <= (columns-1) - i;j++){
printf(" ");
}
for(j = 0;j<=2*i;j++){
if(i == 0||j == 0||j == 2*i){
printf("*");
}else{
printf(" ");
}
}
printf("\n");
}
}
My code is as follows:
int main() {
int i, j;
int columns = 4;
for(i = 0; i < columns; i++){
for(j = 0;j<=(2*i+(columns) - i);j++){
if(j==columns/2+(columns/2-i)||(j == (2*i+(columns) - i))){
printf("*");
}else{
printf(" ");
}
}
printf("\n");
}
for(i = columns; i >=0; i--){
for(j = 0;j<=(2*i+(columns) - i);j++){
if(j==columns/2+(columns/2-i)||(j == (2*i+(columns) - i))){
printf("*");
}else{
printf(" ");
}
}
printf("\n");
}
}
I have the following questions:
Does less loop in rhombus shape printing always faster than using more loops?
Is there a way to print rhombus shape using 1 loop? Without using predefined functions like string().
Sorry for my English, looking forward to hearing from you guys.
Let's address the questions in order...
Does less loop in rhombus shape printing always faster than using more loops?
Firstly, you should not be concerned about speed in a program like this. Except maybe if you are trying to print a HUGE rhombus or this is intended to run on a small battery-operated embedded device requiring low power consumption.
I don't think you're doing any of these.
The answer really is no: both your approaches are doing roughly the same amount of looping. They're not very efficient, because they are calling a fairly expensive function once for each character output.
More importantly, the code is overly complicated, unclear and difficult to read. You should be focusing here, instead of worrying about trivial performance considerations.
Is there a way to print rhombus shape using 1 loop? Without using predefined functions like string().
Yes, I posted an example in the comments where you can just use a specifier in the printf call to output some amount of padding. Internally, that does basically the same thing as your own loops, but it makes shorter, clearer code and fewer printf calls.
Here, you just work out how many spaces are required before the * and then how many after it. You can then ask printf to output the string "*" padded with some number of spaces. Use %*s to indicate there are two parameters: the total width of the string, and the string itself. The width will be the number of spaces you want, plus 1 for the actual string.
#include <stdio.h>
#include <math.h>
int main(void)
{
const int N = 4;
for (int i = 0; i <= N*2; i++)
{
int space_before = abs(N - i);
int space_after = 2 * (N - space_before ) - 1;
if (space_after > 0)
printf("%*s%*s\n", space_before + 1, "*", space_after + 1, "*");
else
printf("%*s\n", space_before + 1, "*");
}
return 0;
}
Now, this is easier to understand, but it's still a bit clunky. How about we move it into a function, and then get rid of the branching in the loop. All the loop iterations output two stars except the first and last ones which are simpler. So, here:
#include <stdio.h>
#include <math.h>
void display_rhombus(int size)
{
if (size > 0)
{
printf("%*s\n", size + 1, "*");
for (int i = 1; i < size*2; i++)
{
int space_before = abs(size - i);
int space_after = 2 * (size - space_before ) - 1;
printf("%*s%*s\n", space_before + 1, "*", space_after + 1, "*");
}
}
printf("%*s\n", size + 1, "*");
}
int main(void)
{
display_rhombus(4);
return 0;
}
Now, you have a function with a name that describes what it does, has simple-to-understand code, and is re-usable. You can call it many times to draw whatever sizes of rhombus you want.
int main(void)
{
for (int size = 0; size < 10; size++)
{
display_rhombus(size);
}
return 0;
}
Finally, I should also mention that it's possible to output a rhombus with no loops, using a technique called recursion. I will leave that as a learning exercise for you.
Well, apart from paddy's excellent answer, here's another one:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
void printStar(int size) {
int j = size / 2;
int i = size % 2 == 0 ? j - 1 : j;
bool flag = false;
while (i <= j) {
std::vector<char> vec(size, ' ');
vec.at(i) = '*';
vec.at(j) = '*';
std::copy(vec.begin(), vec.end(), std::ostream_iterator<char> {std::cout});
std::cout << "\n";
if (!flag) {
i--;
j++;
}
else {
i++;
j--;
}
if (i == -1) {
flag = true;
i += 2;
j -= 2;
}
}
}
int main() {
printStar(5);
return 0;
}
I thought long and hard before asking this in here but I've spent too much time now trying to figure this one out without cheating.
The CS50 mario ps1 (less comfortable) asks for a *simple left align (at first) pyramid, but my code is giving me it upside down and I can't figure why.
#include <cs50.h>
#include <stdio.h>
int main (void)
{
int n;
do
{
n = get_int("Pyramid Height: ");
}
while (n < 1 || n > 8);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n - i ; j++)
printf("#");
for (int j = 0; j < n - i; j++)
{
printf(" ");
}
printf("\n");
}
}
I'm sorry if this type of questioning shows up regularly here but I really do need your help.
Thanks in advance.
edit:
expected result:
........#
.......##
......###
.....####
....#####
...######
..#######
.########
I can change the dots to spaces afterwards, this is just for visualisation;
the restriction for height is 8, so I guess that each line has always eight characters;
I actually added trailing spaces so that the pyramid could be right aligned, I've metioned wrong before;
I'm going to check the How to debug small programs?;
Sorry, I'm new to this, I didn't know there was a difference between here and stack exchange, gonna look into that.
*Sorry for the "meh" english, it is not my native language.
See what is the difference between my and your code (especially how to count):
void draw(int n, int align, int dir)
{
for (int i = 1; i <= n; i++)
{
if(align)
{
for(int s = 0; s < (dir ? (n - i) : i - 1); s++)
{
printf(" ");
}
}
for (int j = 0; j < (dir ? i : (n - i + 1)) ; j++)
{
printf("#");
}
printf("\n");
}
}
int main (void)
{
draw(8,1,0);
printf("\n");
draw(8,1,1);
printf("\n");
draw(8,0,0);
printf("\n");
draw(8,0,1);
}
https://godbolt.org/z/7YT16j
my code is giving me it upside down and I can't figure why
Let's see what the code looks like
// There's a loop executed n times. The body prints a line, so n lines are printed.
// In case you have doubts, the characters are normally printed top to bottom and
// left to right.
for (int i = 0; i < n; i++)
{
// The following loop prints (n - i) characters '#' at the beginning
// of each line. That's NOT what you are supposed to do, kind the opposite.
for (int j = 0; j < n - i ; j++)
printf("#");
// You should first print the spaces, then the '#'s, starting from 1 '#' at
// the first line and increasing the number by one at each line (so you have
// to change the condition in the loop accordingly).
// This loop prints the right amount of spaces, but only after
// all the '#'s and just before the end of the line, so that you just
// can't see them (change the printed char to '.' to visualize those).
for (int j = 0; j < n - i; j++)
{
printf(" ");
}
// Note that you could use putchar('\n'), here and previously, to print
// only one char, instead of using printf() to print string literals.
printf("\n");
}
This is a program on sorting integers.
#include <stdio.h>
int main(void) {
int n, i, j, k;
int nmbr[100];
printf("\n How many numbers ? ");
scanf("%d", &n);
printf("\n");
for (i = 0; i < n; ++i) {
printf(" Number %d : ", i + 1);
scanf("%d", &nmbr[i]);
}
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
if (nmbr[j] > nmbr[j + 1]) {
k = nmbr[j];
nmbr[j] = nmbr[j + 1];
nmbr[j + 1] = k;
}
}
}
printf("\n Numbers after sorting : \n");
for (i = 0; i < n; ++i) {
printf (" %d", nmbr[i]);
}
return 0;
}
It works fine, but when I enter some number that contains more than 2 digits, the first number that is printed is negative and really big. I don't also get the last integer too. I enter N as 4, then the numbers I entered were 25, 762, 588, and 34. The result I get is:
-1217260830 25 34 588
What seems to be the problem?
You are running the loop as for (j = 0; j < n; ++j) which means j will have values from 0 to n-1 which are valid array indices (or array elements with relevant values).
But, inside that loop you are accessing an element beyond the last. For instance, in
if (nmbr[j] > nmbr[j + 1])
you are accessing nmbr[j + 1]. If the current value of j in n-1, then you are accessing nmbr[n-1 + 1] i.e. nmbr[n] which will be a value outside the array and may contain a garbage value (which might as well be negative!).
If you are trying something like Bubblesort, you might want to run the inner loop like for (j = 0; j < n - 1; ++j).
There are multiple problems in your code:
You do not check the return values of scanf(). If any of these input operations fail, the destination values remain uninitialized, invoking undefined behavior and potentially producing garbage output.
You do not verify that the number of values provided by the user is at most 100. The reading loop will cause a buffer overflow if n is too large.
Your sorting logic is flawed: in the nested loop, you refer to nmbr[j + 1] which is beyond the values read from the user. This invokes undefined behavior: potentially causing a garbage value to appear in the output.
Here is a corrected version:
#include <stdio.h>
int main(void) {
int n, i, j, k;
int nmbr[100];
printf("\n How many numbers ? ");
if (scanf("%d", &n) != 1 || n > 100) {
printf("input error\n");
return 1;
}
printf("\n");
for (i = 0; i < n; ++i) {
printf(" Number %d : ", i + 1);
if (scanf("%d", &nmbr[i]) != 1) {{
printf("input error\n");
return 1;
}
}
for (i = 0; i < n; ++i) {
for (j = 0; j < n - 1; ++j) {
if (nmbr[j] > nmbr[j + 1]) {
k = nmbr[j];
nmbr[j] = nmbr[j + 1];
nmbr[j + 1] = k;
}
}
}
printf("\n Numbers after sorting :\n");
for (i = 0; i < n; ++i) {
printf (" %d", nmbr[i]);
}
printf("\n");
return 0;
}
Your Sorting Logic is wrong. It should be:
for (i = 0; i < n; ++i){
for (j = 0; j < (n-1); ++j){
if (nmbr[j] > nmbr[j + 1]){
k = nmbr[j];
nmbr[j] = nmbr[j + 1];
nmbr[j + 1] = k;
}
}
You are trying to access out of bounds of array, when you iterate in your second loop using j. This is causing the garbage value.
As per your example involving 4 elements, when you try to access j+1, it will try to access nmbr[3+1] in the last iteration of second loop which leads to out of bounds access.
Problem is with the sorting logic as suggested by fellow coders. But It is always good coding habit to initialize the variables. Also use the qualifier if are dealing with positive numbers only.
unsigned int n = 0 , i = 0, j = 0, k = 0;
unsigned int nmbr[100] = {0};
If you would have initialized them, out put of your program would be following, which might help you tracing the problem by yourself.
0 25 34 588
I was working though some beginning problem sets with Harvard's online CS50 class. I got the problem to work correctly but I was wondering if there would possibly be a cleaner or better way to get the program to work.
The goal of the program is to print a right-aligned pyramid comprised of hash-tags and space characters. Any guidance in regards to style or tricks would be very welcome.
/* 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;
}
I'm assuming by cleaner you mean "spiffy and fancyer".
This looks spiffy to me:
#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;
}
However, don't get too caught up in making your code fancy. Although it's nice if you're working with others, or yourself really. Your example looked fine.
Now, optimization-wise, that's something to worry about. Just remember that too much optimization can potentially break your program.
For everyone's consideration: this is what "all style and no readability" looks like :)
i = 0;
while (i++ < height*height)
printf ("%c%s", (i-1)/height < height-(i-1)%height-1 ? ' ' : '#',
i % height ? "" : "\n");
It is nigh on impossible to see what the code does without running it. If there is to be a follow-up exercise, this is hard to re-write to form, say, an even-sided pyramid. I'd probably throw this away and start again with the basics, before concatenating it again into a little monster such as this.
(later) Ever so slightly more neat to put the i++ at the end, so two times (i-1) gets traded for a slightly more complicated end-of-line test:
i = 0;
do
printf ("%c%s", i/height < height-i%height-1 ? ' ' : '#',
i % height==height-1 ? "\n" : "");
while (++i < height*height);
I think by cleaner and better way you mean to be a perfect shaped right angled triangle pyramid.
For this you should do as
Change
printf("Height: ");
to
printf("Height: \n\n");
and
for(i = 1 ; i < height; i++)
to
for(i = 0 ; i < height; i++)
And see the sample output.
Here's a suggestion:
#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;
}
Result if the user entered a 5 for the height:
Height:
#
##
###
####
#####
A couple things I considered with this version of the code:
-In C, it's good practice to declare all variables separately from giving them a value and assign values later. Some compilers may bring up this error if you to declare and assign a value in a for loop: "error: ‘for’ loop initial declarations are only allowed in C99 mode". These changes are considered with what I have provided.
//initialize variables
int height, hm2, j, k, i;
-I added a newline here
printf("Height: \n");
-Instead of hm2 = height - 2 I changed it to:
hm2 = height - 1;
-First loop, now we give i a value and set it to 0 to meet the other changes that were made:
for(i = 0; i < height; i++) {
-For the loop creating n spaces I changed it to:
for(k = hm2; k > i; k--)
-Finally removed parenthesis (no need in this case) in last for loop:
for(j = 0; j < i+1; j++)
Cheers