C陷阱和指针基础(三)

*为了保持与过去不能同时进行读写操作的程序向下兼容,一个输入操作不能随后紧跟一个输出操作,反之亦然,如果要同时进行输入输出操作,必须在其中插入fseek函数的调用

*getchar没有输入是返回EOF

* char c; while((c = getchar()) != EOF)有些编译器处理过程:对函数getchar的返回值做截断处理,并把低端字节部分赋给变量c,但比较表达式中并不是比较c与EOF,而是比较getchar的返回值与EOF

*库函数setbuf允许程序员进行实际的写操作之前控制产生的输出数据量,setbuf(stdout,buf);通知输入输出库,所有写入到stdout的输出都应用buf做输出缓冲区,知道buf缓冲区被填满,或者程序员直接调用fflush。buf缓冲区的内容才实际写入stdout中。缓冲区大小由系统头文件stdio.h的BUFSIZ定义

*main函数结束后,作为程序交回控制给操作系统之前,c运行时库要进行清理。避免清理以释放的变量的方法:方法一:显示声明为静态。方法二:声明移到main函数之外(动态分配缓冲区,在程序中并不主动释放分配的缓冲区,因为缓冲区是动态分配的,所以main函数结束时并不释放该缓冲区,这样C运行时库进行清理工作时就不会发生缓冲区以释放的情况)

*宏提供了一种对组成C程序的字符进行变换的方式,而并不作用于程序中的对象。

*如果希望定义f(x)为((x)-1),必须写:#define f(x) ((x)-1) f与(x)不能有空格(此规则不适用于宏调用,只对宏定义适用

*#define toupper(c)  (( c ) >= 'a' && (c) <= 'z' ? (c)+('A'-'a'):(c))

*assert宏的参数是一个表达式,如果该表达式为0,就使程序终止执行,并给出一条适当的出错消息,把assert作为宏来处理,这样就是的我们可以在出错信息中包括有文件名和断言失败处的行号

*宏assert的定义:#define assert(e) ((void)((e) || _assert_error(_FILE_,_LINE_))),此处利用了||的短路性质

*宏的一个常见用途是:使多个不同变量的类型可在一个地方说明

*setbuf可以接受一个空指针作为其第二个参数,这使得setbuf变为非缓冲的,运行变慢。

*#typedef struct foo FOOTYPE;定义了FOOTYPE为一个新的类型,与struct foo完全等效

*#define T1 struct foo *

  typedef struct foo *T2

  T1,T2都是指向结构foo的指针

  T1 a,b;

  T2 a,b;

 第一个被扩展为:struct foo *a,b;错误

 第二个定义了a,b都是指向结构的指针,因为这里T2的行为完全与一个真实的类型相同

*ansi c标准:c实现必须能够区别出前6个字符不同的外部名称,没有区别大写字母与其对应的小写字母

*c字符长度有硬件特性决定

*ansi要求long型整数的长度至少应是32位,而short型和ing型至少是16位

*将字符C转换 为无符号整数时,C将首先被转换为int型整数

*char到int,多余的位将被简单丢弃

*编程者如果关注向右移位时空出的位,那么可以将操作的变量声明为无符号整数,那么空出的为都会被设置为0

*如果被移位的对象长度是n位,那么移位计数必须大于或等于0,而严格小于n(因此不能做到在单次操作中将某个数值中的所有位都移出)

*ansi 标准定义了一个常数RAND_MAX,它的值等于随机数的最大取值

*unix中如果ptr指向的是一块最近一次调用malloc,realloc或calloc分配的内存,即使这块内存已被释放,realloc函数仍然可以工作,因此,可以通过调节free,malloc,realloc的调用顺序,充分利用malloc函数的搜索策略来压缩存储空间。

*( (int)(n%10) + '0')把n的十进制表示的末位数字转换为字符形式,里面的加法操作实际上假定了在机器的字符集中数字式顺序排放,没有间隔的,这样才有‘0’+5的值与‘5’相同。这种假定对某些机器来说可能出错。解决:使用一张代表数字的字符集,因一个字符串常量可以用来表示一个字符数组,所以在数组名出现的地方都可以用字符串常量来替换。上句可改成:("0123456789"[n%10]);

*while ( c == '/t' || c =' ' || c == '/n') c = getc(f);非法,因为=得优先级最低,上式可被解释为:while( (c == '/t' || c) = (' ' || c == '/n'))

*常量尽量放在判断相等的比较表达式的左侧,这样若将==写成了=,编译器可以检查出来。

*考察最简单的特例

*防御性编程:对程序用户和编译器实现的假设不要过多。

*/*/**/对于一个允许嵌套注释的C编译器,无论上面的符号序列后面跟什么,都属于注释的一部分,而对于不允许嵌套注释的C编译器,后面跟的就是实实在在的代码内容

/*/**/"*/"/*"/**/允许嵌套情况下,等效于:"*/",不允许嵌套时等效于:"/*"

 

/*/*/0*/**/1 允许嵌套时等效于:/* /* /0 */ * */ 1值为1

                     不允许嵌套时等效于:/*  /  */  0*  /**/  1值为0*1,也就是0

*移位运算符的优先级低于算术运算符的优先级

*某些C语言实现中,存在着两种不同版本的printf函数,其中一种实现了用于表示浮点格式的项:%e,%f,%g等,而另一种却没有实现这种浮点格式。某些操作系统上,编程者必须显示的通知连接器是否用到了浮点运算,另一些系统则是通过编译器来告知连接器在程序中是否出现了浮点运算

*main() { printf("%g/n",sqrt(2));}可能打印%g,因为连接器可能再从库文件中提取出sqrt前,已经作出了使用何种版本的printf函数的决定

*一个异常终止的程序可能没有机会来请空气输出缓冲区,因此,改程序生成的输出可能位于内存的某个位置,但却永远不会被写出了,解决:调试时不允许对输出进行缓冲,setbuf(stdout,(char *)0);注意:这个语句必须在任何输出被写入到stdout(包括任何对printf函数的调用)之前执行,该语句最恰当的位置就是作为main函数的第一个语句

*getchar常被实现为宏,这个宏在stdio。h头文件中定义,如果一个程序没有包含这个头文件,编译器对getchar的定义就一无所知,这种情况下,编译器会假定gerchar是一个返回类型为整形的函数,程序中忘记包含stdio。h头文件的效果就在在所有getchar宏出现的地方,都用getchar函数调用来替换getchar宏

*printf函数并不打印出%字符,而是查看紧跟%字符之后的若干字符,以获得有关如何转换其下一个参数的指示

*sprintf函数生成的输出数据总是以空字符收尾,如果希望在输出数据中出现一个空字符,我们可以显示地使用%c格式说明把它打印出来

*fprintf,printf,sprintf的返回值都是以传送的字符数,对于sprintf,作为输出数据结束标志的空字符并不计入总的字符数。如果printf和fprintf在试图写入时出现一个I/O错误,将返回一个负值,sprintf函数并不进行I/O操作,因此他不会返回负值

*%x格式项中用小写字母a,b,c。。。f表示10到15的数位值,而%X格式项用大写字母A,B,C。。。F来表示

*8进制和16进制整数总是作为无符号数处理

*%s打印字符串,一直对应得参数是一个字符指针,带输出的字符使与该指针所指向的地址,知道出现一个空字符'/0'才终止

*%s所对应输出的字符串必须以一个空字符('/0')作为结束标志,因为printf函数以此来定位一个字符串何时结束,如果以%s对应的字符串并不是以空字符作结束标志,那么printf函数将不断打印出其后的字符,知道在内存中某处找到一个空字符

*printf(s);把字符s中的任何%字符视为一个格式项的标志

*printf(“%s”,s);打印出任何以空字符结尾的字符串

*%g格式项用于打印那些不需按列对齐的浮点数特别有效,打印时会去掉该数值尾缀的零,保留6位有效数字,当一个数的绝对值大于999999时,%g将采用科学计数法打印,四舍五入到六位有效数字,对于比较小的数值,除非该数的指数小于或等于-5,%g格式项才会采用科学计数法来表示

*%e指数形式,小数点后6位

*%f强制禁止使用指数形式来表示浮点数,保留小数点后6位有效数字

*%%打印一个%字符

*宽度修饰符绝对不会截断一个输出域,待输出数值不能填满位置时,他的左侧会补上空格,带打印的数值太大而超过了指定的域宽时,输出域会适当调整以容纳该数值

*宽度修饰符对所有的格式码都有效,甚至%%也不例外,%8%

*%对于整数格式项%d,%u,%x,%o,精度修饰符指定了打印数字的最少位数,对于%f,%e,%E格式项,精度修饰符指定了小数点后应该出现的数字位数,对于%g,%G精度修饰符指定了打印数值中的有效数字位数,对于%C与%%格式项,精度修饰符将被忽略

*标志字符-的作用是:要求显示方式改为左端对齐,有段填充空白字符(仅当域宽修饰符存在时,-才有意义)

*标志字符+的作用是:规定每个待打印的数值在输出时都应该以它的符号作为第一个字符

*空白字符作为标志字符时,含义是:如果某数是一个非负数,就在他的前面插入一个空白字符,+与空白字符同时出现在一个格式项中,最终效果以+为准

*标志字符#用于微调

*printf(“%*%/n”,n)在宽度为n个字符的域内以右端对齐的方式打印出一个%符号

*新增格式码%p用于以某种形式打印一个指针,%n用于指出已经打印的字符数,这个数被存储在对应参数所指向的整数中

*废止格式项:%D,%O

*in due course在适当的时候

 assignment statement 赋值语句,指派陈述

 braces花括号

 indentation缩进

 multiply by乘以

 fractional part 小数部分

 in particular 尤其,特别

 floating-point arithmetic 浮点运算,整数的除法会截断

 decimal point 小数点

 octal八进制的

 hexadecimal 十六进制

 numetic value数值

 bare-bones极简单的

 escape sequence转义序列

 be identical to与相同

*产生1到10 之间的随机数:srand((int)time(0))

                                       int j = 1 + (int)(10.0*rand()/(RAND_MAX+1.0))

*coordinated universal time(UTC)世界标准时间即GMT

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值