C语言流程控制
流程控制与C语言基础 程序由数据结构和算法构成,算法具有有穷性、可行性等特征。C程序包含顺序、分支和循环三种基本结构,通过控制语句实现流程控制。C语言通过标准库函数实现输入输出,采用缓冲区机制提高效率。输入输出函数如printf需严格匹配格式说明符,缓冲区类型包括全缓冲、行缓冲和无缓冲,影响数据交互时机。程序执行从main函数开始,C语句分为控制语句、函数调用等类型,复合语句用{}组织多条语句。
流程控制
算法(了解)
著名计算机科学家沃斯提出核心公式:
程序 = 数据结构 + 算法
- 数据结构:对数据的描述(如变量、数组、结构体等数据的存储形式)
- 算法:对解决问题的操作步骤的描述
算法的定义
广义上,为解决一个具体问题而设计的有限、可行的操作步骤集合,称为 “算法”。
示例:将大象放入冰箱的算法
- 打开冰箱门 → 2. 将大象放入冰箱 → 3. 关闭冰箱门
算法的五大核心特征
- 有穷性:包含有限的操作步骤,不能无限循环执行。
- 可行性:每一条指令都必须是计算机可执行的(如不能要求 “手动输入无限大的数”)。
- 确定性:每一条指令的含义明确,不会产生歧义(如 “将变量 a 赋值为一个大数” 属于歧义描述,未明确 “大数” 的范围)。
- 输入:算法至少可以有 0 个或多个输入(如累加求和算法可输入待求和的数字集合)。
- 输出:算法至少有 1 个或多个输出(如求和算法输出总和,排序算法输出有序序列)。
算法描述 - 流程图
流程图是直观描述算法步骤的图形化工具,核心元素包括:开始 / 结束框、处理框、判断框、流程线。
程序的三种基本结构(重点)
程序的三种基本结构包括顺序结构、分支结构(条件结构 / 选择结构)、循环结构(重复结构),所有复杂程序均可由这三种结构组合实现。
顺序结构
核心特点:各操作按书写顺序依次执行,无跳转、无判断,是程序的默认结构。
- 执行逻辑:执行完 A 操作后,必然执行 B 操作,不存在跳过或重复执行的情况。
分支结构
核心特点:根据条件是否成立,从一组或多组操作中选择其一执行。
单分支结构
- 执行逻辑:若条件P成立,执行A操作;若不成立,直接跳过A操作,分支结构结束。
双分支结构
- 执行逻辑:条件P成立时执行A操作,不成立时执行B操作;A、B操作必执行其一,执行后分支结构结束。
分支结构分类:
① 单分支(if 语句)
② 双分支(if-else 语句)
③ 多分支(if-else if-else、switch 语句)
循环结构
核心特点:在条件满足的情况下,反复执行某一段操作(循环体),分为两种类型。
当型循环
- 执行过程:先判断条件 P 是否成立 → 若成立,执行循环体 S → 再次判断条件 P → 重复上述步骤,直到 P 不成立,结束循环。
- 核心特点:先判断,后执行,循环体 S 可能一次都不执行。
- 代表语句:while 语句、for 语句
直到型循环
- 执行过程:先执行循环体 S → 判断条件 P 是否成立 → 若成立,再次执行 S → 重复上述步骤,直到 P 不成立,结束循环。
- 核心特点:先执行,后判断,循环体 S 最少执行一次。
- 代表语句:do-while 语句
C语句
定义
- C程序以函数为基本执行单元。
- 函数的执行部分由若干条C语句构成,每条语句完成特定操作。
- 所有C语句必须依赖函数存在(不能脱离函数单独编写)
C程序结构
- 补充说明:一个C程序可包含多个源文件,每个源文件可包含多个函数,但必须有且仅有一个main函数(程序入口)
C语句分类
1. 控制语句
- **作用:**控制程序的执行流程(顺序、分支、循环)
- **常用控制语句:**if-else、for、do-while、continue、break、switch、return、goto(已过时)
2. 函数调用语句
-
**构成:**函数调用 + 分号(
;)。 -
举例:
printf("这是函数调用语句"); // 标准库函数调用 test(); // 自定义函数调用
3. 表达式语句
-
**构成:**表达式 + 分号(
;),最常用的是赋值语句。 -
举例:
a = 3; // 表达式语句:赋值表达式 + ; score >= 90; // 表达式语句:关系表达式 + ; 无分号不是语句 a++; // 表达式语句:自增表达式语句
4. 空语句
-
**构成:**仅一个分号(
;),无实际操作 -
**用途:**作为循环体占位符、分支结构默认操作等
-
举例:
; // 空语句 for (;;){} // 循环条件为空,循环体可为空语句
5. 复合语句
-
**构成:**用大括号
{}括起来的若干条语句(可包含变量声明、执行语句) -
**特点:**在语法上视为一条语句,常用于循环体、分支体等需要多条语句的场景。
-
举例:
{ int z = x + y; // 变量声明 t = z / 100; // 表达式语句 printf("%f\n", t); // 函数调用语句 }
数据的输入与输出
- **输出(output):**计算机向外部设备(显示器,打印机等)输送数据。
- **输入(input):**外部设备(键盘,鼠标,扫描仪)向计算机输送数据。
注:C 语言本身无内置的输入输出语句,需通过标准输入输出库(
stdio.h)中的库函数实现(如printf、scanf),这类与硬件交互的操作称为 “外设 IO”。库函数的实现已编译为目标文件,链接阶段会与用户代码的目标文件合并,生成可执行程序。使用库函数前需通过
#include <stdio.h>引入头文件(头文件包含函数声明、宏定义等必要信息)。
输入输出缓冲机制
缓冲区的概念
- 缓冲区是内存中专门用于暂存输入/输出数据的区域,本质是"数据中转站"。
- 输入数据流向:外部设备 → 输入缓冲区 → 程序(比如变量或者数组等)
- 输出数据流向:程序 → 输出缓冲区 → 外部设备
缓冲区的三种类型
| 缓冲区类型 | 触发实际IO的条件 | 典型应用场景 |
|---|---|---|
| 全缓冲 | 缓冲区填满时 | 磁盘文件读写(windows默认4096字节,linux默认1024字节) |
| 行缓冲 | 遇到换行符(\n)或回车时 |
标准输入(stdin,键盘)、标准输出(stdout,显示器) |
| 无缓冲 | 无缓冲,直接IO | 标准错误流(stderr,错误信息输出) |
缓冲区的刷新条件(数据从缓冲区写入外部设备)
- 缓冲区填满(全缓冲触发)
- 遇到换行符
\n(行缓冲触发) - 手动调用
fflush()函数(如fflush(stdout)刷新输出缓冲区,fflush(stdin)行为未定义,不推荐使用)。 - 程序正常结束(进程退出时自动刷新所有缓冲区)
注意:
scanf()是从输入缓冲区 读取数据,而非 “刷新”:若缓冲区已有数据,直接读取;若为空则等待用户输入。fflush(stdin)(刷新输入缓冲区)的行为在 C 标准中是 未定义 的(不同编译器表现不同),不能依赖。
缓冲区的核心作用
- 提高效率:减少程序与外部设备的直接交互次数(IO操作耗时远高于内存操作)
- 平滑数据流:避免因设备读写速度不匹配导致的数据丢失或阻塞。
简单的输入与输出
用printf函数输出数据
基础用法
-
语法:
printf("格式化控制字符串", 输出列表); -
引入头文件:
#include <stdio.h> -
举例:
int i = 5; printf("i=%d, x=%d, y=%d\n", i, 34, i+1);// i=5,x=34,y=6 -
核心注意:格式控制字符串中格式化符(
%d)需与输出列表的变量/表达式类型、数量一一对应。
格式控制字符串的构成
- **格式说明符:**由
% + 特定字符组成,用于指定输出数据的类型和格式(如%d输出整型,printf中:%f(兼容float/double)、%lf(仅double,与%f等价)。scanf中:%f对应float,%lf对应double(必须匹配,否则数据错误)) - **普通字符:**直接原样输出的说明性文字、符号(如
i=、,、\n)
输出列表要求
- 可包含常量(字面量、符号常量、const变量)、变量、表达式。
- 输出列表的个数必须与格式说明符的个数一致。
常用格式化符
| 格式化符 | 数据类型 | 功能说明 | 示例 |
|---|---|---|---|
| %d | int(有符号整型) | 按十进制输出有符号整数 | printf ("% d", 123); // 输出 123 |
| %u | unsigned int(无符号整型) | 按十进制输出无符号整数 | printf ("% u", 123); // 输出 123 |
| %c | char(字符型) | 输出单个字符 | printf ("% c", 'A'); // 输出 A |
| %s | char [](字符串) | 输出字符串(以 ‘\0’ 结尾) | printf ("% s", "CHINA"); // 输出 CHINA |
| %f | float(单精度浮点型) | 以小数形式输出,默认保留 6 位小数 | printf ("% f", 3.14); // 输出 3.140000 |
| %lf | double(双精度浮点型) | 以小数形式输出双精度浮点数 | printf ("% lf", 3.1415926); // 输出 3.141593 |
| %e/%E | float/double | 以指数形式输出浮点数(% e 小写 e,% E 大写 E),小数点前 1 位非 0,保留 6 位小数 | printf ("% e", 123.45); // 输出 1.234500e+02 |
| %hd | short(短整型) | 输出短整型数据 | printf ("% hd", (short) 123); // 输出 123 |
| %hhd | char | 输出字符的 ASCII 码值 | printf ("% hhd", 'A'); // 输出 65 |
| %ld | long(长整型) | 输出长整型数据 | printf ("% ld", (long) 123456); // 输出 123456 |
| %lld | long long(长长整型) | 输出长长整型数据 | printf ("% lld", (long long) 123456789); // 输出 123456789 |
| %x/%X | int/unsigned int | 按十六进制输出(% x 小写字母,% X 大写字母),无前缀 | printf ("% x", 198); // 输出 c6 |
| %#x/%#X | int/unsigned int | 按十六进制输出,带前缀 0x(%#x)或 0X(%#X) | printf ("%#x", 198); // 输出 0xc6 |
| %o | int/unsigned int | 按八进制输出,无前缀 0 | printf ("% o", 5); // 输出 5 |
| %#o | int/unsigned int | 按八进制输出,带前缀 0 | printf ("%#o", 5); // 输出 05 |
| %p | 指针类型 | 输出指针变量对应的内存地址(十六进制,带前缀 0x) | int a=10; printf ("% p", &a); // 输出 0x7ffeefbff5fc(示例地址) |
| %% | - | 输出百分号 % 本身 | printf ("%%"); // 输出 % |
示例:格式化符综合使用
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("%x,%#x\n", 255, 255); // 输出:ff,0xff(十六进制)
printf("%o,%#o\n", 255, 255); // 输出:377,0377(八进制)
printf("%d,%u,%c\n", 5, 5, '%'); // 输出:5,5,%(整型、无符号整型、字符)
printf("%%\n"); // 输出:%(百分号本身)
printf("%f,%lf,%e\n", 99.12345f, 99.12345, 99.12345); // 输出:99.123450,99.123450,9.912345e+01
return 0;
}
用scanf函数输入数据
基础用法
-
语法:
scanf("格式控制字符串", 地址列表) -
引入头文件:
#include <stdio.h> -
举例:
int a; // 定义变量a,无需给初始值,因为我们可以通过scanf来初始化这个变量 scanf("%d",&a); // &是取地址运算符,&a表示变量的的内存首地址 -
**核心作用:**将键盘输入的数据存入地址列表指定的内存单元中。
核心注意事项
-
地址列表必须是内存地址,不能直接传变量、常量、表达式:
-
普通变量:通过
&变量名获取地址(如&a); -
字符串数组:数组名本身就是首地址,无需加
&,但需确保数组长度足够容纳输入字符串(含结束符\0),避免缓冲区溢出;示例:
char str[10]; scanf("%9s", str); // %9s 限制最多读取9个字符,预留1个位置存\0
-
-
格式控制字符串的规则:
- 格式说明符需与输入数据类型、地址列表顺序一一对应;
- 若格式控制字符串中包含普通字符(如逗号、短横线、文字),输入时必须在对应位置输入相同字符。
示例 1:输入多个整数
-
需求:从键盘输入3个整数,赋值给变量a,b,c,并输出。
-
代码:
#include <stdio.h> int main(int argc,char *argv[]) { int a, b, c; // 接收输入的变量,无需初始化,键盘输入会覆盖默认值 printf("请输入3个整数:\n"); scanf("%d%d%d", &a, &b, &c); // 多个格式符连续书写,scanf无需\n printf("a=%d,b=%d,c=%d\n", a, b, c); return 0; } -
输入分隔规则:多个数据可以通过
空格、Tab键、回车键任意一个进行分隔。
案例2:带普通字符的格式控制
-
代码示例:
// 格式控制包含逗号 scanf("%d,%d", &a, &b); // 输入格式:3,4 (必须使用逗号分隔) // 格式控制包含短横线 scanf("%d-%d-%d", &year, &month, &day); // 输入格式:2026-01-27 (必须用短横线分隔) // 格式控制包含文字 scanf("%d年%d月%d日", &year, &month, &day); // 输入格式:2026年01月27日 (必须用 年 月 日 分隔)
scanf输入的关键细节
-
%c格式输入字符的特殊处理:
-
%c会读取输入缓冲区中的所有字符(包括空格、Tab、\n),视为有效输入。 -
示例:
char a,b,c; scanf("%c%c%c", &a, &b, &c); // 输入:abc → 输出: a='a',b='b',c='c' (正常) // 输入:a b c → 输出:a='a',b=' ',c='b' (空格被视作第2个字符) -
解决方案:若需跳过空白字符,可在
%c前加空格,如scanf("%c %c %c", &a, &b, &c)
-
-
数值型数据的输入结束条件:
-
输入整型(
%d/%u等)、浮点型(%f/%lf等)时,遇到以下情况视为输入结束:- 非法字符(字母、符号
?等)
- 非法字符(字母、符号
-
示例:
int a, b, c; scanf("%d%d%d", &a, &b, &c); // 输入:1234m56 → a=1234(遇到`m`结束),b和c为随机值(未输入有效数据)
-
数据的输入与输出
复杂的输入与输出
复杂的输入输出要指:指定输出宽度、保留小数位数、对齐方式、进制转换等高级格式控制。
输出数据的格式精细化控制
-
整型数据的格式控制(%md,%mo,%mx等)
-
核心格式:
%[标志][宽度]类型(标志可选,宽度为非负整数m) -
常用标志:
-左对齐(默认右对齐)0不足宽度时用0填充(默认用空格填充)+强制显示正负号(正数显示+,负数显示-)
-
宽度m的规则:
- 若实际数据位数 < m:按对齐方式填充(空格或0)
- 若实际数据位数 > m:忽略宽度,按实际位数输出
格式符 功能说明 示例 输出结果 %6d右对齐,宽度 6,空格填充 printf(“%6d”, 12); " 12"(4 个空格 + 12) %-6d左对齐,宽度 6,空格填充 printf(“%-6d”, 12); "12 "(12+4 个空格) %06d右对齐,宽度 6,0 填充 printf(“%06d”, 12); “000012”(4 个 0+12) %+6d右对齐,宽度 6,显示正负号 printf(“%+6d”, 12); “+12”(3 个空格 ++12) %#06x十六进制,宽度 6,0 填充,带 0x 前缀 printf(“%#06x”, 12); “0x000c” %#06o八进制,宽度 6,0 填充,带 0 前缀 printf(“%#06o”, 12); “000014” -
案例代码:
#include <stdio.h> int main(int argc,char *argv[]) { printf("%d\n", 12); // 无宽度控制,“12” (实际列宽为2) printf("%6d\n",12); // 右对齐,宽度6,“ 12” (实际列宽为6) printf("%-6d\n",12); // 左对齐,宽度6,“12 ” (实际列宽为6) printf("%6d\n",1234567); // 实际列宽 > 6: “1234567”(列宽失效) printf("%06d\n",12); // 右对齐,宽度6,“000012” (实际列宽为6) printf("%+d,%+d\n",12,-12);// 无列宽控制,“+12,-12” printf("%#06x,%#06o\n",12,12); // 右对齐,列宽6,“0x000c,000014” return 0; }运行结果:
12 12 12 1234567 000012 +12,-12 0x000c,000014
-
-
字符型与字符串型数据的格式控制
① 字符型(%mc、%-mc)
-
格式规则与整型一致,m为输出宽度。
-
示例:
printf("%3c\n",'a'); // 右对齐,列宽3,“ a” printf("%-3c\n",'a'); // 左对齐,列宽3,“a ”
② 字符串型(%ms、%-ms、%m.ns、%-m.ns)
-
核心格式:
%[标志][宽度].[截取长度]s -
关键参数:
- m:输出总宽度
- n:截取字符串的前n个字符(若n > 字符串长度,取完整字符串)
-
标志规则:
-:左对齐(默认右对齐)- 无标志:不足宽度时用空格填充。
格式符 功能说明 示例 输出结果 %6s 右对齐,宽度 6 printf(“%6s”, “hello”); " hello"(1 个空格 + hello) %-6s 左对齐,宽度 6 printf(“%-6s”, “hello”); "hello "(hello+1 个空格) %7.2s 宽度 7,截取前 2 个字符,右对齐 printf(“%7.2s”, “CHINA”); " CH"(5 个空格 + CH) %-5.3s 宽度 5,截取前 3 个字符,左对齐 printf(“%-5.3s”, “CHINA”); "CHI "(CHI+2 个空格) %.4s 仅截取前 4 个字符,无宽度控制 printf(“%.4s”, “CHINA”); “CHIN” -
案例代码:
#include <stdio.h> int main(int argc,char *argv[]) { printf("%3s\n%7.2s\n%-5.3s\n%.4s\n","CHINA","CHINA","CHINA","CHINA");// CHINA, CH,CHI ,CHIN return 0; } -
运行结果:
CHINA CH CHI CHIN
-
-
浮点型数据的格式控制(%m.nf、%m.ne、%g/%G)
浮点型格式控制和兴时总宽度m和小数/尾数位n,分为三种形式。
格式类型 语法 核心说明 十进制形式 %[标志] m.nf/ %[标志]-m.nfm:总宽度(含整数部分、小数点、小数部分);
n:保留的小数位数(四舍五入)指数形式 %[标志] m.ne/ %[标志]-m.nem:总宽度;
n:保留的尾数位数(小数点后 n 位)自动适配形式 %g / %G自动选择 %f或%e中宽度较短的格式,同时去除无意义的末尾 0 和多余小数点;
示例:
printf(“%g\n”, 123.4500); // 输出123.45(去除末尾0)
printf(“%g\n”, 123.0000); // 输出123(去除小数点和末尾0) printf(“%G\n”, 123.45e2); // 输出12345(自动选择%f格式,避免指数形式)常用标志:
-(左对齐)、0(0 填充)、+(强制显示正负号)。宽度 m 的规则:若
整数部分位数 + 1(小数点) + n(小数位)> m,忽略 m,按实际宽度输出。案例代码:
#include <stdio.h> int main(int argc, char *argv[]) { float f = 123.456f; // 实际存储值约为123.456001(float精度限制) // %8.2f:右对齐,宽度8,保留2位小数(四舍五入)→ " 123.46" // %-8.2f:左对齐,宽度8,保留2位小数 → "123.46 " // %8.6f:保留6位小数,实际宽度>8 → "123.456001" // %9.2e:指数形式,宽度9,保留2位尾数 → " 1.23e+02" // %g:自动适配格式,去除末尾0 → "123.456" // %G:自动适配格式(与%g一致,仅指数部分为大写E)→ "123.456" printf("%8.2f\n%-8.2f\n%8.6f\n%9.2e\n%g\n%G\n", f, f, f, f, f, f); return 0; }运行结果:
123.46 123.46 123.456001 1.23e+02 // 1.23e2 先转指数,在处理保留位 123.456 123.456注意:浮点型数据的小数位保留采用
四舍五入规则,且受数据存储精度影响(如123.456f实际存储为123.456001)
案例:小数点对齐的浮点型输出
-
需求:计算 3 个圆的周长,按小数点对齐输出,保留 2 位小数。
-
代码:
#include <stdio.h> #define PI 3.14 // 定义圆周率常量 int main(int argc, char *argv[]) { double r1 = 1.53, r2 = 21.83, r3 = 123.71; double s1 = 2.0 * PI * r1; // 圆周长公式:2πr double s2 = 2.0 * PI * r2; double s3 = 2.0 * PI * r3; // %6.2f:宽度6,保留2位小数,右对齐 → 自动按小数点对齐 printf("%6.2f\n%6.2f\n%6.2f\n", s1, s2, s3); return 0; }
常见错误:格式符与数据类型不匹配
-
案例代码:
#include <stdio.h> int main() { double x = 34.567; printf("x=%f\n", x); // 正确:%f可输出double(兼容float)→ 34.567000 printf("x=%d\n", x); // 错误:%d(整型)与double(浮点型)不匹配 → 输出随机值(如27263) printf("x=%d\n", (int)x); // 正确:强制类型转换为int → 34 return 0; } -
运行结果:
x=34.567000 x=27263 x=34 -
结论:格式说明符必须与输出数据的类型严格匹配,否则会因类型转换异常导致输出错误。
输入数据格式控制【自学】
整型格式说明符
- 十进制形式(0~9)
| 说明符 | 说明 | 数据类型 |
|---|---|---|
| %d | 用于基本整型 | int |
| %ld | 用于长整型 | long |
| %u | 用于无符号基本整型 | unsigned int |
| %lu | 用于无符号长整型 | unsigned long |
- 八进制形式(0~7)
| 说明符 | 说明 | 数据类型 |
|---|---|---|
| %o | 用于基本整型 | int |
| %lo | 用于长整型 | long |
- 十六进制形式(0~F)
| 说明符 | 说明 | 数据类型 |
|---|---|---|
| %x | 用于基本整型 | int |
| %lx | 用于长整型 | long |
总结:
① 用于输入与输出整型数据的格式说明符完全一致。
② 与输出情形相同,八进制与十六进制的输入格式主要用于接收无符号整型数据。
浮点型格式说明符
| 说明符 | 说明 | 数据类型 |
|---|---|---|
| %f / %e | scanf输入单精度浮点型 |
float |
| %lf / %le | scanf输入双精度浮点型 |
double |
说明:
printf输出时,float和double均可使用%f/%e(double会自动提升精度);但scanf输入时,float必须用%f,double必须用%lf,否则会导致数据读取异常。
总结:
① 与输出不同,输入时无论是单精度还是双精度浮点型,均不能用m.n的形式指定输入宽度和小数点后保留的位数。
② 可指定输入数据所占列数,系统会自动截取对应长度的数据赋值给变量。例如:
scanf("%3d%3d",&a, &b);
输入测试数据:1234567
结果:a=123,b=456
解释:从输入数据1234567中,截取前 3 列(123)赋值给a,再截取后续 3 列(456)赋值给b,剩余的7被舍弃。
③ 若在%后添加*和数字,表示跳过指定列数的数据。例如:
scanf("%2d%*3d%3d",&a, &b);
输入测试数据:12345678
结果:a=12,b=678
解释:从输入数据12345678中,截取前 2 列(12)赋值给a,跳过中间 3 列(345),再截取后续 3 列(678)赋值给b。
案例:
#include <stdio.h>
int main(int argc,char *argv[])
{
int a, b;
printf("通过控制台输入一个数:\n");
// %3d:指定输入宽度为 3 列,截取输入内容的前 3 列字符转换为整数赋值给变量(属于scanf的宽度限定符核心用法)
scanf("%3d%3d",&a, &b);
printf("%d,%d\n",a,b);
printf("通过控制台输入一个数:\n");
// %2d:截取前2个字符;%*d:跳过任意长度的整数;%3d:截取后续3个字符
scanf("%2d%*d%3d",&a, &b);
printf("%d,%d\n",a,b);
return 0;
}
说明:
当整型输入的格式说明符未指定宽度时,输入数据的分隔规则如下:
① 若格式说明符之间无其他字符,输入数据可通过空格、Tab或回车分隔。
② 若格式说明符之间包含其他字符(如逗号、等号),输入时需输入相同字符作为间隔。
示例:定义变量int a,b; float c,d;,需输入a=12,b=78,c=12.5,d=7.6,不同输入语句对应的输入格式:
-
输入语句:
scanf("%d%d%f%f",&a,&b,&c,&d);输入格式:
12 78 12.5 7.6(可用空格、Tab 或回车分隔) -
输入语句:
scanf("%d,%d,%f,%f",&a,&b,&c,&d);输入格式:
12,78,12.5,7.6(需用逗号分隔) -
输入语句:
scanf("a=%d,b=%d,c=%f,d=%f",&a,&b,&c,&d);输入格式:
a=12,b=78,c=12.5,d=7.6(需输入完整非格式字符)
⚠️ 注意:实型输入的格式说明符中不能用m.n指定宽度和小数位数,例如scanf("%7.2f",&a);为错误用法。
输入缓冲区机制:
程序启动时,系统会开辟输入缓冲区暂存键盘输入的数据。执行输入函数时,先检查缓冲区是否有数据:若有则直接读取,若无则等待用户输入。
补充格式说明符
| 说明符 | 含义 | 示例 |
|---|---|---|
| %n | 统计已读取的字符个数 | scanf(“%d%n”, &num, &count); |
案例:
#include <stdio.h>
int main(int argc,char *argv[])
{
int num,count; // count:保存输入数据的字符个数(列宽)
printf("请输入一个数据:\n");
scanf("%d%n",&num,&count); // %d读取整数,%n统计本次scanf调用中已成功读取的字符个数(不包含未读取的缓冲区字符)
printf("num=%d,count=%d\n",num,count);
return 0;
}
更多推荐

所有评论(0)