关键字、标识符、注释、数据、数据类型、常量、变量、printf、
关键字及分类
标识符
注释
数据及数据类型
常量的概述及分类
变量
printf函数
scanf函数
关键字及分类
-
关键字的基本概念
- 关键字就是已被C语言本身使用,不能作其它用途使用的字
- 例如关键字不能用作变量名、函数名等
- C语言中一个有32个关键字
-
数据类型关键字
-
基本数据类型(5个)
- void: 声明函数无返回值或无参数,声明无类型指针,显式丢弃运算结果
- char:字符型类型数据,属于整型 数据的一种
- int: 整型数据,通常为编译器指定的机器字长
- float:单精度浮点型数据,属于浮点数据的一种
- double:双精度浮点型数据,属于浮点数据的一种
-
类型修饰关键字(4个)
- short:修饰int,短整型数据,可省略被修饰的int
- long:修饰int,长整型数据,可省略被修饰的int
- signed:修饰整型数据,有符号数据类型
- unsigned:修饰整型数据,无符号数据类型
-
复杂类型关键字(5个)
- struct : 结构体声明
- union : 共用体声明
- enum : 枚举声明
- typedef : 声明类型别名
- sizeof : 得到特定类型或特定类型变量的大小
-
存储级别关键字(6个)
- auto : 指定为自动变量,由编译器自动分配及释放。通常在栈上分配
- static : 指定为静态变量,分配在静态变量区,修饰函数时,指定函数作用域为文件内部
- register : 指定为寄存器变量,建议编译器将变量存储到寄存器中使用,也可以修饰函数行参,建议编译器通过寄存器而不是堆栈传递参数
- extern : 指定对应变量为外部变量,即表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义
- const : 与volatile合称"cv特性",指定变量不可被当前线程/进程改变(但有可能被系统或其他线程/进程改变)
- volatile : 与const合称"cv特性",指定变量的值有可能会被系统或其他进程/线程改变,强制编译器每次从内存中取得该变量的值
-
-
流程控制关键字
-
跳转结构(4个)
- return : 用在函数体中,返回特定值(或者是void值,即不返回值)
- continue : 结束当前循环,开始下一轮循环
- break : 跳出当前循环或switch结构
- goto : 无条件跳转语句
-
分支结构(5个)
- if : 条件语句,后面不需要放分号
- else : 条件语句否定分支(与if连用)
- switch : 开关语句(多重分支语句)
- case : 开关语句中的分支标记
- default : 开关语句中的"其它"分支,可选
-
循环结构(3个)
- for : for循环结构,for(1; 2; 3) 4;的执行顺序为1 -> 2 -> 4 -> 3 -> 2...循环,其中2为循环条件。在整个for循环过程中,表达式1只计算一次,表达式2和表达式3则可能计算多次,也可能一次也不计算。循环体可能多次执行,也可能一次都不执行
- do : do循环结构,do 1 while(2);的执行顺序是1 -> 2 -> 1...循环,2为循环条件
- while : while循环结构,while(1) 2;的执行顺序是1 -> 2 ->1...循环,1为循环条件以上循环语句,当循环条件表达式为真则继续循环,为假则跳出循环
-
标识符
-
标识符概念及其命名原则
-
标识符
- 在C语言中,符号常亮、变量、数据、函数等都需要一定的名称,我们把这种名称成为标识符
- 标识符划分:关键字、预定义标识符和用户标识符
-
标识符命名原则
- 命名规则:
- 只能由字母、数字、下划线或者美元符号($)组成
- 不能以数字开头
- 不能与关键字重名
- 严格区分大小写
int abcd; // abcd 就是一个标识符 int _a$b; // _a$b 就是一个标识符 int 8a; // 不能以数字开头 int int; // 标识符不能与关键字同名 int ABCD; // ABCD是一个合法的标识符(标识符严格区分大小写) int _; // 下划线是一个合法的标识符
- 命名规则:
-
-
标识符命名的规范
-
命名规范
- 起一个有意义的名字(能够提高代码的可读性)
- 驼峰命名
- 如:userName、userLoginFlag
- 注解:
- 驼峰命名法是电脑程序编写时的一套命名规范(惯例)。为了自己的代码能更容易的在同行之间交流,所以才取统一的可读性比较好的命名方式。例如:有些程序员喜欢全部小写,有些程序员喜欢用下划线,所以如果要写一个my name的变量,他们常用的写法会有myname、my_name、MyName或者myName。这样的命名规则不适合所有的程序员阅读,而利用驼峰命名法来表示,可以增加程序可读性。
- 驼峰命名法就是当变量名或者函数名是由一个或多个单词连接在一起,而构成的唯一标识符时,第一个单词以小写字母开始,第二个单词的首字母大写;或每一个单词的首字母都采用大写字母,例如:myFirstName、myLastName,这样的变量名看上去就像驼峰一样此起彼伏,故得名。
- 驼峰命名法一词来自Perl语言中普遍使用的大小写混合格式,而Larry Wall等人所著的畅销书《Programming Perl》(0';Reilly出版)的封面图片正是一匹骆驼。驼峰命名法规范可视为一种惯例,并无绝对与强制,为的是增加识别和可读性。
-
标识符命名规范详述
-
命名应当直观且可以拼读,要望文知意,便于记忆和阅读
- 标识符最好采用英文单词组成或其组合。不允许使用拼音。程序中的英文单词一般不要太复杂,用词应当准确。
-
命名的长度应当符合“min-length && max-information”原则
- C是一种简洁的语言,命名也应该是简洁的。例如变量名MaxVal就比MaxValueUntilOverflow好用。标识符的长度一般不要过长,较长的单词可通过去掉“元音”形成缩写。
-
另外,英文词尽量不要缩写,特别是非常常用的专业名词,如果有缩写,在同一系统中对同一单词必须使用相同的表示法,并且注明其意思。
-
大多数ANSI编译程序允许有至多31个有效字符。也就是说,只有变量名或者函数的前31个字符的唯一性会被检查,其余的字符将被忽略掉。
- 比如
PrintOutAllTheClientsMonthEndReports(); prt_rpts();
- 比如
-
当标识符由多个词组成时,建议采用"驼峰命名法"
- 比如:int CurrentVal;这样的名字看起来比较清晰,远比一长串字符串好得多
-
尽量避免名字中出现数字编号,如Value1,Value2等,除非逻辑上的钱需要编号
- 比如驱动开发时为管脚命名,非编号名字反而不好。
-
对在多个文件之间共同使用的全局变量或者函数要加范围限定符
- 建议使用模块名(缩写)作为范围限定符。(GUI_,etc)标识符的命名规则;
-
标识符名分为两部分:规范标识符前缀(后缀) + 含义标识。
- 非全局变量可以不用使用范围限定符前缀
-
-
注释
-
C语言中的注释介绍
-
使用注释的目的和应用场景
- 注释是对代码的解释说明,是写给程序员看的,方便程序员之间交流
- 应用场景
- 常见用法一(解释代码)
// 这是主函数 int main() { // 打印语句 printf("Hello, World!\n"); // 返回结果 return 0; }
- 常见用法二(做函数说明)
/* 主函数是一个程序的入口 该函数是由系统调用 返回值为int */ int main(){return 0;}
- 常见用法三(做思路分析)
int sum(int a, int b) { /* 可书写实现该函数的思路 balabalabala... */ return a + b; }
- 常见用法一(解释代码)
-
使用注释的特点
- 注释是不参与编译,编译器遇到注释就跳过
-
-
C语言中的注释使用
-
单行注释
- // 进行单行注释(快捷键:Command + /)
-
多行注释
- /* */ 进行多行注释
-
注释使用
- 从代码中找到自己想要的功能
- 调试bug
-
注释的使用注意
- 单行注释只有一行是注释,并且两个斜杆后面才是注释内容
- command + / 可以增加或者取消单行注释
- 多行注释是可以嵌套单行注释的
- 单行注释是可以嵌套多行注释的,多行注释必须写到一行里面(无意义)
- 多行注释不可以嵌套多行注释
-
数据及数据类型
-
为什么要有数据类型
- 什么是数据
-
生活中时时刻刻都在跟数据打交道,比如体重数据、血压数据、股价数据等。在我们使用计算机的过程中,会接触到各种各样的数据,有文档数据、图片数据、视频数据,还有聊QQ时产生的文字数据,用迅雷下载的文件数据等。
-
数据的计量单位
- 计量单位
- 1B(Byte字节) = 8 bit(位)
- 1 KB(KByte) = 1024B
- 1 MB = 1024 KB
- 1 GB = 1024 MB
- 1 TB = 1024 GB
- 计量单位
-
数据为什么有类型
- 数据类型是指数据以何种方式存储在内存中,不同的类型存储方式不一样
-
- 什么是数据
-
C语言数据类型概述
-
C语言中有5大数据类型:
- 基本类型、构造类型、指针类型、空类型、定义类型
- 常见的数据类型有:int、float、double、char
-
C中常用的数据类型
- 基本类型
- 整型:用于准确的表示整数,根据表示范围的不同分为以下三种
- 短整型short
- 整型int
- 长整型long
- 字符型char:用来描述单个字符
- 实型:用于表示实数(小数)根据范围和精度不同分为以下两种
- 单精度型float
- 双精度型double
- 构造类型
- 数组
- 结构体struct
- 共用型union
- 枚举类型enun
- 指针类型
- 空类型void
- 定义类型typedef
- 整型:用于准确的表示整数,根据表示范围的不同分为以下三种
- 基本类型
-
-
数据类型的内存占用及范围
- 不同的数据类型占用不同的存储空间
First Header | 16位编译器 | 32位编译器 | 64位编译器 |
---|---|---|---|
char | 1 | 1 | 1 |
int | 2 | 4 | 4 |
float | 4 | 4 | 4 |
double | 8 | 8 | 8 |
short | 2 | 2 | 2 |
long | 4 | 4 | 8 |
long long | 8 | 8 | 8 |
void *(指针变量) | 2 | 4 | 8 |
- 不同数据类型表示的范围
关键字 | 所占字节数 | 数的表示范围 |
---|---|---|
int | 4 | -2^31 ~ 2^31 - 1 |
[signed] short [int] | 2 | -2^15 ~ 2^15 - 1 |
[signed] long [int] | 4 | -2^31 ~ 2^31 - 1 |
unsigned int | 4 | 0 ~ 2^32 - 1 |
unsigned short [int] | 2 | 0 ~ 2^16 - 1 |
unsigned long [int] | 4 | 0 ~ 2^32 - 1 |
关键字 | 所占字节数 | 数的表示范围 | 精确表示的数字个数 |
---|---|---|---|
float | 4 | 绝对值E-37 ~ E+38 | 7 ~ 8 |
double | 8 | 绝对值E-307 ~ E+308 | 16 ~ 17 |
常量的概述及分类
-
常量概述
- 生活中的常量
- RMB面值
- C语言中的常量
- C语言中有丰富的数据类型,在开发中,一般用常量或者变量来表示这些数据
- "量"表示数据。常量,则表示一些固定的数据,也就是不能改变的数据
- 生活中的常量
-
常量分类
总的来说,常量有以下几种类别- 整型常量,也就是整常量
- 二进制
- 十进制
- 八进制
- 十六进制
- 实型常量
- 单精度
- 双精度
- 字符型常量
- 普通字符
- 转义字符
- 字符串常量,注意字符串常量和字符型常量是不一样的。
- 整型常量,也就是整常量
变量
- 变量的概念及定义
-
变量的基本概念
- 什么是变量
- 所谓变量,它代表内存的某个空间,它的取值可以变的,是数据的基本单元。变量由两要素构成:变量名与变量类型。
- 程序运行过程中,它的值可以改变的数据,代表着一个存储空间,需要用变量名来找到这个数据
- 变量分为全局变量和局部变量。全局变量定义在函数外部,程序开始到结束一直都在,而局部变量定义在函数内部,只能供函数使用,在函数内部有效;
- 什么是变量
-
变量的定义
- 变量使用的步骤
- 定义(声明)
- 格式1:变量类型 变量名称; // 定义一个变量
int a; // 定义了一个int类型(占用4个字节)的变量,变量名是a float b; // 定义了一个float类型的变量,变量名是b char ch; // 定义了一个char类型的变量,变量名是ch
- 格式2:变量类型 变量名称1,变量名称2; // 表示定义了两个相同类型的变量。如果定义多个变量,每个变量中间使用","分割,但是最后一个变量之后不需要加逗号
int a,b; // 同时定义了两个int类型的变量,变量名分别为a,b
- 格式1:变量类型 变量名称; // 定义一个变量
- 定义(声明)
- 变量使用的步骤
-
变量命名的规范:
1.严格的遵守标识符的命名原则
2.变量名要尽可能的望文知意,简洁
3.变量名要按照驼峰命名法(遵从命名规范)
- 变量的初始化和引用
- 变量的初始化
-
定义的同时进行初始化
int a = 10; int a,b = 10; // 部分初始化 int a = 4, b = 2;
-
先定义,后初始化
int a; a = 10;
-
使用一个变量进行初始化
int a; int b = 10; a = b; // 使用b去初始化a
-
还可以批量的进行初始化
int a,b,c; a = b =c = 0;
-
- 变量的初始化
// 不会报错,但是a存储的数据是不确定性的。有可能是:
// 1.随机数
// 2.上次程序分配的存储空间存的数据
// 3.系统正在用的一些数据
int a;
注意
变量的第一次赋值被称为初始化,以后再赋值相当于覆盖了上一次的值
-
变量的使用
- 进行赋值,赋值是要使用"=",把等号右侧的值放到等号左侧的变量中
int a; int b = 10; // 把b的值赋值给a a = b;
- 进行赋值,赋值是要使用"=",把等号右侧的值放到等号左侧的变量中
-
变量的操作:运算、判断...
-
注意
1.赋值的时候,=号的左侧必须是变量(10 = b是错误的)
2.规范:习惯将 = 的两侧各加上一个空格
- 变量的作用域
-
C语言中所有的变量都有自己的作用域,声明变量的类型不同,其作用域也不同。C语言中的变量,按照作用域的范围可分为两种,即局部变量和全局变量。
-
局部变量
- 局部变量也称为内部变量。局部变量是在函数内或者代码块内作定义说明的。其作用域仅限于函数内,离开该函数后再使用这种变量是非法的。
int main(int argc, const char * argv[]) { // 定义局部变量 // 注意 age 和 age1 都是局部变量 int age; printf("a= %d\n", age); // age = 0 // 代码块 { // 定义了另外一个局部变量 age1 值是10 int age1 = 10; printf("age1 = %d\n", age1); // age1 = 10 // age = 100 访问代码块外部的age age = 100; printf("age = %d\n", age); // age = 100 // 在代码块内部可以定义和代码块外部同名的变量 int age = 1; printf("age = %d\n", age); // age = 1 } // 代码块结束 // age1已经释放了 // printf("age1 = %d\n", age1); printf("age = %d\n", age); // age = 100 return 0; }
- 局部变量也称为内部变量。局部变量是在函数内或者代码块内作定义说明的。其作用域仅限于函数内,离开该函数后再使用这种变量是非法的。
-
全局变量
- 全局变量也称为外部变量,它是在函数外部定义的变量。
// 定义一个全局变量 float score = 59.9f; int main(int argc, const char * argv[]) { printf("main:score = %f\n", score); // main:score = 59.9 // 调用test函数 void test(); test(); return 0; } void test() { printf("test:score = %f\n", score); // test:score = 59.9 }
- 全局变量也称为外部变量,它是在函数外部定义的变量。
-
关于局部变量的作用域说明
1.主函数中定义的变量也只能在主函数中使用,不能在其它函数中使用。同时,主函数中也不能使用其它函数中定义的变量。以为主函数也是一个函数,它与其它函数是平行关系。
2.形参变量是属于被调函数的局部变量,实参变量是属于主调函数的局部变量
3.允许在不同的函数中使用相同的变量名,它们代表不同的对象,分配不同的单元,互不干扰,也不会发生混淆。虽然允许在不同的函数中使用相同的变量名,但是为了程序明了易懂,不提倡在不同的函数中使用相同的变量名。
printf函数介绍及常见用法
-
printf函数介绍及常见用法
-
printf函数介绍
- printf函数是一个标准库函数,能够以精确的格式输出程序运算的结果
- printf函数的调用格式为:
- printf("格式控制字符串", 输出项列表); 如:printf("%d, %d", a, b);
- 格式字符串
- 是由格式字符(包括:转换说明符、标志、域宽、精度)和普通字符组成。转换说明符和百分号(%)一起使用,用来说明输出数据的数据类型、标志、长度和精度。
- 输出项列表
- 可以是常量、变量和表达式,也可以没有输出项,这些输出项必须与格式控制字符串在类型和数量上完全对应,否则,结果将不可预测。当有多个输出项时,各个输出项之间用逗号","分割。
-
格式控制符使用说明
- printf格式控制的完整格式:
- % - 0 m n l或h 格式字符串
- 下面对组成格式说明的各项加以说明:
- %:表示格式声明的起始符号,不可缺少
- -:有-表示左对齐输出(右侧补空格),如省略表示右对齐(左侧补空格)
- 0:有0表示指定空位填0,如省略表示指定空位不填
- m.n:m指域宽,即对应的输出项在输出设备上所占的字符数。N指精度,用于说明输出的实型数的小数位。
- l或h:l对整型指long型,对实型指double型。h用于将整型的格式字符修正为short型
- printf格式控制的完整格式:
-
-
%f输出精度问题
-
关于实型的精度问题
-
对于单精度数,使用%f格式符输出时,仅前7位是有效数字,小数6位。
-
对于双精度数,使用%lf格式符输出时,前16位是有效数字,小数6位。
-
有效数字的位数与指定输出的小数位数(%.7f)是两码事
-
有效数位为7:是指此数据从第一个非零数字开始,误差不超过本数位半个单位的、精度可信的数位7位(包括小数点前的非零数位)。
-
%.7f:是指输出此数据的时候,小数点之后要显示7位数字(但是如果小数点前还有一些非零数位,那么小数点后的这7位并不能保证都是精确可信的有效数位)
int main(int argc, const char * argv[]) { float a = 11111.111111f; float b = 22222.222222f; float c = a + b; // c = 33333.335938 // 有效数字是7位(不含小数点) printf("c = %f\n", c); return 0; }
int main(int argc, const char * argv[]) { float a = 1.1111111f; float b = 2.2222222f; float c = a + b; // c = 3.333333 // 有效数字7位,小数点后6位 printf("c = %f\n", c); return 0; }
int main(int argc, const char * argv[]) { float a = 1.1111111f; flfoat b = 2.2222222f; float c = a + b; // c = 3.33333302 // 有效数位是7位,小数点后6位有效 printf("c = %10.8f", c); return 0; }
int main(int argc, const char * argv[]) { float a = 11111.111f; float b = 22222.222f; float c = a + b; // c = 33333.33593750 // 7位有效数字,小数点后8位 printf("c = %10.8f\n", c); return 0; }
-
-
-
printf函数使用注意事项
-
域宽问题
- %d:按整型数据的实际长度输出
- 关于整数数据打印的时候域宽的问题
- %md:m域宽,打印出来以后,在控制器上,显示m位
- 如果我们要打印的数的位数大于我们设定m则原样输出
- 如果我们要打印的数的位数小于我们设定的位数,则补空白,具体如下:
- 如果m位正数,则左对齐(左侧补空白)
- 如果m位负数,则右对齐(右侧补空白)
int main(int argc, const char * argv[]) { printf("%d", 10); // 10 printf("%3d\n", 1889); // 原样输出 printf("%5d", 1889); // 1个空格+1889 printf("%-5d", 1889); // 1889+1个空格 return 0; }
-
%0md使用注意
- %0md表示不足部分补零
int main(int argc, const char * argv[]) { printf("%02d", 1); // 01 return 0; }
-
转义字符
- \n:换行
- \t:制表符
- \:\
- %%:%
- ":"
- ':'
-
scanf函数
- scanf函数介绍及使用
-
scanf函数(阻塞式函数)
-
scanf函数原型包含在标准输入输出头文件"stdio.h"中,用于接收键盘输入的内容。
-
格式:scanf("格式控制字符串", 输入项列表地址);
-
格式控制字符串:
- 规定数据输入的格式,由格式控制符和普通的字符组成,格式控制符和百分号(%)一起使用,用来说明输入数据的数据类型(格式字符)。
-
输入项地址列表:
- 需要接收数据的变量地址,这些输入项与格式控制字符串在类型和数量上要对应,当有多个输入项时,各个地址之间以逗号","分割,输入项和变量类型要保持一致。
-
另外:在C语言中,一个变量的地址可以通过地址运算符&得到。例如:定义int a, b;则a,b的地址位&a,&b。
-
-
scanf函数格式控制符
- 常见的格式控制符
- 常见使用方法:
-
获取输入单个整型、实数型数据
int main(int argc, const char * argv[]) { // 从键盘上接收一个人的年龄,然后打印出来 // 获取变量的地址:用地址符号& // 定义变量 int age = -1; // 给一个提示,让用户输入一个年龄 printf("请输入年龄:\n"); // 把用户输入的值,放到age变量中 // 如果输入的是小数,此时age只保存整数部分 scanf("您输入的年龄是:%d", %age); // 打印用户输入的年龄 printf("%d", age); return 0; }
int main(int argc, const char * argv[]) { float score = 0.0f; // 此处不允许写%m.nf // 允许指定域宽(%mf) scanf("%f", &score); printf("%f", score); }
-
-
格式 意义 d 输入一个十进制整数 o 输入一个八进制整数 x 输入一个十六进制整数 i 输入一个有符号或无符号的十进制、八进制、十六进制整数 u 输入一个无符号十进制整数 f、e或E、g或者G 输入一个小数形式或者指数形式的浮点数 c 输入一个字符 s 输入一个字符串 常见的格式控制符表
-
scanf使用注意事项
- 注意:
- 如果在输入时,输入了多个空格、回车、Tab都会被系统忽略的。
- 如果要获取的内容是多个整数,中间输入了多个空格、回车、Tab都会被系统忽略。
int main(int argc, const char * argv[]) { // scanf的注意事项 // scanf函数当遇到回车的时候,会结束执行 // 接收单个变量值的时候,在输入值之前,如果我们输入了空格、回车、Tab都会被忽略 int age, num; // %d%d 要求我们在键盘输入的两个整数,并且以空格或者回车隔开 // 输入完第一个值后,如果中间天津了回车、空格、Tab都会被忽略 scanf("%d%d", %age, %num); printf("age = %d, num = %d\n", age, num); return 0; }
// 混合输入问题 int main(int argc, const char * argv[]) { int a = -1, b = -1; char ch; scanf("%d%c%d", &a, &ch, &b); // 12 a 45 printf("%d, %c, %d\n", a, ch, b); // 理想:12, a, 45 实际:12, , -1 return 0; }
-
scanf中的修饰符
scanf函数的修饰符有:数据读入宽度(域宽)、*和长度。 -
关于域宽
- 可以用一个十进制数指定输入数据的数据宽度,系统自动按域宽截取输入数据
int main(int argc, const char * argv[]) { int a; scanf("%5d", &a); // 只读取5位 printf("%d\n", a); return 0; }
-
关于"*"
- 表示按指定格式读入数据但不赋予相应的变量,作用是跳过相应的读入数据
- 思考:如何获取2014-8-30日期中的年份、月份、日
int main(int argc, const char * argv[]) { int a, b, c; // scanf("%d-%d-%d", &a, &b, &c); // 2018/05/20 会出错 scanf("%d%*c%d%*c%d", &a, &b, &c); // %*c 忽略一个字符 printf("%d, %d, %d\n", a, b, c); return 0; }
- %*d跳过一个整数
int main(int argc, const char * argv[]) { int a, b; a = b = -1; scanf("%d%*d%d", &a, &b); printf("a = %d, b = %d\n", a, b); return 0; }
- 表示按指定格式读入数据但不赋予相应的变量,作用是跳过相应的读入数据
-
关于使用"\n"的问题
- scanf中可以使用"\n",但是输入的时候需要原样输入。
int main(int argc, const char * argv[]) { int num = -1; scanf("%d\n", &num); printf("num = %d\n", num); return 0; }
- 注意:
标识符 | 意义 |
---|---|
域宽 | 指定输入数据的宽度 |
* | 跳过相应数据不作处理 |
l或h | 读入长整型、双精度或者短整型数据 |
- scanf函数原理
- 当用户输入内容后,用户输入的内容会被存放到scanf的输入缓冲区中。之后scanf函数会根据格式控制的字符要求,从输入缓冲区依次取内容。
- 如果从缓冲区取的内容和格式要求一致,则把值存放到变量中。
- 如果格式不一致,则不修改变量的值。
int main(int argc, const char * argv[]) { // 已知问题:整型和字符型混合输入 // %d%c%d格式有问题 // 12 a 45 -> 12, , -1 // 导致该问题的原因:输入缓冲区中存放了[12、空格、a、空格、45] // 将12赋值给了a,将空格赋值给了ch,在从缓冲区中取出a赋值给b // 格式不对,导致最后结果为:12, , -1 int a = -1, b = -1; char ch = 'a'; scanf("%d%c%d", &a, &ch, &b); printf("%d, %c, %d\n", a, ch, b); return 0; }
- 如果scanf缓冲区中还有内容,则不会提示我们输入。
int main(int argc, const char * argv[]) { int a = -1, b = -1; char ch = 'a'; // 如果缓冲区有内容,则不会提示我们再输入值 // 当输入23a45则直接打印23, a, 45 scanf("%d", &a); scanf("%c", &ch); scanf("%d", &b); printf("%d, %c, %d\n", a, ch, b); return 0; }