1到4章知识点总结

  • 临近期末考试,感觉C基础语法(尤其是指针)忘得太多了,所以第一次(也是最后一次)把书从头到尾仔细地翻了一遍,发现了好多有意思的东西 (或许你可能觉得没意思QAQ),真长见识了,可惜大部分都不是考点,难受TAT

第一章 概述

  • IOCCC国际模糊C代码大赛 (International Obfuscated C Code Contest)
v,i,j,k,l,s,a[99];
main()
{
	for(scanf("%d",&s); *a-s; v=a[j*=v]-a[i],k=i<s,j+=(v=j<s&&
	(!k&&!!printf(2+"\n\n%c"-(!l<<!j)," #Q"[1^v?(1^j)&1:2])&&
	++l||a[i]<s&&v&&v-i+j&&v+i-j))&&!(1%=s),v||(i==j?a[i+=k]=0:
	++a[i])>=s*k&&++a[--i])
		;
}
  • 额,这不是乱码诶。。。
  • 这个程序是由Doron Osovlanski 和 Baruch Nissenbaum共同编写的,其功能是打印出八皇后问题(此问题要求在一个棋盘上放置8个皇后,使得皇后之间不会出现相互“攻击”的局面)的全部解决方案。
  • 事实上,此程序可用于求解皇后数量在4~99范围内的全部问题,更多的获奖程序可以到竞赛网站www.ioccc.org获取。

问与答 P5

  • lint是做什么的?
  • lint这个名字是如何得来的?
  • 如何获得lint?
  • 有没有办法在不使用lint的情况下强制编译器进行更彻底的错误检查?
    多级警告?
  • 我很关心能让程序尽可能可靠的方法。除了lint和调试工具以外,还有其他有效的工具吗?
    越界检查工具 bounds-checker?
    内存泄漏监测工具 leak-finder?

第二章 基本概念

  • 3种注释方法
    (1)/* */
    (2)//
    (3)#define DEBUG 0
    #if DEBUG
    #endif

问与答 P21

  • GCC是什么的简称?
  • 明白了,但GNU又是什么意思呢?
  • GCC有什么过人之处呢?
  • GCC发现程序中错误的能力如何?
  • 为什么C语言如此简明扼要?如果在C语言中用begin和end代替{ 和 },用integer代替int,如此等等,程序似乎更加易读。
  • 在某些C语言书中,main函数的结尾使用的是exit(0)而不是return=0,二者是否一样呢?
  • 如果main函数末尾没有return语句会产生什么后果?
  • 编译器是完全移除注释还是用空格替换掉注释呢?
  • 如何发现程序有没有未终止的注释?
  • 在一个注释中嵌套另一个注释是否合法?
  • float类型的名字由何而来?
  • 为什么浮点常量需要以字母f结尾?
  • 对标识符的长度真的没有限制吗?
  • 缩进时应该使用多少空格?

第三章 格式化输入/输出

问与答 P33

  • 转换说明%i也可以用于读写整数。%i和%d之间有什么区别?
  • 如果printf函数将%作为转换说明的开始,那么如何显示字符%呢?
  • 转义序列 \t 会使printf函数跳到下一个水平制表符处。如何知道水平制表符到底跳多远呢?
  • 我不能理解scanf函数如何把字符“放回原处”并在以后再次读取。
  • 如果用户在两个数之间加入了标点符号(如逗号),scanf函数将如何处理?

第四章 表达式

  • 运算符/可能产生意外的结果:当两个操作数都是整数时,运算符/会丢掉分数部分来“截取”结果。因此,1/2的结果是0而不是0.5。

  • 运算符%要求操作数是整数。如果两个操作数中有一个不是整数,程序将无法编译通过。

  • 把零用作/或%的右操作数会导致未定义的行为

  • 当运算符/和运算符%用于负操作数时,其结果难以确定。
    根据C89标准,如果两个操作数中有一个为负数,那么除法的结果既可以向上取整也可以向下取整。(例如,-9/7的结果既可以是-1也可以是-2)
    在C89中,如果i或者j是负数,i%j的符号与具体实现有关。(例如,-9%7的值可能是-2或者5)
    但是在C99中,除法的结果总是向零截取的 (因此-9/7的结果是-1),
    i%j的值的符号与i的相同(因此-9%7的值是-2)。

  • v = e
    如果v和e的类型不同,那么赋值运算发生时会把e的值转化为v的类型。
    副作用

  • 注意由于存在类型转换,串在一起的赋值运算的最终结果可能不是预期的结果
    int i;
    float f;
    f = i = 33.3f;
    首先把数值33赋值给变量i,然后把33.0 (而不是预期的33.3)赋值给变量f。

  • 既然赋值运算符要求左操作数是左值,那么在赋值表达式的左侧放置任何其他类型的表达式都是不合法的
    12 = i; //WRONG
    i + j = 0; //WRONG
    -i = j; //WRONG
    编译器会检测出这种错误,并给出诸如“invalid value in assignment"这样的错误消息。

  • 在使用复合赋值运算符时,注意不要交换组成运算符的两个字符的位置。
    交换字符位置产生的表达式也许可以被编译器接受,但不会有预期的意义。
    例如,原打算写表达式i += j但却写成了i =+ j,程序也能够通过编译。但是,后一个表达式i =+ j等价于表达式i = (+j ),只是简单地把 j 的值赋给i。

  • 在表达式中,既在某处访问变量的值又在别处修改它的值是不可取的。
    表达式(b = a+2) - (a = 1)既访问了a的值(为了计算a + 2),又(通过赋值为1)修改了a的值。
    有些编译器在遇到这样的表达式时会产生一条类似 “operation on‘a’may be undefined"的警告消息。

问与答 P45

  • 我注意到C语言没有指数运算符。如何求一个数的幂呢?
  • 我想把%运算符用于浮点数,但程序无法通过编译。该怎么办?
  • 当/运算符和%运算符的操作数是负数时,为什么规则那么复杂?
  • 如果C语言有左值,那么它也有右值吗?
  • 前面提到:如果v有副作用那么v += e不等价于y = v+e。可以解释一下吗?
  • C语言为什么提供++和- -运算符?它们是比其他的自增、自减方法执行得快,还是仅仅更便捷?
  • ++和–是否可以处理float型变量?
  • 在使用后缀形式的++或–时,何时执行自增或自减操作?
  • 丢掉表达式语句的值意味着什么?
  • 但是类似 i = 1; 这样的语句会如何呢? 我没发现有什么东西被丢掉了。

猜你喜欢

转载自blog.csdn.net/qq_42815188/article/details/85564479