第一题:
staticint a = 1;
void test()
{
static int a = 2;
printf("%d",a);
}
答案:a的值为2
说明:1、static关键字
在局部变量名字的前面加上static,可以使局部变量保留多次调用一个方法所得的值,只在程序开始执行时初始化一次,且静态变量的初始值为0,静态局部变量属于静态存储类型,在静态存储区内分配内存,在程序运行期间不释放内存,
静态的全局变量的作用域是本文件;
在定义函数时在函数返回类型前面加上static,该函数则为内部函数(静态函数),其作用域仅限于本文件。
要定义外部函数则在函数前家上exter关键字(省略关键字,默认为外部函数)。
2、如果局部变量和全局变量的类型与名称完全一致,在局部变量定义的有效域中,局部变量将覆盖全局变量。直到退出局部变量定义域,全局变量的定义才又重新可见。
在C++中可以使用作用域限制符“::”来在局部变量和全局变量同名的情况下使用全局变量。
void test()
{
static int a = 2;
cout<<a<<endl;//使用局部变量a
cout<<::a<<endl;//使用全局变量a
}
第二题:
int i=0;
while (1) {
//Lock();
if (i++<=3)
continue;
//UnLock();
printf("i = %d",i);
}
说明:这是一个无限死循环,第一次输出i的值为5,以后每次加1,加一个else跳出循环后叔叔结果为5
int i=0;
while (1) {
//Lock();
if (i++<=3)
continue;
//UnLock();
else
break;
}
printf("i = %d",i);
第三题:写一个代理类
@protocol myDelegate <NSObject>
- (void)thisIsMyDelegate;
@end
@interface Delegate : NSObject
@property (nonatomic,assign) id<myDelegate>delegate;
@end
@implementation Delegate
- (void)test{
//完成什么条件时执行
[_delegatethisIsMyDelegate];
}
@end
第四题:什么是nsnotification?什么时候用delegate?什么时候用nsnotification?
答案:delegate针对one-to-one关系,并且reciever可以返回值给sender;
notification 可以针对one-to-one/many/none,reciever无法返回值给sender;
NSNotificationCenter消息通信机制介绍(KVO)
作用:NSNotificationCenter是专门供程序中不同类间的消息通信而设置的.
注册通知:即要在什么地方接受消息
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mytest:) name:@" mytest" object:nil];
参数介绍:
addObserver: 观察者,即在什么地方接收通知;
selector: 收到通知后调用何种方法;
name: 通知的名字,也是通知的唯一标示,编译器就通过这个找到通知的。
发送通知:调用观察者处的方法。
[[NSNotificationCenter defaultCenter] postNotificationName:@"mytest" object:searchFriendArray];
参数:
postNotificationName:通知的名字,也是通知的唯一标示,编译器就通过这个找到通知的。
object:传递的参数
注册方法的写法:
- (void) mytest:(NSNotification*) notification
{
id obj = [notification object];//获取到传递的对象
}
第五题:const是什么意思?以下声明各是什么意思?
const是一个存储类型说明符,它的作用:
1. const类型定义:指明变量或对象的值是不能被更新,引入目的是为了取代预编译指令
2. 可以保护被修饰的东西,防止意外的修改,增强程序的健壮性;
3. 编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。
4. 可以节省空间,避免不必要的内存分配。
1、定义常量
(1)const修饰变量,以下两种定义形式在本质上是一样的。它的含义是:const修饰的类型为TYPE的变量value是不可变的。
TYPE const ValueName = value; const TYPE ValueName = value;
2、指针使用CONST
(1)指针本身是常量不可变 (char*) const pContent; const (char*) pContent;
(2)指针所指向的内容是常量不可变 const (char) *pContent; (char) const *pContent;
(3)两者都不可变 const char* const pContent;
(4)还有其中区别方法,沿着*号划一条线: 如果const位于*的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量; 如果const位于*的右侧,const就是修饰指针本身,即指针本身是常量。
- 第六题:不引入库文件,自己实现strcpy函数
- char *strcpy1(char *dest,const char *src)
- {
- if(src==NULL)
- {
- returnNULL;
- }
- char *temp;
- temp=dest;
- while(*src!=' ')
- {
- *dest=*src;
- dest++;
- src++;
- }
- *dest = ' ';
- return temp;
- }
- 说明:先要检测需要拷贝的字符串是不是为空,最后还需将 也复制给拷贝到的字符串
第七题:请编程实现,输入一个字符串比如“aaabbcdddd”,输出“3a2bc4d”
没有想到好的方法
第八题:检测单链表是否有环
/*要解决这个问题,最可能采取的方法就是使用两个循环。当外层循环步进一个节点时,内层循环就遍历外层循环节点之后的所有节点,然后比较内外循环的两个节点。若有节点地址相等,则表明该单链表有循环,反之则不存在循环。这种方法无疑效率比较低。
快慢指针的设计思想也是这样。快指针每次步进多个节点(视情况而定但不能够大于循环结点个数),慢指针每次只步进一个节点。那么如果该链表存在循环的话,快指针一定会再次碰到慢指针,反之则不存在循环。*/
struct list_node {
struct list_node *next;
void *data;
};
#define FALSE 0
#define TRUE 1
typedefunsignedcharbool;
bool is_list_exist_loop(struct list_node *head)
{
/*
快指针步进长度,之前我认为可以为其它值,但是从Bean_lee的回复中知道,不能为超过循环节点个数的值。
当超过循环节点个数时,而慢结点还未步入这个循环时,快节点会一直在循环中步进直至慢节点也步入这个循环。
*/
#define FAST_POINT_STEP 2
if (!head) return FALSE;
struct list_node *fast, *slow;
unsignedint i;
/* 快慢指针都处于同一起跑线,即头指针位置 */
fast = slow = head;
while (fast) {
/* 快指针步进 */
for (i = 0; i < FAST_POINT_STEP; ++i) {
fast = fast->next;
if (fast == slow) {
/* 又碰到了慢指针,循环存在 */
return TRUE;
}
else if (!fast) {
/* 快指针跑到头了,循环不存在 */
return FALSE;
}
}
/* 慢指针步进 */
slow = slow->next;
}
returnFALSE;
}