其他知识点

其他知识点

printf族函数

#include <stdio.h>
#include <math.h>
#include <ctype.h>
int main(void)
{

printf("%u\n",-34);
short c;
//short与char类型的参数会被自动扩展为int型,因此-37转换为无符号整数时
//会出错,由于short转换为int类型从小转换为大,因此需要填充符号位.由于-37的
//最高符号位为1,输出为无符号整数时前面会自动填充为0,因此输出结果为4294967259这个极大正整数
c=-37;
printf("%u\n",c);


int n=1;
printf("%d decimal=%o octal= %X hex\n",n,n,n);


//%s格式项所对应输出的字符串必须以一个空字符'\0'作为结束标识
printf("There %s %d item%s in the list.\n",n!=1?"are" :"is",n,n!=1?"s":"");

//printf(s);
//printf("%s",s);

//NULL所指向的内容不能企图使用该指针所指向的内存中存储的内容
printf("%s\n",NULL);

printf("The decimal equivalent of '%c' is %d \n",'*','*');


printf("Pi=%g\n",4*atan(1.0));
printf("%g %g %g %g %g\n",1/1.0,1/2.0,1/3.0,1/4.0,0.0);
printf("%g\n",2.0/3.0);
printf("%g\n",123456789.0);
//对于比较小的数值,除非该数的指数小于或等于-5,%g格式项才会采用科学记数法来表示
printf("%g %g %g\n",3.14159e-3,3.14159e-4,3.14159e-5);

printf("%f\n",1e38);

//%%用于打印一个%字符
printf("%%d prints a decimal value\n");

//在某些机器中,以同样精度存储int型和long型的数值
long size=5;
printf("%d\n",size);
printf("%ld\n",size);

printf("%*%\n",-5);

char str[]="jkagkj";
printf("%*.*s\n",12,5,str);

//新增的格式码为%p与%u
int g;
printf("hello\n%n",&g);

//print



return 0;
}

putc宏解析###

宏putc在库文件stdio.h中的详细定义如下:

__CRT_INLINE int __cdecl __MINGW_NOTHROW putc (int __c, FILE* __F)
{
  return (--__F->_cnt >= 0)
    ?  (int) (unsigned char) (*__F->_ptr++ = (char)__c)
    :  _flsbuf (__c, __F);
}

其中putc的第一个参数为_c,是将要写入文件的字符,第二个参数__F则为一个指向一个用于描述文件的内部数据结构的指针,这里的__c由于是在条件表达式:的两侧,所以只会被求值一次,不会出现问题.
而__F这个指针,代表将要写入字符的文件,总是会被求值两次,但是由于它一般不需要进行递增递减之类有副作用的操作.但是这样也会出现一些错误.

short,char类型自动转换为int类型###

#include <stdio.h>
int main(void)
{

printf("%u\n",-34);
short c;
//short与char类型的参数会被自动扩展为int型,因此-37转换为无符号整数时
//会出错,由于short转换为int类型从小转换为大,因此需要填充符号位.由于-37的
//最高符号位为1,输出为无符号整数时前面会自动填充为0,因此输出结果为4294967259这个极大正整数
c=-37;
printf("%u\n",c);
return 0;
}

printf函数可变参数列表实现机制###

#define va_dcl                             int va_alist;
#define va_start(list)                   list=(char *) &va_alist
#define va_end(list)
#define va_arg(list,mode)          ((mode*) (list +=sizeof(mode))) [-1]

va_list是一个简单的字符型指针,宏va_start把它的参数设定为va_list的地址.
va_arg(list,mode),返回由va_list所指向的恰当类型的数值,同时递增va_list,使它指向参数列表中的下一个参数.使用下标-1来存取正确的返回参数.
注意:由于short,long类型和float类型会自动转换为int类型还有double类型,不能制定为mode这个参数的值.

机制2:使用stdarg.h
使用stdarg.h必须至少有一个固定类型的参数,后面可以跟一组未知数目,未知类型的参数.使用stdargs.h函数直接声明其固定参数,把最后一个固定参数作为va_start宏的参数,即以固定参数为基础.

#include <stdio.h>
#include <stdarg.h>

void error(char *format,...)
{
    va_list ap;
    va_start(ap,format);
    fprintf(stderr,"error: ");
    vfprintf(stderr,format,ap);
    va_end(ap);
    fprintf(stderr,"\n");
    exit(1);
}

EOF解析###

EOF(End of File),即文件结束符.
其定义为:#define EOF (-1).也就是说EOF代表一个整型常量-1,但一般文件的末尾不存在这个结束标识,那它又是如何判断是否到达文件末尾的呢?

1.对于文本文件来说:由于函数读取数据时是不会返回结果为-1的负数的,只有当没有数据可以读取时才会返回EOF,因此可以正常工作。

2.对于二进制文件而言,如果读取的数据为0xFF的话,此时返回值为-1,即EOF,但是这个时候又没有到达文件末尾,造成数据读取读取出现中途中断.

那如果判定二进制文件是否到达文件末尾?

1.在进行数据读取时,将返回的字符型数据定位为整型

若ch为char型,则当将返回值0x 00 00 00 FF返回时,取低8位赋给ch,那么此时ch为-1,此时会误判为到达文件末尾;

而若ch为int型,则当将返回值0x 00 00 00 FF返回时,ch的值为0x 00 00 00 FF,此时ch不为-1,不会误判为文件末尾。

(当然上面所述成立必须是在读取不出错的情况下才成立)

2.使用feof
其函数原型为:

int feof(FILE *fp),若到达文件末尾则返回一个非零值,否则返回0

 #define _IOEOF          0x0010

 #define feof(_stream)     ((_stream)->_flag & _IOEOF)

可知feof函数判断是否到达文件末尾时与_flag这个标志有关。

posted on 2015-09-27 09:51  陆游君语  阅读(144)  评论(0)    收藏  举报

导航