Posted by songfei on 2011/09/14
原来 我写了一篇 宏做函数 多行的处理方法,是使用 do … while(0) 的一个小技巧。
今天有听到了另一个 do … while(0)的用处。
在写程序时,检测到某种错误后,通常会终止下面的执行流程,可是如果简单的 return 就不会释放前面用到的内存, 所有很多人会写 goto去释放前面的资源。
比如:
… 一些语句 …
出错啦
goto Release;
… 一些语句…
:Release
…这里释放…
其实可以直接用
do {
… 某些语句 …
这里出错啦
break;
}while(0)
… 这里释放 …
相当于是一个goto。
Posted by songfei on 2011/09/14
手机上的网络应用,有的时候需要在手机上面抓取数据包进行分析。
简单研究了一下,总结2中方式,原理不同。
第一种是使用PC做代理
在PC上(以Windows为例,Mac也行)安装一个NAT的网络代理软件,我这里使用了 CCProxy。安装后运行,相当于iphone上所有的网络数据都会从PC走,然后用PC上的抓包工具(我用的WireShark)就可以抓包了。
使用PC共享无线,或者iphone和PC在一个网段内。
在iphone上的设置,点击 设置 –> wi-fi –> 点击对应连接右边的小箭头, HTTP代理选择 手动,然后输入PC的IP地址和端口号。
启动 WireShark , 过滤器设置为 host [iphone的IP地址],开始抓包就好了。
这样有一个问题,就是在测试网络速度等问题的时候,会变得不准确,因为连接代理服务要消耗时间。
第二种方法是直接在iphone上面抓包。
iphone既然是运行的类Unix,就可以直接使用Unix下的抓包工具。首先保证手机为越狱的。
首先要通过SSH的方式连接到iphoen上面去,用Cydia安装 OpenSSH。
在PC上使用 Putty(Windows)或者ssh(Linux)等工具连接到iphone。
用户名 root,密码 alpine。
然后可以使用 apt-get install 或者 aptitude 安装一些工具。 我使用了 tcpdump。
安装方法是:aptitude install tcpdump ,当然也可以选择其他的工具。
不过我在使用 aptitude的时候,发现这个也没有安装,找了好久,最后在试Cydia里面安装了 Aptbackup 这个软件,他的一些依赖安装了 apt-get ,然后用 apt-get 安装了 aptitude, 命令式 apt-get install aptitude 。
我还安装了一些其他的工具,比如 vim, adv-cmds , basic-cmds ,bootstrap-cmds ,coreutils ,developer-cmds ,file-cmds ,network-cmds ,shell-cmds ,system-cmds ,inetutils 为了以后方便使用。
安装完成以后,就可以直接使用 tcpdump来抓包了。
最简单的:tcpdump
可以带的参数有 -w 输出的文件
还可以带一些规则,最简单的 :
host [IP地址] 只保留特定源地址或者目的地址的包
port [端口号] 只保留 特定源端口号或者目的端口号的包
比如: tcpdump -w test.pcap port 80 ,这个就是抓取HTTP协议的包,保存在 test.pcap文件中,
可以用 ifun box 或者 scp这样的工具把文件拷出来,用 WireShark打开。
在查看包的时候,出现了 一个包长度错误的提示, 找到了解决方法 加参数 -s0 表示不限制包长度 就好了。
两中方法,完成了抓包,第一种操作方便,在分析包的内容上面很好,第二种稍稍麻烦了一点,不过能反映手机上真实的数据包情况,祝大家iphone开发好心情哦。
Posted by songfei on 2011/09/13
悲剧,悲剧,程序被apple据了,原因使用私有API,总结了一些关于私有API的东西。
https://github.com/kennytm/iphone-private-frameworks
这里有个非官方的私有API列表,可以在这里找到私有API。
不过呢,要提交AppStone是绝对不能有私有API的,所以在提交前可以使用一个工具来检测下。
http://www.chimpstudios.com/AppScanner/
叫 appScanner。
Posted by songfei on 2011/07/12
Posted by songfei on 2011/05/14
优秀的计算机爱好者具有一种无价的技能。可作为一名程序员会跟计算机爱好者一样吗?难道程序员跟那些不知道如何编码的计算机爱好者们相比,会在创造性上处于劣势吗?
下面的这个故事让我看清了他们之间的不同。
我最近被邀请在一个周末创业活动中做指导。周五晚上,我们召集到一起吃匹萨,定创意,建团队以及讨论启动计划。临近结束时,每个人都对这个周末将要做的事情感到非常的满意。
周末早晨我来到现场发现人们都在努力的工作。有些人通宵未回在这赶进度实现他们的想法。这就是创业精神!
但我吃惊的发现如此多的团队都已经开始编码了!感觉是他们急着让东西能在周日晚上之前开发出来,跑起来,这使大多数的团队一心想着实现他们最初的创意想法,而不再去探索不同的创意、选择一个更好的来实现。
听起来没什么不同吗?
有一个团队脱颖而出,因为这个团队中没有会编程的。所以他们把时间都花在用PowerPoint制作原型,走访各个房间跟其他团结交流他们的想法,获得反馈,然后回到他们的桌子边讨论、改进提炼他们的想法。他们是最喧闹的,最有生气的,最热情好善的一组,他们看起来从活动中得到了不少乐趣。最重要的是,他们向前推进的速度比其他组快很多,因为他们没有迷失在要能清楚如何使用Rails或PHP让什么东西跑起来的细节里。
周日早上,他们灵光一闪,抛弃了以前所有的原型,重新回到绘图板前工作。我看到他们在数小时里做出来一个新原型。因为没有写代码,他们并不担心抛弃昨天的作品(毕竟,原型就是用来干这个的)。因为他们使用PowerPoint来模型化他们的想法,他们可以快速的让想法具体化。
在周日晚上,他们并没有交出一个可以运行的应用程序,但他们使用依据他们最终创意制作出来的、具有点击效果的原型吸引力所有的观众。他们不仅呈现了最终创意,他们还带着观众遍历了整个创意的变更迭代过程。
结果呢?他们夺得头筹!
他们并不是赢在创意有多么的好或比其他组包含更多的功能。这个周末产生了很多的创意。但当其他组把有限的时间花在实现细节上时,这个组一直专注于他们的想法的高层面的问题,把更多的时间花在改进它而不是编码上。
他们不是程序员,但他们是计算机爱好者。这个身份最终让他们受益匪浅!
很多创业者认为自己跟那些会编码的人比起来处于一种劣势。他们认为自己不是计算机爱好者,因为不会编程。而事实却是,他们具有一种创造力上的优势,因为他们不会急着一头扎进编码工作里。相反,他们会被迫去“修剪”他们的想法,用上层的工具和平台测试它们,会被限制不去关心细节。这将迫使他们关注于解决用户问题,而不是解决实现问题。
做软件不只是编码的技术。它是一种在事情不同的阶段关注每阶段最重要的事情、而不是过早的陷入细节的思维习惯。
Posted by songfei on 2011/05/12
遇到程序运行后不退出 ,阻塞在最后的情况,检查了好久,找到了问题,不过还是不知道为什么,先记录下来吧。
程序是这样的:
1 #include
2 #include
3
4 int main()
5 {
6 FILE* fp1;
7 FILE* fp2;
8
9 fp1 = fopen(“a”,”wb”);
10
11 if(fp1 == NULL)
12 {
13 printf(“error”);
14 exit(0);
15 }
16
17 free(fp1);
18
19 fp2=fopen(“b”,”wb”);
20 if(fp2 == NULL)
21 {
22 printf(“error”);
23 exit(0);
24 }
25 fclose(fp2);
26
27 printf(“main function over\n”);
28 return 0;
29 }
不小心将FILE* 指针给free了,然后就出现了这个怪异的问题。
程序会输出到 main function over ,然后就阻塞了。
谁来解答一下这个是为什么呢?
Posted by songfei on 2011/04/27
今天偶尔研究了一下,这种类似百度文库的网站,是将文档转换成为swf文件来保存和显示的,那也可以把他下载回来。
研究了一下,它会下载一个 累死:http://ai.wenku.baidu.com/play/d585f01fb7360b4c2e3f6475?pn=1&rn=5 这样的 flash文件,pn和rn参数是表示从第几页开始,加载几页文章。
保存的这个文件是swf格式的,但是用flash播放器打开并不能播放,用UE看了下这个文件的内容。

最前面是一段文本,难怪播放不了呢。 不过在后面看到了熟悉的 CWS 和 0×09 ,这可是swf文件的开始标志啊,09标识是 Flash 9.0格式的。把前面的文本删掉,OK ,可以显示出文章了,不过只有第一页。
再往后看发现,其实这个文件是多个swf文件拼接起来的,因为有多个CWS。 这个也好办,把它分开就好了。
写了个简单的程序,把一个文件分成多个swf。
int main()
{
FILE *fp;
FILE *out;
int i=0;
char temp[30];
fp=fopen("r:\\a.swf","rb");
if(fp==NULL) exit(0);
sprintf(temp,"r:\\%d.swf",i);
out=fopen(temp,"w");
int data=0;
int stat=0;
while(!feof(fp))
{
data = fgetc(fp) ;
switch(stat)
{
case 0:
if(data == 'C') stat =1;
break;
case 1:
if(data == 'W') stat =2;
else stat =0;
break;
case 2:
if(data == 'S') stat =3;
else stat =0;
break;
case 3:
if(data ==9)
{
fclose(out);
i++;
sprintf(temp,"r:\\%d.swf",i);
out=fopen(temp,"wb");
fputc('C',out);
fputc('W',out);
fputc('S',out);
}
else stat =0;
}
fputc(data,out);
}
}
好啦,到此为止,已经可以把下载回来的这个文件,分成了多个可以播放的swf文件,每个文件是一页。
这时候可以用工具把他合在一起转成其他格式了。
Posted by songfei on 2011/04/11
人的思想是在长期的生活实践过程中积累起来的,对是非的判断也是,甚至是潜意识里的。今天也很是神奇,在解决一个编程小问题的时候,让我意识到了这一点。
很简单的一个程序,在C++中使用静态变量(类变量)的初始化问题,代码如下:
#include
useing namespace std;
class A
{
public:
static int a;
};
int A::a = 10;
int main(void)
{
cout<
return 0;
}
在写这段代码的时候,我并不是这么写的,我想使用对象的成员,而不是类的成员,我是一个Java程序员,对C++不是很熟悉,我觉得这是一件天经地义的事情,所以我写出了下面的代码。
int main(void)
{
A *t = new A();
cout << t.a << endl;
return 0;
}
得到的竟然是编译错误,竟然! 我非常惊讶,这为什么会错呢!!!
我是使用Java的观点去思考,就像这样:
public class A {
public static int a=10;
public static void main(String[] argv)
{
A t=new A();
System.out.println(t.a);
}
}
上面这个代码是正确的,这也就是我既有的观念,根深蒂固在我的思想里的观念,这时我去请教了一位资深的C++程序员,得到的回答和我当时的情形一样,他也很惊讶,他惊讶我为什么会有这种想法,他觉得不可思议,觉得那理所应当是不可以的。
这种反映让我陷入了思考,也看过一些文章,有些时候是需要打破思维的定势,打破根深蒂固的想法,会有新的收获。
Posted by songfei on 2011/01/25
如果用宏做函数, 如果宏有好多句话,可以用旁门左道来搞定。
#define foo(args) \
do {
代码段;
}while(0)
Posted by songfei on 2011/01/24