C语言-语句与控制流

目录

语句与程序块

分类

常用语句

赋值语句

输入输出语句

 判断语句

一、if(…) {…}

二、if(…) {…} else {…}

三、if(…) {…} else if(…) {…} … else if(…) {…} else {…}

四、switch() {case …: …; case …: …; … default: …;}

扩展5.1:C语言中输出格式%m.nf的意思

 循环语句

while语句

do while语句

for语句

循环体中的跳转语句

break语句

continue语句

goto语句

参考文献


作者:

Flower_For_Algernon

凉风起天末、

lemonrabbit1987

语句与程序块

一个函数包含声明部分和执行部分。执行部分由语句组成,经编译后产生机器指令。声明部分不是语句,不产生机器指令。一个C程序的结构如下:
construction

分类

C语句分为以下5类
(1). 控制语句

  1. 条件语句:if(表达式) … else if(表达式) … else …
  2. 循环语句:
    (1). for(表达式1; 表达式2; 表达式3) …。在C99标准中允许表达式1定义变量并赋予初值。推荐在这里给仅在循环中用到的变量定义,因为这样能缩短变量的作用域
    (2). while(表达式) …
    (3). do … while(表达式);(注意最后有分号)
    多层循环嵌套时,一般长循环放在内层,短循环放在外层
  3. 跳过本次循环语句:continue
  4. 结束switch或循环语句:break
  5. 多分支选择语句:switch。
switch(整型数据(包括枚举型)或字符型数据) {
	case 常量1: 语句1; break;
	case 常量2: 语句2; break;
	case 常量3:
	case 常量4: 语句3; break;//此时常量3和常量4都进入到语句3
	...
	default: 语句n;(没有default时不符合则跳过)
}
//对于if、switch等选择语句,通常把正常情况,也即出现可能性最大的分支放前面,而可能性小的分支放后面
  1. 函数返回语句:return
  2. 转向语句:goto。先在程序某处添加标记,如"mark: ",然后使用"goto mark;"跳转

(2). 函数调用语句
如printf(“Hello world.”);

(3). 表达式语句
如赋值表达式a=3;,++i;等

(4). 空语句
直接只有一个分号的一行语句。

(5). 复合语句
用{}将语句和声明括起来的复合语句,也称语句块

常用语句

C程序中最常用的是赋值语句和输入输出语句

赋值语句

复合赋值运算符中,x%=y+3、x%=(y+3)、与x=x%(y+3)三者等价
赋值表达式的一般形式为,变量 赋值运算符 表达式三项。其中,算术表达式、常量、以及赋值表达式不能作为左值
连等式中a=(b=5)与a=b=5等价,也即连等式的运算顺序为从右到左
在赋值过程中将占字节多的数据赋值给占字节少的变量时,直接截取相应数据范围的部分

输入输出语句

(1). printf
一般形式为printf(格式控制,输出表列)

  1. d格式符。用来输出有符号十进制整数。%5d表示数据占据5列且数据靠右,若想靠左则为%-5d。但%+d则表示输出整数前的正负号。长整型则为%ld,双长整型为%lld。l可放在d、o、x、u前。而在scanf中%5d则表示只读取前5位整数
  2. c格式符。用来输出一个字符
  3. s格式符。用来输出一个字符串。%5s在printf中表示只输出前5个字符,在scanf中表示只读取前5个字符
  4. f格式符。用来输出实数
    (1). 基本型用%f。实数部分全部输出,小数部分输出6位
    (2). 指定数据宽度和小数位数%m.nf。如果n为0则不会输出小数点。注意其中m是指包含小数点在内的整个浮点数长度而不单单指整数部分
  5. e格式符。用来输出指数形式实数。同样可以用%m.ne形式声明。也可用写成%E,此时输出指数中为大写E
  6. i格式符。在 printf 中没有区别,在 scanf 时,%d 只与十进制形式的整数相匹配;而%i 则可以匹配八进制、十进制、十六进制表示的整数。 如输入的数字有前缀 0(018、025),%i会把它当作八进制数来处理,如果有前缀0x (0x54),它将以十六进制来处理
  7. o格式符。连同符号位一起以八进制整数形式输出
  8. x格式符。连同符号位一起以十六进制整数形式输出。%X时以大写形式输出
  9. u格式符。用来输出无符号整数
  10. g格式符。用来输出浮点数,并由系统自动选择为f格式或e格式输出。%G时以大写形式输出
  11. p格式符。用来输出地址

(2). scanf
一般形式为scanf(格式控制,地址表列)
其中,l可用于输入长整型数据如ld、lo、lx、lu以及double型数据lf、le。h可用于输入短整型数据如hd、ho、hx
在scanf(“a=%d, b=%d”, &a, &b);中输入则必须为a=1, b=2。若为scanf(“a=%d b=%d”, &a, &b);则a=1与b=2之间必须要有1个以上的空白字符
scanf和printf函数都有返回值,scanf返回正确读入了多少个变量,printf返回输出了包括换行符在内的有多少个字符

(3). sprintf
一般形式为sprintf(目标字符串,格式控制,地址表列)
sprintf函数用于将字符串输出到目标字符串而不是屏幕中,要注意字符串的长度要足够容纳打印的内容,否则会出现内存溢出

(4). sscanf
一般形式为sscanf(源字符串,格式控制,地址表列)
sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。sscanf可用来进行数据类型或进制转换以及按特定规则读取源字符串的特定规则。也即使用正则表达式,但是功能并没有正则表达式强大,并且使用时有较多限制。同理,在scanf以及printf中的格式控制都能使用正则表达式。C语言并不直接支持正则表达式,而需要通过函数库regex.h来完成

几种常见的表达方法:

  1. %[abc]读取a、b、或c的任意一员,[a-z]表示匹配小写字母,[a-z0-9]表示匹配小写字母及数字
  2. %[^a-z]读取不在a-z之间的字符串,如果碰到 a-z 之间的字符则停止
  3. %[^=]读取字符串直到碰到=号
  4. %*[^=]%s前面带*号表示不保存变量。跳过字符串中以=结尾的子串而读后包括=在内的后面部分子串

另外,可用*匹配变量到格式字符串中,如printf("%*d\n", a, A);即输出a长度宽的整数A,而printf("%.*lf\n", a, A);则输出a位小数的浮点数A

(4). 字符输入输出

  1. putchar( c )。用于输出字符变量c。若c为整数则当ASCII码处理
  2. c = getchar()。用于输入一个字符,包括控制字符。注意getchar函数返回的不是char类型而是int类型,此时有可能出现潜在错误。一般用法为while((a = getchar() && a!=EOF) != ‘\n’) { }。EOF是指检测文件尾,在头文件中通过宏定义定义值为-1。键盘输入EOF其实是命令行环境遗留下来的,但是很多系统支持仿真的EOF,如用Ctrl+D(Linux系统)或Ctrl+Z(Windows系统)来模拟输入EOF

 判断语句

一、if(…) {…}

1.一般形式:
if (表达式) {语句;}

表达式:
a,用非 0 值表示真,用 0 表示假;
b,if(flag) 相当于 if(flag!=0);
c,浮点数无法与 0 比较,只能用近似的值比较;例: 1e-6 等于1x10的-6次方可以看成0来使用;

2.用于单分支选择结构;
3.如含有交叉关系,使用并列的if语句;

例1:输出两个整数中的最大值

#include <stdio.h>
void main()
{
     int a,b;
     printf("请输入两个整数:");
     scanf("%d %d",&a,&b);
     if(a>b)
     {
     printf("max = %d\n",a);
     }
     if(a<b)
     {
     printf("max = %d\n",b);
     }
}

二、if(…) {…} else {…}

  1. 一般形式: if(表达式) {语句1; } else { 语句2;}
  2. 用于双分支控制的条件语句;
  3. 用于非此即彼的关系时;

例2:输出两个整数中的最大值

例2关于对于非法字符的检查与处理

#include <stdio.h>
void main()
{
	int a,b,max,data;
	printf("Input a,b:");
	data = scanf(" %d,%d",&a,&b);/*记录scanf()的返回值;*/
	if(data!=2)/*根据scanf()的返回值判断输入数据个数或者格式是否错误*/
    {
		printf("格式输入错误!");
		fflush(stdin);/*清除输入缓冲区中的错误内容(fflush()可能带来可移植性的问题)*/
	}
	else
	{
		max = a>b?a:b;/*三目运算符(a>b值为真则输出a的值,反之输出b的值)*/
		printf("%d\n",max);
	}

}

三、if(…) {…} else if(…) {…} … else if(…) {…} else {…}

  1. 一般形式:
    if(表达式1) { 语句1;}
    else if(表达式2) {语句2;}

    else if(表达式n){语句n;}
    else{语句n+1;}

  2. 用于多分支的控制的条件语句;

例3:判断字符

#include <stdio.h>
void main()
{
	char ch;
	printf("请输入一个字符:");
	ch = getchar();/*getchar、putchar专门用于字符输入输出;
				     getchar()写法上要写为 变量 = getchar();
					 putchar()用法为putchar(变量);
					 putchar('\n')输出一个控制符;
					 putchar('字母/字符');输出字母/字符;
					 */
	if(ch<=31)
	{
		printf("这是一个控制字符或通讯专用字符!\n");
	}
	else if(ch >= '0' && ch <= '9')
	{
		printf("这是一个数字!\n");
	}
	else if(ch >= 'A' && ch <= 'Z')
	{
		printf("这是一个大写字母!\n");
	}
	else if(ch >= 'a' && ch <= 'z')
	{
		printf("这是一个小写字母!\n");
	}
	else
	{
		printf("这是其他字符!\n");
	}
}

四、switch() {case …: …; case …: …; … default: …;}

  1. 一般形式:
    switch(表达式)
    {
    case 常量1:语句1;
    case 常量2:语句2;

    case 常量n:语句n;
    default: 语句n+1;
    }
  2. 用于多路选择的语句;

switch语句相当于多个if-else语句;
(表达式)只能是char型或者int型;
case 后面至少要有一个空格,常量后面是冒号
(表达式)与 常量类型要保持一致;
记得记得记得 在需要跳出的时候,在语句后面加上break;

例4:简单的加减乘除计算

#include <stdio.h>
void main()
{
	double a,b;
	char ch;
	printf("Input a(+ - * /)b:");
	scanf("%f%c%f",&a,&ch,&b);
	switch(ch)
	{
	case '+':
		printf("%f%c%f=%.2f\n",a,ch,b,a+b);/*%.2f表示精度,可以理解为保留两位小数*/
		break;
	case '-':
		printf("%f%c%f=%.2f\n",a,ch,b,a-b);
		break;
	case '*':
	case 'X':
	case 'x':
		printf("%f%c%f=%.2f\n",a,ch,b,a*b);/*输入"x" "X" "*" 都执行这一条语句;不加break,会顺语句执行*/
		break;
	case '/':
		printf("%f%c%f=%.2f\n",a,ch,b,a/b);
		break;
	default:
		printf("请输入正确算式!\n");
	}
}

扩展
5.1:C语言中输出格式%m.nf的意思

  • m:表示宽度
  • .n:表示精度
假设,
i=10.1;
printf("%5.2f",i);

输出结果为 10.10(m=5,其中空格占1位,小数(n)占2位)

本文出现任何错误,欢迎留言批评指正。


 循环语句

循环语句是用于重复执行某条语句(循环体)的语句,它包含一个控制表达式,每循环执行一次都要对控制表达式进行判断,如果表达式为真,则继续执行循环。C语言提供了3中循环语句,分别为while语句,do while语句和for语句。

while语句

while语句是控制表达式在循环体之前的循环语句,它的格式如下:

while (表达式) 
    语句

这里的圆括号是强制要求的,圆括号之内的表达式为控制表达式,圆括号之外的语句为循环体。

while语句的执行步骤,首先计算控制表达式的值,如果表达式的值不为0(为真),则执行循环体,接着再次判断控制表达式,如果其值不为0,再次执行循环体。执行这个步骤直到控制表达式的值为0时停止。

/*************************************
 * using_while_1.c                   *
 *                                   *
 * 简单的while语句                   *
 *************************************/

#include <stdio.h>

int main()
{
  int i = 1;
  int sum = 0;

  while(i <= 50)
  {
    sum += i;
    i++;
  }

  printf("1到50之间(包括1和50)的整数之和为%d\n", sum);

  return 0;
}

基本的while语句

如果while的控制表达式一直不为0,那么循环将一直进行下去,称为无限循环。这样的循环在循环体中都包含break,goto,return或者导致程序终止的函数(如exit等),以在适当的时机终止程序。

/****************************************
 * using_while_2.c                      *
 *                                      *
 * 无限循环与break                      *
 ****************************************/

#include <stdio.h>

int main()
{
  int i = 1;
  int sum = 0;
  while(1)
  {
    if ( i > 50)
      break;

    sum += i;

    i++;
  }

  printf("1到50之间(包括1和50)的整数和为%d\n", sum);
  return 0;
}

while和break

do while语句

do while语句与while语句非常相似,只不过do while语句在每次执行完循环体之后对控制表达式进行判断的,因此do while语句的循环体至少会执行一次,而while语句的循环体可能一次都不被执行。do while语句的格式如下:

do 
    语句
while(表达式);

其中控制表达式两端的括号也是必须的。

do while循环的执行步骤如下:首先执行循环体,再计算控制表达式的值,如果表达式的值非零再继续执行循环体,然后再次判断表达式的值。这个过程持续进行,知道控制表达式的值为0,终止do while语句执行。

建议对do while的循环体都使用大括号包裹起来,因为大括号会使do while语句被误认为是while语句。

/*************************************
 * using_do_while.c                  *
 *                                   *
 * C语言中的do while循环             *
 *************************************/

#include <stdio.h>

int main()
{
  int i = 1;
  int sum = 0;

  do
  {
    sum += i;
    i++;
  }while(i <= 50);

  printf("1和50之间(包括1和50)的整数之和为%d\n", sum);

  return 0;
}

dowhile

for语句

for语句的格式如下:

for (表达式1; 表达式2; 表达式3)
    语句

表达式1是初始化步骤,只执行一次,表达式2是控制表达式,控制循环的终止,表达式3在每次循环的最后被执行。

for语句的执行步骤是:首先执行表达式1进行初始化,然后判断表达式2的值是否为真,若为真,则执行循环体,然后执行表达式3.随后再次对表达式2的值进行判断,若为真,则再次执行循环体和表达式3,依次循环直到表达式2的值为0为止。

for语句的3个表达式都可以省略,若省略表达式1,则在执行循环前没有初始化的操作;若省略第三个表达式,则执行完循环体后,没有再需要执行的语句,循环体确保循环能够在有限时间内终止;若省略第二个表达式,则每次判断都默认为真,除非在循环体内使用break,goto和程序终止函数外,循环不会停止。

/*************************************
 * using_for.c                       *
 *                                   *
 * C语言的for语句                    *
 *************************************/

#include <stdio.h>

int main()
{
  int sum = 0;

  int i;

  for (i = 1; i <= 50; i++)
  {
    sum += i;
  }

  printf("1和50之间(包括1和50)的整数之和为%d\n", sum);

  return 0;
}

for语句

循环体中的跳转语句

在循环体中可以使用breakcontinuegoto跳转语句。

break语句

break语句在循环体的中间设置退出点,用以跳出whiledo whilefor循环,直接执行循环语句后面的语句。除此之外,break语句还用于switch语句,用以跳出switch语句而直接执行switch语句后面的语句。对于嵌套的循环语句和(或)switch语句,break只能跳过其所在的那层循环或switch语句。

continue语句

continue语句并不跳出循环,而是将程序执行正好转移到循环体末尾处,跳过本次循环中循环体余下的内容。continue语句只能用于循环体中。

/**************************************
 * using_continue.c                   *
 *                                    *
 * C语言中用于循环体的continue语句    *
 **************************************/

#include <stdio.h>

int main()
{
  int n = 0;
  int sum = 0;

  while (n < 10)
  {
    int i = 0;
    scanf("%d", &i);
    if (i == 0)
      continue;
    sum += i;
    n++;
  }

  printf("以上十个非零数的和为:%d\n", sum);

  return 0;
}

continue

goto语句

goto语句不仅可以用在循环体中,还可以用在程序的任何位置。与continuebreak不同,它可以跳转到同一个函数中任何有标记的语句处。goto依赖于定义在语句开头的标识符,其形式为:标识符 : 语句goto语句的形式为:goto 标识符;

goto易于造成程序混乱,代码难以阅读,并且其他跳转语句、returnexit语句能够满足大多数需要goto语句的情况。除非万不得已,尽量不要使用。

/**************************************
 * using_goto_in_loop.c               *
 *                                    *
 * C语言循环语句的循环体中使用goto语句*
 **************************************/

#include <stdio.h>

int main()
{
  int i = 0;

  while (i < 10)
  {
    switch(i)
    {
    case 0:
    case 1:
    case 2:
    case 3:
      printf("%d 小于 4\n", i);
      break;
    default:
      goto bigThan4;
    }
    i++;
  }

 bigThan4: printf("i开始不小于4\n");
  return 0;
}

goto in loop

参考文献

  1. K.N. King 著,吕秀峰 译. C语言程序设计-现代方法. 人民邮电出版社
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

兔子递归

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值