1、指针的类型和指针所指向的类型
如定义一个指针 int *ptr, 指针ptr的类型是int*,而指针所指向的类型是int。
例1:
int *p; //指针p类型是int* int a; char b; p=&a; //指针p指向类型是int,a为int型,该语句可使p指向a *p=10; //即使得a=10 但语句 p=&b; 错误,因为在声明语句int *p; 中就表示了p指向的类型是int,而b是char类型,故该语句不合法
2、*与&的理解
&为取地址运算,运算结果是个指针,如&a表示a的地址,如a是int型,则结果为int *,可以有int *p=&a;
*是间接运算,如*p表示p指向的东西,即以p为地址的存储单元里的东西,可以有int b=*p;(p要先初始化,不然p未指向任何地址,是个不确定的东西,该语句就不正确,这里仅作示意就省略了。。。)
例2:
int a=12; int b; int *p; int **ptr; p=&a;//&a的结果是一个指针,类型是int*,指向的类型是int,指向的地址是a的地址。 *p=24;//*p的结果,在这里它的类型是int,它所占用的地址是p所指向的地址,显然,*p就是变量a。 ptr=&p;//&p的结果是个指针,该指针的类型是p的类型加个*,在这里是int**。该指针所指向的类型是p的类型,这里是int*。该指针所指向的地址就是指针p自己的地址。 *ptr=&b;//*ptr是个指针,&b的结果也是个指针,且这两个指针的类型和所指向的类型是一样的,所以?amp;b来给*ptr赋值就是毫无问题的了。 p重新指向b,即p=&b; **ptr=34;//*ptr的结果是ptr所指向的东西,在这里是一个指针,对这个指针再做一次*运算,结果就是一个int类型的变量。 即使得b=34;
3、数组和指针的关系
声明了一个数组TYPE array[n],则数组名称array就有了两重含义:
第一,它代表整个数组,它的类型是TYPE [n];
第二,它是一个指针,该指针的类型是TYPE*,该指针指向的类型是TYPE,也就是数组单元的类型,该指针指向的内存区就是数组第0号单元,该指针自己占有单独的内存区,注意它和数组第0号单元占据的内存区是不同的。该指针的值是不能修改的,即类似array++的表达式是错误的。(而*(array+1)可以,这只是访问元素,并没有使得array=array+1)
访问数组可以通过array[i]或者*(array+i)的方式进行,两者含义相同。
例3
char *str[3]={ "Hello,this is a sample!", "Hi,good morning.", "Hello world" }; char s[80]; strcpy(s,str[0]);//也可写成strcpy(s,*str); strcpy(s,str[1]);//也可写成strcpy(s,*(str+1)); strcpy(s,str[2]);//也可写成strcpy(s,*(str+2));
上例中,str是一个三单元的数组,该数组的每个单元都是一个指针,这些指针各指向一个字符串。把指针数组名str当作一个指针的话,它指向数组的第0号单元,它的类型是char**,它指向的类型是char *。
*str也是一个指针,它的类型是char*,它所指向的类型是char,它指向的地址是字符串"Hello,this is a sample!"的第一个字符的地址,即‘H‘的地址。 str+1也是一个指针,它指向数组的第1号单元,它的类型是char**,它指向的类型是char *。
*(str+1)也是一个指针,它的类型是char*,它所指向的类型是char,它指向"Hi,good morning."的第一个字符‘H‘,等等。
4、指针和结构类型的关系
例4
struct MyStruct { int a; int b; int c; } MyStruct ss={20,30,40};//声明了结构对象ss,并把ss的三个成员初始化为20,30和40。 MyStruct *ptr=&ss;//声明了一个指向结构对象ss的指针。它的类型是MyStruct*,它指向的类型是MyStruct。 int *pstr=(int*)&ss;//声明了一个指向结构对象ss的指针。但是它的类型和它指向的类型和ptr是不同的。 //比较推荐的访问结构体元素的方式是:ptr->a; ptr->b; ptr->c;
5、指针和函数的关系
可以把一个指针声明成为一个指向函数的指针。
例5
int fun1(char*,int); int (*pfun1)(char*,int); pfun1=fun1; .... .... int a=(*pfun1)("abcdefg",7);//通过函数指针调用函数。
int a= fun1("abcdefg",7); //常用的函数名调用函数
函数的指针很少用,一般调用函数直接用函数名即可,两种方式结果相同。
本文是在参考了http://www.cnblogs.com/ggjucheng/archive/2011/12/13/2286391.html的 基础上总结了自己的 一点理解。