【20180711】【C/C++基础知】C语言控制语句:if-else,switch,for,while,do-while,goto,break,continue,rand()函数,srand()函数

  • 控制语句:顺序、选择、循环
  • 程序的三种基本结构:顺序结构、选择结构、循环结构。

顺序结构中的语句可能是简单语句,也可能是复合语句,还可能是空语句。

  • 三种语句:

1. 简单语句:以";"结尾的语句。

2. 复合语句:用"{}"把“说明”和若干个有序的简单语句组合在一起构成的集合。

3. 空语句:什么动作都不执行,只有一个分号。

  • 选择语句:if, if-else, switch

1. if语句的功能:单选、多选一

单选:

if(表达式)

    语句(或复合语句)

多选一:if-else, if-else if-else if-…-else

 

程序1:三个人的平均成绩大于90分,则输出平均成绩和excellence。

/* 三个人的平均成绩大于90分,则输出平均成绩和excellence */
/* 我写的程序 */
# include"stdio.h"
#include"stdlib.h"
int main()
{
	float a, b, c, sum, average;
	scanf_s("%f%f%f", &a, &b, &c);
	sum = a + b + c;
	average = sum / 3;
	if (average > 90)
	{
		printf("这三个人的平均成绩是%.2f:\n", average);
		printf("excellence!\n");
	}
	system("pause");
	return 0;
}

 

程序2:求b的绝对值。

/* 取b的绝对值 */
/* 我写的程序 */
# include"stdio.h"
#include"stdlib.h"
int main()
{
	int b;
	scanf_s("%d", &b);
	if (b >= 0)
	{
		printf("b的绝对值为%d\n", b);
	}
	else
	{
		printf("b的绝对值为%d\n", -b);
	}
	system("pause");
	return 0;
}
/* 取b的绝对值 */
# include"stdio.h"
#include"stdlib.h"
int main()
{
	int b,a;
	scanf_s("%d", &b);
	if (b >= 0)
	{
		a = b;
	}
	else
	{
		a = -b;
	}
	printf("b的绝对值是:%d\n", a);
	system("pause");
	return 0;
}

可以优化:用三目运算符表示!!!像下面这样:

/* 取b的绝对值 */
/* 用三目运算符表示 */
# include"stdio.h"
#include"stdlib.h"
int main()
{
	int b,a;
	scanf_s("%d", &b);
	a = b >= 0 ? b : -b;
	printf("b的绝对值是:%d\n", a);
	system("pause");
	return 0;
}

心得:如果要求较大值,那么可以用if-else,也可以用三目运算符,表示为max = a>=b?a:b;

注意配对问题!!!if-else可以嵌套使用(注意配对问题!注意:不是对齐就是配对!配对时不看缩进,以最近配对为原则!因此为了不出错,养成加括号的好习惯!)。

 

2. C语言提供了另一种更方便简洁的进行多重选择的语句:switch语句。

switch(表达式)       // 表达式只能是整数类型或字符类型
{
    case 常数1:语句1
    break;        // 跳出switch语句,如果没有break,那么也会执行后面的case中的语句。
    case 常数2:语句2
    break;
    …
    case 常数n:语句n
    break;
    default:语句n-1;
}

 

程序3:从键盘输入一个月号(1~12),并显示该月号的英文名称。

/* 从键盘输入一个月号(1~12),并显示该月号的英文名称 */
# include"stdio.h"
#include"stdlib.h"
int main()
{
	int month;
	printf("请输入一个月号:\n");
	scanf_s("%d", &month);
	switch (month)   // 即使只有一个变量,也要加括号!!
	{
		case 1:printf("January");   // 注意:case后面的语句也要加分号;!!
			break;
		case 2:printf("February");
			break;
		case 3:printf("March");
			break;
		case 4:printf("April");
			break;
		case 5:printf("May");
			break;
		case 6:printf("June");
			break;
		case 7:printf("July");
			break;
		case 8:printf("August");
			break;
		case 9:printf("September");
			break;
		case 10:printf("October");
			break;
		case 11:printf("November");
			break;
		case 12:printf("December");
			break;
		default:printf("Data Error!");
			break;
	}
	system("pause");
	return 0;
}
  • 选择结构小结:

1.  if语句:单选、二选一、多选一。

2. switch语句:多选一。

  • 三种循环语句:for,while,do while。

1. for语句:

for(表达式1;表达式2;表达式3)   // 后面的三个表达式要用分号分隔开!
    循环体;   // 养成加花括号的好习惯!

for语句执行过程:先计算表达式1(只执行一次),然后判断表达式2,如果2为真则进行循环体执行,循环体执行完毕执行表达式3,表达式3执行完再判断表达式2……

 

程序4:求n的1~5次方。

/* 求n的1~5次方 */
/* 我写的程序 */
# include"stdio.h"
#include"stdlib.h"
int main()
{
	int n,i,m;
	scanf_s("%d", &n);
	for (i = 1;i < 6;i++)
	{
		m = pow(n, i);   // error: "pow"未定义,假设外部返回int(原因:没有加头文件math.h)。
		printf("n的%d次方为%d:\n", i,m);
	}
	system("pause");
	return 0;
}
/* 求n的1~5次方 */
/* 我写的程序 */
# include"stdio.h"
#include"stdlib.h"
#include"math.h"
int main()
{
	int n, i, m;
	scanf_s("%d", &n);
	for (i = 1;i < 6;i++)
	{
		m = pow(n, i);   // error: 从double到int可能丢失数据(因为pow函数两个参数都是double型数据),但最终还是正确输出了。
		printf("n的%d次方为%d:\n", i, m);
	}
	system("pause");
	return 0;
}

由于丢失数据,因此会出现结果错误的情况:

/* 求n的1~5次方 */
/* 用一个变量result来存储之前的n-1次方,也就是递归的思想,优点:降低复杂度,减小所需内存空间 */
# include"stdio.h"
#include"stdlib.h"
int main()
{
	int n, I;
long result = 1;
	scanf_s("%d", &n);
	for (i = 1;i < 6;i++)
	{
		result *= n;
		printf("n的%d次方为%ld:\n", i,result);
	}
	system("pause");
	return 0;
}

注意:for语句十分灵活,里面三个表达式可以对多个变量进行处理,方法是:for(i=0,=100; (j-i)>10; i++,j--)。也就是说三个表达式使用分号分隔,一个表达式内部可以对多个变量进行处理,用逗号分隔。

允许在循环体内改变循环控制变量的值(即表达式2的值),这样可以控制(改变循环次数)。

三个表达式均可缺省:

1. 不需要修改循环变量的值,可缺省表达式3:

for(i=0;i!=100;)     

2. 如果不再需要对循环变量进行初始化,可缺省表达式1:

for(;i>20;i++)

3.一直循环下去(死循环):(前面提到的,循环体内是可以修改循环次数的,并且我们可以借用其他关键字来退出死循环。)

for(; ;)

4. 省略循环体(其实是把循环体放到了for后面的三个表达式中):

for(i=1,j=1;i<1000;i++,j*=1);

它和下面一种表达方式是等价的!

for(i=1,j=1;i<1000;i++)

    j*=1;

程序5:输出9*9乘法表。

/* 输出一个9*9乘法表 */
# include"stdio.h"
#include"stdlib.h"
int main()
{
	for (int i = 1;i <= 9;i++)
	{
		printf("%4d", i);   // 若想输出的数据有空格,那么可以在%d后面加一个空格:'%d '。
	}
	printf("\n----------------------------------------\n");
	for (int i = 1;i < 10;i++)        // 控制行
		for (int j = 1;j < 10;j++)    // 控制列
		{
			if (j != 9)
				printf("%4d", i*j);
			else
				printf("%4d\n", i*j);   // 每行的第9列要进行换行,因此这里用了if-else语句!
		}
	system("pause");
	return 0;
}

 

  • for语句常用于已知循环次数,若事先不知道循环次数,用while和do-while。

1. while语句功能:表达式为真,执行循环体。一般形式为:

while(表达式)
{
    循环体
 }

2. do-while语句功能:先执行一次循环体,再判断表达式是否为真,因此do-while语句至少执行一次循环体。一般形式为:

do
{
    循环体
 }while(表达式);

循环类型:

1. 当型循环(先判断再执行,当表达式为假停止循环)

2. 直到型循环(先执行循环体,再判断)

 

程序6:读入字符并回显,直到读入'*'为止。

/* 读入字符并回显,直到读入'*'为止 */
#include "stdio.h"
#include<stdlib.h>
int main()
{
	char c;
	printf("请输入字符:\n");
	c = getchar();    // 注意:键盘输入一个字符,可以用getchar(),这个函数括号里面没有参数!
	//scanf_s("%c", &c, 1);   // 键盘输入一个字符,也可以用scanf_s函数,注意scanf_s函数用于字符型变量时,应该注明字符个数!
	while (c != '*')     // 注意:这里要加单引号!
	{
		putchar(c);   // 输出一个字符,也可用printf函数
		c = getchar();  
	}
	system("pause");
	return 0;
}
/* 读入字符并回显,直到读入'*'为止 */
/* 优化的程序,getchar在while外面和里面都执行到了,因此可以放到while表达式里面 */
#include "stdio.h"
#include<stdlib.h>
int main()
{
	char c;
	printf("请输入字符:\n");
	while ((c = getchar()) != '*')     
	{
		putchar(c);   
	}
	system("pause");
	return 0;
}

 

  • 循环结构总结:

for语句、while语句、do-while语句。

表达式为真执行循环体。

  • 其他流程控制语句:

1. break两个作用:switch语句中分隔case; 立即跳出循环语句。

2. continue作用:循环中遇到continue,直接跳过continue下面的所有语句,直接进入下一次循环操作。

3. goto语句:无条件转移语句,直接跳到标号所指语句。(  一般形式如下)

goto 标号;
……
标号:语句;

注意:goto语句十分灵活,很容易改变我们的运行流程,尽量避免使用,否则出错不容易找原因。

 

程序7:输入n个实型数,只对正实型数进行输出。

/* 输入n个实型数,只对正实型数进行输出 */
#include "stdio.h"
#include<stdlib.h>
int main()
{
	float x;
	for (int i = 1;i < 100;++i)
	{
		scanf_s("%f", &x);
		if (x < 0.0)
			continue;   // 跳过后面的printf函数,直接进入下一次循环
		printf("%f\n", x);
	}
}

 

程序8:买苹果。每个苹果0.8元,第一天买两个,以后每天买的个数是前一天的两倍,直至购买的苹果个数达到不超过100的最大值,求每天平均花多少钱。

/* 买苹果 */
#include "stdio.h"
#include<stdlib.h>
int main()
{
	float s, m = 0.8, sum=0, msum;
	int n = 2,d;
	for (d=0;n <= 100;++d)
	{
		sum += n;
		n *= 2;
	}
	s = sum * m;
	printf("%d天一共花了%f元!\n", d,s);
	msum = s / d;
	printf("平均每天花费%.2f元\n", msum);
	system("pause");
	return 0;
}

注意:for语句中int d和for前面就int d是不一样的!在外面int d,那么for循环之后d依然可用。但如果是for语句中int d,那么只有在for循环中d可以用,for循环之后不可以用!(我的错误!)

/* n天一共买了多少苹果 */
#include <stdio.h>
#include<stdlib.h>
#include"math.h"
int main()
{
	int n, i, m = 2, sum = 0;
	printf("Input n...\n");  
	scanf_s("%d", &n);
	for (i = 1;i <= n;++i)
	{
		sum += m;
		m *= 2;
	}
	printf("%d天共买了%d个苹果!\n", n, sum);
	system("pause");
	return 0;
}

 

程序9:猜数游戏。计算机想一个[1,100]数,然后猜一个数,计算机给出大了还是小了。

思路:

计算机中随机函数rand()函数可以模拟“想”一个数,它是用来产生[0,rand_max]之间的随机数,头文件是<stdlib.h>,rand_max在头文件中定义,是不大于双字节整数的最大值32767。

产生[0,b-1]之间的随机数:magic = rand() % b;

产生[a,a+b-1]之间的随机数:magic = rand() % b + a;

/* 猜数游戏 */
/* 只猜一次 */
#include "stdio.h"
#include<stdlib.h>
int main()
{
	int a, b;
	a = rand() % 100 + 1;  // 计算机“想”一个[1,100]之间的数!
	scanf_s("%d", &b);
	if (b > a)
	{
		printf("大了\n");
	}
	else if (b < a)
	{
		printf("小了\n");
	}
	else
	{
		printf("right!");
		printf("%d", b);
	}
	system("pause");
	return 0;
}
/* 猜数游戏 */
/* 直到猜对为止 */
#include "stdio.h"
#include<stdlib.h>
int main()
{
	int magic, guess;
	int counter = 0;        // 增加了人猜次数的计数器变量 
	magic = rand() % 100 + 1;  // 计算机“想”一个[1,100]之间的数!
	while (1)
	{
		scanf_s("%d", &guess);
		++counter;
		if (guess > magic)
		{
			printf("大了,请输入小于%d的值......\n",guess);
		}
		else if (guess < magic)
		{
			printf("小了,请输入大于%d的值......\n", guess);
		}
		else
		{
			printf("right!");
			printf("%d", guess);
			break;
		}
		continue;
	}
	system("pause");
	return 0;
}

问题:为什么计算机“想”的数都是42,每次都一样?

答:函数rand()产生的是伪随机数,是用算法得到的,初始值一样,算法一样,因此每次得到的伪随机数都一样。为了得到不同的伪随机数,需要对初始值(随机种子)随机化,随机函数srand()是设置随机种子(产生不同的初始值),因此它可实现对rand()函数的随机化。用法如下:

scanf("%u",&seed);    
srand(seed);       // 产生随机种子
magic=rand()%100+1;    

计算机自动产生随机种子,因为计算机执行的时间不同,因此我们用计算机的时钟值作为随机种子,产生[1,100]间的随机数。函数time()返回以秒计算的当前时间值,该值被转换为无符号整数并用作随机数发生器的种子。time能为程序员提供代表时间的字符串,使用NULL作为函数参数,使其不具备此功能。如下:

#include<time.h>
srand(time(NULL));
magic=rand()%100+1;
/* 猜数游戏 */
/* 直到猜对为止 */
#include "stdio.h"
#include<stdlib.h>
#include<time.h>   
int main()
{
	int magic, guess;
	int counter = 0;        // 增加了人猜次数的计数器变量
	srand((unsigned int)time(NULL));       // 从“time_t”转换到“unsigned int”,可能丢失数据,因此我们做强制转换。
	                                      // time()函数在头文件"time.h"中!
	magic = rand() % 100 + 1;  // 计算机“想”一个[1,100]之间的数!
	while (1)
	{
		scanf_s("%d", &guess);
		++counter;
		if (guess > magic)
		{
			printf("大了,请输入小于%d的值......\n",guess);
		}
		else if (guess < magic)
		{
			printf("小了,请输入大于%d的值......\n", guess);
		}
		else
		{
			printf("right!");
			printf("%d", guess);
			break;
		}
		continue;
	}
	system("pause");
	return 0;
}

/* 猜数游戏 */
/* 最多猜10次 */
#include "stdio.h"
#include<stdlib.h>
#include<time.h>   
int main()
{
	int magic, guess;
	int counter = 0;        // 增加了人猜次数的计数器变量
	srand((unsigned int)time(NULL));       // 从“time_t”转换到“unsigned int”,可能丢失数据,因此我们做强制转换。
	                                      // time()函数在头文件"time.h"中!
	magic = rand() % 100 + 1;  // 计算机“想”一个[1,100]之间的数!
	do
	{
		scanf_s("%d", &guess);
		++counter;
		if (guess > magic)
		{
			printf("大了,请输入小于%d的值......\n",guess);
		}
		else if (guess < magic)
		{
			printf("小了,请输入大于%d的值......\n", guess);
		}
		else
		{
			printf("right!");
			printf("%d", guess);
		}
	} while ((guess != magic) && (counter < 10));    // 注意:do-while语句的while后面还有分号!
	                                                 // 注意:逻辑与是两个&!
	system("pause");
	return 0;
}

程序10:求素数。给定一个数,判断它是不是素数。

判断方法:看2~n-1能不能被n整除,如果能则它不是素数。

/* 求素数 */
/* 编程思路是检查跳出循环时被除数的大小,如果跳出时小于n,则说明不是素数 */
#include <stdio.h>
#include<stdlib.h>
int main()
{
	int m, i, n;
	printf("请输入一个数:\n");
	scanf_s("%d", &n);
    do
	{
		i = 2;
		m = n % i;	
		if (m == 0)
		{
			++i;
		}
		else
		{
			printf("%d不是素数!\n", n);
			break;
		}	
		while (i = n)
		{
			printf("%d是素数!\n", n);
			break;
		}
	} while (i < n);
	system("pause");
	return 0;
}
/* 求素数简化的程序1 */
#include <stdio.h>
#include<stdlib.h>
int main()
{
	int i, n;
	printf("请输入一个数:\n");
	scanf_s("%d", &n);
	for (i = 2;i < n;++i)
	{
		if (n%i == 0)
			break;
	}
	if (i < n)
		printf("%d is not prim!\n", n);
	else
		printf("%d is prim!\n", n);
	system("pause");
	return 0;
}

/* 求素数简化的程序2 */
/* 大于根号n的那些数一定不能被n整除 */
/* 不再检查大于根号n的那些值,省去了很多无用功,但问题是这样即使它是素数,i的退出值也是小于n */
#include <stdio.h>
#include<stdlib.h>
#include"math.h"
int main()
{
	int i, n, bprim = 1;       // 引入一个变量bprim,初始值设为1,表示是素数,如果中途判断不是素数,则只需修改它的值
	printf("请输入一个数:\n");
	scanf_s("%d", &n);
	for (i = 2;i < sqrt(n);++i)    // sqrt()函数需要头文件<math.h>
	{
		if (n%i == 0)
		{
			bprim = 0;
			break;
		}
	}
	if (bprim==0)         // 只需判断bprim的值即可!
		printf("%d is not prim!\n", n);
	else
		printf("%d is prim!\n", n);
	system("pause");
	return 0;
}
/* 输入一个正整数,输出1~n之间的所有素数 */
#include <stdio.h>
#include<stdlib.h>
#include"math.h"
int main()
{
	int n, i,m ;
	printf("Print n...\n");
	scanf_s("%d", &n);
	for (i = 1;i <= n;++i)
	{
		int bprim = 1;
		for (m = 2;m <= sqrt(i);++m)
		{
			if (i%m == 0)
			{
				bprim = 0;
				break;
			}

		}
		if (bprim == 1)
			printf("%d is prim!\n", i);
		else
			printf("%d is not prim!\n", i);
	}
	system("pause");
	return 0;
}

我的错误:scanf_s("%d\n", &n);   // 这样会没有输出结果!!!

结果不对的话要进行调试(调试技术):逐过程、逐步。调试方法:加断点!

 

猜你喜欢

转载自blog.csdn.net/weixin_40583722/article/details/81085648