暑假期间继续写博客,写完了往后学。
全书共分17章,这是关于本书第4章内容的博客,本章主要介绍了printf()和scanf()函数,也有一些其他内容。本章细节的地方也比较多,不要太陷进去。博客的目录和书上目录是相似的。此系列博客的代码都在Visual Studio 2022环境下编译运行。
我目前大一刚刚结束,水平有限,博客中若有错误或者总结不到位的地方也请见谅。
目录
4.1 字符串简介
本部分知识后面第11章会详细介绍。
4.1.1 char类型数组和null字符
字符串是一个或多个字符的序列,要用双引号括起来,双引号不是字符串的一部分,作用是告诉编译器括起来的内容是字符串。
C语言没有专门存储字符串的变量类型,一般将字符串存储在char类型数组中。数组由连续的存储单元组成,是同类型数据元素的有序序列,这部分详细内容在第10章。定义数组时,名称后面的方括号[]表示这是一个数组,里面的数字表明元素数量。
\0是空字符,在C语言中用于标记字符串的结束。空字符是非打印字符,ASCII码值为0。
4.1.2 使用字符串
用%s输出字符串。
在读取输入时,scanf()函数已经将空字符放入字符串结尾,scanf()函数读取字符串在遇到空格时停止。字符串常量结尾也不用写空字符,编译器会在末尾加上空字符。
4.1.3 strlen()函数
strlen()函数给出字符串的字符长度(不包括空字符)。
头文件string.h包含了很多与字符串相关的函数原型,包括strlen()。一般地,C语言把函数库相关的函数归为一类,为每类函数提供头文件。例如,printf()和scanf()函数的原型在stdio.h中。
很长的printf()语句可以在参数之间断为两行,但不要在字符串之间断开。
sizeof后面是否使用圆括号取决于运算对象是类型还是特定量,是类型时圆括号必不可少,对特定量可有可无,但最好都使用圆括号。
4.2 常量和C预处理器
有些常量在程序中多次使用,这种情况下使用符号常量更好。因为常量名表达的信息更多更清楚,
另外如果要修改值的情况下也很方便。
创建符号常量可以使用一个变量,然后将值设置为一个常量。但是程序可能无意改变值。C语言中还可以使用#define语句创建一个明示常量。通用格式为
#define NAME value
名称最好用大写,可以提高程序的可读性,与变量区分。命名规则和变量相同。末尾不用加分号,也不用使用等号连接。在编译程序时,所有出现符号常量名的地方会被替换为后面的内容,在运行时已替换完成。
4.2.1 const限定符
const关键字限定一个变量为只读(但还是变量,不是常量)。使用时在类型前加上const。使用后该变量的值不可修改。
4.2.2 明示常量
C语言的头文件limits.h和float.h提供了与整数和浮点数类型大小限制相关的信息,这两个头文件提供很多相关明示常量。
把FLT替换为DBL和LDBL表示double和long double型对应明示常量。
4.3 printf()和scanf()
printf()和scanf()函数能让用户与程序交流,属于输出/输入函数,或I/O函数。C库中的所有函数都不是C语言定义的一部分,由具体编译器实现,标准提供了标准版本。
printf()和scanf()函数工作原理几乎相同,都使用格式字符串和参数列表。
4.3.1 printf()函数
C语言由转换说明指定如何把数据转换为可显示的形式。
4.3.2 使用printf()
printf()函数的格式是printf(格式字符串,待输出项1,待输出项2...)
待输出项可以是变量,常量或表达式的值。格式字符串包括实际要输出的字符和转换说明。转换说明的类型数量一定要与后面的项一一匹配,否则可能会导致严重后果。
如果只输出文字,就不需要转换声明,如果只输出数据,也不需要在格式字符串中加入说明文字。输出%需要格式字符串中对应位置有两个相邻的%。
4.3.3 printf()的转换说明修饰符
在%和转换字符之间插入修饰符可以修饰基本的转换说明。如果要插入多个字符,其顺序应该与下表的顺序相同。
stddef.h头文件(包含stdio.h头文件就已包含)中定义sizeof返回的类型为size_t类型,被称为底层类型。在printf()中用z修饰符表示输出此类型。C语言定义ptrdiff_t类型和t修饰符表示系统两个地址差值。
4.3.4 转换说明的意义
转换说明把以二进制格式存储在计算机中的值转换为一系列字符以便于显示。
printf()函数也有返回值,返回打印字符的个数,如果有输出错误则返回一个负值,通常很少用到。
在字符串中可以使用\n表示换行字符,但是不能通过按Enter产生实际的换行符。
给字符串断行可以使用多个printf()语句,可以用\和Enter断行(但下一行必须从最左端开始,最左端不能有空格,否则字符串会包括空格),也可以将两个双引号括起来的字符串用空白隔开。
4.3.5 使用scanf()
scanf()把输入的字符转换为对应的格式。scanf()也使用格式字符串和参数列表,格式字符串表明字符输入流的目标数据类型。scanf()的参数列表中使用指向变量的指针(第10章详细介绍指针,读取基本变量类型的类型值要在变量名前加&)。
scanf()函数使用空白(换行符、制表符和空格)把输入分为多个字段,在依次把转换说明和字段匹配时跳过空白。但是使用%c转换说明时,scanf()会读取空白。
scanf()的转换说明和printf()几乎相同。但是printf()函数对float和double类型的转换说明相同,但scanf()函数只将其用于float类型,要对double类型使用l修饰符。
scanf()函数也可以在转换说明中使用修饰符。
如果读取的字符不能用于转换声明要求的类型,字符会被放回缓冲区中,同时停止读取。如果首个非空白字符不能用于转换声明要求,则不进行赋值。使用带有多个转换说明的scanf(),会在第一个出错处停止读取输入。使用%s转换说明会读取除空白外所有字符。
scanf()函数允许把普通字符放在格式字符串中,此时除空格字符外的普通字符必须与输入严格保持一致。格式字符串的空白意味着跳过下一个输入项前面的所有空白。除了%c,其他转换说明都自动跳过输入值前面的空白。
scanf()函数返回成功读取的项数。检测到文件结尾时会返回EOF。
4.3.6 printf()和scanf()的*修饰符
printf()和scanf()都可以使用*修饰符来修改转换说明的含义。
printf()函数中,可以用*修饰符代替字段宽度,但是需要在待输出项前面加一个参数表示字段宽度。
scanf()函数中使用*会跳过相应的输入项。
4.3.7 printf()的用法提示
想把数据打印成列,可以指定字段宽度。使用足够大的固定字段宽度可以使输出整齐美观。
在两个转换说明中间插入一个空白字符,可以防止两个数据内容相连。
要在文字中嵌入数字,通常指定小于等于该数字宽度的字段。
C语言可以选择特定的本地化设置。