看下面几个程序并分析:
1、在vc6.0下
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
char buf[] = {'a','b','\r','c','\n','a','\0'};
int size = sizeof(buf);
int len = strlen(buf);
printf("buf = %s",buf);
printf("len = %d",len);
}
其中关于ascii等会讲解。
上例输出结果是:cuf = ab
alen = 6Press any key to continue
分析:1、对于printf标准IO操作都是带缓冲的,只有对缓冲区刷新才会输出。
2、字符串都是以\0为结束符的,该字符不占用长度但还是需要占用一个字符空间的,毕竟\0还是有对应的ASCii的。
3、所以输出size = 7,而len = 6。
4、因为\r是回车的意思并没有换行所以buf中的b被换行之后的c字符覆盖了,补充(像\t,\n,\r等都是控制符)。
2、下面以linux平台下运行另一同类程序
int main(void)
{
char buf[1024] = {'a','b','c','\n','d','\0'};
int len = strlen(buf);
write(STDOUT_FILENO,buf,1024);
printf("buf = %s",buf);
printf("len = %d",len);
return 0;
}
输出结果:abc
dbuf = abc
dlen = 5[root@localhost test]#
分析:1、len肯定是等于5的,而write是一个系统调用并不是标准IO所以是直接输出的,故有abc,d输出。
2、接着第二行d后面printf是一个标准IO所以输出需要缓冲,但buf内部有\n所以会直接输出buf = abc,d。
3、因为字符串输出时以\0结尾的,所以会输出成那样,如果这个把最后一个字符\0去掉,那么输出会出现乱码,因为已经超出了内存。
3、以上例换一下输出顺序看一下结果
int main(void)
{
char buf[1024] = {'a','b','c','\n','d','\0'};
int len = strlen(buf);
printf("buf = %s",buf);
printf("len = %d",len);
write(STDOUT_FILENO,buf,1024);
return 0;
}
输出结果:buf = abc
abc
ddlen = 5[root@localhost test]#
大家可以先自己分析下。
3、补充:
全缓冲:可自动冲洗(当写满缓冲区时),另用fflush冲洗一个流,fflush真正作用就是立即将缓冲区内容输出设备同时清空缓冲区。
行缓冲:当输入或输出中遇到换行符时,标准IO库执行IO操作,但如果写入的每一行缓冲区满也会进行IO操作。
ASCII字符集
字符 '\0':十进制为0,nul 一般为终止符 ,空操作,就是一个空格
字符 '0' : 十进制为48,;
字符 '\t' : 十进制为9, table符
字符 ' ' : 十进制为32;
字符 '\n' 十进制为10, 换行符
空格符号与空字符: ASCII里空格(space)符号ASCII码为32,而空字符是0,一般用来描述一个字符串的结尾,其实是控制符的一种,但不能理解为没有字符,其中字符串就是以'\0'为结尾标志,'\0'是一个空操作字符,它不做任何字符,只是一个标志,它不计入串的长度。空NULL,0,'\0'几乎相同,但类型存在内存大小不同。
比较下下面程序:
#include <stdio.h>
int main(int argc, char* argv[])
{
char p[] = {'a','b',' ','c','\t','0',0,'d'};
printf("p = %s\n",p);
return 0;
}
输出结果:ab c 0
分析:其中0与‘\0’是一样的,所以遇到0就结束,不会输出d字符。