第1章 C语言概述
第2章 C语言数据类型,运算符与表达式
第3章 分支,循环
http://zhece.com
1. do-while和while的区别?
2. 写出几个死循环?
第4章 函数,数组,结构体
1.关键字volatile是什么含义?并给出三个不同的例子
2. 关键字const有什么含义?关键字volatile有什么含义?并给出三种不同的例子;
static 关键字的作用?extern “C”的作用?
3. 动态绑定?
4. 关键字const什么含义?
(1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;
(2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const;
(3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;
(4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;
(5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。例如:
const classA operator*(const classA& a1,const classA& a2);
operator*的返回结果必须是一个const对象。如果不是,这样的变态代码也不会编译出错:
classA a, b, c;
(a * b) = c; // 对a*b的结果赋值
操作(a * b) = c显然不符合编程者的初衷,也没有任何意义。
5. static作用?
(1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;
(2)在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;
(3)在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;
(4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;
(5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。
6. 编写函数——memmove说明如下:实现c语言库函数memmove的功能:将一块缓冲区中的数据移动到应一块缓冲区中。可能有重复?
7. 请写出下面程序的执行结果,
Int a[3][2] = {10,20,30,40,50,60};
Int (*pw) [2] = a;
Printf(“**(pw + 2) = %d\n”, **(pw + 2));
Printf(“**pw + 2 = %d\n”, **pw + 2);
Printf(“*(*(pw + 2) +1) = %d\n”, *(*(pw + 2) +1));
Printf(“*((*pw + 2) + 1) = %d\n”, *( (*pw + 2) + 1));
8. 请写出下面程序的执行结果 char str[] = “Hello”;
Char * p = str;
Printf(“%d, %d, %d, %d\n”, sizeof(str), strlen(str), sizeof(p), strlen(p));
9. 一个猴子吃桃一天吃桃子剩余数量的一半,感觉不够,再吃一个,共10天吃完,问一共吃了多少桃子,写出你的代码。
10. 写一个程序,反转一个链表(头结点为head,为节点指向null)
11. 数组有1000个元素,设为数组a[1000],存放1-1000的数值,但是现在有一个数值重复了,只扫描一遍数组,找出那个重复的数
12. 现在有m个人,每个房间可以住n个人,请问一共需要多少房间?(请用一行代码写出结果,不要用if等条件判断和三目运算符)
13. 给定一个整形变量a,写两段代码,第一个设置a的bit 3 ,第二个清除a的 bit 3 ,以上两个操作中,要保持其他位不变。
14. 写一个程序,判断当前机器是小端机还是大端机。
15. 现在有50阶楼梯,你可以一步一阶,也可以一步两阶,请问走完这50阶可以有多少种走法?写出你的思路和算法。
16.现在有两个矩形A,B 。A的左上角的坐标为(Xa1,Ya1),右下角坐标为(Xa2,Ya2),B的左上角坐标为(Xb1,Yb1),右下角坐标为(Xb2,Yb2),此坐标系为平面直角坐标系,x轴向右,y轴向上,如何判断这两个矩形没有交叉重叠,写出你的思路和算法。
18.用递归算法判断数组a[N]是否为一个递增
19.编写一个标准strcpy函数
20. 设计一个算法,要求在20个数字中(0到19)随机选取十个数字,但是这十个数字不能重复(用C语言或者OC实现)
21. 找错
void test1()
{
char string[10];
char* str1 = "0123456789";
strcpy( string, str1 );
}
答案: 字符串str1需要11个字节才能存放下(包括末尾的’\0’),而string只有10个字节的空间,strcpy会导致数组越界;
22.找错
void test2()
{
char string[10], str1[10];
int i;
for(i=0; i<10; i++)
{
str1 = 'a';
}
strcpy( string, str1 );
}
答案: 如果面试者指出字符数组str1不能在数组内结束可以给3分;如果面试者指出strcpy(string, str1)调用使得从str1[url=]内存[/url]起复制到string内存起所复制的字节数具有不确定性可以给7分,在此基础上指出库函数strcpy工作方式的给10分;
23.找错
void test3(char* str1)
{
char string[10];
if( strlen( str1 ) <= 10 )
{
strcpy( string, str1 );
}
答案; if(strlen(str1) <= 10)应改为if(strlen(str1) < 10),因为strlen的结果未统计’\0’所占用的1个字节。
综上得出的结论: 考查对基本功的掌握:(1)字符串以’\0’结尾;(2)对数组越界把握的敏感度;(3)库函数strcpy的工作方式,
下面编写一个标准的strcpy函数:
char * strcpy( char *strDest, const char *strSrc ) //将源字符串加const,表明其为输入参数,加2分
{
//对源地址和目的地址加非0断言,加3分
assert( (strDest != NULL) && (strSrc != NULL) );
char *address = strDest;
while( (*strDest++ = * strSrc++) != ‘\0’ );
return address; //为了实现链式操作,将目的地址返回,加3分!
}
(4)对strlen的掌握,它没有包括字符串末尾的'\0'。
读者看了不同分值的strcpy版本,应该也可以写出一个10分的strlen函数了,完美的版本为: int strlen( const char *str ) //输入参数const
{
assert( strt != NULL ); //断言字符串地址非0
int len;
while( (*str++) != '\0' )
{
len++;
}
return len;
}
24.找错
void GetMemory( char *p )
{
p = (char *) malloc( 100 );
}
void Test( void )
{
char *str = NULL;
GetMemory( str );
strcpy( str, "hello world" );
printf( str );
}
答案: 传入中GetMemory( char *p )函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值,执行完
char *str = NULL;
GetMemory( str ); 后的str仍然为NULL;
25.找错
char *GetMemory( void )
{
char p[] = "hello world";
return p;
}
void Test( void )
{
char *str = NULL;
str = GetMemory();
printf( str );
}
答案: 试题中
char p[] = "hello world";
return p;
的p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常犯的错误,其根源在于不理解变量的生存期。
26.找错
void GetMemory( char **p, int num )
{
*p = (char *) malloc( num );
}
void Test( void )
{
char *str = NULL;
GetMemory( &str, 100 );
strcpy( str, "hello" );
printf( str );
}
答案: 试题26的GetMemory避免了试题24的问题,传入GetMemory的参数为字符串指针的指针,但是在GetMemory中执行申请内存及赋值语句
*p = (char *) malloc( num );
后未判断内存是否申请成功,应加上:
if ( *p == NULL )
{
...//进行申请内存失败处理
}
27.找错
void Test( void )
{
char *str = (char *) malloc( 100 );
strcpy( str, "hello" );
free( str );
... //省略的其它语句
}
答案: 试题27存在与试题26同样的问题,在执行
char *str = (char *) malloc(100);
后未进行内存是否申请成功的判断;另外,在free(str)后未置str为空,导致可能变成一个“野”指针,应加上:
str = NULL;
试题26的Test函数中也未对malloc的内存进行释放。
24-27题结论; 试题24~27考查面试者对内存操作的理解程度,基本功扎实的面试者一般都能正确的回答其中50~60的错误。但是要完全解答正确,却也绝非易事。
对内存操作的考查主要集中在:
(1)指针的理解;
(2)变量的生存期及作用范围;
(3)良好的动态内存申请和释放习惯。
28.找错
swap( int* p1,int* p2 )
{
int *p;
*p = *p1;
*p1 = *p2;
*p2 = *p;
}
问题: 在swap函数中,p是一个“野”指针,有可能指向系统区,导致程序运行的崩溃。在VC++中DEBUG运行时提示错误“Access Violation”。该程序应该改为:
swap( int* p1,int* p2 )
{
int p;
p = *p1;
*p1 = *p2;
*p2 = p;
}
29. 分别给出BOOL,int,float,指针变量 与“零值”比较的 if 语句(假设变量名为var)
解答:
BOOL型变量:if(!var)
int型变量: if(var==0)
float型变量:
const float EPSINON = 0.00001;
if ((x >= - EPSINON) && (x <= EPSINON)
指针变量: if(var==NULL)
解析: 考查对0值判断的“内功”,BOOL型变量的0判断完全可以写成if(var==0),而int型变量也可以写成if(!var),指针变量的判断也可以写成if(!var),上述写法虽然程序都能正确运行,但是未能清晰地表达程序的意思。
一般的,如果想让if判断一个变量的“真”、“假”,应直接使用if(var)、if(!var),表明其为“逻辑”判断;如果用if判断一个数值型变量(short、int、long等),应该用if(var==0),表明是与0进行“数值”上的比较;而判断指针则适宜用if(var==NULL),这是一种很好的编程习惯。
浮点型变量并不精确,所以不可将float变量用“==”或“!=”与数字比较,应该设法转化成“>=”或“<=”形式。如果写成if (x == 0.0),则判为错,得0分。
30. 编写一个函数,作用是把一个char组成的字符串循环右移n个。比如原来是“abcdefghi”如果n=2,移位后应该是“hiabcdefgh”
函数头是这样的:
//pStr是指向以'\0'结尾的字符串的指针
//steps是要求移动的n
void LoopMove ( char * pStr, int steps )
{
//请填充...
}
解答:
正确解答1:
void LoopMove ( char *pStr, int steps )
{
int n = strlen( pStr ) - steps;
char tmp[MAX_LEN];
strcpy ( tmp, pStr + n );
strcpy ( tmp + steps, pStr);
*( tmp + strlen ( pStr ) ) = '\0';
strcpy( pStr, tmp );
}
正确解答2:
void LoopMove ( char *pStr, int steps )
{
int n = strlen( pStr ) - steps;
char tmp[MAX_LEN];
memcpy( tmp, pStr + n, steps );
memcpy(pStr + steps, pStr, n );
memcpy(pStr, tmp, steps );
}
解析:
这个试题主要考查面试者对标准库函数的熟练程度,在需要的时候引用库函数可以很大程度上简化程序编写的工作量。
31. 有一组数字,从1到n,从中减少了3个数,顺序也被打乱,放在一个n-3的数组里
请找出丢失的数字,最好能有程序,最好算法比较快
假设n=10000
答案:
我的思路剖析:
1.申请一个数组,长度为n,每个字节初始化为1
2.遍历待检查的数组,取出值作为索引对应之前申请的数组相应位置为0
3.遍历第1步里面的数组,如果相应位为1则把该数组下标加1后添加到结果集中
以上就是一个最容易理解的思路,不过这个还可以进一步改进。
算法改进:
我们可以用位向量来存储域(这个域就是1到n),这样我们申请 (n+7)/8 *8bit 的空间就好了,因为C里面没有bit的直接I/O,所以我们通过位运算来实现。具体看了代码就明白了。
代码如下:
[cpp] view plaincopyprint?
int func(int* result,int dest[],int destLength,int n){
int resultCount =0;
int BitCharLength = (n+7)/8;
int i;
if ((n-destLength)==0) {//待检查数组长度等于域长度
return -1;
}
char* BitChar = (char*)malloc(BitCharLength*sizeof(char));
if (BitChar==NULL) {//申请位向量空间失败
return -2;
}
result = (int*)malloc((n-destLength)*sizeof(int));
if (result==NULL) {//申请结果集空间失败
return -3;
}
for (i = 0;i<(n+7)/8; i++) {//位向量所有位都置1
BitChar[i] = 127;
}
for (i = 0; i把dest[i]在BitChar中对应的bit置为0
BitChar[dest[i]>>3] &=~(1<<(dest[i] & 7));
}//这个完成以后存在的bit位全置0了,不存在的还是1;
for (i = 0; i<(n+7)/8; i++) {//把BitChar[i]中为一的位对应的索引写到result中
if ((BitChar[i] & 1) != 0) {//00000001
resultCount++;
result[resultCount]= 8*i+1;
}
if ((BitChar[i] & 2) != 0) {//00000010
resultCount++;
result[resultCount]= 8*i+2;
}
if ((BitChar[i] & 4) != 0) {//00000100
resultCount++;
result[resultCount]= 8*i+3;
}
if ((BitChar[i] & 8) != 0) {//00001000
resultCount++;
result[resultCount]= 8*i+4;
}
if ((BitChar[i] & 16)!= 0) {//00010000
resultCount++;
result[resultCount]= 8*i+5;
}
if ((BitChar[i] & 32)!= 0) {//00100000
resultCount++;
result[resultCount]= 8*i+6;
}
if ((BitChar[i] & 64)!= 0) {//01000000
resultCount++;
result[resultCount]= 8*i+7;
}
if ((BitChar[i] &128)!= 0) {//10000000
resultCount++;
result[resultCount]= 8*i+8;
}
if (resultCount == (n - destLength)) {
return resultCount;
}
}
return resultCount;
}
32. 请写一个C函数,若处理器是Big_endian的,则返回0;若是Little_endian的,则返回1
解答:
int checkCPU()
{
{
union w
{
int a;
char b;
} c;
c.a = 1;
return (c.b == 1);
}
}
解析: 嵌入式系统开发者应该对Little-endian和Big-endian模式非常了解。采用Little-endian模式的CPU对操作数的存放方式是从低字节到高字节,而Big-endian模式对操作数的存放方式是从高字节到低字节。例如,16bit宽的数0x1234在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:
内存地址存放内容
0x40000x34
0x40010x12
而在Big-endian模式CPU内存中的存放方式则为:
内存地址存放内容
0x40000x12
0x40010x34
32bit宽的数0x12345678在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:
内存地址存放内容
0x40000x78
0x40010x56
0x40020x34
0x40030x12
而在Big-endian模式CPU内存中的存放方式则为:
内存地址存放内容
0x40000x12
0x40010x34
0x40020x56
0x40030x78
联合体union的存放顺序是所有成员都从低地址开始存放,面试者的解答利用该特性,轻松地获得了CPU对内存采用Little-endian还是Big-endian模式读写。如果谁能当场给出这个解答,那简直就是一个天才的程序员。
33. 写一个函数返回1+2+3+…+n的值(假定结果不会超过长整型变量的范围)
解答:
int Sum( int n )
{
return ( (long)1 + n) * n / 2; //或return (1l + n) * n / 2;
}
剖析:
对于这个题,只能说,也许最简单的答案就是最好的答案。下面的解答,或者基于下面的解答思路去优化,不管怎么“折腾”,其效率也不可能与直接return ( 1 l + n ) * n / 2相比!
int Sum( int n )
{
long sum = 0;
for( int i=1; i<=n; i++ )
{
sum += i;
}
return sum;
}
所以程序员们需要敏感地将数学等知识用在程序设计中
34.异常exception 怎么捕获?不同的CPU结构上开销怎样?C中又什么类似的方法?
35. 大概是一百个数,按123123循环,将23去掉,循环。最后胜的那个数,编号多少。二十分钟。
36. 证明是不是回文数 ("回文数"是一种数字。如:98789, 这个数字正读是98789,倒读也是98789,正读倒读一样,所以这个数字就是回文数)
37. sprintf,strcpy,memcpy的功能,在使用上有哪些要注意的地方.
用预处理指令#define声明一个常数,用以表明1年中有多少秒(忽略闰年);
38.new、delete、malloc、free关系
39.#define DOUBLE(x)x+x, i=5*DOUBLE(5); i是多少?
40.struct和class的区别
41.分别写出BOOL,int,float,指针类型的变量a与“零”的比较语句;
第5章 指针
1.用变量a写出下面的定义,
a)一个整型数__________________
b)一个指向整型数的指针___________
c)一个指向指针的指针,它指向的指针是指向一个整型数_______________
d)一个有10个整型数的数组___________
e) 一个有10个整型数的数组,该指针是指向一个整型数的_______________
f)一个指向有10个整型数数组的指针_______
g)一个指向函数的指针,该函数有一个整型参数并返回一个整型数_____________
2. 用变量a给出下面定义
A 一个指向指针的指针,它指向的指针是指针
B 一个有10个指针的数组,该指针是指向
C 一个指向有十个整形数组的指针
D一个有十个指针的数组,该指针指向一个函数,该函 数有一个整形参数并返回一个整形数
3. 设置一个绝对地址为0x67a9的整形变量的值为0xaa66 编译器是一个纯粹的ANSI编译器。写代码去完成这一任务。
4.写个子程序实现这个功能:把一个输入字符串的特定字符串,全部移到字符串尾部。
例如:输入字符串是source[]=“zoboydo1f$+g,把‘o’调整到尾部,成为“zbyd1f$+gooo”
再例如,输入字符串是source[]=“1987y.1204”,把‘1’调整到尾部,成为“987y.20411”;
请描述一下算法,并写出你的算法的空间复杂度和时间复杂度的表示式。
第6章 宏,枚举
1.用预处理指令#define声明一个常数,表示1年中有多少秒(忽略闰年)
2.写一个宏MIN,这个宏输入两个参数并返回较小的一个
答:#define MIN(A,B) ((A) <= (B)? (A) : (B))
这个测试是为下面的目的而设的:
1). 标识#define在宏中应用的基本知识。这是很重要的,因为直到嵌入(inline)操作符变为标准C的一部分,宏是方便产生嵌入代码的唯一方法,
对于嵌入式系统来说,为了能达到要求的性能,嵌入代码经常是必须的方法。
2). 三重条件操作符的知识。这个操作符存在C语言中的原因是它使得编译器能产生比if-then-else更优化的代码,了解这个用法是很重要的。
3). 懂得在宏中小心地把参数用括号括起来
4). 我也用这个问题开始讨论宏的副作用,例如:当你写下面的代码时会发生什么事?
least = MIN(*p++, b);
3. 用宏定义交换两个数
第7章 Objective-C 语言概述
1.#import跟#include有什么区别,@class呢?(重复题)
2. obj-c的优缺点?
3. 不使用中间值交换a、b。a=69,b=78交换后是a=78,b=69.
4. 用OC语言写一个方法,输入一个年份,输出这个年份之后的三个闰年。
5. objective - c有私有方法吗? 不是的话有什么替代方法?(重复题)
6. 我们说的obc是动态运行时语言是什么意思?(When we call objective c is runtime language what does it mean?)
答案:多态:主要是将数据类型的确定由编译时,推迟到了运行时。 这个问题其实浅涉及到两个概念,运行时和多态。 简单来说,运行时机制使我们直到运行时才去决定一个对象的类别,以及调用该类别对象指定方法。 多态:不同对象以自己的方式响应相同的消息的能力叫做多态。意思就是假设生物类(life)都用有一个相同的方法-eat; 那人类属于生物,猪也属于生物,都继承了life后,实现各自的eat,但是调用是我们只需调用各自的eat方法。 也就是不同的对象以自己的方式响应了相同的消息(响应了eat这个选择器)。 因此也可以说,运行时机制是多态的基础?
7. 关于多态性(Polymorphism?)
答案:多态,子类指针可以赋值给父类。 这个题目其实可以出到一切面向对象语言中, 因此关于多态,继承和封装基本最好都有个自我意识的理解,也并非一定要把书上资料上写的能背出来。 最重要的是转化成自我理解。
8. Cocoa中有虚基类的概念么?怎么简洁的实现?
9.如何在Objective-C中使用C++类并成功编译?
10.多态,虚函数,纯虚函数。
11.重载(overload)和重写(override,也有叫做“覆盖”)的区别?
12.全局变量和局部变量在内存中是否有区别?如果有,是什么区别?
第8章 面向对象
1. Object-C有多继承吗?没有的话用什么代替?
答: Object-c的类不可以多重继承,只支持单继承,如果要实现多继承的话,可以通过类别和协议的方式来实现,cocoa中所有的类都是NSObject的子类,多继承在这里是用protocol委托代理来实现的;可以实现多个接口,通过实现多个接口可以完成C++的多重继承;Category是类别,一般情况用分类好,用Category去重写类的方法,仅对本Category有效,不会影响到其他类与原有类的关系。
(知识补充:伪继承: 尽管在objtive-C中不提供多继承,但它提供了另外一种解决方案,使对象可以响应在其它类中实现的消息(别的语言中,一般叫方法,两者无差别). 这种解决方案叫做消息转发,它可以使一个类响应另外一个类中实现的消息。
在一般情况下,发送一个无法识别的消息会产生一个运行时的错误,导致应用程序崩溃,但是注意,在崩溃之前,iphone运行时对象为每个对象提供了第二次机会来处理消息。捕捉到一条消息后可以把它重定向到可以响应该消息的对象。
这个功能完全通过消息转发来实现,发送消息给一个无法处理该选择器的对象时,这个选择器就会被转发给 forwardInvocation 方法.接收这条消息的对象,用一个NSInvocation的实例保存原始的选择器和被请求的参数.所以,我们可以覆盖 forwardInvocation 方法,并把消息转发给另外一个对象.)
2. 封装 继承 多态(类目、延展、协议)
3. 类变量的@protected ,@private,@public,@package声明各有什么含义?
答:访问修饰符扩展:@protected受保护-类和子类内可访问的成员,实例编码的访问修饰默认为@protected;
@private私有-仅类内可访问的成员;
@public公共-类外可访问的成员;
@package-…
4. 如何在有一个属性名和值的情况,给一个对象赋值
5. 1objective - c中是所有对象间的交互是如何实现的?
6. 什么是抽象类?抽象类有什么作用?能实例化吗?
7. 用objective - c写冒泡法?
8. 对@interface和@property的理解?
9. iphone开发中控制类有什么作用?
10. cocoa 函数库的使用?
11. 写委托代理
12. 有如下一个类定义
@interface MyClass : NSObject
@property(retain) NSString *myProp;
@end
请完成myProp属性的set方法:
- (void)setMyProp:(NSString *)aProp
{
}
13. 写一个setter方法用于完成@property (nonatomic,retain)NSString *name,写一个setter方法用于完成@property(nonatomic,copy)NSString *name
答:
- (void) setName:(NSString*) str
{
[str retain];
[name release];
name = str;
}
- (void)setName:(NSString *)str
{
id t = [str copy];
[name release];
name = t;
}
14. 系统有哪些单例,把你知道的都写出来。然后手写一个单例,(单例名称,成员变量自己觉得,单纯考查单例的语法)
15. 写一个NSMutableArray的单例
16. #import 跟#include 有什么区别,@class呢, #import<> 跟#import””又有什么区别?(常考@class关键字有什么作用)
答: #import是Objective-C导入头文件的关键字,#include是C/C++导入头文件的关键字,使 用#import头文件会自动只导入一次,不会重复导入,相当于#include和#pragma once;@class告诉编译器某个类的声明,当执行时,才去查看类的实现文件,可以解决头文件的相互包含;#import<>用来包含系 统的头文件,#import””用来包含用户头文件。简单说,@class一般用于头文件中需要声明该类的某个实例变量的时候用到,在m文件中还是需要使用#import,而#import比起#include的好处就是不会引起交叉编译.
17. id 声明的对象有什么特性?
答: Id 声明的对象具有运行时的特性,即可以指向任意类型的objcetive-c的对象;(附加:id数据类型也叫动态数据类型,没有*号,可以指向任何类的对象(设置是nil),而不关心其具体类型,可以对其发送任何(存在时)消息,在运行时检查其具体类型).
18. 写出属性的set和get方法
19. 对于单例的理解(Singleton?)
答:题目其实出的有点泛泛的感觉了,可能说是编程语言需要或是必备的基础。 基本能用熟悉的语言写出一个单例,以及可以运用到的场景或是你编程中碰到过运用的此种模式的框架类等。 进一步点,考虑下如何在多线程访问单例时的安全性。
20. 方法和选择器有何不同?(Difference between method and selector?)
答案:selector是一个方法的名字,method是一个组合体,包含了名字和实现. 详情可以看apple文档。
21.对于语句NSString* testObject = [[NSData alloc] init];testObject 在编译时和运行时分别是什么类型的对象?
22. 读程序写输出结果
-(void)getNSString(const NSString *inputString){
inputString = @”This is a mai test\n”;
return;
}
int main(int argc,const char *argv[]){
NSString *a = @”Main”;
NSString *aString = [NSString stringWithString:@”%@”,getNSString(a)];
NSLog(@”%@\n”,aString);
}
最后输出的字符串是( )
23.property中属性retain,copy,assgin的含义分别是什么?有什么区别?将其转换成get/set方法怎么做?有什么注意事项?
24. 分别叙述strong weak retain release alloc 的用法
25. readwrite,readonly,assign,retain,copy,nonatomic属性的作用.
第9章 内存管理
1.简述Objective-C的内存管理
2.对象是什么时候被release的?
3. iOS有没有垃圾回收?
4. 内存管理 Autorelease、retain、copy、assign的set方法和含义?
5. 解释retainCount
6. 说说你对ARC的理解
7. 以下每行代码执行后,person对像的retain count分别是多少?
Person *person =[person alloejinit];
[person retain];
[person release];
[person release];
8. autorelease的对象,在什么时候被释放? 一般什么情况下会用到它?
9. 说说Auto Release Pool,内存管理模式, GC, retain count
10. copy 与 retain 的区别
11. 调用一个类的静态方法需不需要release?
12. autorelease 和垃圾回收制(gc)有什么关系?
13. iphone os 有没有垃圾回收(gc)?
答案: OC2.0有Garbage collection,但是iOS平台不提供。 一般我们了解的objective-c对于内存管理都是手动操作的,但是也有自动释放池。 但是差了大部分资料,貌似不要和arc机制搞混就好了。