Archive for » November, 2006 «

《神探狄人杰》其实一点都不神

  最近很多人都在看CCTV8的神探狄人杰,很多人都被狄人杰神乎其神的断案忽悠的不行!其实我感觉这个片子中的狄人杰一点都不神,很多很多地方都经不住推敲,仔细思考,发现狄人杰若干次发现断案线索都是那么巧合和那么有运气,若干次对手都可以随手把狄人杰杀了,不过如果那样也就没有戏演了,所以这些安排貌似神奇,其实很低级。

  相反的,我感觉片子中狄人杰的那些对手都非常神,尤其蛇灵,计策长达十几年,而且不管从大面上还是细节处,都神乎其神,但是片子肯定要宣扬邪不压正的正面思想,所以不管他们多么神机妙算,最后总会因为运气或者某一点点的失误而全盘皆输,每次这个时候狄人杰就会来一个大总结,要么是“我终于明白了。。。”,要么是“事情原来是这样的,听我慢慢道来!。。。”,总结完后,对手往往不作任何抵抗就结束了战斗,哈哈,这是真的太神了,没有他的大总结,观众的思路是不会跟着导演走的,因为看电视的大部分人都是思想懒惰的。

  仔细一想,发现这样的片子跟我们看过的若干个国产战争片、警匪片都一样,只是这次道具安排上换成了古装,实在没劲,已经决定不在看下去了!最近准备搞一套《越狱》来看看,这才是真的好片子!

Category: 西拉东扯  2 Comments

突闻谢文离职(被解职?),Yahoo中国被马云折腾得可以

  下午在msn上跟谭晓生推荐一个应届毕业生到yahoo面试的时候,还没有听说,晚饭刚过就从他那里得知了这样的消息,donews上一看果然消息也够快!这突如其来的消息,着实让我吃惊不小,马云够能折腾,谢文估计是yahoo历史上最短的总经理了。

  想当初10月17日,国内各媒体头版竞相报道谢文高调出任yahoo中国总经理的消息,当时这的确给中国IT圈带来不小的触动,yahoo中国这两年已经够动荡的,一波三折,今天的这个变化更是有点一波未平一波又起的味道,说实话,真不得不佩服马云折腾的能力,从无聊收购合并开始,yahoo中国一直都处在风波之中,一直对这个类似暴发户自以为是的家伙就没有怎么看好过。
more »

用apache的动态so模式编写和编译php扩展

看过我另外一篇关于用c语言编写php扩展so模块的朋友,应该已经了解大致的php模块编写过程,(原文:http://www.toplee.com/blog/56.html) 不过该文中没有专门针对已经安装好的系统进行说明,如何在现有apache、php运行环境下添加一个动态的so扩展,下面简单的整理一下。
more »

Category: PHP / Zend  Tags: , , ,  2 Comments

用C语言操作MySQL数据库,进行连接、插入、修改、删除等操作

  很多人用到MySQL来开发一些项目,有时为了性能,我们会直接用C语言来开发相关的模块,尤其在我们的web应用中,虽然PHP、JSP等脚本均提供了MySQL的接口,但是显然直接使用C语言具有更好的安全性和性能,Michael以前用PHP开发的多个项目中就使用了C语言编写的这类接口,然后再编译到php里面,供php脚本直接使用,这方面的话题就不多说了,下面主要说一下在Linux下如何用C语言连接MySQL数据库,并且读取里面的数据返回,同时如何进行编译。

  这里的大部分代码参考了MySQL发行包里面的.c源文件,大家也可以去里面找找相关的代码,下面这段代码实现了连接到本地MySQL服务器上9tmd_bbs_utf8数据库,从数据表tbb_user中根据输入的userid取得该用户的用户名并打印输出到终端。

#if defined(_WIN32) || defined(_WIN64)  //为了支持windows平台上的编译
#include <windows.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include "mysql.h"  //我的机器上该文件在/usr/local/include/mysql下
 
//定义数据库操作的宏,也可以不定义留着后面直接写进代码
#define SELECT_QUERY "select username from tbb_user where userid = %d"
 
int main(int argc, char **argv) //char **argv 相当于 char *argv[]
{
    
MYSQL mysql,*sock;    //定义数据库连接的句柄,它被用于几乎所有的MySQL函数
    
MYSQL_RES *res;       //查询结果集,结构类型
    
MYSQL_FIELD *fd ;     //包含字段信息的结构
    
MYSQL_ROW row ;       //存放一行查询结果的字符串数组
    
char  qbuf[160];      //存放查询sql语句字符串
    
    
if (argc != 2) {  //检查输入参数
        
fprintf(stderr,"usage : mysql_select <userid>\n\n");
        
exit(1);
    
}
    
    
mysql_init(&mysql);
    
if (!(sock = mysql_real_connect(&mysql,"localhost","dbuser","dbpwd","9tmd_bbs_utf8",0,NULL,0))) {
        
fprintf(stderr,"Couldn't connect to engine!\n%s\n\n",mysql_error(&mysql));
        
perror("");
        
exit(1);
    
}
    
    
sprintf(qbuf,SELECT_QUERY,atoi(argv[1]));
    
if(mysql_query(sock,qbuf)) {
        
fprintf(stderr,"Query failed (%s)\n",mysql_error(sock));
        
exit(1);
    
}
    
    
if (!(res=mysql_store_result(sock))) {
        
fprintf(stderr,"Couldn't get result from %s\n", mysql_error(sock));
        
exit(1);
    
}
    
    
printf("number of fields returned: %d\n",mysql_num_fields(res));
        
    
while (row = mysql_fetch_row(res)) {
        
printf("Ther userid #%d 's username is: %s\n", atoi(argv[1]),(((row[0]==NULL)&&(!strlen(row[0]))) ? "NULL" : row[0])) ;
        
puts( "query ok !\n" ) ;
    
}
    
    
mysql_free_result(res);
    
mysql_close(sock);
    
exit(0);
    
return 0;   //. 为了兼容大部分的编译器加入此行
}

编译的时候,使用下面的命令

gcc -o mysql_select ./mysql_select.c -I/usr/local/include/mysql -L/usr/local/lib/mysql -lmysqlclient (-lz) (-lm) 后面两个选项可选,根据您的环境情况

运行的时候,执行下面的命令

./mysql_select 1

将返回如下结果:

number of fields returned: 1
Ther userid #1 's username is: Michael
query ok !

上面的代码我想大部分都能看明白,不明白的可以参考一下MySQL提供的有关C语言API部分文档,各个函数都有详细说明,有时间我整理一份常用的API说明出来。

C/C++中内存管理参考

Show All   1 2 3

  程序员们经常编写内存管理程序,往往提心吊胆。如果不想触雷,唯一的解决办法就是发现所有潜伏的地雷并且排除它们,躲是躲不了的。本文的内容比一般教科书的要深入得多,读者需细心阅读,做到真正地通晓内存管理。

1、内存分配方式

内存分配方式有三种:

(1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。

(2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

(3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。

2、常见的内存错误及其对策

  发生内存错误是件非常麻烦的事情。编译器不能自动发现这些错误,通常是在程序运行时才能捕捉到。而这些错误大多没有明显的症状,时隐时现,增加了改错的难度。有时用户怒气冲冲地把你找来,程序却没有发生任何问题,你一走,错误又发作了。 常见的内存错误及其对策如下:

* 内存分配未成功,却使用了它。

  编程新手常犯这种错误,因为他们没有意识到内存分配会不成功。常用解决办法是,在使用内存之前检查指针是否为NULL。如果指针p是函数的参数,那么在函数的入口处用assert(p!=NULL)进行检查。如果是用malloc或new来申请内存,应该用if(p==NULL) 或if(p!=NULL)进行防错处理。

* 内存分配虽然成功,但是尚未初始化就引用它。

  犯这种错误主要有两个起因:一是没有初始化的观念;二是误以为内存的缺省初值全为零,导致引用初值错误(例如数组)。内存的缺省初值究竟是什么并没有统一的标准,尽管有些时候为零值,我们宁可信其无不可信其有。所以无论用何种方式创建数组,都别忘了赋初值,即便是赋零值也不可省略,不要嫌麻烦。

* 内存分配成功并且已经初始化,但操作越过了内存的边界。

例如在使用数组时经常发生下标“多1”或者“少1”的操作。特别是在for循环语句中,循环次数很容易搞错,导致数组操作越界。

* 忘记了释放内存,造成内存泄露。

  含有这种错误的函数每被调用一次就丢失一块内存。刚开始时系统的内存充足,你看不到错误。终有一次程序突然死掉,系统出现提示:内存耗尽。

  动态内存的申请与释放必须配对,程序中malloc与free的使用次数一定要相同,否则肯定有错误(new/delete同理)。

* 释放了内存却继续使用它。

有三种情况:

(1)程序中的对象调用关系过于复杂,实在难以搞清楚某个对象究竟是否已经释放了内存,此时应该重新设计数据结构,从根本上解决对象管理的混乱局面。

(2)函数的return语句写错了,注意不要返回指向“栈内存”的“指针”或者“引用”,因为该内存在函数体结束时被自动销毁。

(3)使用free或delete释放了内存后,没有将指针设置为NULL。导致产生“野指针”。

【规则1】用malloc或new申请内存之后,应该立即检查指针值是否为NULL。防止使用指针值为NULL的内存。

【规则2】不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。

【规则3】避免数组或指针的下标越界,特别要当心发生“多1”或者“少1”操作。

【规则4】动态内存的申请与释放必须配对,防止内存泄漏。

【规则5】用free或delete释放了内存之后,立即将指针设置为NULL,防止产生“野指针”。

3、指针与数组的对比

  C++/C程序中,指针和数组在不少地方可以相互替换着用,让人产生一种错觉,以为两者是等价的。

  数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。数组名对应着(而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变。

  指针可以随时指向任意类型的内存块,它的特征是“可变”,所以我们常用指针来操作动态内存。指针远比数组灵活,但也更危险。

下面以字符串为例比较指针与数组的特性。

3.1 修改内容

示例3-1中,字符数组a的容量是6个字符,其内容为hello。a的内容可以改变,如a[0]= ‘X’。指针p指向常量字符串“world”(位于静态存储区,内容为world),常量字符串的内容是不可以被修改的。从语法上看,编译器并不觉得语句 p[0]= ‘X’有什么不妥,但是该语句企图修改常量字符串的内容而导致运行错误。

char a[] = “hello”;
a[0] = ‘X’;
cout << a << endl;
char *p = “world”; // 注意p指向常量字符串
p[0] = ‘X’; // 编译器不能发现该错误
cout << p << endl;

示例3.1 修改数组和指针的内容

3.2 内容复制与比较

  不能对数组名进行直接复制与比较。示例7-3-2中,若想把数组a的内容复制给数组b,不能用语句 b = a ,否则将产生编译错误。应该用标准库函数strcpy进行复制。同理,比较b和a的内容是否相同,不能用if(b==a) 来判断,应该用标准库函数strcmp进行比较。

  语句p = a 并不能把a的内容复制指针p,而是把a的地址赋给了p。要想复制a的内容,可以先用库函数malloc为p申请一块容量为strlen(a)+1个字符的内存,再用strcpy进行字符串复制。同理,语句if(p==a) 比较的不是内容而是地址,应该用库函数strcmp来比较。

// 数组…
char a[] = "hello";
char b[10];
strcpy(b, a); // 不能用 b = a;
if(strcmp(b, a) == 0) // 不能用 if (b == a)

// 指针…
int len = strlen(a);
char *p = (char *)malloc(sizeof(char)*(len+1));
strcpy(p,a); // 不要用 p = a;
if(strcmp(p, a) == 0) // 不要用 if (p == a)

示例3.2 数组和指针的内容复制与比较

3.3 计算内存容量

  用运算符sizeof可以计算出数组的容量(字节数)。示例7-3-3(a)中,sizeof(a)的值是12(注意别忘了’’)。指针p指向a,但是 sizeof(p)的值却是4。这是因为sizeof(p)得到的是一个指针变量的字节数,相当于sizeof(char*),而不是p所指的内存容量。 C++/C语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。示例7-3-3(b)中,不论数组a的容量是多少,sizeof(a)始终等于sizeof(char *)。

char a[] = "hello world";
char *p = a;
cout<< sizeof(a) << endl; // 12字节
cout<< sizeof(p) << endl; // 4字节

示例3.3(a) 计算数组和指针的内存容量

void Func(char a[100])
{
 
cout<< sizeof(a) << endl; // 4字节而不是100字节
}

示例3.3(b) 数组退化为指针

Show All   1 2 3

影片《厨房之恋》进一步资料

  在前一段CCTV1只看到上集后,(点击这里查看详情)一直期待能有机会看到下集,可惜BT的CCTV不播了,网上也暂时没有找到下载,无意中得到厨房之恋正确的原文翻译,看来离找到下载视频不远了!

  正确的原文翻译是 Mai storie d’amore in cucina (TV) 相关介绍如下:
导演: Giorgio Capitani / Fabio Jephcott
主演: Bianca Guaccero / Chisco Amado / Stefania Sandrelli
上映年度: 2004
语言: Italian / Catalan
制片国家/地区: Spain / Italy
chef4
chef1chef2chef3
  这是一部浪漫喜剧,以爱情加美食这一广受欢迎的主题为主线,在向观众展现丰富的意大利饮食文化的同事,讲述了意大利年轻一代的生活和爱情。
  埃韦利娜出生在意大利的一座小镇,父亲和母亲共同经营一家餐厅,生意红火。但是埃韦利娜的理想是当一名大厨,因而当她从电视上看到西班牙著名大厨费尔南多的厨艺表演后,便背着父亲来到了巴塞罗那,在费尔南多主厨的餐厅当上了助理。助理的工作并不像埃韦利娜的想象,不仅又脏又累,而且难得见上费尔南多一面,更不用说从他那里学艺了。在一次鸡尾酒会上,埃韦利娜见到了她崇拜已久的人,而费尔南多也被年轻漂亮的埃韦利娜吸引,对她一见钟情。但是埃韦利娜却因为怕失去费尔南多而不愿意透露真实的身份,谎称自己是艺术学院的学生,开始了和费尔南多的约会……

顺利安装成功IE7正式版,初步体验感觉不错

  本子上安装的是XP SP2,是D版的英文版(多年之经验,E文版windows更稳定,占用资源更少),今天尝试安装IE7正式版,按照网友的经验,一次成功,也不需要什么破解文件,不错!

  初步的体验感受还是不错的,IE7的界面和以前的各个版本IE有了较大改动,默认的不显示菜单栏,直接就是地址栏和tab栏,有效显示页面的范围增大,同时按钮的布局也有了改变。IE7支持一个浏览器下打开多个网页,这个和腾讯的TT浏览器类似,这个功能唯一不让我满意的就是不支持双击关闭和输入新地址回车自动打开新窗口,这和FireFox类似,不过还是可以接受的。另外,IE7给我最大的新感受就是字体的变化,感觉更加柔和舒适。

  初步判断IE7还是值得升级安装的!

ie7

张怀旧评价“刘翔是傻子”经典语录摘选

  最近网上炒得比较火的事件之一,感觉有点意思,其实世事无绝对,看站在什么角度看问题了。下面是从网上摘录的部分信息和摘选。

  素有“网络愤青”之称的张怀旧,最近频频“发炮”,先是说“刘翔是傻子”,接着批评“刘翔没文化”。如今,张怀旧又玩起“博客掐架”,直骂“王军霞假装自己有文化”,原因是王军霞替小师弟刘翔“出头”。而且,张怀旧还把文章到处转贴,想借机吸引“粉丝”前来观战,结果却落得个“尴尬境地”,成为众多网民“口诛笔伐”的对象。
more »

费德勒和罗迪克今晚在上海上演了经典一站

  晚上的这场比赛现场直播,看得我差点喘不过气来,比赛实在太紧张了,扣人心弦!尤其在第二盘罗迪克拥有两个赛点的时候还是自己发球局,当时我想今天费天王肯定失利了,没想天王上演了惊天大逆转!神奇的在抢七的比赛中以10:8扳平比分,进入第三盘决胜盘,而后的比赛罗迪克显然受到第二盘的影响,失去了前面的精彩表现。费天王在继之前的对阵罗迪克11胜1负的历史战绩后,再次获胜,罗迪克今天的表现也相当精彩,可惜最终功亏一篑,虽然我是费天王的球迷,今天的比赛也不得不为罗迪克喝彩和感到可惜。

  今天的这场上海大师赛比赛,一定会让很多的球迷记忆深刻,一场经典的对决!继续支持费天王!

风送来寒冷,带走了北京的秋

北京的秋天很美,但是却非常短暂,也因为短暂,而让人倍加珍惜和留恋。

也因为短暂,使得北京的秋天显得更美。

more »