数据类型 与 标准IO

/*
    数据类型 与 标准IO

A,数据类型

    1,GCC中float=4,double=8,long double=12
    2,VC2010中,float=4,double=8,long double =8
    3,关于数据范围:int(32位)大概是21亿不到22亿(10个数), long大概是900京(19个数)
                float(32位)小数位为6,且四舍五入, double(32位) 小数位17位,且四舍五入,long double(32位)小数位17位,且四舍五入
    4,在VC10中,long double就是double。GCC中不是, GCC是12个字节。
    5,Intel的CPU采用小端(低为低)存储,int a=0x12345678;则低地址为0x78;

    6,如果数据定义为局部变量,那么不会被初始化,比如,在main中,int a;那么a不会为0. 如果定义为全局变量,那么a=0。结构体也一样。

B,printf格式控制

    表达式:%[-][0][m.n][l或h]格式字符
    1, “ % ” 是必须的
    2,“ - ” 表示左对齐,没有表示右对齐
    3,“ 0 ” 表示0填充,没有表示空白填充
    4,“ m.n ” 表示所占宽度m,精度为n
    5,“ l ” 表示long, “ h ”表示short
    6,格式字符

    7,printf时,long double 对应Lf。 double与float 对应f或者lf或者llf或者llll..lllf。(float会自动扩展为double)
    8,printf时,long 对应ld, long long 对应lld。l与L无区别

C,scanf:(好像只有scanf是这样)
   
    1,换行(/n)垃圾:
        首先理解缓存区的机制:当用户输入时,输入数据不会被函数直接读入,而是被读入到缓存区,当敲回车时,会读入缓存区一个'/n'后,触发IO函数读取缓存区。
    读取%d,%s等时,IO函数扫描缓存区,过滤碰到割断(空格或者/n),然后读取数据,直到再碰到隔断,这是处理隔断之间的数据,但后面的隔断不会从缓存区清空
    ,而是留下来。如果后面要读取的是一个%c,那么这个隔断会被作为字符读入。而如果是%d或者%s等,则会过滤隔断。所以对于%c才会产生垃圾。
   
        举例1:char a,b; scanf("%c", &a); scanf("%c", &b);
            输入 a<CR>
            过程分析:<CR>触发scanf处理缓存区。缓存区中为['a' '/n' ], scanf按%c,读取‘a’到char a中,然后返回。这时,缓冲区中为['/n'],
            scanf读取缓冲区,将‘/n’赋给char b;
        举例2:char buf[100]; char c; scanf("%s", buf); scanf("%c", &c);
            输入:123abc<SPACE>e<CR>
            过程分析:<CR>触发scanf处理缓存区。scanf从缓存区中扫描,碰到隔断<SPACE>,将隔断前的字符串赋给buf。这是<SPACE>并不被处理,然后scanf读取char c。
            这时把<SPACE>赋给char c。

        举例3: char c; int b; scanf("%c", &c); scanf("%d", &b);
            输入:a<CR>12<CR>
            过程分析:<CR>触发scanf处理缓冲区,a被读入char c中,读取int b时,a后面的<CR>被过滤掉,直到碰到其他有效输入,这是12被读入b中。
        举例4:可以正常读入 scanf("%c", &a);scanf(" %c", &b); 或者scanf("%c ", &a);scanf("%c", &b);
        举例5:char a; char c; scanf("abc%c efg", &a); scanf("%c", &c);
            输入:abcd<CR>efgh<CR>, 最终结果为a=‘d’,c=‘h’
            输入:abd,最终结果是 scanf扫描缓冲区,先过滤a,再b,过滤c的时候,发现输入串不合法,所以第一个scanf返回0结束,
        第二个scanf读入d给char c。

        综上:scanf不过为%c过滤之前的'/n'、空格等字符。但是会为%s、%d等过滤。且scanf读入数据后,不会丢弃掉/n、空格等字符,依然将它们留在缓冲区内。
            gets()函数不会这样.
    2,scanf时,float 只对应f,double只对应lf,long double只对应LF或者llf。
    3,scanf的返回值表示成功读入的数据个数
    4, scanf(" %c", &c); %c之前有个空格,会帮助在读取%c时,先过滤之前的换行空格等字符,再读入c中,即过滤了垃圾.
     
D,其他

    1,getch从键盘直接读入,不用回车键
    2,scanf从缓存区读入,逐字符扫描,直到空格(32)和新行(10),将扫描区间处理。
    3,gets从缓冲区读入,不以空格(32)为结束标志。只以新行(10)为标志。有点像getLine
    4,putch
    5,puts

    文件 I/O
A,常见IO函数
    0, putch, getch, puts, gets, printf, scanf, getchar
    1, fputc, fgetc, fputs, fgets, fprintf, fscanf
    2, putw, getw, fread, fwrite
    3, feof, ferror, clearerr
    4, ftell, rewind, fseek
    5, fflush, freopen
    6, rename, remove, tmpnam

    4, 不适用gets,适用fgets(pBuf, 12, stdin), where pBuf is a char*, and 12 is size of Buf. read 11 symbols from stdin
    6, fgets() 会在结尾处多读一个'/n'

关于回车换行:
    1,内存里:‘/n’解释为 new line 更好,而不是换行。 回车(‘/r’)表示表示光标回到本行开头,而不换行。‘/n’表示新的一行,实际为回车换行。
        敲回车后,会产生/n字符到缓存区中,并触发处理缓存区的动作,动作完毕后,清空缓存区。
    2,文本里:windows把‘/n’存储到硬盘时,自动扩展为‘/r/n’.读取时,自动把‘/r/n’读成为‘/n’(文本模式下).而linux不这样。

*/

<think>好的,我现在需要回答用户关于文件IO标准IO区别的问题。首先,我得仔细看看用户提供的引用内容,确保准确理解两者的不同点。 用户提到了四个引用,其中引用1、2、3、4都IO操作相关。首先,引用1指出标准IO是C语言的标准库,跨平台,而文件IO是Linux的系统调用,只能在Linux下使用。这点很重要,跨平台性是关键区别之一。 接下来引用2详细解释了IO的不同类型,包括用户I/O、文件I/O、网络和设备I/O,以及五层模型。这里提到标准IO函数是ANSI标准,对文件IO进行了二次封装,使用缓冲区提高效率,而文件IO是系统调用,可移植性低。这点需要强调缓冲区管理的区别,以及性能差异。 引用3中的代码示例展示了文件IO的使用,比如open、write、read等系统调用。注意到代码中的文件描述符(fd)和错误处理,而标准IO可能使用FILE指针和不同的函数如fopen、fprintf等。此外,引用3还提到标准IO和文件IO在处理文件指针位置时的不同,比如在写入后需要重新打开文件才能读取,这可能是因为标准IO的缓冲区会自动处理,而文件IO需要手动操作。 引用4虽然主要讲strncmp,但可能对比较函数有帮助,但暂时不太相关。需要忽略这部分。 现在综合这些信息,整理出主要区别点: 1. **定义来源**:标准IO是C库函数,文件IO是系统调用。 2. **跨平台性**:标准IO可移植,文件IO依赖于操作系统。 3. **缓冲机制**:标准IO有缓冲区,减少系统调用次数,提高效率;文件IO无缓冲或手动管理。 4. **操作对象**:标准IO使用FILE指针,文件IO使用文件描述符。 5. **性能开销**:文件IO涉及用户态到内核态切换,开销较大。 6. **函数示例**:标准IO如fopen、fprintf;文件IO如open、write。 需要确保每个点都有引用支持,比如引用1和2说明跨平台性,引用2和3说明缓冲机制,引用3中的代码展示操作对象的不同。同时,用户可能关心实际应用中的选择,比如何时使用哪种IO,这也是相关问题可以生成的方向。 另外,用户的问题可能需要更结构化的回答,分点列出区别,并给出例子。比如使用代码片段对比两者,如标准IO的fopen和文件IO的open。但根据用户示例中的结构,可能需要用中文详细解释每个区别,并在适当位置添加引用标记。 最后,生成相关问题时要围绕区别展开,比如缓冲区的影响、性能比较、适用场景等。确保问题具体且有针对性,帮助用户深入理解。</think>### 文件IO标准IO的区别 #### 1. **定义来源** - **标准IO**是C语言标准库提供的函数(如`fopen`、`printf`),通过二次封装系统调用实现,具有跨平台性[^1][^2]。 - **文件IO**是操作系统直接提供的系统调用(如Linux的`open`、`read`),操作系统绑定,可移植性较低[^1][^3]。 #### 2. **缓冲机制** - **标准IO**使用**缓冲区**(内存区域)暂存数据,减少硬件或文件的直接交互次数,提高效率。例如:`printf`输出时数据可能先存入缓冲区,待条件满足后(如缓冲区满或程序结束)才写入目标[^2][^3]。 - **文件IO**通常**无缓冲或需手动管理**,每次调用直接触发系统调用,适合实时性要求高的场景[^3]。 #### 3. **操作对象** - **标准IO**操作的是`FILE`类型的**流指针**(如`FILE *fp`),提供更高层次的抽象(如按行读写)[^2]。 - **文件IO**操作的是**文件描述符**(整数类型,如`int fd`),直接内核交互,需处理底层细节(如文件偏移量)[^3]。 #### 4. **性能开销** - **标准IO**通过缓冲区减少系统调用次数,**性能更优**。例如:频繁调用`fprintf`时数据可能批量写入[^2]。 - **文件IO**每次调用涉及**用户态到内核态的切换**(CPU模式转换),耗时较多,需谨慎使用[^3]。 #### 5. **代码示例对比** ```c // 标准IO示例(使用C库函数) FILE *fp = fopen("test.txt", "w"); fprintf(fp, "Hello World"); fclose(fp); // 文件IO示例(使用Linux系统调用) int fd = open("test.txt", O_WRONLY | O_CREAT, 0644); write(fd, "Hello World", strlen("Hello World")); close(fd); ``` #### 6. **适用场景** - **标准IO**:通用文件操作、需要跨平台移植的代码[^1]。 - **文件IO**:需要精细控制文件行为(如非阻塞I/O)、直接操作设备(如串口通信)[^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值