C语言关键字浅析-while

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Johan_Joe_King/article/details/84325038

### C语言关键字浅析系列 ###

### ISO/ANSI C 关键字 ###

while在英文中常被翻译为“在……的时候,当……时”,私以为在C语言的while里,应当为“当……的时候,一直……”

因为这样说,才符合while表示循环的身份,while循环结构也是C语言很常见和很重要的一种语法

while的作用是:

表示一种入口条件循环——while循环结构。

1、while的使用

如果你已经有C程序的编程经验,那可能while已经是你的老熟人了,如果你正在学循环结构,不妨也一起回顾一下while的格式:

int i = 0;
while (i < 10)   /* while关键字后跟小括号,括号内是逻辑表达式,只要逻辑表达式成立,就循环地执行while后的语句 */
	i++;     /* 这是一条循环体的语句,这段代码的效果是i从0开始一直自增1,i=10的时候循环结束 */

int i = 0, sum = 0;
while (i < 10)   /* 如果循环体是复合语句,需要加大括号 */
{                /* 这段代码的效果是,sum保存的是0到9的和 */
	sum += i;
	i++;
}

2、谈谈逻辑表达式

和if-else的逻辑表达式类似,效果都是看看是否成立,成立的标准是看表达式的值是不是非零或者true,反之不成立是0和false

作为一种入口条件循环,while关键字后的逻辑表达式只要成立,就会执行循环体,然后返回再看逻辑表达式是否成立,以此循环

所以你可能注意到了,如果逻辑表达式一直成立呢?这就是我们常说的死循环:

while (1)
{
	/* 这种死循环很常见,并非人为疏忽造成的bug,而是利用死循环的特性写的程序,如多线程编程中常用这种死循环 */
        /* 提示:如果逻辑表达式是整数常量,记住,只有0表示false,非零常量都表示true,3,1024,-1 ,-10等等 */
        /* 不过习惯上就写while (1)就行,写while (1024)的话其他同事看着不知道你这是什么名堂 */
}

while (true)
{
        /* true是bool常量,当然也表示成立,java转过来的程序员对这种写法应该更倍感亲切,因为java的死循环喜欢这样写 */
}

int i = 0;
int j = 1, sum = 0;
while (i < 10)
{
	sum += j;
	j++;
	/* 整个循环体中忘记了对循环条件做处理导致的死循环,这种bug在使用while结构且循环体比较长的时候可能发生 */
}

有一种常见的while循环的应用,叫做读循环,它是指循环地输入一些数据然后处理,一遍一遍地执行这样的操作:

int a, b, flag;
flag = scanf("%d%d", &a, &b);   /* 输入两个整数 */
while (flag == 1)
{
	printf("Summary is %d\n", a + b);   /* 打印两个数的和 */
	flag = scanf("%d%d", &a, &b);       /* 再输入两个数,循环上述步骤 */
}

/* 顺便提醒一句,编程需要谨慎认真,专心致志,==运算符一定要与=运算符区分好,下面这种是常见错误 */
while (flag = 1)   /* 这相当于把flag赋值为1了,而不是逻辑表达式 */
{
        /* 好的编译器在这里会报错 */
}

这只是读循环的一个小demo,一般输入语句存在于while之前和循环体的最后,不过在C语言的风格中,还有一种更简练的写法:

int a, b;                               /* flag直接省了 */
while (scanf("%d%d", &a, &b))           /* 这样用scanf是因为它被成功调用时会返回一个1,这里索性把==运算符也省了 */
{
	printf("Summary is %d\n", a + b);   /* 打印两个数的和 */
}

ACMer或者参加过程序设计大赛、算法比赛和认证的人可能对上面这种很大神的操作很熟悉,那是对付OJ系统上的输入类的题的一种技巧

3、while的应用

说到while的常见使用,我首先能想起的是人性化输入纠错(自己安的名字):

char sex;
scanf("%c", &sex);                 /* 输入性别,只能是字符m或f */
while (sex != 'm' && sex != 'f')   /* 只要输入的不是m和f,就重来 */
{
	printf("Wrong character, input again:\n");
	scanf("%c", &sex);
}
/* 另外常见的还有必须输入正数,必须输入数字,必须输入字母,必须是某几种枚举,为的是保证输入数据符合后面的程序处理 */

还有一种很常见应用就是与指针的配合了,比如链表的遍历:

cur = head->next;   /* p指向带头结点的链表的第一个结点 */
while (cur)         /* 这里其实应该写为cur != NULL */
{
	printf("%d\t", cur->value);
	cur = cur->next;
}
/*
	因为在一个链表中,尾结点的next指针一般是NULL的,而NULL可以作为不成立的逻辑表达式,与false和0效果一样
	所以上述程序的效果就是,cur指针按序指向每个结点,当遍历完最后一个结点后,cur=cur->next=NULL
	回到while头的循环条件判断时则会不成立,由此跳出了循环,所以最后一条语句一定要有,否则会死循环
*/

当然,多线程中也常见while,而且是死循环的while(死循环一般很少用do-while循环和for循环):

/* 常规操作:while(1) */
while (1)   /* 报时器 */
{
	Sleep(1000);   /* 线程休眠1s */
	char* time;
	getSystemTime(time);
	printf("Current time : %s\n");   /* 打印当前时间 */
}

/* 非主流操作:for(;;) */
for(;;)
{
	Sleep(1000);   /* 线程休眠1s */
	char* time;
	getSystemTime(time);
	printf("Current time : %s\n");   /* 打印当前时间 */
}

/* 魔鬼般的操作:do-while */
do{
	Sleep(1000);   /* 线程休眠1s */
	char* time;
	getSystemTime(time);
	printf("Current time : %s\n");   /* 打印当前时间 */
}
while (1)

——参考《C Primer Plus第五版》

相关文章:

C语言关键字浅析-for

C语言关键字浅析-do

C语言关键字浅析-break

C语言关键字浅析-continue

猜你喜欢

转载自blog.csdn.net/Johan_Joe_King/article/details/84325038