1.int *p,q; //定义整形指针p,整形变量q
如果两个都要定义成指针,可以这样写
int *q,*p;
或者用typedef 给特殊类型指定一个别名
typedef int* int_p;
int_p 则成为了(int *)类型的别名
int_p p,q;就可以定义两个指针
2.用const时注意它限定的是什么
int const *p ;// int const 跟 const int 含义一样 限定的是*p,因此p指向的那个值为一个常量 不能改变。
int* const p; //限定的是p,因此指针为常量指针,指针地址不能变,因此指向的变量不能变。
3.const定义的常量,用指针可以改。
int const num=1;
int *p=# //警告,类型不匹配
num=2; //错误,只读变量不能被修改
*p=2; //通过
这样,通过变量的地址可以“偷偷的”改变只读变量的值。编译器会给出警告,因此正确使用const,有助于
发现类似的错误。
4.void* 类型的指针跟任何其他类型指针完成自动转换都没有警告,同时对其使用*操作符也无意义。
NULL的定义是((void*)0),因此其与其他任何类型的指针直接进行赋值、比较等操作也不会有警告。
5.比较两种字符串
char str1[ ]=“hello”;
char str2[ ]=“hello”;
str1是字符数组,初始内容为hello,str1可代表数组的首地址,但本身不能被修改。str1的每个元素却可以被修改。
str2是字符指针,指向一个内容为hello的字符数组,str2本身的值可以修改,但是数组的元素不能修改。
6.函数指针的使用
int sum(int a,int b);//函数声明
int (*pfun)(int,int)=∑ //声明了一个返回整形指针的函数
事实上&操作符是不必要的
函数的本质是调用函数指针来实现的
int result;
result= (&sum)(2,3);
result=pfun(2,3);
result=sum(2,3);
三者都可以实现。
7.继续讲define //前面的总结提到了define
<1>定义宏的时候加上小括号,避免出现
#define sum 1+2
sum*3; //1+2*3=7
因此#define sum (1+2)
<2>#undef sum //去掉sum的宏定义
<3>带参数的宏
#define square ( i ) ( ( i ) * ( i ) )
sqr=square(a+b) //sqr=( (a+b) * (a+b) )
8.让参数出现
#define str(s) "s" //不论s给什么内容,展开后得到的都是s
#define str(s) #s //使用#表示的参数变成字符串 这样定义后str(hello) 就会展开成 hello
让参数出现的更特殊的情况
#define get(v) get_##v(void)
//这样get(name) 会展开为get_name(void)
9.宏与函数
#define swap_int(a,b) \
do{ \
int tmp; \
tmp=(a);(a)=(b);(b)=tmp; \
}while(0)
//do while(0)的作用是让它看起来更像一个函数,这样需要加上分号
也可以用typeof操作符,使之更有通用性
#define swap(a,b) \
do{ \
typeof(a) tmp; \
tmp=(a);(a)=(b);(b)=tmp; \
}while(0)
10.屏蔽代码
因为/* */ 注释不能嵌套
#if 0
{
............................................
process() ;
}
#endif