类别的局限性?
普通类别只是对类的方法拓展,不能增加类的实例变量,
类别拓展的方法名如果和类的方法名相同,那么在调用该方法时,就会被类别方法覆盖,造成不能调用原类方法的目的,或者造成程序崩溃.
类别的作用
功能:1.扩充现有类的功能
2.扩充自定义类的功能,将自定义类的方法进行分类,使结构更加清晰,调用更加方便
3.声明非正式的协议
4.匿名分类(@interface 类名 () @end),一般在依赖类的.m文件的最上面生成匿名分类,专门用来声明私有的属性和方法
什么是延迟加载(懒加载)?
懒加载即重写get方法,此方法多用于已有的数据加载方法,加载数据后赋值给数组.
char const p
如果const位于的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;
如果const位于*的右侧,const就是修饰指针本身,即指针本身是常量。
数据的持久性存储
1.属性列表 主要涉及到NSUserDefaults 用于存储配置信息
2.对象归档 使用基本对象类型定制个性化缓存
3数据库存储(SQLite) 用于存储查询需求较多的数据
4Core Data 。 用于规划应用中的对象
数据请求方法:
NSURLConnection 系统的,常用的方式
NSURLSession 系统的,ios7.0之后出现的,使用了Block,提高了效率
ASIHttpRequest 第三方的,原来经常使用的数据请求库,缺点:环境是mrc,要进行ARC与MRC之间的转化,没有使用block
AFNetworking 第三方的,现在被经常使用,内部集成了NSURLConnection和NSURLSession,环境是ARC,使用了Block,提高了效率,不用系统库的支撑
程序的生命周期
application didFinishLaunchingWithOptions:开始
applicationWillResignActive:变成不活跃
applicationDidEnterBackground:进入后台
applicationWillEnterForeground:进入前台
applicationDidBecomeActive:变成活跃
applicationWillTerminate:即将关闭
视图控制器的生命周期
1.initWithNibName: //初始化方法(一次初始化) 通常用xib创建对象时进行的初始化工作放在这里
2.init //初始化方法(一次初始化方法) 通常用纯代码创建对象的时候调用
loadView //加载视图(初始化方法)
viewDidLoad //二次初始化方法(纯代码,xib创建对象都要调用)
viewWillAppear:(BOOL)animated //视图将要出现
viewDidAppear:(BOOL)animated //视图已经出现
viewWillDisappear:(BOOL)animated//视图将要消失
viewDidDisappear:(BOOL)animated //视图已经消失
堆和栈的区别:
一、堆栈空间分配区别:
1、栈(操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈;
2、堆(操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。
二、堆栈缓存方式区别:
1、栈使用的是一级缓存, 他们通常都是被调用时处于存储空间中,调用完毕立即释放;
2、堆是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。
三、堆栈数据结构区别:
堆(数据结构):堆可以被看成是一棵树,如:堆排序;
栈(数据结构):一种先进后出的数据结构。
1.static静态变量的作用
答:1.表示全局静态,用来修饰成员变量和成员方法
2.被修饰的变量和方法独立于该类的任何对象,即它不依赖类特定实例,被类的所有实例共享
3.静态方法可以直接通过类名调用,任何实例也可调用。
4.静态变量可以不进行外置声明,直接调用,使用静态方法,不用实例化,创建类的对象,使方法调用方便,节省空间
5.static成员是不能被其所在class创建的实例访问的,其默认值是0,只要执行一次,运行时开辟全局内存空间,存储上一次数据,便于下次调用,对于实例变量,没创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响(灵活)。
2.get和post使用时的区别
答:1.get是从服务器上去获取数据,post是向服务器传输数据(一般是用于图片的传输)
2.. get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。post是通过HTTP post机制,将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址。用户看不到这个过程。
3. 对于get方式,服务器端用Request.QueryString获取变量的值,对于post方式,服务器端用Request.Form获取提交的数据。
4. get传送的数据量较小。post传送的数据量较大,一般被默认为不受限制。
5. get安全性非常低,post安全性较高。但是执行效率却比Post方法好。
建议:
1、get方式的安全性较Post方式要差些,包含机密信息的话,建议用Post数据提交方式;
2、在做数据查询时,建议用Get方式;而在做数据添加、修改或删除时,建议用Post方式;
3.@class和#import的区别
1.#import包含被引用类所有的信息,被引用类的变量和方法;@class是前向声明,只是告诉编译器在某一个类的.h文件中声明另一个类,没有声明具体信息。
2.使用@class只需要被引用类的名称,在.m文件使用#import来包含被引用类的头文件,因为实现类时需要用到被引用类的实体变量和方法。
bundle(沙盒):一个应用只能在自己的沙盒中读取或存储文件,而不能操作其他沙盒中的文件。好处:保护应用的隐私不受侵犯,保护系统文件的安排,应用删除后相关文件也能被全部清除。
每个应用都有自己的沙盒,沙盒的根目录的获取方法是NSHomeDirectory()。
根目录下的内容:
-.app文件,实际上是一个文件夹,包含了可执行文件、Nib文件、图片资源、plist等。XCode中能看到的资源,及编译后的可执行文件,都封装在app中。
-Documents文件夹,用于存放你的应用所产生的数据,该文件夹可通过iTunes备份,可以存储游戏进度等。
-Library文件夹,用于存放用户偏好和临时文件。
-tmp文件夹是系统的中转站。
自动释放池是什么,如何工作
当您向一个对象发送一个autorelease 消息时,Cocoa就会将该对象的一个引用放入到最新的自动释放池。它仍然是个正当的对象,因此自动释放池定义的作用域内的其它对象可以向它发送消息。当 程序执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对象也就被释放。
- ojc-c 是 通过一种"referring counting"(引用计数)的方式来管理内存的, 对象在开始分配内存(alloc)的时候引用计数为一,以后每当碰到有copy,retain的时候引用计数都会加一, 每当碰到release和autorelease的时候引用计数就会减一,如果此对象的计数变为了0, 就会被系统销毁.
- NSAutoreleasePool 就是用来做引用计数的管理工作的,这个东西一般不用你管的. 3. autorelease和release没什么区别,只是引用计数减一的时机不同而已,autorelease会在对象的使用真正结束的时候才做引用计数减一.
obj-c的优缺点
objc优点: 1) Cateogies 2) Posing 3) 动态识别 4) 5)弹性消息传递 6) 不是一个过度复杂的 C 衍生语言 7) Objective-C 与 C++ 可混合编程 缺点: 1) 不支持命名空间 2) 不支持运算符重载
3) 不支持多重继承
4) 使用动态运行时类型,所有的方法都是函数调用,所以很多编译时优化方法都用不到。(如内联函数等),性能低劣。
readwrite,readonly,assign,retain,copy,nonatomic属性的作用
@property是一个属性访问声明,扩号内支持以下几个属性: 1,getter=getterName,setter=setterName,设置setter与getter的方法名 2,readwrite,readonly,设置可供访问级别 2,assign,setter方法直接赋值,不进行任何retain操作,为了解决原类型与环循引用问题 3,retain,setter方法对参数进行release旧值再retain新值,所有实现都是这个顺序(CC上有相关资料) 4,copy,setter方法进行Copy操作,与retain处理流程一样,先旧值release,再Copy出新的对象,retainCount为1。这是为了减少对上下文的依赖而引入的机制。 5,nonatomic,非原子性访问,不加同步,多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。锁被加到所属对象实例级。
1。assign和retain,copy的区别
assign就是和普通语言的赋值一样
retain 在一个对象中保存该对象需要拥有的对象
对该对象进行应用计数+1
@property (retain) 为了写程序方便
copy主要是赋值
一般 代理的申明都是assign 为什么
原因有2个,
1 根本就没有必要把代理的计数器+1
- 主要是为了避免引用技术嵌套,递归
2。如何持久保存数据
NSUserDefaults, Plist, SQLite3, file
3。网络方面得 比如如何检测联网 http xml等
ASIHTTPRequest Reacheable.[hm]
原理是ifconfig 是不是有ip地址
Reachability
来判断是否有网络3G Wifi
4。类之间得继承关系 比如UIview得父类是哪一个等等?
UIResponder,处理触摸,
touchBegin, touchEnd, nextResponder
5。异常处理
都是自己判断 错误信息
longjmp
char *p = malloc(100);
if (p == NULL) {
}
区分frame与bounds
//都是表示位置
//区别 frame:它的参考坐标系是(世界坐标系)(父视图),设置坐标时以父类的左上角为坐标原点(参考点)
//bounds:参考坐标系(本地坐标系)(自身),设置坐标时以自己的左上角为坐标原点(参考点)
//当先给视图设置了frame,再设置bouns时,视图会以frame的中心点为中心,去设置bounds时的视图的位置
//注意:bounds的坐标是不起作用的.
//当直接给视图用bounds设置位置时,视图会以父视图的左上角为中心点设置自己的大小
//注意:在使用时,如果需要坐标点就使用frame 如果只是用大小就使用bounds
1—Autorelease pool
自动释放池(Autorelease pool)是OC的一种内存自动回收机制,可以将一些临时变量通过自动释放池来回收统一释放
自动释放池本事销毁的时候,池子里面所有的对象都会做一次release操作
(1)在自动释放池@autoreleasepool{}中alloc一个对象后(如p1),仍然需要用[p1 autorelease];只是这个语句和[p1 release];不同,后者表示把p1的retainCount-1,而前者仅仅表示把p1放到自动释放池中返回一个self,自动释放池结束销毁时, 统一对里面的对象引用计数retainCount-1。
(2)@autoreleasepool{}可以随意创建,也可以嵌套使用。
(3)不管这个对象是在自动释放池内还是外创建的,只要在自动释放池内写一个[p1 autorelease];p1就会被放到自动释放池中。注意autorelease是一个方法,且只有在自动释放池中使用才有效。
(4)如果把一个对象重复加到自动释放池如[p1 autorelease];[p1 autorelease];,那么会出错。原因是:加载几次,届时自动释放池就会用[p1 release];释放几次,但是由于这两个加载的对象其实是一个对象同样地址,所以第一次自动释放正确,第二次自动释放时发现已经被释放了,所以p1就 变成了野指针
2⃣️4⃣️
2—简述内存分区情况
(1)代码区:存放函数二进制代码
(2)数据区:系统运行时申请内存并初始化,系统退出时由系统释放。存放全局变量、静态变量、常量
(3)堆区:通过malloc等函数或new等操作符动态申请得到,需程序员手动申请和释放
(4)栈区:函数模块内申请,函数结束时由系统自动释放。存放局部变量、函数参数
另一种说法:代码区,静态区,常量区,堆区。栈区
3---视图的生命周期
当一个视图控制器被创建,并在屏幕上显示的时候。 代码的执行顺序
1、 alloc 创建对象,分配空间
2、init (initWithNibName) 初始化对象,初始化数据
3、loadView 从nib载入视图 ,通常这一步不需要去干涉。除非你没有使用xib文件创建视图
4、viewDidLoad 载入完成,可以进行自定义数据以及动态创建其他控件
5、viewWillAppear 视图将出现在屏幕之前,马上这个视图就会被展现在屏幕上了
6、viewDidAppear 视图已在屏幕上渲染完成
当一个视图被移除屏幕并且销毁的时候的执行顺序,这个顺序差不多和上面的相反
1、viewWillDisappear 视图将被从屏幕上移除之前执行
2、viewDidDisappear 视图已经被从屏幕上移除,用户看不到这个视图了
3、dealloc 视图被销毁,此处需要对你在init和viewDidLoad中创建的对象进行释放
在同一个类A中,有方法a和方法b,方法b如何调用方法a?
[self a];
有A、B两个类,B类继承于A类,都实现了方法xx。创建B类实例b,如何让b调用A类?
[super a];
const和Volatile分别代表什么意思?
Volatile表示每次都从内存取数据
类型id代表什么意思?
面向对象包含哪些元素?
继承和分类的区别?
Catogory
Catogory实现起来麻烦一些,但是使用方便
NSSet类的作用是什么?
集合
编写一个完整程序,在控制台打印字符串“HelloWorld!”
用递归实现计算n的阶乘。(用objective-c语法实现)
//
static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?
C语言中讲讲static变量和static函数有什么作用
static关键字有两种意思,你看上下文来判断
1,表示变量是静态存储变量
表示变量存放在静态存储区.
2,表示该变量是内部连接
(这种情况是指该变量不在任何{}之内,就象全局变量那样,这时候加上static)
,也就是说在其它的.cpp文件中,该变量是不可见的(你不能用).
当static加在函数前面的时候
表示该函数是内部连接,之在本文件中有效,别的文件中不能应用该函数.
不加static的函数默认为是全局的.
也就是说在其他的.cpp中只要申明一下这个函数,就可以使用它.
1、static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?
答:全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。
从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。
static函数与普通函数作用域不同。static函数仅在本文件中使用。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件
static全局变量与普通的全局变量有什么区别:static全局变量只初使化一次,防止在其他文件单元中被引用;
static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值;
static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝
2、如何引用一个已经定义过的全局变量?
答:extern
可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变写错了,那么在编译期间 会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。
3、全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么?
答:可以,在不同的C文件中以static形式来声明同名全局变量。
可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时连接不会出错。
什么是UDP和TCP的区别是什么?
TCP的全称为传输控制协议。这种协议可以提供面向连接的、可靠的、点到点的通信。
UDP的全称为用户数据报协议,它可以提供非连接的不可靠的点到多点的通信。
用TCP还是UDP,那要看你的程序注重哪一个方面?可靠还是快速?
TCP/IP 建立连接的过程
在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。
第一次握手:建立连接时,客户端发送连接请求到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到客户端连接请求,向客户端发送允许连接应答,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的允许连接应答,向服务器发送确认,客户端和服务器进入通信状态,完成三次握手。
(所谓的三次握手就是要有三次连接信息的发送/接收过程。TCP连接的建立需要进行三次连接信息的发送/接收。)
-(void) print:(NSString*) msg
{
NSLog(@"%@",msg);
}
printf("%d,%c\n",i,c)
char str[10]=",str2[]={"China"};
strcpy(str1,str2);
printf("%d",max(a,b));
把 max(a,b)作为printf函数的一个参数。
obj-c有多重继承么?不是的话有什么替代方法?
cocoa 中所有的类都是NSObject 的子类,多继承在这里是用protocol 委托代理来实现的。你不用去考虑繁琐的多继承,虚基类的概念。多态特性在 obj-c 中通过委托来实现。
线程与进程的区别和联系?
进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。
程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
自动释放池是什么,如何工作?
当您向一个对象发送一个autorelease消息时,Cocoa就会将该对象的一个引用放入到最新的自动释放池。它仍然是个正当的对象,因此自动释放池定义的作用域内的其它对象可以向它发送消息。当程序执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对象也就被释放。
- ojc-c 是通过一种"referring counting"(引用计数)的方式来管理内存的, 对象在开始分配内存(alloc)的时候引用计数为一,以后每当碰到有copy,retain的时候引用计数都会加一, 每当碰到release和autorelease的时候引用计数就会减一,如果此对象的计数变为了0, 就会被系统销毁.
- NSAutoreleasePool 就是用来做引用计数的管理工作的,这个东西一般不用你管的.
- autorelease和release没什么区别,只是引用计数减一的时机不同而已,autorelease会在对象的使用真正结束的时候才做引用计数减一。
什么是KVC和KVO?答:KVC(Key-Value-Coding)内部的实现:一个对象在调用setValue的时候,(1)首先根据方法名找到运行方法的时候所需要的环境参数。(2)他会从自己isa指针结合环境参数,找到具体的方法实现的接口。(3)再直接查找得来的具体的方法实现。KVO(Key-Value-Observing):当观察者为一个对象的属性进行了注册,被观察对象的isa指针被修改的时候,isa指针就会指向一个中间类,而不是真实的类。所以isa指针其实不需要指向实例对象真实的类。所以我们的程序最好不要依赖于isa指针。在调用类的方法的时候,最好要明确对象实例的类名。
kvc 就是一种通过字符串去间接操作对象属性的机制。
iphone中,自定义协议?
Protocol , 看代理 viewController
协议在oc中主要用在代理中
绑定的概念?
代理的概念?对它怎么理解?
为了模块之间的松耦合
网络编程中协议的概念。
NetworkDataDelegate;
3个函数理解 didReceive,
苹果上架流程?
数据持久化存储的方式 应用的场景
C语言中讲讲static变量和static函数有什么作用
static关键字有两种意思,你看上下文来判断
1,表示变量是静态存储变量
表示变量存放在静态存储区.
2,表示该变量是内部连接
(这种情况是指该变量不在任何{}之内,就象全局变量那样,这时候加上static)
,也就是说在其它的.cpp文件中,该变量是不可见的(你不能用).
当static加在函数前面的时候
表示该函数是内部连接,之在本文件中有效,别的文件中不能应用该函数.
不加static的函数默认为是全局的.
也就是说在其他的.cpp中只要申明一下这个函数,就可以使用它.
13.列举几种进程的同步机制,并比较其优缺点。答案: 原子操作 信号量机制 自旋锁 管程,会合,分布式系统
1.进程之间通信的途径答案:共享存储系统消息传递系统管道:以文件系统为基础
2.进程死锁的原因答案:资源竞争及进程推进顺序非法
3.死锁的4个必要条件答案:互斥、请求保持、不可剥夺、环路
4.死锁的处理答案:鸵鸟策略、预防策略、避免策略、检测与解除死锁
14.堆和栈的区别管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生memory leak。1.申请大小:栈: 在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在 WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示 overflow。因此,能从栈获得的空间较小。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。2.碎片问题:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出3.分配方式:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由 alloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。4.分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的。 15.什么是键-值,键路径是什么模型的性质是通过一个简单的键(通常是个字符串)来指定的。视图和控制器通过键来查找相应的属性值。
在一个给定的实体中,同一个属性的所有值具有相同的数据类型。
键-值编码技术用于进行这样的查找—它是一种间接访问对象属性的机制。键路径是一个由用点作分隔符的键组成的字符串,用于指定一个连接在一起的对象性质序列。第一个键的性质是由先前的性质决定的,接下来每个键的值也是相对于其前面的性质。键路径使您可以以独立于模型实现的方式指定相关对象的性质。通过键路径,您可以指定对象图中的一个任意深度的路径,使其指向相关对象的特定属性。16.c和obj-c如何混用1)obj-c的编译器处理后缀为m的文件时,可以识别obj-c和c的代码,处理mm文件可以识别obj-c,c,c++代码,
但cpp文件必须只能用c/c++代码,而且cpp文件include的头文件中,也不能出现obj- c的代码,因为cpp只是cpp。2) 在mm文件中混用cpp直接使用即可,所以obj-c混cpp不是问题3)在cpp中混用obj- c其实就是使用obj-c编写的模块是我们想要的。如果模块以类实现,那么要按照cpp class的标准写类的定义,头文件中不能出现obj-c的东西,包括#import cocoa的。
实现文件中,即类的实现代码中可以使用obj-c的东西,可以import,只是后缀是mm。如果模块以函数实现,那么头文件要按 c的格式声明函数,实现文件中,c++函数内部可以用obj-c,但后缀还是mm或m。总结:只要cpp文件和cpp include的文件中不包含obj-c的东西就可以用了,cpp混用obj-c的关键是使用接口,
而不能直接使用实现代码,实际上cpp混用的是 obj-c编译后的o文件,这个东西其实是无差别的,所以可以用。obj-c的编译器支持cpp.
17.cocoa touch框架iPhone OS 应用程序的基础 Cocoa Touch 框架重用了许多 Mac 系统的成熟模式,但是它更多地专注于触摸的接口和优化。
UIKit 为您提供了在 iPhone OS 上实现图形,事件驱动程序的基本工具,其建立在和 Mac OS X 中一样的 Foundation 框架上,
包括文件处理,网络,字符串操作等。 Cocoa Touch 具有和 iPhone 用户接口一致的特殊设计。有了 UIKit,您可以使用 iPhone OS 上的独特的图形接口控件,按钮,
以及全屏视图的功能,您还可以使用加速仪和多点触摸手势来控制您的应用。各色俱全的框架 除了 UIKit 外,Cocoa Touch 包含了创建世界一流 iPhone 应用程序需要的所有框架,从三维图形,到专业音效,
甚至提供设备访问 API 以控制摄像头,或通过 GPS 获知当前位置。
Cocoa Touch 既包含只需要几行代码就可以完成全部任务的强大的 Objective-C 框架,也在需要时提供基础的 C 语言 API 来直接访问系统。这些框架包括:Core Animation:通过 Core Animation,您就可以通过一个基于组合独立图层的简单的编程模型来创建丰富的用户体验。Core Audio:Core Audio 是播放,处理和录制音频的专业技术,能够轻松为您的应用程序添加强大的音频功能。Core Data:提供了一个面向对象的数据管理解决方案,它易于使用和理解,甚至可处理任何应用或大或小的数据模型。功能列表:框架分类下面是 Cocoa Touch 中一小部分可用的框架:音频和视频:Core Audio ,OpenAL ,Media Library ,AV Foundation数据管理 :Core Data ,SQLite图形和动画 :Core Animation ,OpenGL ES ,Quartz 2D网络:Bonjour ,WebKit ,BSD Sockets用户应用:Address Book ,Core Location ,Map Kit ,Store Kit
18.自动释放池是什么,如何工作 当您向一个对象发送一个autorelease消息时,Cocoa就会将该对象的一个引用放入到最新的自动释放池。
它仍然是个正当的对象,因此自动释放池定义的作用域内的其它对象可以向它发送消息。
当程序执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对象也就被释放。1. ojc-c 是通过一种"referring counting"(引用计数)的方式来管理内存的, 对象在开始分配内存(alloc)的时候引用计数为一,
以后每当碰到有copy,retain的时候引用计数都会加一, 每当碰到release和autorelease的时候引用计数就会减一,如果此
对象的计数变为了0, 就会被系统销毁.2. NSAutoreleasePool 就是用来做引用计数的管理工作的,这个东西一般不用你管的.3. autorelease和release没什么区别,只是引用计数减一的时机不同而已,autorelease会在对象的使用真正结束的时候才做引用计数减一.
19.objc优点: 1) Cateogies 2) Posing 3) 动态识别 4) 指标计算 5)弹性讯息传递 6) 不是一个过度复杂的 C 衍生语言 7) Objective-C 与 C++ 可混合编程 objc缺点: 1) 不支援命名空間 2) 不支持运算符重载 3) 不支持多重继承 4) 使用动态运行时类型,所有的方法都是函数调用,所以很多编译时优化方法都用不到。(如内联函数等),性能低劣。
20.sprintf,strcpy,memcpy使用上有什么要注意的地方 strcpy是一个字符串拷贝的函数,它的函数原型为strcpy(char *dst, const char *src);将src开始的一段字符串拷贝到dst开始的内存中去,结束的标志符号为 '\0',由于拷贝的长度不是由我们自己控制的,
所以这个字符串拷贝很容易出错。具备字符串拷贝功能的函数有memcpy,这是一个内存拷贝函数,它的函数原型
为memcpy(char dst, const char src, unsigned int len);将长度为len的一段内存,从src拷贝到dst中去,这个函数的长度可控。但是会有内存叠加的问题。sprintf是格式化函数。将一段数据通过特定的格式,格式化到一个字符串缓冲区中去。sprintf格式化的函数的长度不可控,
有可能格式化后的字符串会超出缓冲区的大小,造成溢出。21. 用变量a给出下面的定义a) 一个整型数(An integer) b)一个指向整型数的指针( A pointer to an integer) c)一个指向指针的的指针,它指向的指针是指向一个整型数( A pointer to a pointer to an intege)r d)一个有10个整型数的数组( An array of 10 integers) e) 一个有10个指针的数组,该指针是指向一个整型数的。(An array of 10 pointers to integers) f) 一个指向有10个整型数数组的指针( A pointer to an array of 10 integers) g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer) h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions that take an integer argument and return an integer ) 答案是: a) int a; // An integer b) int *a; // A pointer to an integer c) int a; // A pointer to a pointer to an integer d) int a[10]; // An array of 10 integers e) int a[10]; // An array of 10 pointers to integers f) int (a)[10]; // A pointer to an array of 10 integers g) int (a)(int); // A pointer to a function a that takes an integer argument and returns an integer h) int (a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer
22.readwrite,readonly,assign,retain,copy,nonatomic 属性的作用@property是一个属性访问声明,扩号内支持以下几个属性:1,getter=getterName,setter=setterName,设置setter与 getter的方法名2,readwrite,readonly,设置可供访问级别2,assign,setter方法直接赋值,不进行任何retain操作,为了解决原类型与环循引用问题3,retain,setter方法对参数进行release旧值再retain新值,所有实现都是这个顺序(CC上有相关资料)4,copy,setter方法进行Copy操作,与retain处理流程一样,先旧值release,再 Copy出新的对象,retainCount为1。
这是为了减少对上下文的依赖而引入的机制。5,nonatomic,非原子性访问,不加同步,多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法
都为原子型事务访问。锁被加到所属对象实例级(我是这么理解的...)。
23.http和scoket通信的区别。
http是客户端用http协议进行请求,发送请求时候需要封装http请求头,并绑定请求的数据,服务器一般有web服务器配合(当然也非绝 对)。 http请求方式为客户端主动发起请求,服务器才能给响应,一次请求完毕后则断开连接,以节省资源。服务器不能主动给客户端响应(除非采取http长连接 技术)。iphone主要使用类是NSUrlConnection。
scoket是客户端跟服务器直接使用socket“套接字”进行连接,并没有规定连接后断开,所以客户端和服务器可以保持连接通道,双方 都可以主动发送数据。一般在游戏开发或股票开发这种要求即时性很强并且保持发送数据量比较大的场合使用。主要使用类是CFSocketRef。
TCP全称是Transmission Control Protocol,中文名为传输控制协议,它可以提供可靠的、面向连接的网络数据传递服务。传输控制协议主要包含下列任务和功能:* 确保IP数据报的成功传递。* 对程序发送的大块数据进行分段和重组。* 确保正确排序及按顺序传递分段的数据。* 通过计算校验和,进行传输数据的完整性检查。
6、TCP和UDP的区别 TCP提供的是面向连接的、可靠的数据流传输,而UDP提供的是非面向连接的、不可靠的数据流传输。 简单的说,TCP注重数据安全,而UDP数据传输快点,但安全性一般
24.mvc设计模式是什么? 你还熟悉什么设计模式?设计模式:并不是一种新技术,而是一种编码经验,使用比如java中的接口,iphone中的协议,继承关系等基本手段,
用比较成熟的逻辑去处理某一种类型的事情,总结为所谓设计模式。面向对象编程中,java已经归纳了23中设计模式。mvc设计模式 ,模型,视图,控制器,可以将整个应用程序在思想上分成三大块,对应是的数据的存储或处理,前台的显示,
业务逻辑的控制。 Iphone本身的设计思想就是遵循mvc设计模式。其不属于23中设计模式范畴。代理模式:代理模式给某一个对象提供一个代理对象,并由代理对象控制对源对象的引用.比如一个工厂生产了产品,
并不想直接卖给用户,而是搞了很多代理商,用户可以直接找代理商买东西,代理商从工厂进货.常见的如QQ的自动回复就属于代理拦截,代理模式在iphone中得到广泛应用.单例模式:说白了就是一个类不通过alloc方式创建对象,而是用一个静态方法返回这个类的对象。系统只需要拥有一个的全局对象,
这样有利于我们协调系统整体的行为,比如想获得[UIApplication sharedApplication];任何地方调用都可以得到 UIApplication的对象,
这个对象是全局唯一的。观察者模式: 当一个物体发生变化时,会通知所有观察这个物体的观察者让其做出反应。实现起来无非就是把所有观察者的对象给这个物体,
当这个物体的发生改变,就会调用遍历所有观察者的对象调用观察者的方法从而达到通知观察者的目的。工厂模式:
public class Factory{ public static Sample creator(int which){ if (which==1) return new SampleA(); else if (which==2) return new SampleB(); } }25.你了解svn,cvs等版本控制工具么?版本控制 svn,cvs 是两种版控制的器,需要配套相关的svn,cvs服务器。scm是xcode里配置版本控制的地方。版本控制的原理就是a和b同时开发一个项目,a写完当天的代码之后把代码提交给服务器,
b要做的时候先从服务器得到最新版本,就可以接着做。 如果a和b都要提交给服务器,并且同时修改了同一个方法,就会产生代码冲突,
如果a先提交,那么b提交时,服务器可以提示冲突的代码,b可以清晰的看到,并做出相应的修改或融合后再提交到服务器。
26.什么是push(了解一下)。
客户端程序留下后门端口,客户端总是监听针对这个后门的请求,于是 服务器可以主动像这个端口推送消息。
27.静态链接库(了解一下)
(此为.a文件,相当于java里的jar包,把一些类编译到一个包中,在不同的工程中如果导入此文件就可以使用里面的类,
具体使用依然是#import “ xx.h”)。
28.fmmpeg框架(了解一下)
(音视频编解码框架,内部使用UDP协议针对流媒体开发,内部开辟了六个端口来接受流媒体数据,完成快速接受之目的).
29.fmdb框架(了解一下)
(数据库框架,对sqllite的数据操作进行了封装,使用着可把精力都放在sql语句上面)。
30.320框架(了解一下)
(ui框架,导入320工程作为框架包如同添加一个普通框架一样)。
cover(open) flower框架 (2d 仿射技术),内部核心类是CATransform3D.
31.什么是沙箱模型?哪些操作是属于私有api范畴?
某个iphone工程进行文件操作有此工程对应的指定的位置,不能逾越。iphone沙箱模型的有四个文件夹,分别是什么,永久数据存储一般放在什么位置,得到模拟器的路径的简单方式是什么.
documents,tmp,app,Library。
(NSHomeDirectory()),
手动保存的文件在documents文件里
Nsuserdefaults保存的文件在tmp文件夹里
Documents 目录:您应该将所有de应用程序数据文件写入到这个目录下。这个目录用于存储用户数据或其它应该定期备份的信息。
AppName.app 目录:这是应用程序的程序包目录,包含应用程序的本身。由于应用程序必须经过签名,
所以您在运行时不能对这个目录中的内容进行修改,否则可能会使应用程序无法启动。
Library 目录:这个目录下有两个子目录:Caches 和 Preferences
Preferences 目录包含应用程序的偏好设置文件。您不应该直接创建偏好设置文件,而是应该使用NSUserDefaults类来取得和设置应用程序的偏好.
Caches 目录用于存放应用程序专用的支持文件,保存应用程序再次启动过程中需要的信息。
tmp 目录:这个目录用于存放临时文件,保存应用程序再次启动过程中不需要的信息。
获取这些目录路径的方法:
1,获取家目录路径的函数:
NSString *homeDir = NSHomeDirectory();
2,获取Documents目录路径的方法:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
3,获取Caches目录路径的方法:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachesDir = [paths objectAtIndex:0];
4,获取tmp目录路径的方法:
NSString *tmpDir = NSTemporaryDirectory();
5,获取应用程序程序包中资源文件路径的方法:
例如获取程序包中一个图片资源(apple.png)路径的方法:
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@”apple” ofType:@”png”];
UIImage *appleImage = [[UIImage alloc] initWithContentsOfFile:imagePath];
代码中的mainBundle类方法用于返回一个代表应用程序包的对象。
文件IO写入
1,将数据写到Documents目录:
-
(BOOL)writeApplicationData:(NSData *)data toFile:(NSString *)fileName {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
if (!docDir) {
NSLog(@”Documents directory not found!”); return NO;
}
NSString *filePath = [docDir stringByAppendingPathComponent:fileName];
return [data writeToFile:filePath atomically:YES];
}
2,从Documents目录读取数据:
(NSData *)applicationDataFromFile:(NSString *)fileName {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
NSString *filePath = [docDir stringByAppendingPathComponent:fileName];
NSData *data = [[[NSData alloc] initWithContentsOfFile:filePath] autorelease];
return data;
}
NSSearchPathForDirectoriesInDomains这个主要就是返回一个绝对路径用来存放我们需要储存的文件。-
(NSString *)dataFilePath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:@"shoppingCar.plist"];
}
NSFileManager* fm=[NSFileManager defaultManager];
if(![fm fileExistsAtPath:[self dataFilePath]]){
//下面是对该文件进行制定路径的保存
[fm createDirectoryAtPath:[self dataFilePath] withIntermediateDirectories:YES attributes:nil error:nil];
//取得一个目录下得所有文件名
NSArray *files = [fm subpathsAtPath: [self dataFilePath] ];
//读取某个文件
NSData *data = [fm contentsAtPath:[self dataFilePath]];
//或者
NSData *data = [NSData dataWithContentOfPath:[self dataFilePath]];
}
iphone常见私有api的应用(比如直接发送短信,访问沙箱之外的磁盘文件).32.你在开发项目中时,用到了哪些数据存储方式,iphone中常见的方式有哪些,各有什么区别?
数据存储五种形式的应用范围和性能区别
(core data, sqllite,对象序列化,文件直接读写,NSUserDefault(保存数据到temp文件夹中))文件直接读写 >core data> 对象序列化> sqllite>NSUserDefault.
33.线程的常见方法有哪些,你是如何处理多线程的,多线程同步问题你了解么?线程创建的几种方式,线程的加锁,休眠,唤醒,解锁,退出,
多线程要考虑同步问题,解决同步问题的方式就是对某一资源加锁,当一个线程操作本资源时,其他线程不能操作 。 系统自带线程池(NSOpertionQueue)的作用:
凡是需要启动多个线程的地方都可以使用NSOpertionQueue,加入到NSOpertionQueue中的对象都需要继承NSOpertion。 NSOpertionQueue会在系统内部启动一个独立线程去执行这个被加入对象的main方法。
常用的地方是用nsoprationqueue 下载图片,文件。如果是自己创建一个线程池,无非就是启动多个线程的时候,
把这些线程对象放到一个大数组中,如果需要启动线程的时候,先从数组中找空闲线程来使用。
自己管理线程池最大的难题是不好处理当启动多个线程后,用户在多个界面的跳转的时候,对线程方法的回调管理。
而NSOpertionQueue可以很好的处理他。
34.init和initwithobject区别(语法)?
init创建的对象不带自动释放
35.你连接服务器用的是什么方法,如果请求过程中,网络出了问题这么办?NSUrlConnection 连接后,有一系列委托方法来接受来自服务器的响应和数据,
其中接受相应的方法回得到服务器要传回的数据有多大,接受数据的方法会反复调用来不断接受服务器数据,
如果网络出了问题了,会调用一个方法让你来做相关处理。
36.你使用过json解析方式么,他们的底层是如何处理的你了解么?
json解析的用法,用框架的用法简单介绍:
底层原理遍历字符串中的字符,最终根据格式规定的特殊字符,比如{}号,[]号, : 号 等进行区分, {}号是一个字典的开始,[]号是一个数组的开始, : 号是字典的键和值的分水岭,最终乃是将json数据转化为字典,
字典中值可能是字典,数组,或字符串而已。
37.xml解析的原理是什么,你还用过其他解析方式么?NSXMLParser, 其他解析方式有自定义二进制解析,就是按字节去解析,电话会谈就是如此,
还可以是字符串之间用特殊符号连接的数据,将此数据用特殊符号可以分割成所用数据。
38.协议是什么,有什么作用.?
协议很像java中的接口,某个类实现协议后,就必须实现协议中规定的@require的方法,比如一个类A, 一个类B都实现某“协议”后,
这个类A的对象和B的对象都可以赋值给这个协议的类型变量,比如 id<协议> 变量名 = A类或B类的对象,
于是这个变量就完成了能够指向多个不同的类的对象并调用对象中的实现协议的方法。39.类别有什么作用?类别的使用 。 类别有三大作用,
- 可以使本来需要在.h中声明的方法放到.m文件中声明,达到了可以使方法不对外公开。
- 可以方便的扩展类,甚至系统类都可以轻易扩展,维护了代码原本的结构不受影响。
- 类别可以写到不同的.h或.m文件中,可以分散代码到跟类别的扩展功能想关联的地方,方便查看。40.分线程回调主线程方法是什么,有什么作用?[self performSelectorOnMainThread:@selector(buttonGo2) withObject:nil waitUntilDone:YES];[self performSelector:@selector(buttonGo2) onThread:[NSThread mainThread] withObject:nil waitUntilDone:YES];需要即时刷新ui控件的时候,经常使用。41.iphone阅读器,如果要读取一个文本文件,请问你是如何处理编码问题的?另外像pdf格式的文件,你如何读取。?
iphone手机阅读器中对于PDF格式的阅读,可以直接用UIWebView控件显示,也可以从网上下到很多直接读取pdf格式的代码
直接从pdf中得到数据。复杂表格动画- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation; -(void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
42.你在开发大型项目的时候,如何进行内存泄露检测的? 可以通过xcode的自带工具run---start with performance tool里有instruments下有个leaks工具,
启动此工具后,运行项目,工具里可以显示内存泄露的情况,双击可找到源码位置,可以帮助进行内存泄露的处理。
43.你做iphone开发时候,有哪些传值方式,view和view之间是如何传值的?
压栈。
44.让一个物体从界面中的一点运动到另外一点,有哪些方法?四种方式:1. beginAnimation
2. 线程
3. NSTimer
4. 图层动画(路径)
45.你了解哪些加密方式? Base64, MD5, 循环右移位等.
46.地图定位
CLLocationManager位置管理器 使用Core Location框架来确定iphone的位置(GPS,蜂窝基站三角网,wps三种方式)
MKMapView提供了一套可植入的地图接口,可以让我们在应用中展示地图,并对其进行相关的操作。一般来说,我们可以指定一个展示区域,放一些标记在上面,还可以加盖一些层在上面。
MKMapView依赖Google map里面相关服务(如Google Earth API等),所以地图的左下角会有Google字样。
47.打开url
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://8004664411"]];mailto:// sms://
http网络通信
ASIHTTPRequest 是一个直接在CFNetwork上做的开源项目:提供直接提交(HTTP POST)文件的API,异步请求与队列,自动管理上传与下载队列管理机,ASIFormDataRequest用于适合上传文件,图片数据。图片浏览
UIImagePickerController可以从相册,相机,胶卷里获得图片。对像序列化
NSCoding encodeWithCoder initWithCoder
NSKeyedUnarchiver NSKeyedArchiver各种picker
UIDatePicker UIPickerView电影播放
MPMoviePlayerController
音乐播放
MPMusicPlayerController
53.线程 ?
a. 线程的创建和使用规则?
答:NSThread
三种方法
- (id)init; // designated initializer
- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;
- (void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument
-
(void)start;
b. 主分线程
答:启动分线程,上面已提到!加到主线程方法performSelector!
//加到主线程addData()是主线程的方法!只有加到主线程后,才能调用主线程的方法
[target performSelector:@selector(addData:) onThread:[NSThread mainThread] withObject:item waitUntilDone:YES];
//[target addData:item];//没有加到主线程后,调用主线程的方法!一定会崩!c.线程锁 答:NSCondition 方法: [thread lock];//加锁 sleep(n);//线程休眠 [thread singnal];//相当于通知,线程启动 [thread unlock];//解锁 [thread exit];//线程退出
54.各种 排序算法?
希尔排序、快速排序、冒泡排序、
55.通信底层原理
答:OSI七层模型
7 应用层: ftp,smtp,http,telnet,tftp(通过各种协议,最终还是包装成TCP数据包,发送到网络中!)
6 表现层:
5 会话层:
4 传输层: tcp udp
3 网络层: ip,ICMP,IGRP,EIGRP,OSPF,ARP
2 数据链路层: STP,VT
1 物理层:
-
为什么很多内置类如UITableViewController的delegate属性都是assign而不是retain的?
答:
会引起循环引用
所有的引用计数系统,都存在循环应用的问题。例如下面的引用关系:
* 对象a创建并引用到了对象b.
* 对象b创建并引用到了对象c.
* 对象c创建并引用到了对象b.这时候b和c的引用计数分别是2和1。
当a不再使用b,调用release释放对b的所有权,因为c还引用了b,所以b的引用计数为1,b不会被释放。
b不释放,c的引用计数就是1,c也不会被释放。从此,b和c永远留在内存中。
这种情况,必须打断循环引用,通过其他规则来维护引用关系。我们常见的delegate往往是assign方式的属性而不是retain方式 的属性,
赋值不会增加引用计数,就是为了防止delegation两端产生不必要的循环引用。
如果一个UITableViewController 对象a通过retain获取了UITableView对象b的所有权,这个UITableView对象b的delegate又是a,
如果这个delegate是retain方式的,那基本上就没有机会释放这两个对象了。自己在设计使用delegate模式时,也要注意这点。 以下每行代码执行后,person对象的retain count分别是多少?
Person *person = [[Person alloc] init]; count 1
[person retain]; retain count 2
[person release];retain count 1
[person release];retain count = 0
58.在一个对象的方法里面:
self.name = “object”;
和
name =”object”
有什么不同吗?
答:self.name = "object"会调用对象的setName()方法,会使object引用计数加1,name = "object"会直接把object赋值给当前对象的name 属性,引用计数不增加。
59.readwrite,readonly,assign,retain,copy,nonatomic属性的作用?
@property是一个属性访问声明,扩号内支持以下几个属性:1,getter=getterName,setter=setterName,设置setter与getter的方法名2,readwrite,readonly,设置可供访问级别
3,assign,setter方法直接赋值,不进行任何retain操作,为了解决原类型与环循引用问题4,retain,setter方法对参数进行release旧值再retain新值,所有实现都是这个顺序(CC上有相关资料)
5,copy,setter方法进行Copy操作,与retain处理流程一样,先旧值release,再Copy出新的对象,retainCount为1。这是为了减少对上下文的依赖而引入的机制。
6,nonatomic,非原子性访问,不加同步,多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。锁被加到所属对象实例级(我是这么理解的…)。
7,@synthesize xxx; 来实现实际代码
60.1.main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d,%d",(a+1),(ptr-1));
}
答:2,5
*(a+1)就是a[1],*(ptr-1)就是a[4],执行结果是2,5
&a+1不是首地址+1,系统会认为加一个a数组的偏移,是偏移了一个数组的大小(本例是5个int)
int *ptr=(int *)(&a+1);
则ptr实际是&(a[5]),也就是a+5
原因如下:
&a是数组指针,其类型为 int ()[5];
而指针加1要根据指针类型加上一定的值,不同类型的指针+1之后增加的大小不同。
a是长度为5的int数组指针,所以要加 5sizeof(int)
所以ptr实际是a[5]
但是prt与(&a+1)类型是不一样的(这点很重要)
所以prt-1只会减去sizeof(int*)
a,&a的地址是一样的,但意思不一样
a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址,
a+1是数组下一元素的地址,即a[1],&a+1是下一个对象的地址,即a[5].