预处理指令
以一个井号开头的行都叫做预处理指令。除了#include指令外,我们还经常用到#define指令。#define指令可以告诉编译器,编译时把代码中出现的特定标识当作什么来处理。例如,我们可以这样写:#define NAME_OF_MY_POTENTIAL_GF "ZPR"
这样,编译器会在编译前把代码中出现NAME_OF_MY_POTENTIAL_GF的地方全部替换成"ZPR"。这种替换是无条件的,但是有一个例外:当指定的标识属于某个字符串(被引号引起来)时替换不会发生。例如,下面两行代码会输出NAME_OF_MY_POTENTIAL_GF defined as: ZPRprintf("NAME_OF_MY_POTENTIAL_GF defined as: ");
printf(NAME_OF_MY_POTENTIAL_GF);
其中,后面那个NAME_OF_MY_POTENTIAL_GF被自动替换为"ZPR"。如果哪一天ZPR不要我了,我就可以非常方便地让整个程序适用于另一个MM。
C语言中通常会用#define代替const。例如,下面的代码假设了输入数据n<=2000。#include <stdio.h>
#define MAX 2000
int main()
{
int f[MAX][MAX];
int i,j,n;
scanf("%d",&n);
for ( i=0; i<n; i++ )
{
for ( j=0; j<=i; j++ )
{
f[i][j] = j ? (f[i-1][j] + f[i-1][j-1]) % 10000 : 1;
printf( "%5d" , f[i][j] );
}
printf("n");
}
return 0;
}
下面的这些指令也是合法的:#define begin {
#define end }
#define and &&
#define or ||
#define定义的指令允许带参数。例如,下面的定义也是合法的:#define sqr(x) x*x
观察下面的这个程序:#include <stdio.h>
#define begin {
#define end }
#define writeln(num) printf("%dn",num)
#define sqr(x) x*x
int main()
begin
writeln(sqr(100));
writeln(sqr(10+2));
end
程序输出:10000
32
为什么第二个输出的数是32不是144?不要忘了sqr中的x不是一个变量,编译器仅仅是把x替换为10+2,因此sqr(10+2)的结果是10+2*10+2,当然是32咯。为了避免这种情况,这样写就没问题了:#define sqr(x) ( (x) * (x) )
下面这个定义很常用:#define MAX(a,b) ( ((a) > (b)) ? (a) : (b) )
如果你想写出一个很有个性的C代码,反复使用#define是一个不错的选择。例如,这段代码就极具个性,一个光棍的形象跃然于屏幕上。然而,真正把#define发挥得淋漓尽致的,还是要数这段代码。
static声明
在函数中的变量声明前加一个static可以使这个变量具有“记忆性”。观察下面的程序:#include <stdio.h>
void printNum()
{
int a=1;
static int b=1;
printf("%d %dn", a++, b++);
}
int main()
{
int i;
for ( i=1; i<=5; i++ )
printNum();
return 0;
}
程序输出:1 1
1 2
1 3
1 4
1 5
short类型和int类型的范围
最初我们列出的C语言类型和Pascal类型的对比只能提供一个参考。事实上不同的编译器中short和int的范围可能不同。你可以查一下前面说过的limits.h来确定这些类型的实际范围。通常short是16位整数,long是32位整数。在Windows下Dev-C++中int类型是32位。
对64位整型的处理
和Free Pascal一样,对64位整数类型的处理总是比较麻烦。
首先,对long long赋值很可能会发生错误,你可以在常数后添加一个LL表明这是long long类型。其次,C语言中有些函数是要区分数据类型的,你需要根据数据类型选用恰当的函数。最后,long long类型的输出很可能也有问题,此时你可以用"%lld"来替换"%d",表明输出的是一个long long类型。在Windows下总要装点怪,我在Windows编译时非要用"%I64d"才行。
下面的程序代码在Windows下Dev-C++中一切正常。#include <stdio.h>
#include <stdlib.h>
int main()
{
long long a;
a = -5841314520LL;
a = llabs(a);
a = a + 1;
printf("%I64d",a);
return 0;
}
查漏补缺
这个系列到这里就结束了。还有我没有说到的语法点吗?欢迎大家补充。
后记
C语言速成手册到这里就结束了。这很可能是网上现有的原创C语言教材中讲解最快,篇幅最短的,因为它只适合已经学过其它语言,了解程序设计基础知识的人。这一系列的文章略过了大量的概念讲解、示例代码和习题,你可以自己在网上阅读一些C语言程序作为补充。以后我可能还会写一些类似的文章介绍其它语言。下一步我计划写C与C++的区别,对象和类的介绍以及C++的新特性。再以后我可能会向Java或者Ruby的方向发展。
祝各位努力转C的OIer暑假愉快。
Matrix67原创
转贴请注明出处