春暖花开
雪化了,花开了,春天来了
posts - 149,comments - 125,trackbacks - 0

       刚刚休息了一个暑假。不要盲目羡慕我啊,只有短短一个星期。上研以来,还真的没有什么假期可言,寒暑两假一年加起来也就两个多星期,相比同学悠哉的两三个月来说真的是少啊。
       眼看明年也快要毕业了,于是邀请父母还有淘气的小侄来北京逛逛看看。父亲的北京记忆还停留在80年代初,还话说他开着大卡车从除了天门前的其他街道呼啸而过。北京已经变化得令他陌生。小侄则郁闷为什么去哪都要不停的倒车,嚷着再不做地铁的他,做了一回公交后,再也没有这种想法。
        上星期还算天公作美,刚开始的几天还算温度适宜,领着逛了逛石景山游乐园,鸟巢,天文馆,北京市海洋馆,西单,前门,天安门。剩下几天的高温天气,奈何我有兴致,他们却个个都不逛了。原因有二,一是money消耗了不少,父母也替我心疼钱了;二是高温加交通不顺,老的累了,小的也累了。情愿开着空调,家里看电视。
        几天下来,小侄竟然发出了这样的感慨,北京没有家好。父母也觉得没有家好。在这个城市生活了两年多的我,为什么没有这种感觉呢。习惯了,习惯了拥堵,习惯了走路,习惯了忙碌,习惯了这个城市带给我的感觉,也渐渐觉得自己融入了进来。毕竟这里会让自己跑得更快些,跳得更高些,是这里的机遇与挑战吸引了我,我想这也是吸引很多人的理由。要不,这么多人,拥挤在这个城市总该有个往前奔的理由。
        还没毕业,所以高得不能再高的房价还暂时对我带不来什么冲击,只是眼下的经济形式,让我面临着就业压力。父母的到来,让我为自己找到了一个很好放松的理由。假期的结束,又让自己回到了毕业的思考。
        似乎这是一个热门话题,身边的同学、同事以及朋友都会问及此事。程序员是我的首选职业,因为我喜欢,喜欢那种挑战和不断学习的感觉,享受那种解决问题的快乐。我会选择这个一直下去,有着成为小小专家的梦想。只是现在需要一个跳板,跳得更高,飞得更远。
         梦能飞得多远,在于我能跑得多块。假期给我带来了一些疲惫,看看《蜡笔小新》,居然能缓解疲劳。其实小新有时比我小侄听话好多。今天终于恢复了早起的习惯,工作也要认真起来。旧项目终于完结了,新项目又要开始了,项目总结也要赶着写,学习进步也要加紧些。事情很多,都得一件一件来。在豆瓣网上看到的晨型人,5点多起来对于我来说真的太困难了,还是老时间起来吧,七点多,才能保证一天之精神饱满。加油起来,坚持就会胜利。

posted @ 2009-08-19 19:38 Sandy 阅读(235) | 评论 (0)编辑 收藏
     摘要: 目前做了一些版本涉及到海外的一些东西, 有些没有办法测试,只要写死IMSI号码。每回翻邮件真的很痛苦,遂在网络上查了一下。还挺全的。摘自:http://blog.csdn.net/wyymaomi/archive/2009/04/19/4091396.aspx 国际移动客户识别码 IMSI International Mobile Subscriber Identification Number&...  阅读全文
posted @ 2009-08-06 11:41 Sandy 阅读(8041) | 评论 (0)编辑 收藏

         最近越来越感觉效率的重要性。为什么呢?
         写程序不仅仅是简单的实现功能。原来写代码时没有注意这些问题,现在暴漏出来了,也无计可施。多个功能再加界面,导致了界面很慢。用户体验不好。所以这需要在以后工作中引以为戒。

         要把自己的代码写的漂亮一些。
posted @ 2009-08-05 17:01 Sandy 阅读(191) | 评论 (0)编辑 收藏

今天在进行memcpy出现了一些问题。
原因是这样的:
我定义了这样一个接口,里面涉及memcpy操作。

举个例子吧,如接口addItem,
void addItem(int iType, LPVOID *pItem);

里面有一个对象是TCHAR szStr[512];
我直接进行了这样的拷贝,memcpy(szStr, pItem, sizeof(szStr));
今天就出问题了。提示某块内存无法访问。于是重新看这个问题。为什么会这么写这样的接口呢?
我原先写的是 void addItem(int iType, TCHAR *pItem);
后来由于需求的变化,变成了LPVOID。改成这个以后,原先的字符串wcscpy就变成了memcpy。这个一直没有引起警觉。其实这一步的改变,就应该对接口做相应的调整,接口应该变为
void addItem(int iType, LPVOID *pItem, DWORD cbItem);
增加一个参数来说明pItem的大小。然而这一步没有做。

所以今天的教训就是要注意修改接口的时候,注意相应的变化。

还有是字符串的操作问题,宽字符和ASCII字符串的操作要注意。

posted @ 2009-07-29 11:58 Sandy 阅读(172) | 评论 (0)编辑 收藏
这也是《程序员面试攻略》上的一道题,题目是这样的:
请编写一个函数,确定一个整数的计算机内部表示中有几个“1”。

思索了一下这个题目,我是这样考虑的,也学书上给出伪代码
count = 0;
while (这个整数不为0)
{
      如果这个整数对2求余的结果是1,则count加1;
     将这个整数向右移移位
}

代码写出来是这样的:
int numOnesInBinary(int num)
{
    
int count = 0;
    
while (num != 0)
    
{
        
if (num % 2 == 1)
            count
++;
        num 
= num>>1;
    }


    
return count;
}

看了一下书中的答案,的确比我简练很多。对于求余这个方法还是比较笨的。书中采用了逻辑与。

判断条件从“num%2 == 1”变成 “num&1 == 1”,从程序中更倾向与后者。
所以在分析问题的时候,要学会用逻辑“与、或、异或”进行判断。

到这一步,看似已经很完美了。但是书中又出奇的给了另一种解法。这种想法我真的没有想到。

想法的出发点是考虑一个数字减1时,它的二进制发生了什么变化。减1得到的结果是,从最低位的1到最低位都发生了翻转,其他高位保持不变。如果您对这个整数和减一后的结果进行AND操作,得到的新的数字与原来的整数相比,只有最后一个1变成0.

如果进行多次这样的操作,这个整数的值变为0。这样我们也就获得了这个数的计算机表示中“1”的个数。

int numOnesInBinary2(int num)
{
    
int count = 0;
    
while(num != 0)
    
{
        num 
= num & (num-1);
        count
++;
    }

    
return count;
}


第一方法的时间复杂度为o(n),第二种的时间复杂度为o(m),m为1的个数。

后记:
最近一周多,一直在做这本书上的编程题。一天3道,自己先尝试编写,运行成功后再与书上的解答进行对比。稍有几次略感比书上稍好些。但大多数情况还是效率差一些。想想原因,还是练得比较少。所以继续努力。多多积累,养成良好的思维习惯。

posted @ 2009-07-28 15:56 Sandy 阅读(638) | 评论 (3)编辑 收藏
编程无他,唯手熟尔。

七星重剑的博客上看到的,非常赞同。
posted @ 2009-07-28 15:11 Sandy 阅读(235) | 评论 (0)编辑 收藏
这是《程序员面试攻略》上的一道题,先前也有一位公司同事问过我,今天有重新拿起看了一下。

书中介绍了两种方法
第一种是这样的利用强制类型转换
bool endianness()
{
      int testNum;
     char*  ptr;

     testNum = 1;
     ptr = (char*)&testNum;
     return ptr;
}

这个方法还比较好理解。

第二种方法就是利用union。
bool endianness()
{
    union{
         int theInteger;
         char singleChar;
   }endianTesg;

   endianTest.theInteger = 1;
   return endianTest.singleChar;
}

这种方法很巧妙。带着困意就是没有看懂,一个个问号就蹦出来了?这是为什么呢?

说实话,union在学习和工作中用的还真的不是很多。其用法还真是不记得。
所以赶快到网上去搜了一下。有篇文章还不错,我看懂了。
共用体union用法讲解
链接地址:http://blog.ednchina.com/likee/20666/message.aspx

Union表示几个变量公用一个内存位置, 在不同的时间保存不同的数据类型和不同长度的变量。其长度为Union中最大的变量长度。

这样,我们就不难理解上面的程序,theInteger和singleChar是共用一个内存位置的,如果是小尾数法的话,那么singleChar为1,对应theInteger的低八位;如果是大尾数法的话,那么singleChar为0, 对应theInteger的低八位。


继续努力学习!
朝着梦想加油前进。
posted @ 2009-07-28 15:04 Sandy 阅读(770) | 评论 (0)编辑 收藏

去同学那玩,看到这么一本书《C++沉思录》。这本书很早听过,但是没有读过。于是捧起书读了几章,感觉很是不错。其中第四章就是讲“类设计者的核查表”。虽然用c++有几年,但是有一些东西还是需要铭记于心的。

 

类设计者的核查表

一、        您的类需要一个构造函数么?

有些类太简单,无需构造函数,但有些类太复杂,他们需要构造函数来隐藏它们的内部工作方式。

二、           您的数据成员是私有的么?

通常使用公有的数据成员不是什么好事,因为类设计者无法控制何时访问这些成员。

三、           您的类需要一个无参的构造函数么?

如果一个类已经有了构造函数,想声明该类的对象可以不必显示地初始化它们,则必须显示地写一个无参的构造函数。

四、           是不是每一个构造函数初始化所有的数据成员?

构造函数的用途就是用一种明确定义的状态来设置对象。对象的状态由对象的数据成员进行反映。每个构造函数都要负责为所有的数据成员设置经过明确定义的值。

有时这种说法也未必总是正确的。有时,类会有一些数据成员,它们只在它们的对象存在了一定时间之后才有意义。提这个问题,只是激励你进行思考。

五、           类需要构造函数么?

不是所有有构造函数的类都需要构造函数。如果深入考虑一个类要做些什么,那么该类是否需要析构函数的问题就十分明显了。应该问一问该类是否分配了资源,而这些资源又不会有成员函数自动释放,这就足够了。特别是那些构造函数里包含了new表达式的类,通常要在析构函数中加上相应的delete表达式,所以需要一个虚析构函数。

六、        类需要一个虚析构函数么?

有些类需要虚析构函数只是为了声明他们的析构函数是虚的。当然,决不会用做基类的类是不需要虚析构函数的:任何虚函数只在继承的情况下才有用。

虚析构函数通常是空的。

七、           你的类需要复制构造函数么?

很多时候答案都是“不”,但是有时候答案是“是”。关键在于复制该类对象是否就相当于复制其数据成员和基类对象。如果并不相当,就需要复制构造函数。

如果你的类在构造函数内分配资源,则可能需要一个显示的复制构造函数来管理资源。有析构函数的类通常是析构函数来释放构造函数分配的资源,这通常说明需要一个复制构造函数。(空的虚析构函数除外)

如果不想用户能够复制该类的对象,就声明复制构造函数为私有的。如果其他的成员不会使用这些成员函数,声明就足够了,没有必要定义它们。

八、           你的类需要一个赋值操作么?

如果需要复制构造函数,同理多半也会需要一个赋值操作。

九、           你的赋值操作符能正确地将对象赋给对象本身么?

赋值总是用新值取代目标对象的旧值。如果原对象和目标对象是同一个,而我们又奉行“先释放旧值,再复制”的行事规程,那么就可能在还没有实施复制之前就把原对象销毁了。

十、           你的类需要定义关系操作符么?

如果你的类逻辑上支持相等操作,那么提供operate== operate!=可能会有好处。类似的,如果你的类的值有某种排序关系,那就可能会想提供余下的关系操作符。只要它们想创建你的类型的有序集合,你就必须提供关系操作符。

十一  删除数组时你记住了用delete[]么?

这个形式的存在,是C++希望在保持与C的兼容性的同时关注效率。C++要求用户告知要被删除的是不是数组。如果是,该实现就可能会提供另一个地方来存储长度,因为与数组所需的内存量相比,这个常数的开销会小很多。

十二   记得在复制构造函数和赋值操作符的参数类型中加上了const么?

复制构造函数应该是像X::X(const X&)这样,毕竟复制对象不会改变原对象。实际上,由于绑定一个非const引用到一个临时对象是非法的,使用X::X(X&)作为复制构造函数不会允许复制任何特殊表达式的结果。同样道理适用于赋值。

十三   如果函数有引用参数,它们应该是const引用么?

只有当函数想改变参数时,它才应该有不用const声明的引用参数。

 

   其中很多作者提到,提这些问题并不是希望去寻求答案,只是希望能够激励你进行思考。所以当我们设计一个类的时候,多思考一下,有没有什么地方需要注意的,我们设计的类将会更合理,更健壮一些。
posted @ 2009-07-25 08:32 Sandy 阅读(275) | 评论 (0)编辑 收藏

今天抱着书在做这么一道题:
整数/字符串转换
编写两个转换例程。第一个例程将一个字符串转换成带符号的整数。您可以假定这个字符串只包含数字和符号字符('-'),是一个格式正确的整数,而且这个数字在int类型的范围之内。第二个例程将Int类型中存储的有符号整数转换回字符串。

其中碰到了int与char的转换问题。这个还真的把我难住了。我先用最笨的方法switch进行了转换。你也知道这肯定不是最优的方法。直接转换,值也肯定不对。

后来发现竟然是这么使用的,赶快记录下来。
1、int 转换成char
      例如:
                int  n = 1;
                char ch = char(n + '0');
                不过需要注意,此处的n只能是0-9之间的字符
2、char转换成Int
                char ch = '9';
                 int n = int(ch) - int('0');
                  此处ch也是‘0’至‘9’的数字字符

多多学习,抓住机遇。

posted @ 2009-07-24 17:45 Sandy 阅读(2548) | 评论 (0)编辑 收藏

快捷方式的读取和创建

一、快捷方式的获取

SHGetShortcutTarget

功能:

获取快捷方式的目标路径

原型:

BOOL SHGetShortcutTarget(

  LPTSTR szShortcut,

  LPTSTR szTarget,

  int cbMax

);

参数:

szShortcut :包含快捷方式名字的字符串

szTarget :包含快捷方式目标路径的字符串, 字符串的大小至少是cbMax

cbMax :将被拷贝到缓存szTarget的最大字符串

返回值:

成功返回TRUE,否则返回FALSE

示例代码:

TCHAR StartMenuFilePath[MAX_PATH];
::SHGetSpecialFolderPath(NULL, StartMenuFilePath, CSIDL_PROGRAMS, FALSE);
TCHAR szShortPath[MAX_PATH];
wsprintf(szShortPath, _T("%s\\%s"), StartMenuFilePath, _T("搜索.lnk"));
TCHAR szFilePath[MAX_PATH];
:SHGetShortcutTarget(szShortPath, szFilePath, sizeof(szFilePath));

执行完毕后,
szFilePath 的值为shfind.exe

二、快捷方式的创建

SHCreateShortcut

功能:

创建快捷方式。

原型:

DWORD WINAPI SHCreateShortcut(

  LPTSTR szShortcut,

  LPTSTR szTarget

);

参数:

szShortcut :包含快捷方式名字和路径的字符串。在路径指定的位置创建快捷方式。

szTarget 包含快捷方式目标路径和参数的字符串。大小限定在256个字符以内。

返回值:

成功返回TRUE,否则返回FALSE。如果指定的快捷方式已经存在的话将返回FALSE

示例代码:

SHCreateShortcut(_T("\\搜索.lnk"), _T("shfind.exe"));
执行结果为在根目录下创建了“搜索.lnk”这个快捷方式文件。

三、补充说明

这里主要针对获取快捷方式的内容进行几点说明:

我们获取快捷方式的时候,内容不一定只包含路径,有可能存在一下的情况,如:

1、路径后跟随名称

\Windows\“开始”菜单\程序\任务.lnk

2、缩写名

poutlook.exe tasks

\Windows\“开始”菜单\程序\ActiveSync.lnk

:MSSYNCAPP

3、路径后跟随数字

\Windows\“开始”菜单\程序\游戏\icon.lnk

shellres.dll,-8229

考虑以上这几种情况,我们在获取快捷方式路径时,需要对路径做一些特殊处理。这里重点说一下第二种情况,这个缩写代表什么意思?在网上搜索了一下,原来我们可以在[HKEY_LOCAL_MACHINE\Software\Microsoft\Shell\Rai\]键值下找到名为:MSSYNCAPP的子键,键值为1的子键数值指明了名为:MSSYNCAPP的程序名称。但我们从这里获得的值,有时也不是路径,还会再次出现上述三种情况。所以,如果我们想从快捷方式中获取路径的话,就需要留意一些了。

至于为什么会这样,我还不是很明白。

posted @ 2009-07-23 18:13 Sandy 阅读(1612) | 评论 (1)编辑 收藏
仅列出标题
共15页: 1 2 3 4 5 6 7 8 9 Last