HeadFirstC笔记_13 十大遗漏知识点

#1.  运算符
递增与递减
递增将数字加1,递减将数字减1
   
    
    
  1. ++i; // 递增1,返回新值
  2. i++; // 递增1,返回旧值
  3. --i; // 递减1,返回新值
  4. i--; // 递减1,返回旧值
  5. //这些表达式都会改变 i 的值
  6. //++ 和 -- 的位置决定了表达式返回i 的原始值还是新值,例如:
  7. int i = 3;
  8. int j = i++; //这行代码执行以后,j==3,i==4。

三目运算符
   
    
    
  1. if (x == 1)
  2. return 2;
  3. else
  4. return 3;
  5. // 上面的可以简写为:
  6. return (x == 1) ? 2 : 3;

位运算
运算符 说明
~a a 中所有位都取反
a & b a 中的位“与” b 中的位
a | b a中的位“或”b中的位
a ^ b a 中的位“异或” b 中的位
<< 位左移(值增加)
>> 位右移(值减小)
<< 运算符可以用来快速地将某个整型值乘以2的幂,但小心 千万别溢出。

用逗号分割表达式
如果你想在循环末尾执行多个运算怎么办?可以使用逗号 运算符:
   
    
    
  1. for (i = 0; i < 10; i++, j++){ //递增i和j
  2. ......
  3. }

#2.  预处理指令
每次你在编译一个包含头文件的程序时都使用了预处理指令:
    
     
     
  1. #include <stdio.h>
预处理器会扫描C源文件然后生成一个修改过的版本,编译器 会使用这个修改后的文件编译程序。对 #include 这条指令来 说,预处理器会插入stdio.h文件的内容。
指令总是出现在行首, 以井号( # )字符开头。除了 #include ,用得最多的指令就 是 #define :
     
      
      
  1. #define DAYS_OF_THE_WEEK 7
  2. ...
  3. printf(" 一星期有 %i 天 \n", DAYS_OF_THE_WEEK);
#define 指令创建了一个宏,预处理器会扫描整个C源文件然 后把宏的名字替换为它的值。
宏不是变量,因为它的值在运行时无法改变
宏在程序编译前就被替换掉了,你甚至可以创建 功能类似函数的宏:
      
       
       
  1. #define ADD_ONE(x) ((x) + 1) //x是宏的参数,要注意在宏中加括号。
  2. ...
  3. printf(" 答案是 %i\n", ADD_ONE(3));

条件编译
条件编译可以开、 关部分源代码:
如下面,SPANISH 宏定义与否会改变这段代码的编译方式
      
       
       
  1. #ifdef SPANISH // 如果SPANISH这个宏存在
  2. char *greeting = "Hola"; // 就包含这段代码
  3. #else
  4. char *greeting = "Hello"; //否则就包含这段
  5. #endif
#ifdef 和 #endif 总是成对出现,就像if{...}的大括号一样。

#3.  static关键字
想象你要创建一个带有计数功能的函数,可以这么写:
   
    
    
  1. int count = 0;
  2. int counter()
  3. {
  4. return ++count;
  5. }
这段代码有什么问题吗?它使用了一个叫 count 的全局变量。 因为 count 在全局作用域,所以其他函数可以修改它的值。如 果你在写一个大型程序,就需要小心控制全局变量的个数,因 为它们可能导致代码出错。
好在C语言允许你创建只能在函数 局部作用域访问的全局变量:
      
       
       
  1. /**
  2. * static关键字表示将在两次counter()函数调用期间保持该变量的值。
  3. * 虽然count是全局变量,但它只能在函数内部访问.
  4. * static 关键字会把变量保存在存储器中的全局量区,
  5. * 但是当其他函数试图访问 count变量时编译器会抛出错误。
  6. */
  7. int counter() {
  8. static int count;
  9. if (count == 0)
  10. count++;
  11. else
  12. count = count + 10;
  13. return count;
  14. }
  15. int main() {
  16. printf(" count= %i\n", counter());
  17. printf(" count= %i\n", counter()); // 第二次调用时,count已经变了,尽管又声明了一次
  18. // printf(" count= %i\n", count); // 编译报错
  19. return 0;
  20. }
运行结果:

用static定义私有变量或函数
也可以在 函数外使用 static 关键字,它表示“只有这个.c文件 中的代码能使用这个变量(或函数)”。
static 关键字用来控制变量或函数的作用域,防止其他代码 以意想不到的方式访问你的数据或函数。 例如:
       
        
        
  1. static int days = 365; //只能在这个源文件中使用这个变量,类似java中的private
  2. //只能在这个源文件中使用这个函数
  3. static void update_account(int x) {
  4. ...
  5. }

#4.  数据类型的大小
你已经知道了怎么用 sizeof 运算符来查看数据类型在存储器中
的大小,但如果你想知道数据类保存的值的范围呢?例如,你
知道 int 在你的机器上占4字节,但 int 变量能保存的最大正数
和最小负数分别是多少呢?理论上可以通过它占用的字节数计
算出来,但这很麻烦。
可以使用定义在 <limits.h>头文件中的宏。
通过  LONG_MAX 宏,可以查看
long 可以保存的最大值,
通过  SHRT_MIN  宏,可以查看short  可以保存的最小值,其他的以此类推。
int INT
short SHRT
long LONG
char CHAR
float FLT
double DBL
你可以在它们后面加上 _ MAX (最大正数)或 _MIN (最小负数)。
如果想查看更具体的数据类型, 还可以加上前缀U(unsigned)、S(signed)或L(long)。
    
     
     
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <limits.h>
  4. int main() {
  5. // 如果你想知道long 可以保存的最大值,可以使用 LONG_MAX 宏
  6. printf("On this machine an int takes up %lu bytes\n", sizeof(int));
  7. printf("And ints can store values from %i to %i\n", INT_MIN, INT_MAX);
  8. printf("And shorts can store values from %i to %i\n", SHRT_MIN, SHRT_MAX);
  9. return 0;
  10. }
运行结果:
 
#5. 自动化测试
测试代码的重要性不言而喻,如果能把测试的过程自动化,生 活会变得更轻松。几乎所有程序员现在都在使用自动化测 试,C语言的测试框架也不胜枚举,而在Head First实验室最受 欢迎的是AceUnit:  http://aceunit.sourceforge.net/projects/aceunit
AceUnit和其他语言中的xUnit框架很像(比如NUnit和JUnit)。
如果你写的是命令行工具,用的是Unix的命令行,还有一个好 用的工具叫 shunit2:  http://code.google.com/p/shunit2/
shunit2 允许创建shell脚本来测试脚本和命令。

#6.  再谈gcc
gcc还可 以做更多的事:
优化
如果 gcc 发现你在循 环中对一个变量赋了相同的值,它就会把赋值语句移动到循环 外;
如果一个小函数只在少数几个地方用到了, gcc 就会把它 转化为内联代码,然后插到程序中。
虽然 gcc 可以做很多优化,但绝大多数优化选项默认是关闭的。 为什么?因为优化需要花很长时间,如果你尚处于开发阶段, 通常希望快速编译代码。一旦准备发布代码,就可以打开优化 选项。 
gcc 一共有四个级别的优化:
标志 描述
-O 如果在 gcc 命令中加上 -O (字母O)标志,就能得到第一级别的优 化。
-O2 如果想提升优化等级,降低编译速度,就选择 -O2 。
-O3 如果想再升一级,就选 -O3 ,它会使用 -O 和 -O2 中的所有优化,再 附加一些额外的优化。
-Ofast -Ofast 会打开最高级别的优化,同时编译速度也会降到最低。谨慎 使用 -Ofast,因为它生成的代码可能和C标准相去甚远。
警告
如果代码没有严重错误,但做了一些可疑的事情,比如把一个 类型的值赋给一个错误类型的变量,编译器就会显示警告。
可以用 -Wall 选项提高警告检查的门槛:
     
      
      
  1. 命令:gcc fred.c -Wall -o fred
-Wall 选项表示“所有警告(All Warnings)”,但因为一些历 史原因, -Wall 其实并不会显示所有的警告。如果你想让 gcc 那么做,就必须加上 -Wextra 选项:
      
       
       
  1. 命令:gcc fred.c -Wall -Wextra -o fred
如果你希望遵循严格的编译,就可以使用 -Werror 选项,只要 有一个警告,编译就会失败:
       
        
        
  1. 命令:gcc fred.c -Werror -o fred //它表示“把警告当错误处理”
当多人开发同一个项目时, -Werror 就显得特别有用,因为它 可以维持代码的质量。
更多 gcc 选项请参阅:  http://gcc.gnu.org/onlinedocs/gcc

#7.  再谈make
make 是构建C程序的强大工具,但在本书中你只使用过一些 简单的命令。为了看到更多 make 神奇的功能,请阅读Robert   Mecklenburg的《GNU Make项目管理》: http://shop.oreilly.com/product/9780596006105.do
这里先列举 make 的一些特性。
变量
变量可以大大缩短你的makefile,例如你想把一组标准的命令 行选项传给 gcc ,就可以把它们定义成变量,
可以用等号(=)定义变量,然后用 $(...) 读取变量的值,如:
         
          
          
  1. CFLAGS = -Wall -Wextra -v
  2. fred: fred.c
  3. gcc fred.c $(CFLAGS) -o fred
使用%、^和 @
很多编译命令看起来都很像:
        
         
         
  1. fred: fred.c
  2. gcc fred.c -Wall -o fred
这时你可以用 % 符号写一条更通用的“目标/生成方法”:
         
          
          
  1. %: %.c // 假设你想根据<文件>.c创建<文件>。
  2. gcc $^ -Wall -o $@
  3. // $^是依赖项的值(.c文件)
  4. // $@是目标的名字
这些符号看起来有些奇怪。假设你想创建一个叫fred的文件, 这条规则会让 make去寻找一个叫fred.c的文件,然后生成方法 会运行一条 gcc 命令,用依赖项(由特殊符号 $^ 给出)创建目 标fred(由 $@ 给出)。

隐式规则
make 工具对编译过程一清二楚,即使你不告诉它如何构建 文件,它也可以使用隐式规则自行构建。
例如,你有一个 叫fred.c的文件,但没有makefile,可以用以下命令编译它:

 即使我们不告诉make怎么 编译,它同样创建了编译 命令,这是一条隐式规则.
原因是 make 内置了一批生成方法。关于 make 的更多信息,请 参见:

#8.  开发工具
gdb
gdb (GNU Project Debugger,GNU调试器)允许你在程序运 行期间研究它的代码。如果你想找出代码中隐蔽的错误,会发 现它特别有用。 gdb 既可以在命令行中使用,也可在Xcode或 Guile那样的IDE中使用。
gprof
如果你的程序没有预期的那么快,就有必要分析一下它的性 能。 gprof (GNU Profiler,GNU分析器)可以告诉你程序中 哪个部分是最慢的,这样你就能进行适当优化。 gprof 会修改 程序,修改后的程序在结束时会生成一份性能报告,然后你可 以用 gprof 命令行工具分析它,找到程序的瓶颈所在。
gcov
还有一个分析工具叫 gcov (GNU Coverage,GNU覆盖率测试 工具)。 gprof 用来检查你代码的性能,而 gcov 用来检查代码 中哪些部分运行了,哪些部分没运行。这在写自动化测试时特 别有用,因为你需要保证测试代码覆盖了所有你想覆盖的代码。 http://gcc.gnu.org/onlinedocs/gcc/Gcov.html

#9.  创建GUI
Linux——GTK
Linux有很多库可以用来创建GUI程序,其中最有名的要属 GTK+(GIMP toolkit,GIMP工具包): http://www.gtk.org/
GTK+常用于Linux程序中,但你也可以在Windows和Mac中 使用它。
Windows
Windows自带了十分高级的GUI库。Windows编程是非常专业 的领域,在你开始创建GUI程序前,可能需要花一点时间来 学习Windows API(Application Programming Interface,应用 程序编程接口)。越来越多Windows程序开始用基于C的语言 来开发,例如C#和C++。以下是Windows编程的在线介绍:
Mac——Carbon
苹果的GUI系统叫Aqua。如果你想在Mac上用C语言写GUI程 序,可以用Carbon库,不过更时髦的方式是用Cocoa库,它需 要用C语言的另一个后代Objective-C来编程。现在你已经来到 了本书的终点,正是学习Objective-C的大好时机,Head First 实验室的人对“书呆子牧场”出品的Mac编程书籍和课程爱不 释手:

#10.  参考资料
以下是一些热门的C编程书籍和网站:
C程序设计语言》
Brian W. Kernighan,Dennis M. Ritchie著
C语言的开山之作, C程序员应该人手一本。
《C语言参考手册》
Samuel P. Harbison,Guy L. Steele Jr.著
很好的C语言参考书,你在写代码时一定希望边上放着这本书。
《C专家编程》
Peter van der Linden著
如果你想了解更多高级C语言编程技巧就去看Peter van der Linden 的这部佳作。
《实用C语言编程》
Steve Oualline著
这本书列出了一些实用的C语言开发细节。

网站:
关于C标准: 
更多C教程:
综合参考资料:
综合C编程教程:




猜你喜欢

转载自blog.csdn.net/woshiwangbiao/article/details/53884054