2009年12月17日星期四

设置终端窗口的大小和位置

如我的自启动选项脚本里面是如下设置的:
gnome-terminal --geometry 98x16+0-0 --hide-menubar --tab
--working-directory ~/Work/dppd_linux_dev/dhpd_cam --tab
--working-directory ~/Work/dppd_linux_dev/pddemo_sdl/src --tab
--working-directory ~/Work/rd_pdex_its/admin/iso9000/2规划阶段/

解释:
1. --geometry 98x16+0-0 设置窗口长宽为98、16个字宽, +0-0
表示窗口位置在左下角,同理,-0-0为右下角;
2. --tab 为单开个tab页,可以开多个tab页;
3. --working-directory为设定默认路径;

DM642启动过程分析

DM642复位后,芯片先从CE1空间读取1K字节的数据到内部SRAM,然后从地址0开始运行。因为一般的程序都远远大于1K字节,所以一般都是有一个二级bootloader,用它来加载主程序。Bootloader运行完后调用c_int00()来进行C运行时刻初始化,如堆栈,静态变量等,之后会调用BIOS_init,最后开始运行main函数,main函数结束后DSP/BIOS的任务管理器开始运行。

具体实现起来时要稍复杂一些,因为有一些实际问题需要考虑。
1.外部存储器一般是NOR
Flash,容量较大时,因为DM642的CE1只有1MB空间,需要使用GPIO配合的分页模式。因为GPIO的缺省值是输入,内有上拉电阻,所以bootloader需要写在最高页。DM642复位后采用最慢的读写时序。
2.Bootloader需要在有限的1K字节内完成SDRAM初始化,并将主程序搬运到内存中然后开始运行。TI的例子是用汇编写的,因为此时c的运行环境还没有初始化。其中最关键的是栈指针没有初始化,我们给它赋值后其他部分就可以用c来写,但要注意仍不能使用c库函数。

汇编部分进行栈指针初始化:
_boot_sp:
mvk .S2 0x0600, B15
mvkl .S2 _boot_loader, B0
mvkh .S2 _boot_loader, B0
b .S2 B0
nop 5

boot.c进行EMIF初始化,并分段将主程序从Flash读入SDRAM
#pragma CODE_SECTION(boot_loader, ".boot_load");

void boot_loader(){
Uint32 program_addr,size;
Uint8* src,*dest;

program_addr=0x90000404;//First Entry

//Init the EMIF interface
EMIFA_GCTL = 0x00052060;
EMIFA_CE0 = 0x00000040;
EMIFA_CE1 = 0x21E28E01; //0x11518a01
EMIFA_CE2 = 0xffffffd3;
EMIFA_CE3 = 0xffffffd3;
EMIFA_SDRAMCTL = 0x6b228000;
EMIFA_SDRAMTIM = 0x000003A9;
EMIFA_SDRAMEXT = 0x000505cd;
EMIFA_CE0SECCTL= 0x00000071;
EMIFA_CE1SECCTL= 0x00000002;
EMIFA_CE2SECCTL= 0x00000002;
EMIFA_CE3SECCTL= 0x00000002;

//Load Second Bootloader to SDRAM
size=*(Uint32*)program_addr;
while(size){
program_addr+=4;
dest=(Uint8*)(*(Uint32*)program_addr);
program_addr+=4;
src=(Uint8*)program_addr;
program_addr+=size;
if(size%4)program_addr+=4-(size%4);
while(size--){*dest++=*src++;}
size=*(Uint32*)program_addr;
}

c_int00();//Run the Second Bootloader
3.经常遇到的问题是bootloader调试时运行正常,写到flash就启动不了。这里的区别在于调试时CCS负责将程序装载到内存中,然后程序直接从c_int00()开始运行,而烧到flash就得一切靠自己了。调试这个问题的办法是CCS加载程序后,先查看内存0地址处,是否是bootloader的代码,如果不对就是linker的cmd文件或DSP/BIOS内存设置有问题,需要将bootloader放在片内SRAM中。然后让程序从0地址开始运行,看主程序是否正确地加载到内存中。
.boot_load{
boot_sp.obj
boot.obj
}>BOOT_RAM
BOOT_RAM是起始地址为0,长度1K的内部SRAM空间。
4.bootloader调试完毕后就是烧写到flash。先用TI的Hex6x将输出转换成hex文件,然后用flashburn或自己的代码烧写。Flash的头1K字节是bootloader,然后是主程序的代码段。代码的格式可以参见boot.c

关于DSP程序编译优化选项o3的问题

今天我在优化代码的时候。出现了问题。如下:
//----------------PERIPH.C---------------------
/* 读寄存器,参数 地址 返回内容*/
unsigned int ReadCMD(unsigned char addr)
{
unsigned int temp;
XCS_L();
WriteByte(0x03);
WriteByte(addr);
temp = ReadByte();
temp <<= 8;
temp += ReadByte();
XCS_H();
return temp;
}

//------------------MAIN.C-----------------
#define ReadHDAT0() ReadCMD(SPI_HDAT0)

hdat0=ReadHDAT0();//读文件帧头信息

假如我不用o3优化项。我读出的数据是正确的。但用的话,每次读出来的数据都错。而且都不相同(数值和正确的数值相差不大,可以说在正确数值下波动)。
然后我就查了对应o3的资料,书本有如下一段:
"-o3:表示最大可能优化级别。各种循环优化都执行了,并且各种文件级性质也用来改善性能。"

请问:
1、假如我要选用o3优化的话,我该怎样做才不出错?
2、o3的说明中,"各种循环优化都执行了",各种循环优化,具体怎么优化?在什么条件下?优化了些什么?
3、"各种文件级性质也用来改善性能",文件级性质指的是什么?它何以改善性能?

O3是最大的优化级别,特别对循环试图进行软件流水。优化后一些不常用的中间变量将被释放掉,优化前中间变量被定义在L2缓存里,优化后直接分配在了CPU内部寄存器里,所以这些变量将不能被看到。建议买一本DSP优化方面的书,一般讲得很清楚

很正常,采用O3优化后,少些代码会不正常,我也遇见过好几次,把C代码的方法改一下,再采用FULLL-DEBUG模式回过去看看(MIX模式)汇编确认一下。

我跑的是一个视频采集和压缩的程序,压缩用的是JPEG压缩算法, 程序在 不选-O2
或者-o3选项优化的时候,可以正常工作,而且比较稳定,但使用-o2或者-o3选项后,程序工作不稳定,会出错。而且程序在使用-o2或者-o3选项后,很多变量被优化掉了,有些语句的顺序也被调整了,调试起来也不是很方便,还需要继续研究。

程序中还使用了CSL支持库中
DAT_COPY,用于从外部SRAM中搬移数据到内部L2RAM中,没有使用-o2或者-o3选项时,DAT_COPY工作正常,
在使用-o2或者-o3选项后,DAT_COPY函数工作不正常了, 还得继续整。

肯定要使用-O3,不然全用手工优化,得把人累死。
至于错误的原因,不能怪-O3,只能说程序不严谨!
03出错,有时是用指针读写内存的错误,可以把程序分成比较小的文件,一个文件一个文件的O3,每次-O3一个文件,缩小错误的范围。
不会使用-O3的工程师,不算合格的DSP工程师。

投资之道 策略制胜

我们在面对投资决策之时就像身处一个迷宫,有太多的选择和岔路,大多数人望着目标在每个岔路口选择自己认为最近的路,而真正走出去的寥寥。问题何在?问题就出在对待投资的态度——盲目、急躁、冲动等等。而正确的对待投资的观念及策略就像一张地图,带你走的也许是百转千回的路,但那是唯一制胜的捷径。

  "兵无常势,水无常形",投资也如打仗用兵,需要根据形势的变化用灵活的策略应对之,才能立于常胜不败之地。小女不才,不善于总结提炼大的道理,今天与大家分享几个小故事共勉。

  故事一:几十年前,纽约街头有一个流浪汉偶然在街边捡到一百万美元。狂喜之后他对钱的安排采用了四种策略。第一种策略,到拉斯维加斯豪赌。结果是回到街上流浪。第二种策略,全数存入银行。结果是他花的每一分钱都来源于他的本金,通货膨胀帮他一起花。第三种策略,买入曼哈顿市中心的房子。结果是过着优越而富足的生活。第四种策略,买入量子基金。结果是富可敌国,该基金平均每年为其创造超过百分之三十的复利增长,经过几十年的累计,可怕的复利为其累计了巨额的财富。四种不同的策略成就了他今天不同的生活。在今天的世界中,财富正以自己的规律快速的增加和转移,究竟应该持有什么资产渡过漫长的岁月,穿越这个时代?在中国,我建议的策略是:买基金、买房子、买黄金以及与有钱的人待在一起。是的,股市的泡沫会破灭,楼市的泡沫亦会破灭,黄金也可能因为美元的走强而下跌,但是在漫长的岁月里,泡沫破灭后会是另一个。当然我们可以做波段,只要我们明白上面三者是可以持有穿过漫长岁月的,我们就能在恐慌蔓延时勇敢决断。

  故事二:有一位急性子的先生,由于有事需要到北京。于是他开着新买的小车出发了,在上海市中心遇上了烦人的堵车,一个小时过去了,两个小时过去了,一辆辆自行车从他身边飞驰而过。他,却寸步难行。终于他忍受不了这样等待的煎熬。跳下他的小车,就地叫卖,当场把他的小车以低得惊人的价格卖掉又买了一辆自行车向他的目的地北京进发了,骑上自行车时他心中无比畅快,终于又在前行了。可是,猜猜,何年何月才能骑到北京呢?这个故事看来很荒谬,但是在面对投资决策时,有太多这样的投资人。08年时股市低迷,大家都把主动式投资基金转化成固定收益理财产品,这不就是在把堵住的小车换自行车么?若目标选定了,就请坚持使用真正能带您到目的地的交通工具。做长期决策时需要问自己:究竟想要什么样的旅程,目的地是哪里?做短期决策时需要问自己:气球就要爆破之前,还能为之充多少气?

  故事三:07年初时2800点时,我有一位朋友开始投资股票。初涉这个市场不敢买多,投了10万元,不到一个月就赚进2万元,欣喜若狂下赶紧落袋为安。哪知股市接着往上,不甘心再次买入。这次胆子大了一些,加倍买!投入二十万,忐忑不安地观察了一阵,又赚了不少。心中开始欣赏自己,周围的看多的人群与日俱增,大家与我同在,更加大胆的加码投入!就这样市场一路涨,这位朋友一路加码投资。随着本金的不断追加以及前期投入本金的增值,6000点时几乎满仓。股市急转直下跌到4200点时,他已经分文不赚,跌回2800点时本金已经亏损掉一半。盲目随性的投资,没有策略和纪律是这位朋友失败的关键。风险与回报就像铁路平行的两边,大部分投资者的风险偏好却像钟摆,赚钱时自我膨胀,潮水退去才发现自己在裸泳。投资的大忌是感性的选择。参与投资之前运筹帷幄,制定策略,运用理性和纪律严格的执行才能成为市场长期的赢家。

  事实上,投资之道犹如在迷宫中,最近的道路并非直线而是曲折蜿蜒,若没有全局观念仅盯住眼前几尺之地,或没有退既是进的胸怀和淡定就很难走到目的地。展望2010年,应是经济复苏的整固年。也因此,很多市场人士预测明年主要的投资主线仍将围绕经济复苏进程的反复确认和整固进行,而在经济复苏不同阶段的优势行业会有较大差异,选择不同的投资策略将对投资回报起到较大的影响。至于具体的策略,对于普通的投资者而言,由于A股风格正面临转换,原先以指数型基金为代表的"傻瓜式"投资或许在未来将逐步弱化,2010年要获得好的收益,将更为考验投资者对于行业和个股的主动挖掘。如果个人的时间精力不够,也可以借助基金、券商等专业投资管理来帮助构建主题投资的组合,以期获得较好的收益。

年轻时我们不可不懂

当人们还在猜测大盘今天是否,突破,变盘的时候。
当人们还在憧憬惊天一涨的时候,
当有人昨天就买进图形走式完美的某一股票期待今天停版的时候。
市场给了我们答案,然后,我们在猜测,憧憬,在看图分析,
在我看来,我们是可笑的。
我们什么都不要做,我们只需要问我们自己这样几个问题:
1 是不是今天大盘跌了,我们所持有的企业就变坏了如果没有,那么我们就做下面的事情。
2 安静的阅读我们持有的公司的年报或者公告,或者是财务报表,甚至是所以关于这个企业的新闻,也可以是本行业的数据,历史,以及未来的发展。等待自己烦躁了就做下面的事情。
3 想想历史上有多少次的大跌,有多少次的经济危机,有多少我们所不可以预测的事件。他们对于优秀的企业产生影响了吗,还可以做下面的事情。
4 回归到我们投资的本质,生活的本质,想明白这些事情,我想是对我们有益的,我喜欢这样一句话,
巴非特之所以伟大,并不在与他在76岁时拥有400多亿美圆的财富,而在于他在很年轻的时候就想明白了很多事情,并且用一生的时间来监守。



2009年12月16日星期三

什么是 socket?

什么是 socket?
  你经常听到人们谈论着
"socket",或许你还不知道它的确切含义。现在让我告诉你:它是使用 标准Unix
文件描述符 (file descriptor) 和其它程序通讯的方式。
什么?

struct sockaddr.。这个结构 为许多类型的套接字储存套接字地址信息:
struct sockaddr {
   unsigned short sa_family; /* 地址家族, AF_xxx */
   char sa_data[14]; /*14字节协议地址*/
   };
sa_family 能够是各种各样的类型,但是在这篇文章中都是 "AF_INET"。
sa_data包含套接字中的目标地址和端口信息。这好像有点 不明智。
为了处理struct sockaddr,程序员创造了一个并列的结构: struct sockaddr_in
("in" 代表 "Internet"。)
struct sockaddr_in {
   short int sin_family; /* 通信类型 */
   unsigned short int sin_port; /* 端口 */
   struct in_addr sin_addr; /* Internet 地址 */
   unsigned char sin_zero[8]; /* 与sockaddr结构的长度相同*/
   };
用这个数据结构可以轻松处理套接字地址的基本元素。

一个指向 sockaddr_in结构体的指针也可以被指向结构体sockaddr并且代替它。这
样的话即使 socket() 想要的是 struct sockaddr *,你仍然可以使用 struct
sockaddr_in,并且在最后转换。同时,注意 sin_family 和 struct sockaddr 中的
sa_family 一致并能够设置为 "AF_INET"。最后,sin_port和 sin_addr
必须是网络字节顺序 (Network Byte Order)!
htons()--"Host to Network Short"
  htonl()--"Host to Network Long"
  ntohs()--"Network to Host Short"
  ntohl()--"Network to Host Long"
为什么在数据结构 struct sockaddr_in 中, sin_addr 和 sin_port
需要转换为网络字节顺序,而sin_family 需不需要呢? 答案是: sin_addr 和
sin_port 分别封装在包的 IP 和 UDP 层。因此,它们必须要
是网络字节顺序。但是 sin_family 域只是被内核 (kernel) 使用来决定在数
据结构中包含什么类型的地址,所以它必须是本机字节顺序。同时, sin_family
没有发送到网络上,它们可以是本机字节顺序。

IP 地址和如何处理它们
现在我们很幸运,因为我们有很多的函数来方便地操作 IP 地址。没有
必要用手工计算它们,也没有必要用"<<"操作来储存成长整字型。
首先,假设你已经有了一个sockaddr_in结构体ina,你有一个IP地
址"132.241.5.10"要储存在其中,你就要用到函数inet_addr(),将IP地址从
点数格式转换成无符号长整型。使用方法如下:
ina.sin_addr.s_addr = inet_addr("132.241.5.10");
注意,inet_addr()返回的地址已经是网络字节格式,所以你无需再调用
函数htonl()。
我们现在发现上面的代码片断不是十分完整的,因为它没有错误检查。
显而易见,当inet_addr()发生错误时返回-1。记住这些二进制数字?(无符
号数)-1仅仅和IP地址255.255.255.255相符合!这可是广播地址!大错特
错!记住要先进行错误检查。
好了,现在你可以将IP地址转换成长整型了。有没有其相反的方法呢?
它可以将一个in_addr结构体输出成点数格式?这样的话,你就要用到函数
inet_ntoa()("ntoa"的含义是"network to ascii"),就像这样:
printf("%s",inet_ntoa(ina.sin_addr));
它将输出IP地址。需要注意的是inet_ntoa()将结构体in-addr作为一
个参数,不是长整形。同样需要注意的是它返回的是一个指向一个字符的
指针。它是一个由inet_ntoa()控制的静态的固定的指针,所以每次调用
inet_ntoa(),它就将覆盖上次调用时所得的IP地址。

微软的面试题

第一组
  1.烧一根不均匀的绳,从头烧到尾总共需要1个小时。现在有若干条材质相同的绳子,问如何用烧绳的方法来计时一个小时十五分钟呢?
  2.你有一桶果冻,其中有黄色、绿色、红色三种,闭上眼睛抓取同种颜色的两个。抓取多少个就可以确定你肯定有两个同一颜色的果冻?
  3.如果你有无穷多的水,一个3公升的提捅,一个5公升的提捅,两只提捅形状上下都不均匀,问你如何才能准确称出4公升的水?
  4.一个岔路口分别通向诚实国和说谎国。来了两个人,已知一个是诚实国的,另一个是说谎国的。诚实国永远说实话,说谎国永远说谎话。现在你要去说谎国,但不知道应该走哪条路,需要问这两个人。请问应该怎么问?
  5.12个球一个天平,现知道只有一个和其它的重量不同,问怎样称才能用三次就找到那个球。13个呢?(注意此题并未说明那个球的重量是轻是重,所以需要仔细考虑)
  6.在9个点上画10条直线,要求每条直线上至少有三个点?
  7.在一天的24小时之中,时钟的时针、分针和秒针完全重合在一起的时候有几次?都分别是什么时间?你怎样算出来的?
  8.怎么样种植4棵树木,使其中任意两棵树的距离相等?
  第二组
  1.为什么下水道的盖子是圆的?
  2.中国有多少辆汽车?
  3.将汽车钥匙插入车门,向哪个方向旋转就可以打开车锁?
  4.如果你要去掉中国的34个省(含自治区、直辖市和港澳特区及台湾省)中的任何一个,你会去掉哪一个,为什么?
  5.多少个加油站才能满足中国的所有汽车?
  6.想象你站在镜子前,请问,为什么镜子中的影象可以颠倒左右,却不能颠倒上下?
  7.为什么在任何旅馆里,你打开热水,热水都会瞬间倾泻而出?
  8.你怎样将Excel的用法解释给你的奶奶听?
  9.你怎样重新改进和设计一个ATM银行自动取款机?
  10.如果你不得不重新学习一种新的计算机语言,你打算怎样着手来开始?
  11.如果你的生涯规划中打算在5年内受到奖励,那获取该项奖励的动机是什么?观众是谁?
  12.如果微软告诉你,我们打算投资五百万美元来启动你的投资计划,你将开始什么样商业计划?为什么?
  13.如果你能够将全世界的电脑厂商集合在一个办公室里,然后告诉他们将被强迫做一件事,那件事将是什么? 

第三组
  1.你让工人为你工作7天,回报是一根金条,这个金条平分成相连的7段,你必须在每天结束的时候给他们一段金条。如果只允许你两次把金条弄断,你如何给你的工人付费?
  2.有一辆火车以每小时15公里的速度离开北京直奔广州,同时另一辆火车每小时20公里的速度从广州开往北京。如果有一只鸟,以30公里每小时的速度和两辆火车同时启动,从北京出发,碰到另一辆车后就向相反的方向返回去飞,就这样依次在两辆火车之间来回地飞,直到两辆火车相遇。请问,这只鸟共飞行了多长的距离?
  3.你有四个装药丸的罐子,每个药丸都有一定的重量,被污染的药丸是没被污染的药丸的重量+1。只称量一次,如何判断哪个罐子的药被污染了?
  4.门外三个开关分别对应室内三盏灯,线路良好,在门外控制开关时候不能看到室内灯的情况,现在只允许进门一次,确定开关和灯的对应关系?
  5.人民币为什么只有1、2、5、10的面值?
  6.你有两个罐子以及50个红色弹球和50个蓝色弹球,随机选出一个罐子,
随机选出一个弹球放入罐子,怎么给出红色弹球最大的选中机会?在你的计划里,得到红球的几率是多少?
  7.给你两颗6面色子,可以在它们各个面上刻上0-9任意一个数字,要求能够用它们拼出任意一年中的日期数值
  第四组
  第一题 .
五个海盗抢到了100颗宝石,每一颗都一样大小和价值连城。他们决定这么分:
  抽签决定自己的号码(1、2、3、4、5)
  首先,由1号提出分配方案,然后大家表决,当且仅当超过半数的人同意时,按照他的方案
  进行分配,否则将被扔进大海喂鲨鱼
  如果1号死后,再由2号提出分配方案,然后剩下的4人进行表决,当且仅当超过半数的人同
  意时,按照他的方案进行分配,否则将被扔入大海喂鲨鱼
  依此类推
  条件:每个海盗都是很聪明的人,都能很理智地做出判断,从而做出选择。
  问题:第一个海盗提出怎样的分配方案才能使自己的收益最大化?
  第二题 . 一道关于飞机加油的问题,已知:
  每个飞机只有一个油箱,
  飞机之间可以相互加油(注意是相互,没有加油机)
  一箱油可供一架飞机绕地球飞半圈,
  问题:
  为使至少一架飞机绕地球一圈回到起飞时的飞机场,至少需要出动几架飞机?(所有飞机从同一机场起飞,而且必须安全返回机场,不允许中途降落,中间没有飞机场)第三题.
汽车加油问题
  一辆载油500升的汽车从A开往1000公里外的B,已知汽车每公里耗油量为1升,A处有无穷多的油,其他任何地点都没有油,但该车可以在任何地点存放油以备中转,问从A到B最少需要多少油
  第四题. 掷杯问题
  一种杯子,若在第N层被摔破,则在任何比N高的楼层均会破,若在第M层不破,则在任何比M低的楼层均会破,给你两个这样的杯子,让你在100层高的楼层中测试,要求用最少的测试次数找出恰巧会使杯子破碎的楼层。
  第五题. 推理游戏
  教授选出两个从2到9的数,把它们的和告诉学生甲,把它们的积告诉学生乙,让他们轮流猜这两个数
  甲说:"我猜不出"
  乙说:"我猜不出"
  甲说:"我猜到了"
  乙说:"我也猜到了"
  问这两个数是多少
  第六题. 病狗问题
  一个住宅区内有100户人家,每户人家养一条狗,每天傍晚大家都在同一个地方遛狗。已知这些狗中有一部分病狗,由于某种原因,狗的主人无法判断自己的狗是否是病狗,却能够分辨其他的狗是否有病,现在,上级传来通知,要求住户处决这些病狗,并且不允许指认他人的狗是病狗(就是只能判断自己的),过了7天之后,所有的病狗都被处决了,问,一共有几只病狗?为什么?
  第七题.
U2合唱团在17分钟内得赶到演唱会场,途中必需跨过一座桥,四个人从桥的同一端出发,你得帮助他们到达另一端,天色很暗,而他们只有一只手电筒。一次同时最多可以有两人一起过桥,而过桥的时候必须持有手电筒,所以就得有人把手电筒带来带去,来回桥两端。手电筒是不能用丢的方式来传递的。四个人的步行速度各不同,若两人同行则以较慢者的速度为准。BONO需花1分钟过桥,EDGE需花2分钟过桥,ADAM需花5分钟过桥,LARRY需花10分钟过桥,他们要如何在17分钟内过桥呢?
  第八题.
监狱里有100个房间,每个房间内有一囚犯。一天,监狱长说,你们狱房外有一电灯,你们在放风时可以控制这个电灯(熄或亮)。每天只能有一个人出来放风,并且防风是随机的。如果在有限时间内,你们中的某人能对我说:"我敢保证,现在每个人都已经至少放过一次风了。"我就放了你们!问囚犯们要采取什么策略才能被监狱长放掉?如果采用了这种策略,大致多久他们可以被释放?

第五组
  1.某手机厂家由于设计失误,有可能造成电池寿命比原来设计的寿命短一半(不是冲放电时间),解决方案就是免费更换电池或给50元购买该厂家新手机的折换券。请给所有已购买的用户写信告诉解决方案。
  2.一高层领导在参观某博物馆时,向博物馆馆员小王要了一块明代的城砖作为纪念,按国家规定,任何人不得将博物馆收藏品变为私有。博物馆馆长需要如何写信给这位领导,将城砖取回。
  3.营业员小姐由于工作失误,将2万元的笔记本电脑以1.2万元错卖给李先生,王小姐的经理怎么写信给李先生试图将钱要回来?
  4.给你一款新研制的手机,如果你是测试组的组长,你会如何测试?
  5.如何为函数int atoi(const char * pstr)编写测试向量?
  第六组
  1.链表和数组的区别在哪里?
  2.编写实现链表排序的一种算法。说明为什么你会选择用这样的方法?
  3.编写实现数组排序的一种算法。说明为什么你会选择用这样的方法?
  4.请编写能直接实现char * strcpy(char * pstrDest,const char *
pstrSource)函数功能的代码。
  5.编写反转字符串的程序,要求优化速度、优化空间。
  6.在链表里如何发现循环链接?
  7.给出洗牌的一个算法,并将洗好的牌存储在一个整形数组里。
  8.写一个函数,检查字符是否是整数,如果是,返回其整数值。(或者:怎样只用4行代码
  9.给出一个函数来输出一个字符串的所有排列。
  10.请编写实现void * malloc(int)内存分配函数功能一样的代码。
  11.给出一个函数来复制两个字符串A和B。字符串A的后几个字节和字符串B的前几个字节重叠。
  12.怎样编写一个程序,把一个有序整数数组放到二叉树中?
  13.怎样从顶部开始逐层打印二叉树结点数据?请编程。
  14.怎样把一个链表掉个顺序(也就是反序,注意链表的边界条件并考虑空链表)?
--
  15.请编写能直接实现int atoi(const char * pstr)函数功能的代码
答案:
第一组题答案:
  1)三根绳,第一根点燃两端,第二根点燃一端,第三根不点
  第一根绳烧完(30分钟)后,点燃第二根绳的另一端,第二根绳烧完(45分钟)后,点燃第三根绳子两端,第三根绳烧完(1小时15分)后,计时完成
  2)根据抽屉原理,4个
  3)3升装满;3升-〉5升(全注入);3升装满;3升-〉5升(剩1升);5升倒掉;3升-〉5升(注入1升);3升装满;3升-〉5升;完成(另:可用回溯法编程求解)
  4)问其中一人:另外一个人会说哪一条路是通往诚实国的?回答者所指的那条路必然是通往说谎国的。
  5)12个球:
  第一次:4,4 如果平了:
  那么剩下的球中取3放左边,取3个好球放右边,称:
  如果左边重,那么取两个球称一下,哪个重哪个是次品,平的话第三个重,是次品,轻的话同理
  如果平了,那么剩下一个次品,还可根据需要称出次品比正品轻或者重
  如果不平:
  那么不妨设左边重右边轻,为了便于说明,将左边4颗称为重球,右边4颗称为轻球,剩下4颗称为好球
  取重球2颗,轻球2颗放在左侧,右侧放3颗好球和一颗轻球
  如果左边重
  称那两颗重球,重的一个次品,平的话右边轻球次品
  如果右边重
  称左边两颗轻球,轻的一个次品
  如果平
  称剩下两颗重球,重的一个次品,平的话剩下那颗轻球次品
  13个球:
  第一次:4,4,如果平了
  剩5颗球用上面的方法仍旧能找出次品,只是不能知道次品是重是轻
  如果不平,同上 
6)
  o o o
  o o o
  o o o
  7)
  23次,因为分针要转24圈,时针才能转1圈,而分针和时针重合两次之间的间隔显然>
1小时,它们有23次重合机会,每次重合中秒针有一次重合机会,所以是23次
  重合时间可以对照手表求出,也可列方程求出
  8)
  在地球表面种树,做一个地球内接的正四面体,内接点即为所求
  第二组 无标准答案
  第三组
  1.
分成1,2,4三段,第一天给1,第二天给2取回1,第3天给1,第4天给4取回1、2,第5天给1,第6天给2取回1,第七天给1
  2. 求出火车相遇时间,鸟速乘以时间就是鸟飞行的距离
  3.
四个罐子中分别取1,2,3,4颗药丸,称出比正常重多少,即可判断出那个罐子的药被污染
  4.
三个开关分别:关,开,开10分钟,然后进屋,暗且凉的为开关1控制的灯,亮的为开关2控制的灯,暗且热的为开关3控制的灯
  5. 因为可以用1,2,5,10组合成任何需要的货币值,日常习惯为10进制
  6. 题意不理解...*_*
  7. 012345 0126(9)78
  第四组 都是很难的题目
  第一题:97 0 1 2 0 或者 97 0 1 0 2 (提示:可用逆推法求出)
  第二题:3架飞机5架次,飞法:
  ABC
3架同时起飞,1/8处,C给AB加满油,C返航,1/4处,B给A加满油,B返航,A到达1/2处,C从机场往另一方向起飞,3/4处,C同已经空油箱的A平分剩余油量,同时B从机场起飞,AC到7/8处同B平分剩余油量,刚好3架飞机同时返航。所以是3架飞机5架次。第三题:需要建立数学模型
  (提示,严格证明该模型最优比较麻烦,但确实可证,大胆猜想是解题关键)
  题目可归结为求数列 an=500/(2n+1)
n=0,1,2,3......的和Sn什么时候大于等于1000,解得n> 6
  当n=6时,S6=977.57
  所以第一个中转点离起始位置距离为1000-977.57=22.43公里
  所以第一次中转之前共耗油 22.43*(2*7+1)=336.50升
  此后每次中转耗油500升
  所以总耗油量为7*500+336.50=3836.50升
  第四题:需要建立数学模型
  题目可归结为求自然数列的和S什么时候大于等于100,解得n> 13
  第一个杯子可能的投掷楼层分别为:14,27,39,50,60,69,77,84,90,95,99,100
  第五题:3和4(可严格证明)
  设两个数为n1,n2,n1> =n2,甲听到的数为n=n1+n2,乙听到的数为m=n1*n2
  证明n1=3,n2=4是唯一解
  证明:要证以上命题为真,不妨先证n=7
  1)必要性:
  i) n> 5 是显然的,因为n <4不可能,n=4或者n=5甲都不可能回答不知道
  ii) n> 6
因为如果n=6的话,那么甲虽然不知道(不确定2+4还是3+3)但是无论是2,4还是3,3乙都不可能说不知道(m=8或者m=9的话乙说不知道是没有道理的)
  iii) n <8 因为如果n> =8的话,就可以将n分解成 n=4+x 和
n=6+(x-2),那么m可以是4x也可以是6(x-2)而4x=6(x-2)的必要条件是x=6即n=10,那样n又可以分解成8+2,所以总之当n>
=8时,n至少可以分解成两种不同的合数之和,这样乙说不知道的时候,甲就没有理由马上说知道。
  以上证明了必要性
  2)充分性
  当n=7时,n可以分解成2+5或3+4
  显然2+5不符合题意,舍去,容易判断出3+4符合题意,m=12,证毕
  于是得到n=7 m=12 n1=3 n2=4是唯一解。第六题:7只(数学归纳法证明)
  1)若只有1只病狗,因为病狗主人看不到有其他病狗,必然会知道自己的狗是病狗(前提是一定存在病狗),所以他会在第一天把病狗处决。
  2)设有k只病狗的话,会在第k天被处决,那么,如果有k+1只,病狗的主人只会看到k只病狗,而第k天没有人处决病狗,病狗主人就会在第k+1天知道自己的狗是病狗,于是病狗在第k+1天被处决
  3)由1)2)得,若有n只病狗,必然在第n天被处决
  第七题:(提示:可用图论方法解决)
  BONO&EDGE过(2分),BONO将手电带回(1分),ADAM&LARRY过(10分),EDGE将手电带回(2分),BONO&EDGE过(2分)
2+1+10+2+2=17分钟
  第八题:
  约定好一个人作为报告人(可以是第一个放风的人)
  规则如下:
  1、报告人放风的时候开灯并数开灯次数
  2、其他人第一次遇到开着灯放风时,将灯关闭
  3、当报告人第100次开灯的时候,去向监狱长报告,要求监狱长放人......
  按照概率大约30年后(10000天)他们可以被释放
  第五组无标准答案
  第六组部分题参考答案:
  4.
char * strcpy(char * pstrDest,const char * pstrSource)
{
assert((pstrDest!=NULL)&&(pstrSource!=NULL));
char * pstr=pstrDest;
while((*(pstrDest++)=*(pstrSource++))!= '\0 ');
return pstr;
}

  5.
char * strrev(char * pstr)
{
assert(pstr!=NULL);

char * p=pstr;
char * pret=pstr;
while(*(p++)!= '\0 ');
p--;
char tmp;
while(p> pstr)
{
tmp=*p;
*(p--)=*(pstr);
*(pstr++)=tmp;
}
return pret;