指针变量
什么是指针?
直接访问:通过变量地址直接存取变量值;
间接访问:通过特殊变量存的地址,再访问变量的值;
这个专门存储其他变量地址的特殊变量就是指针变量,他的值就是地址;
在X86平台,指针占4字节,X64平台占8字节;
变量的指针与指向变量的指针变量
变量的指针:变量的地址,因此指针就是地址;
指向变量的指针变量:一个变量存放另一个变量的地址,则该变量就是指向另一个变量的指针变量;
定义:类型 *ptr;
*ptr++:*与++优先级同级,但是结合顺序从右往左,等价于*(ptr++),而ptr++表示指针越过所指类型字节数的地址;
指针变量作为函数参数
引用传递而非单向值传递,传入地址进函数,对其修改可反馈带实参指向变量;
指向数组元素的指针变量
定义与赋值
int arr[]={1,2,3,4,5};
int *parr=&arr[0];//int *parr=arr;
通过指针引用数组
使用方法一:
arr[n]=*(parr+n)=*(arr+n)//但是没有arr++这种用法,数组的首地址不能改变;
parr+n:表示从当前地址往后移动n个当前类型数据所占空间;
使用方法二:
arr[n]=parr[n];
指向多维数组的指针与指针变量探究
既然数组名的一系列操作都可以看做地址,那就可以赋值给指针变量,使用指针也可以访问多维数组:
ptr=a[1];//得到第1行数组首地址(从0行开始);*ptr+1表示a[1][1];
指针数组与数组指针
指针数组:int *p[10];//存指针的数组,这个数组可以存10个指针;
数组指针:int (*p)[10];//数组的指针(指向数组),p指向类型为int [10]的数组
如何区分这两个易混淆的概念:
内在逻辑:[]优先级高于*,所以只有(*p)才能表示这是一个指针,即数组指针,否则是数组;
精华说法:以什么结尾就是什么:指针数组——数组,存指针,数组指针——指针,指向数组;
main函数参数
指针数组有个重要应用,作为main函数的参数:
int main(int argc,char *argv[])
agrc表示命令行参数个数;默认为1;
agrv记录命令行参数,默认第一个为可执行文件完整路径名;都是由系统调用传递的
字符串指针与指向字符串的指针变量
字符数组
char mystr[]=”I Love China!”;//末尾会自动带上/0
printf(“%s”,mystr);
char mystr1[]=”I Love China!”;
虽然都是存储I Love China,但是mystr!=mystr1;
字符指针变量
char *mystr=”I Love China!”;//末尾会自动带上/0
printf(“%s”,mystr);
char *mystr1=”I Love China!”;
都是指向I Love China,mystr==mystr1;这是因为I Love China被特意存放在一个专有内存中,因此指向的地址一致,但是要注意是按照常量存放的,因此不支持修改,如mystr1[3]=’c’;是不合法的;
字符数组与字符指针变量的区别:
- 存储方式不同:字符数组实际存储字符串,每个元素实际存储一个字符;字符指针变量:存储字符串首地址;
- 赋值方式不同:字符数组有定义时初始化与使用strXXX函数进行修改的方式,没有=直接赋值方式;但是字符指针可以改变指向char *str; str=”XXX”;
- 指针变量值可以改变(改变指向,因为并不改变存储空间位置,只改变存储内容),数组首地址不能改变(他是一块独立的存储空间);
函数指针与返回指针的函数
函数指针
原理:函数名就是函数的地址;
定义:声明一个与函数匹配的函数指针int (*pFunc)(int,int);
给定地址:pFunc=max;//这一步赋值之后两者值实际并不相等,pFunc是函数真正的调用地址,但是max实际是与存储函数表的相对地址;(他通过重载=实现,通过表相对关系查找真实地址)
函数调用: pFunc(5,12) or *pFunc(5,12);
函数指针不可进行++,--等操作,因为并非连续空间偏移,这将毫无意义;
函数指针可做函数参数,进行传递:
int test(int a,int b,int (*pFunc)(int,int))
{
return pFunc(a,b);
}
test(5,12,max);//调用
返回指针的函数
定义:int *Func(参数表);//返回值类型为int *
注意事项:这种返回值对应函数内返回变量地址,要注意这个不要是普通局部变量,否则出函数这个变量内存被回收,但是地址被获得,将产生无法预计的错误;