-
一、带参宏
宏只是简单的字符替换,带参宏的形参没有类型,带参函数有类型
#define S(a, b) a*b 注意具有副作用,加括号消除
eg:S(2+3, 4); <==> 2+3*4
- 二、选择性预编译
#ifdef....#else....#endif
#ifndef....#else....#endif 常用于头文件,防止重复编译
#ifndef __MAX_H__
#define __MAX_H__
...
#endif
#if......#else......#endif 可用于裁剪代码
#define AAA 0或1
#if AAA
...
#else
...
#endif
- 三、编译
动态编译:只是将可执行文件和库文件建立关系,编译后可执行文件小
静态编译:将库和.c文件一块编译到可执行文件,编译后可执行文件大,包含程序运行所需的全部库文件
可进行静态库和动态库的制作
- 四、指针
1、指针的定义
* :在定义的时候表示修饰,说明是指针变量;
在一行上定义多个指针变量,每个变量前都需要加*
* :单目运算符在其他时候表示取值
& :取地址
函数内部定义指针变量但是不赋初值,其值随机,导致指向不确定,产生野指针
2、指针类型
不同类型指针变量的大小相等,都是用来存放地址的;在32位平台下都是4字节
对应类型的指针只能保存对应类型数据的地址,否则需要强制类型转换
*p++具体加几个字节由指针类型决定
3、数组元素的引用方法
方法一:数组名[下标]
int a[10];
a[2]=100;
方法二:指针名[下标] 数组名就是数组的首地址 a<==>&a[0]
int a[10];
int *p;
p=a;
p[2]=100;//因为 p 和 a 等价
方法三:通过指针运算加取值的方法来引用数组元素
nt a[10];
int *p;
p=a;
*(p+2)=100;//也是可以的, 相当于 a[2]=100
4、指针的运算
指针可以加一个整数,往下指几个它指向的变量,结果还是个地址
在两个指针类型相同且指向同一个数组的元素时,两个指针变量可以比较大小,才有意义,指向前面元素的指针小于指向后面元素的指针
在两个指针类型相同且指向同一个数组的元素时,两个指针可以做减法,减法的结果是两个指针之间的元素个数
两个相同类型的指针可以相互赋值,类型不同时需要强制转换
5、指针数组(还是数组)
指针数组本身是个数组, 是个指针数组, 是若干个相同类型的指针变量构成的集合
常用于字符串操作
int * p[10];//定义了一个整型的指针数组 p, 有 10 个元素 p[0]~p[9]
#include <stdio.h>
int main(int argc, char *argv[])
{
char *name[5] = {"Follw me","BASIC","Greatwall","FORTRAN","Computer"};
int i;
for(i=0;i<5;i++)
{
printf("%s\n",name[i]);
}
return 0;
}
6、指针的指针
int a;
int *p;
p=&a;
//*p 等价于 a
int **q;
q=&p;
//*q 等价于 p
//**q 等价于 *p 等价于 a
int ***m;
m=&q;
//*(*(*m)) 等价于 a
p q m 都是指针变量, 都占 4 个字节, 都存放地址编号, 只不过类型不一样而已