C learning_7

Table of contents

1. for loop

1. Although both the while loop and the for loop can realize loops in essence, they still have some differences in usage methods and occasions.

2. There are three necessary conditions for the loop in the while loop, but due to the style problem, the three parts are likely to deviate far away, so the search and modification are not concentrated and convenient enough. Therefore, the style of the for loop is better; the frequency of the for loop is also the highest.

2.break and continue in the for loop

3. Lvalues ​​and rvalues

4.do...while() loop

5. break and continue in do while loop

6. Exercise with small exercises

1. Calculate the factorial of n.

2. Calculate 1!+2!+3!+…+10!

3. Find a specific number n in an ordered array. (Explain binary search)

4. Write code that demonstrates that multiple characters move from the ends and converge toward the middle.

5. Write code to simulate the user login scenario, and can only log in three times. (It is only allowed to enter the password three times. If the password is correct, it will prompt to log in. If it is entered incorrectly three times, it will exit the program.


1. for loop

We already know the while loop, how about we introduce the for loop this time?

A for loop is a common looping construct that executes a piece of code multiple times until a certain condition is met.

Its syntax is as follows:

for ( initialization statement ; loop condition ; post-loop operation )

{    

        // block of code to execute

}

Among them, the initialization statement is used to initialize the loop control variable, the loop condition is a Boolean expression, if it is true, then continue to execute the loop, otherwise exit the loop, and the post-loop operation is a statement executed at the end of each loop.

The execution process of the for loop is as follows:

1. Execute the initialization statement .

2. Check the loop condition , if it is false, exit the loop and execute the subsequent statement.

3. Execute the code block.

4. Perform post-loop actions .

5. Go back to step 2 and continue to execute the loop until the loop condition is false.

The for loop is widely used to iterate data structures such as arrays, lists, and collections, and to repeat tasks for a fixed number of times.

#define _CRT_SECURE_NO_WARNINGS 1

//for循环使用
#include<stdio.h>
int main()
{
	int i = 0;
	//打印一次i的值
	i++;
	printf("%d\n", i);
	
	//当我们要多次打印时,这时就需要用到循环
	//先用我们上次介绍的while
	i = 0;//1.初始化
	while (i < 10)//2.判断
	{
		i++;//3.调整
		printf("%d ", i);
	}

	//我们发现while循环中由三部分
	//1.初始化 2.判断 3.调整
	//而这是组成循环的必要条件
	//接下来我们看看for语句如何完成上面的while语句
	i = 0;
	for (i = 1; i <= 10; i++)
	//   初始化  判断   调整
	{
		printf("%d ", i);
	}
	//我们发现for也有1.初始化 2.判断 3.调整
	//所以for语句也具有while语句一样的循环功能
	return 0;
}

Now that we have a while statement that can implement a loop, why do we need to introduce a for statement with the same function?

1. Although both the while loop and the for loop can realize loops in essence, they still have some differences in usage methods and occasions.

        The for loop is mainly used for repeated operations for a certain number of times, especially for traversing arrays or collections, and using each element in the array or collection as a loop variable. At the same time, the code structure of the for loop is very compact. The brackets of for() include the initialization of the loop variable, the judgment of the loop condition, and the change of the loop variable. The control of the loop can be completed in one line of code, which is suitable for scenarios with simple code.

        The while loop is mainly suitable for scenarios that need to perform operations repeatedly according to certain conditions, such as verification and inspection of user input information. The code structure of the while loop is relatively flexible, and different loop conditions can be set according to different needs to flexibly control the execution of the loop.

2. There are three necessary conditions for the loop in the while loop, but due to the style problem, the three parts are likely to deviate far away, so the search and modification are not concentrated and convenient enough. Therefore, the style of the for loop is better; the frequency of the for loop is also the highest.

int i = 0; // achieve the same function, use while

i=1;//initialization part

while(i<=10)//judgment part

{

        printf("hehe\n");

        .

        . (multiple lines of code omitted)

        .

        i = i+1;//Adjustment part

}

//To achieve the same function, use for

for(i=1; i<=10; i++)

{

        printf("hehe\n");

}

2.break and continue in the for loop

//code 1
#include <stdio.h>
int main()
{     int i = 0;     for (i = 1; i <= 10; i++)     {         if (i == 5)             break;//jump out of the loop         printf( "%d ", i);//1 2 3 4     }     return 0; }









//code 2
#include <stdio.h>
int main()
{     int i = 0;     for (i = 1; i <= 10; i++)     {         if (i == 5)             continue;//jump out of this loop         printf("%d ", i);//1 2 3 4 6 7 8 9 10     }     return 0; }








In the for loop, we should pay attention to two problems:

1. Do not modify the loop variable in the body of the for loop to prevent the for loop from getting out of control.

#include <stdio.h>
int main()
{
	int i = 0;
	for (i = 1; i <= 10; i++)
	{
		if (i = 5)
		//if(i=5)将5赋给i,使得if语句括号的内容恒为真,造成死循环
        //当i为1,进入循环,此时又将i=5,由于为真,执行continue,不执行打印,
          随后i++,i=6,进入循环
			continue;
		printf("%d ", i);
	}
	return 0;
}

2. It is suggested that the value of the loop control variable of the for statement should be written in the form of "close before and then open".

#include<stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int i = 0;
	for (i = 0; i < 10; i++)
	//前闭后开容易观察到循环的次数 - 10次
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

​

Next, let's look at the four for-related codes to see why

code 1

#include <stdio.h>
int main()
{     //code 1     for (;;)     {         printf("hehe\n");     }     return 0; }






        This program has an infinite loop that keeps printing "hehe" until the program is stopped manually or some exception occurs. The for(;;) line is an infinite loop syntax structure, which is equivalent to while(true) or while(1), which means that the loop condition is always true, so the loop will never exit. If you run this program, it will output "hehe" until you stop it manually. So in the for statement, we must not omit the judgment condition, otherwise it will cause the program to enter an infinite loop.

code 2

#include<stdio.h>
int main()
{     int i = 0;     int j = 0;     //How many hehe print here?     for (i = 0; i < 10; i++)     {         for (j = 0; j < 10; j++)         {             printf("hehe\n");         }     }     return 0; }











        This program will print "hehe" 100 times because it has two nested for loops. The outer loop starts from i=0, increments by 1 each time, and continues execution when i<10. The inner loop starts from j=0, increments by 1 each time, and continues execution when j<10. Therefore, every time the inner loop loops, it will output "hehe" once, and the outer loop controls the execution times of the inner loop, so the inner loop will execute a total of 10 times and output "hehe" 10 times, and the outer loop will also The loop is 10 times, so a total of 100 "hehe" will be output.

code 3

#include<stdio.h>
int main()
{     int i = 0;     int j = 0;     //If the initialization part is omitted, how many hehe will be printed here?     for (; i < 10; i++)     {         for (; j < 10; j++)         {             printf("hehe\n");         }     }     return 0; }











This program will print "hehe" 10 times. When the first loop, i = 0, the inner loop starts to execute for the first time and enters the inner loop. The value of j is from 0 to 9 for a total of 10 times, and it will print 10 times "hehe ", when j<10 is not satisfied, jump to the outer loop, and then execute i++; i=1, enter the inner loop, but at this time the value of j in the inner loop is already 10, and the value of j has not been reassigned to zero. Therefore, if j<10 is not satisfied, "hehe" will not be printed. After that, as i<10 and i++ are performed, the program j<10 is still not satisfied, and "hehe" cannot be printed.

code 4

#include<stdio.h>
int main()
{     int x, y;     //use more than one variable to control the loop     for (x = 0, y = 0; x < 2 && y < 5; ++x, y++)     {         printf("hehe\n");     }     return 0; }







In this program, two variables `x` and `y` are used to control the loop. Among them, the variable `x` is initialized to 0, and the variable `y` is also initialized to 0, which are respectively used as two test conditions. Before each loop starts, the expressions `++x` and `y++` will increment them by 1 respectively. The loop condition of the loop is `x < 2 && y < 5`, that is, when `x` is less than 2 and `y` is less than 5, the loop continues to execute. In each loop body, the string "hehe" is output once. When `x` increments to 2, the loop condition `x<2` is no longer true, the loop exits, and the program ends and prints "hehe".

Next, let's practice it to see if you have mastered it.

// How many times does the loop need to loop?
#include <stdio.h>
int main()
{     int i = 0;     int k = 0;     for (i = 0, k = 0; k = 0; i++, k++)         k++;     return 0; }





In this program, the loop condition of the loop is `k = 0`, each loop will assign the variable `k` to 0 and judge whether the assignment result is true or false, because 0 is considered "false", so the result of the loop condition Always false, the loop will not enter. Therefore, this program does not loop once and returns 0 directly. The k=0 above means that the loop condition becomes 0, 0 is false, and the loop condition i of the program will not be satisfied. Let's take an example to see the value of this way of writing

 It can be seen that the result of b=7 is 7, so the result of k=0 is 0.

3. Lvalues ​​and rvalues

In computer programming, each variable has a memory location to store it, which we call an L-value. An lvalue can appear on the left or right side of an assignment statement. When an lvalue appears on the left side of an assignment statement, we can regard it as a container for storing values, and we can assign a new value to it, or modify its value.

In an assignment statement, the value on the right is called an r-value (R-value), which is a value that can be assigned to an l-value. An rvalue can be a constant, variable, expression, or the return value of a function call. An rvalue is invalid when it appears on the left side of an assignment statement.

For example, if we define a variable `a`, then `a` is the lvalue of its memory location. When we perform an assignment operation on `a`, `10` in the assignment statement `a=10` is an rvalue, which is assigned to the variable `a`, and the value of `a` becomes `10`.

In summary, an lvalue is an identifier that represents an object or container that stores a value, while an rvalue is a value that can be assigned to an lvalue.

#include<stdio.h>
int main()
{
	int a = 10;
	// a - 左值
	a = 20;//其实是把20放到a的这块空间,这里使用的是a的空间

	// a - 右值
	int b = a;//其实是使用了a中存放的值,把a中的20存到b中

	return 0;
}

Next we introduce a loop

4.do...while() loop

        The do...while() loop is a loop structure that judges whether the loop condition is true after the loop body is executed at least once. Its grammatical structure is as follows:

do {

        loop body statement block

} while (loop condition);

The do...while()` loop first executes the loop body statement block once, and then judges whether the loop condition is true. If the loop condition is true, it continues to execute the loop body statement block until it exits the loop when the loop condition is false.

Unlike the `while` loop and the `for` loop, the loop condition of the `do...while()` loop follows the statement block of the loop body, so whether the loop condition is true or not, the loop body will be executed at least once.

//使用do - while()语句打印1-10
#include <stdio.h>
int main()
{
    int i = 1;//初始化
    do
    {
        printf("%d ", i);
        i = i + 1;//调整
    } while (i <= 10);//判断
    return 0;
}

5. break and continue in do while loop

#include <stdio.h>
int main()
{
    int i = 1;
    do
    {
        if (5 == i)
            break;
        printf("%d ", i);//1 2 3 4
        i = i + 1;
    } while (i <= 10);

    return 0;
}


#include <stdio.h>
int main()
{
    int i = 1;

    do
    {
        if (5 == i)
            continue;
        printf("%d ", i);//1 2 3 4 死循环
        i = i + 1;
    } while (i <= 10);

    return 0;
}

6. Exercise with small exercises

1. Calculate the factorial of n.

/*
	1. 计算 n的阶乘。
	5! = 1*2*3*4*5
	n! = 1-n 累积相乘
*/
#include<stdio.h>
int main()
{
	int n = 0;
	scanf("%d", &n);//不考虑溢出
	int i = 0;
	int num = 1;
	//产生1-n的数字然后进行累积相乘
	for (i = 1; i <= n; i++)
	{
		num *= i;
	}
	printf("%d\n", num);
	return 0;
}

        This program implements the calculation of the factorial of the input positive integer n. The program reads an integer n from the standard input, then uses a for loop to calculate the product of 1 to n, and stores the result in the variable num. The variable i in the for loop starts from 1, and each loop multiplies i by num, and finally num is the product of all numbers from 1 to n, that is, the factorial of n. Finally, the program uses the printf function to print the calculation result to the standard output, and returns 0 to indicate the normal end of the program. It should be noted that the program does not perform overflow check and processing on the calculation results. When n is relatively large, the calculation results may exceed the value range of the int type. Need to use high-precision calculations or other methods to avoid overflow.

2. Calculate 1!+2!+3!+…+10!

//写法一
#include<stdio.h>
int main()
{
	int n = 0;
	scanf("%d", &n);
	int i = 0;
	int sum = 0;
	int num = 1;
	for (i = 1; i <= n; i++)
	{
		num *= i;
		sum += num;
	}
	printf("%d\n", sum);
	return 0;
}


//写法二
#include<stdio.h>
int main()
{
	int n = 0;
	int i = 0;
	int sum = 0;
	int num = 1;
	for(n=1;n<=3;n++)
	{
		for (i = 1; i <= n; i++)
		{
			num *= i;
		}
		sum += num;
	}
	printf("%d\n", sum);//15
	//结果不对,1!+2!+3!=9
	//?
	return 0;
}

        The goal of this program is to calculate the sum of the factorials of all numbers from 1 to 3. The program achieves this goal using two nested for loops.

        The inner loop calculates the factorial of a number and adds it to sum, and the outer loop controls the calculation of all numbers from 1 to 3. However, when calculating the factorial, the program does not reset the variable num to 1 , which causes the multiplication operation to be performed on the basis of the factorial of the previous number when calculating the factorial of each number, so the result calculated by the program is wrong.

        For example, in the first loop, the factorial when n=1 is calculated, the value of num is 1, and 1 is added to sum when the factorial of 1 is calculated. However, when calculating the factorial when n=2, the value of num is already the factorial result of 1, that is, num=1, instead of restarting the calculation of the factorial of 2, resulting in an error in the result of the program calculation.

        The solution to this problem is to reset num to 1 before each calculation of the factorial in the inner loop.

The modified procedure is as follows:

#include <stdio.h>

int main() {
    int n = 0;
    int i = 0;
    int sum = 0;
    int num = 1;
    for (n = 1; n <= 3; n++) {
        num = 1; // 重置num的值为1
        for (i = 1; i <= n; i++) {
            num *= i;
        }
        sum += num;
    }
    printf("%d\n", sum); // 输出结果:9
    return 0;
}

Now the output of the program is correct, that is, factorial of 1+factorial of 2+factorial of 3=1+2+6=9.

3. Find a specific number n in an ordered array. (Explain binary search)

//这种写法是遍历数组寻找数字,虽然能找到,但是浪费了数字有序这个条件
#include<stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };//升序的10个数字
	int k = 7;//要查找的数字
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		if (arr[i] == k)
		{
			printf("找到了,下标是:%d\n", i);
			break;
		}
	}
	if (i == 10)
		printf("找不到!\n");
	return 0;
}
//二分查找法
/*
	1.确定数组的范围的前后下标begin和end
	2.根据begin和end,确定中间的元素的下标end
	3.根据mid锁定的元素,和查找的元素比较,确定新的查找范围
	4.循环上面步骤,逐渐缩小begin和end的范围,确定能否找到k
*/
#include<stdio.h>
int main()
{
	int arr[] = { 8, 17, 26, 32, 40, 72, 87, 99 };//升序的8个数字
	int k = 40;//要查找的数字
	int length = sizeof(arr) / sizeof(arr[0]);//确定数组的元素个数
	int begin = 0;
	int end = length - 1;
	int flag = 0;
	while (begin <= end)
	{
		int mid = (begin + end) / 2;
		if (arr[mid] < k)
		{
			begin = mid + 1;
		}
		else if (arr[mid] > k)
		{
			end = mid - 1;
		}
		else
		{
			printf("找到了,下标是:%d\n", mid);
			flag = 1;
			break;
		}
	}
	if(flag == 0)
		printf("找不到!\n");
	return 0;
}

         This program implements the binary search method for finding a specific number k in a known ascending array. The basic idea of ​​the program is to continuously narrow the search range until k is found or the search range becomes empty. The program first defines an ordered integer array arr, and determines the number of elements in the array, length, and the number k to be searched. Then define begin and end to indicate the search range, starting with the subscripts of the first and last elements of the array. The program uses a while loop to search, and each cycle reduces the search range by half. In each loop, the program uses mid to denote the index of the middle element of the search range, and compares k to arr[mid]. If k is less than arr[mid], it means that the number to be searched is on the left of mid, and end is assigned as mid-1; if k is greater than arr[mid], it means that the number to be searched is on the right of mid, and begin is assigned to mid+1; if k is equal to arr[mid], it means that k is found, print out the value of mid, and set flag to 1 to indicate that k is found. When the search ends, the program judges the value of flag. If it is 0, it means that k is not found, and outputs "not found!". It should be noted that the correctness of the program requires that the array is ordered , and each cycle will reduce the search range by half, so the time complexity is O(log n) .

4. Write code that demonstrates that multiple characters move from the ends and converge toward the middle.

/*
	输出格式:
	w##########################!
	we########################!!
	wel######################!!!
	welc####################a!!!
	welco##################ba!!!
	welcom################oba!!!
	welcome##############aoba!!!
	welcome ############iaoba!!!
	welcome t##########xiaoba!!!
	welcome to########uxiaoba!!!
	welcome to ######huxiaoba!!!
	welcome to b####nhuxiaoba!!!
	welcome to be##enhuxiaoba!!!
	welcome to benbenhuxiaoba!!!

	两组数据
	welcome to benbenhuxiaoba!!!
	############################
	left                   right
*/

#include<stdio.h>
#include<string.h>
#include<windows.h>
int main()
{
	char arr1[] = "welcome to benbenhuxiaoba!!!";
	char arr2[] = "############################";
	int left = 0;
	int right = strlen(arr1) - 1;
	while (left <= right)
	{
		arr2[left] = arr1[left];
		arr2[right] = arr1[right];
		printf("%s\n", arr2);
		Sleep(1000);//休息1000毫秒
		left++;
		right--;
	}
	return 0;
}

        The function of this program is to output an effect similar to a hanging character, gradually displaying a string from both ends to the middle. The program first defines two character arrays arr1 and arr2, which are the original string and the display effect respectively. At the same time, two indexes left and right are defined, indicating the left and right positions of the display effect respectively. Initially, the left position is 0, and the right position is the length of the original string minus one. Then enter the while loop, the loop condition is that the left bit is equal to the right bit. In each loop, assign the left and right characters of arr1 to the left and right positions of arr2 respectively, output arr2, and use the Sleep function to pause for 1000 milliseconds (that is, 1 second) to make the effect more obvious. Then move the left and right positions one position toward the middle, respectively. Since each cycle will display the display effect to the middle one bit, the final output result is the effect that the original string is gradually displayed from both sides to the middle. It should be noted that the Sleep function is a function provided by the Windows API, which can make the program pause for a certain period of time, and the unit is milliseconds. In this program, using the Sleep function can make the effect look more smooth and natural.

5. Write code to simulate the user login scenario, and can only log in three times. (It is only allowed to enter the password three times. If the password is correct, it will prompt to log in. If it is entered incorrectly three times, it will exit the program.

#include<stdio.h>
int main()
{
	char password[20] = { 0 };
	int i = 0;
	do
	{
		printf("请输入密码:>");
		scanf("%s", password);
		//两个字符串比较不能使用等号
		//需要使用库函数strcmp
		//strcmp返回值 = 0,表示字符串1 = 字符串2
		//strcmp返回值 > 0,表示字符串1 > 字符串2
		//strcmp返回值 < 0,表示字符串1 < 字符串2
		if (strcmp(password, "123456") == 0)
		{
			printf("密码正确\n");
			break;
		}
		else
		{
			printf("密码错误\n");
		}
		i++;
	} while (i < 3);
	if (i == 3)
	{
		printf("登录失败\n");
	}
	return 0;
}

        The function of this program is: let the user enter the password, if the input password is 123456, the password is considered correct, and the program ends; otherwise, it prompts that the password is wrong and requires re-entering. When the user enters the wrong password more than 3 times in a row, the program will exit.

        The program first defines a character array password with a length of 20, which is used to store the password entered by the user. Then use the do-while loop, the loop condition is i<3, that is, the user can enter the password up to 3 times. In each loop, the program prompts the user to enter a password, and uses the scanf function to save the entered password into the password array. Then use the strcmp function to compare whether the password entered by the user is the same as the correct password, and if they are the same, output "the password is correct" and jump out of the loop; otherwise, output "the password is wrong".

        After each loop, the program increments i by 1. When i is equal to 3, it means that the user has entered an incorrect password for 3 consecutive times. At this time, the program will output "login failure" and end the operation. If the user enters the correct password within the first 3 times, the program will use the break statement in the loop to break out of the loop, and then output "password is correct".

        It should be noted that the equal sign cannot be used when comparing strings, and the library function strcmp needs to be used. The return value of the strcmp function is 0, indicating that the two strings are the same, the return value greater than 0 indicates that the first string is greater than the second string, and the return value less than 0 indicates that the first string is smaller than the second string. In this program, if the return value of the strcmp function is 0, it means that the password entered by the user is correct, and the program will output "the password is correct" and end the operation.

Guess you like

Origin blog.csdn.net/qq_64446981/article/details/130227385