嫌弃前文内容多:请直接看总结!

一,问题提出

情形一:
1,代码:利用数组循环输入 10 个数字,输出打印 10 个数字

#include <stdio.h>
int main( )
{
   int i;
   int c[10];

   for(i=0;i<10;i++){
	   //c[i] = getchar();
	  // fflush(stdin);
	   scanf("%d", &c[i]);
	   
   }

   for(i=0;i<10;i++){
	   printf("%d", c[i]);
   }

   return 0;
}

2,运行结果:结果显示正确

循环实现1到10数字输出mysql 循环输入10个数_循环实现1到10数字输出mysql

情形二:
1,代码:利用字符数组循环输入 10 个字符,输出打印 10 个字符

#include <stdio.h>
 
int main( )
{
   int i;
   //int c[10];
   char c[10];
	
   printf("输入:\n");
   for(i=0;i<10;i++){
	   //c[i] = getchar();
	  // fflush(stdin);
	  // scanf("%d", &c[i]);
	   scanf("%c", &c[i]);
	   
   }
   printf("\n输出:\n");

   for(i=0;i<10;i++){
	   printf("%c", c[i]);
   }

   return 0;
}

2,运行结果:结果显示错误

循环实现1到10数字输出mysql 循环输入10个数_缓存_02

二者情形对比结果分析:

情形一的结果是符合预期的,即输入 10 个数字,然后打印 10 个数字;
情形二的结果是不符合的,即输入 5 个字符后,就直接输出,后续的第 6 个字符,第 7 个字符无法输入。

情形二的解决办法:

1,代码:在 scanf() 函数后面增加一行代码 fflush(stdin),即

scanf("%c", &c[i]);
	   fflush(stdin);

2,结果:此时可以发现可以得到正确结果

循环实现1到10数字输出mysql 循环输入10个数_循环实现1到10数字输出mysql_03


问题提出:

这里就提出一个问题,为什么情形一不需要加 fflush 就可以正确运行,而情形二却需要添加这一行代码。

答案就是:缓冲区的概念。

二,问题解决

1,首先理解缓冲区概念:
定义: 缓冲区又称为缓存,它是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。
类型: 缓冲区分为三种:

  • 全缓冲:例如文件读写,即缓冲区满了才写入文件
  • 行缓冲:例如本题的 scanf 标准输入输出操作,当按下 Enter 时候就输出
  • 不缓冲:这里 stderr 出错信息,直接输出。

2,本题解释:
本题情形二中,
第一次输入: 当输入一个字符,比如 ’a’,
缓存情况:只有一个字符 ‘a’

a

第二次输入: 要想进行输入 ‘b’ ,由于是行缓存的类型,所以必须按下 Enter 键才可以进行下一次输入 ’b’,
按下 ‘Enter’ 缓存情况:字符 ’a’ 出缓存,Enter 继续保留在缓存中

\n

第三次输入: 这时才轮到输入 ‘b’,
缓存情况:这时有上一次缓冲区保留的 Enter,还有本次输入的 ‘b’

\n b

此时要想输入 ‘c’,也就回到了第二次的输入情况

总结

情形二的数组元素的输入情况是:

地址

0

1

2

3

4

5

6

7

8

9

内容

a

\n

b

\n

c

\n

d

\n

e

\n

而用了flush之后就直接清理了了缓存, \n 被清除。注意是这里是清除,而不是输出。二者的区别在于清除指的是: \n 消失了,输出指的是:\n 被输出到数组中去。用了 flush 之后便有了正确的情况:

地址

0

1

2

3

4

5

6

7

8

9

内容

a

b

c

d

e

补充:

如果你要想知道为什么情形一是正确的,那么可以告诉你的是,因为情形一是数字数组,不会读取 \n 字符。