------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
1. 函数指针与指针函数的区别:
int * f(int * p);
int (*f)(int * p);
第一个:
先找到变量名f,f()的优先级比*f的优先级高 所以f是个函数名,()中是这个函数的形参 int *p 去掉f()以及其中的形参 剩下的int * 就是该函数的 返回值 于是第一个就是一个返回值是int指针的函数简称指针函数
第二个:
找到变量名f,因为()的原因 f先和*结合,于是f就是个指针名,然后(*f)右边又有()说明这是个指向函数的指针,而这个函数的形参是*p 返回值就是去掉(*f)(int*p)剩下的 int
总结就是f是个指向形参为int型指针返回值为int型的函数的指针,简称函数指针。
更加复杂的声明也可以这样辨别。
比如float(*(*f)(int,int,int))(int);
1先找到变量名f 然后发现f先和*结合 说明f是个指针
2(*f)右边有个(int int int)说明f是个指向函数的指针 形参为3个int
3替换掉(*f)(int int int) 剩下的就是这个函数的返回值 float(*p)(int)
4 这个上面已经解释过是个指向形参int返回值float的函数的指针
5所以f是个函数指针 指向的函数形参为3个int 返回值还是个函数指针指针指向一个返回值float形参int的函数。
总之就是记号()[]的优先级相等从左往右结合,*的优先级是比()低一级的而*是从右往左结合然后声明是从变量名开始一层一层往外加,解读也是从变量名开始一层一层解读。无论是函数还是数组还是指针都很清楚了
2. 常量指针和指针常量的区别
1> 定义:
常量指针就是指针指向的是常量,它不能指向变量,它指向的内容不能被改变,不能通过指针来修改它指向的内容,但是指针自身不是常量,它自身的值可以改变,从而指向另一个常量。
指针常量是指向的地址是不可改变的,但地址里的内容可以通过指针改变。它指向的地址将伴其一生,直到生命周期结束。有一点需要注意的是,指针常量在定义时必须同时赋初值。
2> 使用方法:
使用时写法上的区别: 常量指针:const 在*之前 指针常量:const在*之后。 当然我们也可以定义常量指针常量,那就需要加上两个const,一前一后!以上只是从定义上给出两者的本质上的不同,在具体使用上,还有很多变化,但万变不离其宗,我们可以根据它的原理分析出各种复杂用法的实质。
3> 使用举例
3.1 常量指针使用:如
int b,c;
intconst *a;
a =&b;
a =&c;
都可以,唯独它指向的内存不能被修改。如:*a=20;这是违法的!错误!
3.2 指针常量使用如:
Int a;
IntaTest;
Int *const p = &a;
表示p是一个常量指针它指向变量a的内存。指针常量不能再用p指向
其他变量,如 p =& aTest; 错误!可以修改指向内存的值,如:* p =10;
3.3 使用技巧
使用指针常量可以增加代码的可靠性和执行效率。
如 Int a;
Int *const p = &a;
增加可靠性:不用担心p被修改或释放导致非预期结果;
增加执行效率:不用在子函数中对p做为空检查可以提高效率。
3. 用三种方法来交换两个整形变量的值。
1> 第一种方法,大家会借助第三个中间变量来实现:
int temp,a,b;
temp=a;
a=b;
b=temp;
这种方法需要借助第三变量来实现;思想:如果你两个手都拿着苹果,两手想要交换苹果,需要将一个苹果先放下,再交换。
2> 第二种方法是利用加减法实现两个变量的交换,
int a,b ;
a=b-a;
b=b-a;
a=a+b;
思想:利用加法来进行两变量的交换,主要就是利用相加和相减,然后赋值,写法可以有多种。
3> 第三种方法是得用位异或运算来实现,也是效率最高的一种,在大量数据交换的时候,效率明显优于前两种方法,
int a,b;
a=a^b;
b=a^b;
a=a^b;
思想:利用一个数异或本身等于0和异或运算符合交换率。
4. 构造方法在执行的过程中内存分析:
1> Person*p = [ [Person alloc] init ];
Person先分配一块内存空间,由于Person继承的是NSOject,其父类中有isa成员变量,并且在初始化前,子类和父类的成员变量值都为0。然后调用init的构造方法(里面主要是对init父类方法的重写,完整的代码为 if( self = [super init] )),如果self分配成功,则对成员变量进行初始化(成员变量包括子类和继承过来的父类的)。
2> Student*s = [ [Student alloc] init];
Student alloc是先给Student分配内存空间,然后初始化调用的是init方法是来自student的,就近原则,然后super找到person的init方法,而Person的 super init方法又要找到NSOject的,然后先对父类的成员变量赋值,再到子类。