ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

一、C语言——2. C语言数据类型和变量

一、C语言——2. C语言数据类型和变量 目录数据类型介绍signed 和 unsigned数据类型的取值范围变量算术操作符、-、*、/、%赋值操作符 和复合赋值单⽬操作符、–、、-强制类型转换scanf和printf介绍1. 数据类型介绍使⽤整型类型来描述整数使⽤字符类型来描述字符使⽤浮点型类型来描述小数。所谓“类型”就是相似的数据所拥有的共同特征编译器只有知道了数据的类型才知道怎么操作数据。1.1 字符型字符的英⽂单词是 character 在C语⾔中使用 char 表示字符类型。char //character [signed] char //有符号的 unsigned char //无符号的字符类型在存储时存的ASCLL码ASCLL值是整数所以字符类型是属于整数类型的.1.2 整型整数的英⽂单词是 integer 在C语⾔中使用 int 表⽰整型类型//整数 - integer //短整型 short [int] [signed] short [int] unsigned short [int] //整型 int [signed] int unsigned int //⻓整型 long [int] [signed] long [int] unsigned long [int] //更⻓的整型 //C99中引⼊ long long [int] [signed] long long [int] unsigned long long [int]1.3 浮点型float //单精度浮点型 double //双精度浮点型 long double1.4 布尔类型C 语⾔原来并没有为布尔值单独设置⼀个类型而是使用整数 0 表⽰假非零值表示真。在 C99 中也引⼊了布尔类型 是专门表示真假的。布尔类型的使用得包含头⽂件 stdbool.h布尔类型变量的取值是 true真或者 false假flag为真#include stdio.h #include stdbool.h int main() { _Bool flag true; if (flag) printf(I like C\n); }结果flag为假#includestdio.h#includestdbool.hintmain(){_Boolflagfalse;if(flag)printf(I like C\n);return0;}结果布尔类型一般用在 if 判断里_Bool可以简写成 bool 程序也能正常执行1.5 各种数据类型的长度每⼀种数据类型都有自己的⻓度使⽤不同的数据类型能够创建出⻓度不同的变量变量⻓度的不同存储的数据范围就有所差异。1.5.1 sizeof 操作符sizeof 是⼀个关键字也是操作符专门是⽤来计算 sizeof 的操作数的类型长度的单位是字节。sizeof 操作符的操作数可以是类型也可是变量或者表达式。sizeof( 类型 ) sizeof 表达式sizeof 的操作数如果不是类型是表达式的时候可以省略掉后边的括号的。sizeof 后边的表达式是不真实参与运算的根据表达式的类型来得出大小。sizeof 的计算结果是 size_t 类型的如果要打印在屏幕上需要使⽤%zu的占位符。sizeof 运算符的返回值C 语⾔只规定是⽆符号整数并没有规定具体的类型而是留给系统自己去决定 sizeof 到底返回什么类型。不同的系统中返回值的类型有可能是unsigned int 也有可能是 unsigned long 甚⾄是 unsigned long long 对应的 printf() 占位符分别是 %u 、 %lu 和 %llu 。这样不利于程序的可移植性。C 语⾔提供了⼀个解决⽅法创造了⼀个类型别名 size_t ⽤来统⼀表示 sizeof 的返回值类型。对应当前系统的 sizeof 的返回值类型可能是 unsigned int 也可能是unsigned long long 。size_t的返回值类型是%zu1.5.2 数据类型长度#include stdio.h int main() { printf(%zu\n, sizeof(char)); printf(%zu\n, sizeof(_Bool)); printf(%zu\n, sizeof(short)); printf(%zu\n, sizeof(int)); printf(%zu\n, sizeof(long)); printf(%zu\n, sizeof(long long)); printf(%zu\n, sizeof(float)); printf(%zu\n, sizeof(double)); printf(%zu\n, sizeof(long double)); return 0; }结果C语言规定sizeof(long) sizeof(int) sizeof(long double) sizeof(double) 所以sizeof(long)可能是4个字节也可能是8个字节sizeof(long double)可能是8个字节也可能是16个字节参考资料数据类型⻓度和取值范围一个汉字占两个字符空间1.5.3 sizeof 中表达式不计算#include stdio.h int main() { short s 12; int b 10; printf(%zu\n, sizeof(s b1)); printf(s %d\n, s); return 0; }结果sizeof 在代码进行编译的时候就根据表达式的结果 s 的类型推导并确定了类型的⻓度而表达式真要被执行却要在程序运行期间才会发生如果在编译期间已经被 sizeof 处理掉了那么在运行期间就不会执行表达式了。2. signed 和 unsignedC 语⾔使⽤ signed 和 unsigned 关键字修饰字符型和整型类型的。signed 关键字表⽰⼀个类型带有正负号包含负值unsigned 关键字表⽰该类型不带有正负号只能表示零和正整数。对于 int 类型默认是带有正负号的也就是说 int 等同于 signed int 。由于这是默认情况关键字 signed ⼀般都省略不写但是写了也不算错。int 类型也可以不带正负号只表⽰⾮负整数。这时就必须使⽤关键字 unsigned 声明变量。整数变量声明为 unsigned 的好处是同样长度的内存能够表示的最大整数值增大了⼀倍。⽐如16位的 signed short int 的取值范围是-32768~32767最⼤是32767⽽unsigned short int 的取值范围是0~65535最⼤值增⼤到了65535。32位的 signed int的取值范围可以参看 limits.h 中给出的定义。unsigned int ⾥⾯的 int 可以省略所以上⾯的变量声明也可以写成下⾯这样。unsigned a;字符类型 char 也可以设置 signed 和 unsigned 。注意C 语⾔规定 char 类型默认是否带有正负号由当前系统决定。这就是说 char 不等同于 signed char 它有可能是 signed char 也有可能是unsigned char 。这⼀点与 int 不同 int 就是等同于 signed int 。所以在使用char时有符号的要写signed char无符号的要写unsigned charpow函数 - x的y次方sqrt函数 - 开平方3. 数据类型的取值范围每⼀种数据类型有⾃⼰的取值范围也就是存储的数值的最⼤值和最⼩值的区间有了丰富的类型就可以在适当的场景下去选择适合的类型。如果要查看当前系统上不同数据类型的极限值limits.h ⽂件中说明了整型类型的取值范围。float.h 这个头⽂件中说明浮点型类型的取值范围。为了代码的可移植性需要知道某种整数类型的极限值时应该尽量使⽤这些常量。SCHAR_MIN SCHAR_MAX signed char 的最⼩值和最⼤值。SHRT_MIN SHRT_MAX short 的最⼩值和最⼤值。INT_MIN INT_MAX int 的最⼩值和最⼤值。LONG_MIN LONG_MAX long 的最⼩值和最⼤值。LLONG_MIN LLONG_MAX long long 的最⼩值和最⼤值。UCHAR_MAX unsigned char 的最⼤值。USHRT_MAX unsigned short 的最⼤值。UINT_MAX unsigned int 的最⼤值。ULONG_MAX unsigned long 的最⼤值。ULLONG_MAX unsigned long long 的最⼤值。4. 变量4.1 变量的创建类型是⽤来创建变量的。C语⾔中把经常变化的值称为变量不变的值称为常量。变量命名的⼀般规则只能由字⺟包括⼤写和⼩写、数字和下划线_组成。不能以数字开头。⻓度不能超过63个字符。变量名中区分⼤⼩写的。变量名不能使⽤关键字。变量的名字最好有意义变量在创建的时候就给⼀个初始值就叫初始化。在给float类型的变量赋值时要在赋的值后面加上一个 f。浮点型变量在赋值时默认是double类型的加 f 不属于强制类型转换属于一种语法格式。float weight 55.5f;4.2 变量的分类全局变量在⼤括号外部定义的变量就是全局变量全局变量的使⽤范围更⼴整个⼯程中想使⽤都是有办法使⽤的。局部变量在⼤括号内部定义的变量就是局部变量局部变量的使⽤范围是⽐较局限只能在⾃⼰所在的局部范围内使⽤的。#include stdio.h int n 1000; int main() { int n 10; printf(%d\n, n); return 0; }结果当局部变量和全局变量同名的时候局部变量优先使用。创建变量时能用局部变量就用局部变量如果不能用局部变量才用全局变量。全局变量和局部变量在内存中存储在静态区和栈区局部变量是放在内存的栈区全局变量是放在内存的静态区堆区是⽤来动态内存管理的⼀般在学习C/C语⾔的时候会关注内存中的三个区域栈区、堆区、静态区。 但其实内存区域的划分会更加细致。5. 算术运算符、-、*、/、%C语⾔中为了⽅便运算提供了⼀系列操作符其中有⼀组操作符叫算术操作符。分别是 - * / %这些操作符都是双⽬操作符。注操作符也被叫做运算符是不同的翻译意思是⼀样的。和-⽤来完成加法和减法。和-都是有2个操作数的位于操作符两端的就是它们的操作数左操作数和右操作数这种操作符也叫双⽬操作符。运算符*⽤来完成乘法。5.1/运算符/⽤来完成除法。除号的两端如果是整数执⾏的是整数除法得到的结果也是整数。如果变量 x 的类型是 float 浮点数但是x 6 / 4 得到的结果是 1.0 ⽽不是1.5 。原因就在于 C 语⾔⾥⾯的整数除法是整除只会返回整数部分丢弃⼩数部分。如果希望得到浮点数的结果两个运算数必须⾄少有⼀个浮点数这时 C 语⾔就会进⾏浮点数除法。int main() { printf(%d\n,4 / 5); printf(%f\n,4.0 / 5); return 0; }结果例⼦int main() { int score 5; printf(%d\n,(score / 20) * 100); return 0; }结果经过运算 score 等于 0 。这是因为score / 20 是整除会得到⼀个整数值 0 所以乘以 100 后得到的也是 0 。为了得到预想的结果可以将除数 20 改成 20.0 让整除变成浮点数除法。int main() { int score 5; printf(%f\n,(score / 20.0) * 100); return 0; }结果5.2%运算符%表⽰求模(余)运算即返回两个整数相除的余值。这个运算符只能⽤于整数不能⽤于浮点数。#include stdio.h int main() { int x 6 % 4; return 0; }结果负数求模的规则是结果的正负号由第⼀个运算数的正负号决定。#include stdio.h int main() { printf(%d\n, 11 % -5); printf(%d\n,-11 % -5); printf(%d\n,-11 % 5); return 0; }结果第⼀个运算数的正负号 11 或 -11 决定了结果的正负号。%可以用来计算一个整数的最后一位intmain(){printf(%d,1234%10);printf(%d,101%10);}结果6.赋值操作符和复合赋值在变量创建的时候给⼀个初始值叫初始化在变量创建好后再给⼀个值这叫赋值。int a 100; //初始化 a 200; //赋值赋值操作符 是⼀个随时可以给变量赋值的操作符。从右向左赋值6.1 连续赋值赋值操作符也可以连续赋值但是写出的代码不容易理解建议还是拆开来写这样⽅便观察代码的执⾏细节。int a 3; int b 5; int c 0; c b a3;//连续赋值从右向左依次赋值的。 //这样写在调试时每⼀次赋值的细节都是可以很⽅便的观察的。 b a 3; c b;6.2 复合赋值符在写代码时我们经常可能对⼀个数进⾏⾃增、⾃减的操作int a 10; a a3; -- a 3; a a-2; -- a - 2;结果是一样的C语⾔中提供了复合赋值符这些赋值符有 - * / % | ^7. 单目操作符:、--、(正)、-(负)C语⾔中还有⼀些操作符只有⼀个操作数被称为单⽬操作符。、--、(正)、-(负)就是单⽬操作符的。7.1和--是⼀种⾃增的操作符⼜分为前置和后置–是⼀种⾃减的操作符也分为前置–和后置–.不管是前置还是后置对操作数都是 1 有影响的是赋值7.1.1 前置计算⼝诀先1后使⽤a原来是10先1后a变成了11再使⽤就是赋值给bb得到的也是11所以计算结束后a和b都是11int a 10; int b a; printf(a%d b%d\n,a , b);结果7.1.2 后置计算⼝诀先使⽤后1a原来是10先使⽤就是先赋值给bb得到了10然后再1然后a变成了11所以结束后a是11b是10int a 10; int b a; printf(a%d b%d\n,a , b);结果7.1.3 前置–计算⼝诀先-1后使⽤int a 10; int b --a; printf(a%d b%d\n,a , b);结果7.1.4 后置–计算⼝诀先-1后使⽤int a 10; int b a--; printf(a%d b%d\n,a , b);结果7.2 和 -这⾥的是正号-是负号都是单⽬操作符。运算符 对正负值没有影响是⼀个完全可以省略的运算符但是写了也不会报错。int a 10; int a 10;运算符 - ⽤来改变⼀个值的正负号负数的前⾯加上 - 就会得到正数正数的前⾯加上 - 会得到负数。int a -10; int b -a; int c a; printf(a%d b%d c%d\n,a,b,c);结果8. 强制类型转换在操作符中还有⼀种特殊的操作符是强制类型转换语法形式很简单形式如下int a 3.14;//a的是int类型, 3.14是double类型两边的类型不⼀致编译器会报警告为了消除这个警告可以使⽤强制类型转换int a (int)3.14;//意思是将3.14强制类型转换为int类型这种强制类型转换只取整数部分结果9. scanf 和 printf 介绍9.1 printf9.1.1 基本用法printf( ) 的作⽤是将参数⽂本输出到屏幕。它名字⾥⾯的 f 代表 format 格式化表⽰可以定制输出⽂本的格式。printf() 不会在⾏尾⾃动添加换⾏符运⾏结束后光标就停留在输出结束的地⽅不会⾃动换行。为了让光标移到下⼀行的开头可以在输出⽂本的结尾添加⼀个换行符 \n 。如果⽂本内部有换行也是通过插⼊换⾏符来实现printf( ) 是在标准库的头⽂件 stdio.h 定义的。使⽤这个函数之前必须在源码⽂件头部引⼊这个头⽂件。9.1.2 占位符printf( ) 可以在输出⽂本中指定占位符。所谓 “占位符”就是这个位置可以⽤其他值代⼊。There are %d apples\n 是输出⽂本⾥⾯的 %d 就是占位符表⽰这个位置要⽤其他值来替换。占位符的第⼀个字符⼀律为百分号 % 第⼆个字符表⽰占位符的类型 %d 表示这⾥代⼊的值必须是⼀个十进制的整数。printf() 的第⼆个参数就是替换占位符的值这里There are %d apples\n ,3 是整数 3 替换 %d 。执⾏后的输出结果就是 There are 3 apples输出⽂本里面可以使⽤多个占位符但必须一一对应。#includestdio.hintmain(){printf(%s says it is %d oclock\n,lisi,21);return0;}结果输出⽂本 %s says it is %d o’clock 有两个占位符第⼀个是字符串占位符 %s 第⼆个是整数占位符 %d 分别对应 printf() 的第⼆个参数 lisi 和第三个参数 21 。执⾏后的输出就是 lisi says it is 21 o’clock 。printf() 参数与占位符是逐个对应关系如果有 n 个占位符 printf() 的参数就应该有 n 1 个。如果参数个数少于对应的占位符 printf() 可能会输出内存中的任意值。9.1.3 占位符列举printf() 的占位符有许多种类与 C 语⾔的数据类型相对应。%a⼗六进制浮点数字⺟输出为⼩写。%A⼗六进制浮点数字⺟输出为⼤写。%c字符。//char%d十进制整数有符号的10进制整数。// int%e使⽤科学计数法的浮点数指数部分的 e 为⼩写。%E使⽤科学计数法的浮点数指数部分的 E 为⼤写。%i整数基本等同于 %d 。%f小数包含 float 类型和 double 类型。//float %f double - %lf%g6个有效数字的浮点数。整数部分⼀旦超过6位就会⾃动转为科学计数法指数部分的 e为⼩写。%G等同于 %g 唯⼀的区别是指数部分的 E 为⼤写。%hd十进制 short int 类型。%ho⼋进制 short int 类型。%hx十六进制 short int 类型。%huunsigned short int 类型。%ld十进制 long int 类型。%lo⼋进制 long int 类型。%lx⼗六进制 long int 类型。%luunsigned long int 类型。%lld十进制 long long int 类型。%llo⼋进制 long long int 类型。%llx⼗六进制 long long int 类型。%lluunsigned long long int 类型。%Le科学计数法表⽰的 long double 类型浮点数。%Lflong double 类型浮点数。%n已输出的字符串数量。该占位符本⾝不输出只将值存储在指定变量之中。%o⼋进制整数。%p指针用来打印地址。%s字符串。%u无符号整数unsigned int。%x十六进制整数。%zu size_t 类型。%%输出⼀个百分号。9.1.4 输出格式printf() 可以定制占位符的输出格式。9.1.4.1 限定宽度printf() 允许限定占位符的最小宽度。intmain(){printf(%5d\n,123);printf(5d\n,123456);return0;}结果%5d 表⽰这个占位符的宽度⾄少为5位。如果不满5位对应的值的前⾯会添加空格。如果超过5位如6位,则无任何变化直接打印出6位。输出的值默认是右对⻬即输出内容前⾯会有空格如果希望改成左对⻬在输出内容后⾯添加空格可以在占位符的%的后⾯插⼊⼀个 - 号。intmain(){printf(%-5d,123);printf(%s\n,hehe);return0;}结果输出内容 123 的后⾯添加了空格。对于⼩数这个限定符会限制所有数字的最⼩显⽰宽度。intmain(){printf(%12f\n,123.45);return0;}结果%12f 表⽰输出的浮点数最少要占据12位。由于 %f 的默认显⽰精度是⼩数点后6位所以 123.45 输出结果的头部会添加2个空格。小数点也算一位9.1.4.2 总是显示正负号默认情况下 printf() 不对正数显⽰ 号只对负数显⽰ - 号。如果想让正数也输出 号可以在占位符的 % 后⾯加⼀个 。intmain(){printf(%d\n,123);printf(%d\n,-123);return0;}结果%d 可以确保输出的数值总是带有正负号。9.1.4.3 限定小数位数输出⼩数时有时希望限定⼩数的位数。比如希望⼩数点后⾯只保留两位占位符可以写成 %.2f 。intmain(){printf(%f\n,12.37);printf(%.2f\n,12.37);printf(%.1f\n,12.37);printf(%6.1f,12.37);return0;}结果%6.1f 表⽰输出字符串总最⼩宽度为6⼩数位数为1。所以输出字符串的头部有两个空格。会自动四舍五入最⼩宽度和⼩数位数这两个限定值都可以⽤ * 代替通过 printf() 的参数传⼊。intmain(){printf(%*.*f\n,6,2,12.34);return0;}结果%*.*f的两个星号通过 printf() 的两个参数 6 和 2 传⼊。9.1.4.4 输出部分字符串%s 占位符⽤来输出字符串默认是全部输出。如果只想输出开头的部分可以⽤%.[m]s指定输出的⻓度其中[m]代表⼀个数字表⽰所要输出的⻓度。intmain(){printf(%.5s\n,hello world);return0;}结果占位符 %.5s 表⽰只输出字符串“hello world”的前5个字符即“hello”。9.2 scanf当我们有了变量给变量输⼊值使⽤ scanf 函数将变量的值输出在屏幕上使⽤ prinf 函数intmain(){inta0;printf(请输入一个数字 );scanf(%d,a);printf(a%d\n,a);return0;}结果9.2.1 基本用法scanf() 函数⽤于读取用户的键盘输⼊。程序运⾏到这个语句时会停下来等待用户从键盘输⼊。用户输⼊数据、按下回车键后 scanf() 就会处理用户的输⼊将其存⼊变量。它的原型定义在头⽂件 stdio.h 。scanf() 的语法跟 printf() 类似。inti0;scanf(%d,i);它的第⼀个参数是⼀个格式字符串⾥⾯会放置占位符与 printf() 的占位符基本⼀致告诉编译器如何解读用户的输⼊需要提取的数据是什么类型。这是因为 C 语⾔的数据都是有类型的scanf() 必须提前知道用户输⼊的数据类型才能处理数据。它的其余参数就是存放用户输⼊的变量格式字符串里面有多少个占位符就有多少个变量。上⾯⽰例中 scanf() 的第⼀个参数 %d 表⽰用户输⼊的应该是⼀个整数。 %d 就是⼀个占位符d 表⽰整数。第⼆个参数 i 表⽰将用户从键盘输⼊的整数存⼊变量 i 。注意变量前⾯必须加上 运算符指针变量除外因为 scanf() 传递的不是值⽽是地址即将变量 i 的地址指向用户输⼊的值。如果这⾥的变量是指针变量比如字符串变量那就不⽤加 运算符。先解读要提取的变量类型再判断是否处理数据也可以键盘输⼊并读⼊多个变量scanf(%d%d%f%f,i,j,x,y);格式字符串 %d%d%f%f 表示用户输⼊的前两个是整数后两个是浮点数⽐如 1-20 3.4 -4.0e3 。这四个值依次放⼊ i 、 j 、 x 、 y 四个变量。scanf() 处理数值占位符时会自动过滤空白字符包括空格、制表符、换行符等。所以用户输⼊的数据之间有⼀个或多个空格不影响 scanf() 解读数据。另外用户使⽤回车键将输⼊分成⼏⾏也不影响解读。用户分成四⾏输⼊得到的结果与⼀⾏输⼊是完全⼀样的。每次按下回⻋键以后scanf() 就会开始解读如果第⼀⾏匹配第⼀个占位符那么下次按下回⻋键时就会从第⼆个占位符开始解读。scanf() 处理用户输⼊的原理是用户的输⼊先放⼊缓存等到按下回⻋键后按照占位符对缓存进⾏解读。解读⽤用户输⼊时会从上⼀次解读遗留的第⼀个字符开始直到读完缓存或者遇到第⼀个不符合条件的字符为⽌。intmain(){intx;floaty;scanf(%d,x);printf(%d\n,x);scanf(%f,y);printf(%f\n,y);return0;}结果scanf() 读取用户输入时 %d 占位符会忽略起⾸的空格从 - 处开始获取数据读取到 -13 停下来因为后⾯的 . 不属于整数的有效字符。这就是说占位符 %d 会读到 -13 。第⼆次调⽤ scanf() 时就会从上⼀次停⽌解读的地⽅继续往下读取。这⼀次读取的⾸字符是 . 由于对应的占位符是 %f 会读取到 .45e12 这是采⽤科学计数法的浮点数格式。后⾯的不属于浮点数的有效字符所以会停在这⾥。小数有可能不会精确保存导致无限接近0.45又因为科学计数法为10的12次方所以结果会变成449999994880.000000由于 scanf() 可以连续处理多个占位符所以上⾯的例⼦也可以写成下⾯这样。intmain(){intx;floaty;// ⽤⼾输⼊ -13.45e12# 0scanf(%d%f,x,y);printf(%d\n%f\n,x,y);return0;}结果是一样的9.2.2 scanf 的返回值scanf() 的返回值是⼀个整数表⽰成功读取的变量个数。如果没有读取任何项或者匹配失败则返回 0 。如果在成功读取任何数据之前发⽣了读取错误或者遇到读取到⽂件结尾则返回常量 EOF (-1)。EOF - end of file ⽂件结束标志intmain(){inta0;intb0;floatc0.0;intCount0;printf(请输入三个数字 );Countscanf(%d %d %f,a,b,c);printf(a%d b%d c%f\n,a,b,c)printf(Count%d\n,Count);return0;}结果如果在输入2个数字后按 ctrlz 提前结束输⼊可以看到Count是2表⽰正确读取了2个数值如果⼀个数字都不输⼊直接按ctrl z ,输出的Count是-1也就是EOF算法题中常见的用法连续加和intmain(){inta0;intb0;intsum0;while(scanf(%d %d,a,b)2)//或者while(scanf(%d %d, a, b) EOF){printf(sum%d\n,sumab);}return0;}结果按Ctrl z 结束运算9.2.3 占位符scanf() 常⽤的占位符如下与 printf() 的占位符基本⼀致。%c字符。%d整数。%f float 类型浮点数。%lf double 类型浮点数。%Lf long double 类型浮点数。%s字符串。%[]在⽅括号中指定⼀组匹配的字符⽐如%[0-9]遇到不在集合之中的字符匹配将会停⽌。int main() { char a[100]; scanf(%[a-zA-Z], a); printf(a%s\n, a); return 0; }结果intmain(){chara[100];scanf(%[0-9],a);printf(a%s\n,a);return0;}结果scanf中不要使用 \n还有空格上⾯所有占位符之中除了 %c 以外都会自动忽略起首的空白字符。 %c 不忽略空⽩字符总是返回当前第⼀个字符⽆论该字符是否为空格。int main() { char c 0; scanf(%c,c); printf(--c%c--\n, c); return 0; }如果要强制跳过字符前的空⽩字符可以写成 scanf( %c, ch) 即 %c 前加上⼀个空格表⽰跳过零个或多个空⽩字符。int main() { char c 0; scanf( %c,c); printf(--c%c--\n, c); return 0; }结果占位符 %s 不能简单地等同于字符串。它的规则是从当前第⼀个⾮空白字符开始读起直到遇到空⽩字符(即空格、换⾏符、制表符等)为⽌。int main() { char arr[100]; scanf(%s,arr); printf(arr%s\n, arr); return 0; }结果因为 %s 不会包含空⽩字符所以⽆法⽤来读取多个单词除⾮多个 %s ⼀起使⽤。这也意味着scanf() 不适合读取可能包含空格的字符串⽐如书名或歌曲名。另外scanf() 遇到 %s 占位符会在字符串变量末尾存储⼀个空字符 \0。arr是数组名数组名本来就是地址这里就不需要在取地址了scanf() 将字符串读⼊字符数组时不会检测字符串是否超过了数组⻓度。所以储存字符串时很可能会超过数组的边界导致预想不到的结果。为了防⽌这种情况使⽤ %s 占位符时应该指定读⼊字符串的最大⻓度即写成%[m]s其中的[m]是⼀个整数表⽰读取字符串的最⼤⻓度后⾯的字符将被丢弃。intmain(){charname[11];//需要给空字符\0留一个位置scanf(%10s,name);return0;}结果上⾯⽰例中 name 是⼀个⻓度为11的字符数组 scanf() 的占位符 %10s 表⽰最多读取用户输⼊的10个字符后⾯的字符将被丢弃这样就不会有数组溢出的⻛险了。9.2.4 赋值忽略符有时用户的输⼊可能不符合预定的格式。intmain(){intyear0;intmonth0;intday0;scanf(%d-%d-%d,year,month,day);printf(%d %d %d\n,year,month,day);return0;}结果用户输⼊2026-7-6 就会正确解读出年、⽉、⽇。问题是用户可能输⼊其他格式⽐如2026/7/6 这种情况下 scanf() 解析数据就会失败。为了避免这种情况 scanf() 提供了⼀个赋值忽略符assignment suppression character * 。只要把 * 加在任何占位符的百分号后⾯该占位符就不会返回值解析后将被丢弃。intmain(){intyear0;intmonth0;intday0;scanf(%d%*c%d%*c%d,year,month,day);return0;}结果%*c就是在占位符的百分号后⾯加⼊了赋值忽略符*表⽰这个占位符没有对应的变量解读后不必返回。
返回列表