C语言标准库概述
1)库函数分类
我们暂时需要记住的有:
标准输入输出函数库:stdio
数学应用函数库:math
字符串处理函数库:string
2)调用函数库时,我们需要预编译指令:
即:
//或者
#include"头文件名"
需要注意的是,第一种写法,一般在使用标准函数库时使用,第二种写法,一般在使用用户自己定义的函数库时使用。
格式输出函数:printf
1)前言:
从计算机向外部设备输出信息称为输出,即将计算机内的信息以打印或者存储的形式转到终端。
printf函数在<stdio.h>函数库中
预编译指令为:#include<stdio.h>
2)标准格式输出:
printf("格式输出控制表列",输出参数表列);
格式输出控制表列包括普通字符和格式字符组成,普通字符如:hello,world;
格式字符以%开头,后跟一个字符表示数据类型。如:%d,%f等。
输出参数表列在控制表列中如果没有格式字符,可以省略:如:printf("Hello,world!");
这里,我们给出两个实例帮助理解:
printf("Hello,world!");
printf("%d",100);
printf("521%d!",1314);
3)格式控制符
在明白输出函数的基本使用方法后,我们剖析一下格式控制符。
1、%d格式
标准输出函数中以%作为格式输出控制索引。%d是以十进制在屏幕上显示输出参数表列的值。当然输出参数表列可以为字符型,整型,浮点型等类型,不过最终都以10进制输出。我们看一个例子:
main()
{
char c='A';
int a=1,b=2;
printf("c=%d,a/b=%d,b/a=%d,(float)a/b=%d",c,a/b,b/a,(float)a/b);
printf("123.456=%d",123.456);
printf("%d");
reeturn 0;
}
最终的输出结果出乎我们意料,
c=65,a/b=0,b/a=2,(float)a/b=0
123.45=446676599
2367460
我们在这里解释一下,首先字符型的'A'在ASICC中的数值是65,所以最终以十进制输出的是65;由于,a/b的值理应为0.5,在这里,由于是整型输出,所以小数部分被截断,最终的结果为0,同理,我们不难理解最后的(float)是什么情况,那么b/a的结果显然是2,我们不在阐述。下一个输出,123.456是float类型,不过在C语言中,所有的浮点型都按照double型计算,%d输出常量123.456在内存中低4字节数据,所以最后结果是446676599,这似乎有点欧亨利结局了,出乎意料却又在情理之中。最后一个输出,由于没有输出参数表列,所以会输出一个任意值。
2、%ld格式
毫无疑问,%ld中的l是long的简写,所以%ld是用来长整型类型输出的,不过值得注意的是,在32位的操作系统中,int和long型都分配四个字节存储空间,所以使用%d,%ld无本质区别。
3、%u格式
%u用来输出无符号整型类型,定义为:unsigned int a;
其中,引入无符号整型的意义就是用在无负数的场景中,以增大int存储范围。
printf("%d",-1);
printf("%u",-1);
在这个程序中,我们得到的结果是不同的,第一个输出为-1,第二个输出为4294967295
解释一下第二个奇怪的结果,由于负数在计算机内部以补码形式存在,-1的补码为0xffffffff,所以在转换为无符号整型时,符号位被当做数值操作,最终输出的结果为0xffffffff,换算成十进制为4294967295
4、%c格式
%c格式中的c为char类型,所以控制输出字符型,值得注意的是,在其他类型转换为char型时,我们关注的该类型的二进制代码的低八位所代表的的数值(char代表的为0-255)。
//那如果是负数呢?
printf("%c,%c",-159,97);
通过运行,我们可以发现,两个输出的结果都为c,那这是为什么呢?
我们不妨分析一下-159,和97的区别,发现97+159=256.根据负数在计算机内部存储的为补码,我们通过补码的实质可以发现,-159的补码等于256对159取余,我们得到了97,由于我们取得是低八位数值,所以自然而然输出结果为相同的c。
我们给出以下证明:
[-159]原码=1000 0000 0000 0000 0000 0000 1001 1111
[-159]反码=1111 1111 1111 1111 1111 1111 0110 0000
[-159]补码=1111 1111 1111 1111 1111 1111 0110 0001
[97]补码=0000 0000 0000 0000 0000 0000 0110 0001
于是,去低八位的值是相同的。
5、%f格式
%f格式以浮点型输出,主要用于输出float和double型,默认输出小数点后6位数字,不够6位补零输出,例如:
printf("%f,%f",123.456,789);
//输出结果为:123.456000,0.000000;
什么?又被震惊到了,789为什么变成了0.000000?这不柯学,我们分析一下,789在内存中以补码存在,
其值为:
[789]补码=0000 0000 0000 0000 0000 0011 0001 0101
由于%f以单精度输出,所以,最高位为符号位,低23位为位数位,中间8位为指数位,所以内存中的数值构成浮点数0.00000000000001100010101*2^0
加上输出为7位有效数字,所以最终结果为0.000000,也就不奇怪了。
6、%e格式
%e格式以指数形式输出,指数形式由数符,数值,字符,阶符和阶码构成。
正数 | 负数 |
---|---|
数值E 阶符 阶码 | 数符 数值E 阶符 阶码 |
其中,数符用来表示数据的正负,我们在书写时,需要注意一下格式:
(+/-)[数字]e(+/-)[数字]的格式书写
1e+2,-1e+2,1e-1……
关于指数和float类型,我们后面补充相关指数。
7、%s格式
%s格式用来输出字符串,我们需要注意的有,在输出时,如果字符串中有转义字符,会执行这些转义字符,而%c不会这样。
printf("%s","Hello\nwor\0ld");
/*输出结果:Hello
wor
*/
8、%o,%x格式,%和\输出
这两个格式不常用,但是我们仍然需要注意,%o以八进制输出,%x以十六进制输出.
而%和\作为控制符,如果我们需要输出这两个字符,我们需要在前面重写一遍该字符
例如:printf("%%=%d",123);
4)格式输出控制字符
1、%md,%-md,%mc,%-mc格式
对于这里的m,我们解释为控制位宽输出,即用于按指定的宽度m以相应格式输出数据,其特点如下:
如果数据位宽大于m,则按实际宽度输出,如果输出数据宽度小于m,则左补空格,共输出m列。
而‘-’号代表如果数据位宽大于m,则按实际宽度输出,如果输出数据宽度小于m,则右补空格,共输出m列。
2、%mf,%-mf,%.nf,%m.nf,%-m.nf格式
对于这里的前两个与第一种格式相似,我们不在阐述。
而后面的几个格式控制表示为:
%.nf指定小数点后的输出宽度,当n大于数据有效位数时,右边补零,当n小于有效位数时,采取四舍五入规则。
%m.nf,m用于指定整数和小数的总位宽,m大于输出宽度时,左补空格,m小于输出宽度时,按实际宽度输出,n用于指定小数点后的宽度,如果n大于有效宽度,右补零,n小于有效宽度时,按四舍五入规则截取
我们需要注意的有:我们应首先考虑n的值,即在满足n的值得基础上在判断m对数据输出的影响,当m小于等于n是,m对输出数据不起作用,我们举一个栗子:
printf("%6.2f,%5.3f,%8.4f",1.234,19.87654,100000.23);
/*输出结果为:
_ _ 1.23,19.877,100000.2300
*/
加上负号代表左对齐.
格式输入函数
前言:从输入设备向计算机输入数据称为输入,我们用标准输入函数scanf完成。
格式:一般格式为:scanf("格式输入控制表列",输入参数地址表列);
需要注意的是我们在输入参数地址表列中书写的是变量的地址,我们需要使用取地址符完成上述操作.
eg:scanf("%d",&x);
scanf的格式控制字符与printf的相似,这里不再一一展开,不过,我们需要阐述一个事实,scanf会产生“历史遗留问题”;
scanf("%d",&x);
scanf("%c",&c);
printf("%d",c);
当我们按下回车时,c中是有值得,大家猜一下输出多少。
为了避免这种问题,我们常常使用getchar()来消除scanf的遗留问题。
我们列出一些容易出错的点:
1)在读取字符串时,会在字符串末尾自动添加'\0',所以存储字符串的字符数组的长度应该为:max(max_strlen_str)+1;
2)在读取字符串时,我们不需要添加&,因为字符串的名字本身就是地址常量,后面会有说明。
3)使用scanf()时,应该遵循写什么输入什么的原则,即如果格式输入控制列表中有空格,那么在读入数据时应该加上空格,防止读入错误的数据,导致程序报错。
字符输入输出函数
前言:在stdio库中,还有两个字符输入输出函数,即getchar和putchar函数。
putchar的作用是向终端输出一个字符,其一般格式为:pruchar(c);
这里我们列出一些putchar的常见用法:
1)输出字符,可以为变量也可以是常量
2)可以输出转义字符
3)自动将ASICC码转换为字符型输出
getchar()的作用是从标准输入设备中获取一个字符,
一般格式为:c=getchar();