Zero basis plays with the third chapter of C language series - circular statements

Posted by hd_webdev on Sat, 06 Nov 2021 17:46:47 +0100

[preface]: the knowledge points supplemented by circular sentences are very important. Iron juice should be recorded with snacks.

1, while statement

while statement

while((expression)
{
    Loop statement;
}

[knocking on the blackboard]: the execution times of the conditional expression are 1 more than that of the loop body.

break and continue statements in the loop:

The function of break statement in a loop: break is to permanently terminate the loop;

Function of continue statement in the loop: continue is used to terminate this loop, that is, the code after continue in this loop will not be executed, but directly jump to the judgment part of the while statement  

Supplement 1: getchar()

Function prototype:

int getchar(void)

  Function:

Read a character in the standard input buffer and return the ASCII value of the read character. If the reading fails, return EOF (- 1)

Q: why does getchar() return ASCII values of characters? Why should the return value of a function be placed in a variable of type int? Shouldn't it be placed in a variable of type char?

For example:

int ch = 0;
ch = getchar();

Answer:

  • getchar() returns the ASCII code value of the character. The ASCII code value is an integer. There is no problem storing it in an integer variable;
  • This is also the most important point. When getchar() fails to read, it returns EOF. The essence of EOF is - 1 (#define EOF -1). It is an integer value that cannot be stored in a char type;
  • Combined with the prototype of getchat() function, the return type of getchar() is defined as int, so the return data should be stored in the int variable

getchar(): get / enter a character;

putchar(): output one character

Note that these two functions can only operate on one character at a time. Without scanf(),printf() is fully functional  

Supplement 2: input buffer

introduce:

#include<stdio.h>

int main()
{
	char input[20] = { 0 };
	printf("Please input a password:>");
	scanf("%s", input);//Enter abcdef followed by \ n
	printf("Please confirm the password:(Y / N):>");
	int ch = getchar();
	if (ch == 'Y')
	{
		printf("Confirmation successful\n");
	}
	else
	{
		printf("Confirmation failed\n");
	}
	return 0;
}

At this time, abcdef \ n is placed in the input buffer. The scanf() function reads away abcdef and leaves one \ n, so \ n is directly read by getchar(). Therefore, what is placed in ch at this time is \ n, and the confirmation fails without waiting for us to confirm the password.  

Existing problems: enter abcdef and press enter. Before we enter the character (Y/ N), we directly output "confirmation failure". How can we change it to what we want?

Add a statement below scanf(): getchar(); there is only one purpose. Take the Enter key ('\ n'),

 

Existing problems: this change can only ensure that "abcdef" can be executed normally, but if "abcdef hehe" is entered, it will directly output "confirmation failure". I don't believe you see  

I lost it. What the hell is this? Why is it wrong again!?

be careful:

Scanf ('% s',...); / / scanf() stops reading the string when it encounters spaces  

Analyze the code above:

#include<stdio.h>

int main()
{
	char input[20] = { 0 };
	printf("Please input a password:>");
	scanf("%s", input);//scanf() only read "abcdef"
	getchar();//getchar() reads a space, so there is a problem here. getchar() here can only take one character. What we want is that it can store the buffer
	//Remove all remaining characters from the file until '\ n'
	printf("Please confirm the password:(Y / N):>");
	int ch = getchar();
	if (ch == 'Y')
	{
		printf("Confirmation successful\n");
	}
	else
	{
		printf("Confirmation failed\n");
	}
	return 0;
}

Yes, getchar() here can only take one character. What we want is that it can take all the rest in the buffer until it takes' \ n '. How to change it?

#include<stdio.h>

int main()
{
	char input[20] = { 0 };
	printf("Please input a password:>");
	scanf("%s", input);//scanf() only read "abcdef"
    
    //Clear buffer
	int tmp = 0;
	while ((tmp = getchar()) != '\n')
	{
		;//Empty statement, do nothing, just take the characters
	}
	printf("Please confirm the password:(Y / N):>");
	int ch = getchar();
	if (ch == 'Y')
	{
		printf("Confirmation successful\n");
	}
	else
	{
		printf("Confirmation failed\n");
	}
	return 0;
}

In this way, pay attention to the function of cleaning the buffer above.

  2, for loop

be careful:

The for loop has a better style and is used the most frequently.

Recommendations:

  • Loop variables cannot be modified in the for loop body to prevent the for loop from losing control
  • It is suggested that the value of the loop control variable of the for statement should be "closed before open"

For example:

for(i = 10; i < 10; i++)   //Front closing and rear opening

for(i = 10; i <= 10; i++)  //Front closure and back closure (this is not recommended, but it can also be used for better interpretation)

Some variants of the for loop:

  • The initialization, judgment and adjustment of for can be omitted;
  • If the judgment part in the middle is omitted, it means that the judgment is always true, forming a dead cycle.

Therefore, if conditions permit, it is not recommended to omit.

Written test questions:

//Q: how many times has it been printed hehe?
#include<stdio.h>
int main()
{
	int i = 0;
	int j = 0;
	for (; i < 3; i++)
	{
		for (; j < 3; j++)
		{
			printf("hehe\n");
		}
	}
	return 0;
}

Hei hei, Tiezhi must have her own answer in her heart. See if it's the same as the correct answer?

  Haha, to tell you the truth, the first time I did this topic was 9 times. Why 3 times?

  See, so try not to omit the expression in the for loop.

  Add another test question:

int i = 0;
int k = 0;
for(i = 0, k = 0; k = 0; i++, k++)   //k = 0 is the assignment, 0 is false, and the judgment expression is always false, so the loop is executed 0 times
{
    k++;
}

3, do...while() loop

The difference between the do...while loop and the previous two loops is that its loop body is executed at least once!

do
    Circular statement;
while(expression);

Note: the do...while statement is used in limited scenarios, so it will not be used often.

4, Exercises

Exercise 1: calculate the factorial of n

Pseudo code:

int ret = 1;
int i = 0;
for(i = 1; i <= n; i++)
{
    ret = ret * i;
}

Exercise 2: calculate 1!+2!+3!+...+n!

In exercise 1, we know how to calculate the factorial of N, so it's much easier to calculate 1!+2!+3!+...+n.

Let's take a look at an error demonstration:

//In order to facilitate the test, I simply calculate to 1! + 2! + 3!
#include<stdio.h>

int main()
{
	int i = 0;
	int ret = 1;
	int sum = 0;
	int n = 0;
	for (n = 1; n <= 3; n++)
	{
		for (i = 1; i <= n; i++)
		{
			ret = ret * i;
		}
		sum = sum + ret;
	}

	printf("%d\n", sum);
	return 0;
}

In fact, 1! + 2! + 3! = 9, but in fact, the result is

The result is 15. Why?  

Because ret in the second level loop is the value left over from the last time, and we want to calculate the factorial of a number once, we need to reset ret to 1, and then calculate the factorial of the next number.

Therefore, rewrite the code as follows:

//In order to facilitate the test, I simply calculate to 1! + 2! + 3!
#include<stdio.h>

int main()
{
	int i = 0;
	int ret = 1;
	int sum = 0;
	int n = 0;
	for (n = 1; n <= 3; n++)
	{
        ret = 1;//Pay attention
		for (i = 1; i <= n; i++)
		{
			ret = ret * i;
		}
		sum = sum + ret;
	}

	printf("%d\n", sum);
	return 0;
}

Although the above code is correct, it is still not efficient enough. The time complexity is O(N^2). Can it be solved by using only one layer of loop? In fact, it is possible because the above calculation has been repeated many times.

If 1! + 2! + 3! Is calculated above, it will be repeated many times

//ret * 1
//ret * 1 * 2
//ret * 1 * 2 * 3

So rewrite it into efficient code as follows:

for(n = 1; n <= 3; n++)
{
    //n*(n-1)! = n!
    ret = ret * n;
    sum = sum + ret;
}

[knocking on the blackboard]: when we write an algorithm, don't be proud. Think about how to be more refined, so learn more and practice more!

Come on!!  

 

Topics: C C++