最近在复习C语言,要找工作啦,发现写下来总结下,有助于掌握和理解知识,当然里面有很多东西是网上找到,自己整理了下而已。
1.指针数组与数组指针
首先要明白优先级顺序:优先级:()>[]>*
先来看指针数组,定义int *p[10],[]优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。这里执行p+1时,则p指向下一个数组元素,可以这样*p=a; 这里*p表示指针数组第一个元素的值,a的首地址的值。
指针数组是多个指针变量,以数组形式存在内存当中,占有多个指针的存储空间。
再来看数组指针,定义 int (*p)[10],()优先级高,*与p先结合成为一个指针,即首先p是一个指针,指向一个整型的一维数组,这个一维数组的长度是10,也可以说是p的步长。也就是说执行p+1时,p要跨过n个整型数据的长度。
如要将二维数组赋给一指针,应这样赋值:
int a[3][4];
int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。
p=a; //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0]
p++; //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]
所以数组指针也称指向一维数组的指针,亦称行指针。
常见的难点
int main()
{
inta[4]={1,2,3,4};
int*ptr1=(int *)(&a+1);//指向a数组后面的内存单元,&a+1表示向后移16个存储单元
int*ptr2=(int *)((int)a+1);//表示a的存储单元的地址增加一个字节
printf("%x,%x",ptr1[-1],*ptr2);//ptr1[-1]其实指向的是a数组的最后一个单元,*ptr1则表示a数组的地址后移一个字节之后的4个连续存储单元所存储的值
return 0;
}
ptr1:将&a+1 的值强制转换成int*类型,赋值给int* 类型的变量ptr,ptr1 肯定指到数组a 的下一个int 类型数据了。ptr1[-1]被解析成*(ptr1-1),即ptr1 往后退4 个byte。所以其值为0x4。
ptr2:按照上面的讲解,(int)a+1 的值是元素a[0]的第二个字节的地址。然后把这个地址强制转换成int*类型的值赋给ptr2,也就是说*ptr2 的值应该为元素a[0]的第二个字节开始的连续4 个byte 的内容。
2指针函数与函数指针
指针函数:
例:int*f(x,y);
它是带指针的函数,本质是一个函数。
首先它是一个函数,只不过这个函数的返回值是一个地址值,经常使用在返回数组的某一元素地址上。函数返回值必须用同类型的指针变量来接受,也就是说,指针函数一定有函数返回值,而且,在主调函数中,函数返回值必须赋给同类型的指针变量。
例如:
float *fun();
float *p;
p = fun(a);
函数指针:
函数指针是指向函数的指针变量,即本质是一个指针变量
例:int(*f) (int x); /* 声明一个函数指针*/
f=func; /* 将func函数的首地址赋给指针f*/
指向函数的指针包含了函数的地址,其功能是通过它来调用函数。
举个例子:
void (*p1)(); 定义一个函数指针,同样也是根据优先级顺序,先是一个指针,再是一个函数。
void love(), hate(); 定义了两个函数
main()
{
p1= love;
(*p1)();//调用
p1= hate;
(*p1)();//调用
}
3指针与引用
1引用的基本问题:一般变量的引用和指针变量的引用
一般:
例int &b=a;表示b被声明为a的引用,对比赋值就是对a赋值注:引用使用时必须初始化,例如:int &c; 是错误的
指针变量的引用:
例:intb=10;
int a=1;
int *p=&a;// 声明整型的指针变量p指向a.
int* &pa=p;// 声明pa为指针变量p的引用。
当然还有参数引用和常量引用就不再细说了
指针和引用的区别:
NO1: 引用在创建的同事必须初始化,而指针在定义的时候可以不初始化,但指针在后面必须初始化。否则指针会成为野指针。
N02:引用一旦被初始化,就不能被另外一个对象引用,而指针是可以的。
NO3:引用不会指向空值,使用引用之前不用测试他的合法性,而指针需要。
NO4:由于不存在空值引用,引用也不会在初始化后指向另一个对象,因此比指针安全。