采用插件机制的批量文件扫描及进程处理工具

由于平常工作中需要大批量处理文件,所以用蹩脚的JavaScript语言编写了这个脚本,基本实现了文件及进程的枚举扫描,然后可以通过额外插件实现处理相应的文件或者进程,插件放在plugins文件夹里。

我这里写了3个插件,分别是批量打印Word文档、枚举系统活动进程、枚举RMVB、RM、AVI、WMV、MKV格式的电影文件。
[点击这里下载]

批量文件扫描及进程处理
function Component(ActiveXObject) {

  // 创建对象建议使用ActiveXObject.open(名称);
  // 比如ActiveXObject.open("Word.Application");

  this.name = "插件名称"; // 将显示在主界面下拉框中
  this.cancel = false; // 是否取消扫描,运行中设为true会自动中止扫描
  this.success = true; // 是否处理成功
  this.log = new Log(); // 日志对象
  
  // 日志分为3种,将会在列表框反应出来
  // this.log.error("出错消息文本");
  // this.log.info("正常消息文本");
  // this.log.warning("警告消息文本");

  this.load = function() {
    // 加载插件时所要运行的代码
  }
  
  this.unload = function() {
    // 卸载插件时所要运行的代码
  }
  
  this.dispatch = function(parentObj, selfObj, msg){
    switch(msg) {
      case "file": // 文件处理分支
      // parentObj.self (注意这里的.self)
      //就是Scripting.FileSystemObject对象
      // selfObj为每个File对象
      break;
      case "process": // 进程处理分支
      // parentObj 就是winmgmts的GetObject对象
      // selfObj为Win32_Process 每个进程对象
      break;
    }
    return false;
  }
}

目前已知的问题
1. 某些系统上双击启动会报错,请关闭IE浏览器并清除进程中多余的iexplore.exe进程后再试,如果错误依旧,请再次手动打开IE浏览器,然后再试。如果问题还是存在,建议关闭其他浏览器。(感谢 威言威语 提供)
2. 外文计算机上执行可能会出错,建议将脚本内中文改成英文后再运行。(感谢解皞在日文系统下的测试)

如果有什么问题或者建议欢迎提出!

Posted in:
  • VBScript/JavaScript/Python
  • 系统应用程序开发
Tagged
  • wscript
  • 系统工具

避免谷歌广告影响页面加载速度

也许大家喜欢往自己的站点上放点广告来捞取外快,但是当确实这么做时却发现网页的加载速度变慢了,为什么呢?

因为目前浏览器总是阻塞式(blocking)的读取网页引用的外部JavaScript,所以 雅虎网页优化14条准则 中也提到把外部引用的脚本放在页面的底部,差不多是</body>之前。这样网页基本上能最快渲染完毕,然后再加载这些外部脚本。

好了,了解这么多,大家肯定想这样广告只能显示到页面底部了,我想自定义广告的位置该怎么办?Aaron Peters给出了个办法,大家可以参考他博客上的这篇文章 《Non-blocking Google Adsense ads: improve page speed》 ,也就是说我们可以在要放广告的地方放置一个div层,然后把页面底部的广告脚本代码appendChild加载到这个层即可。

不过我不太明白的是为什么Aaron Peters要把页面底部的广告层设置为display:block,貌似这样加载页面的时候,底部会先出现广告,然后才加载至指定位置的层,起初我是这样想的,首先把底部位置的广告层设置为display:none,然后加载至指定位置时再display:block, 想法很好,但是实际操作的时候,广告死活显示不出来,经过摸索,终于找到了解决方案,也就是说,在底部的广告代码层的display:block,但是外面再套个display:none的层,这样基本就完美了,下面分享下我的做法。 (注:发现原来是自己脚本写错了实际这个方法也是可以的)

function speed_ads() {
	var ad = document.getElementById('adsense'),
		loader = document.getElementById('adsense-loader');
	if (ad && loader) {
		ad.appendChild(loader);
		loader.style.display='block';
		ad.style.display='block';
		ad.style.height='60px';
	}
}
window.onload=function() {speed_ads();}
<html>
 <head>
 <!--上述脚本位置-->
 </head>
 <body>
   <!--指定的广告显示位置-->
   <div id="adsense"></div>
   <!--其他内容位置-->
   <p></p>
   <p></p>
   <!--广告代码位置-->
   <div style="display:none">
     <div id="adsense-loader" style="display:block">
       <script type="text/javascript">
       // 谷歌广告代码
       </script>
     </div>
   </div>
 </body>
</html>

有网友给Aaron Peters指出了个问题,原文如下。

Important: Will Alexander posted a comment about the failure of this trick: it may (and often will) result in double impressions for ads served to visitors with Gecko (Firefox) and WebKit (Chrome) browsers. Do Not Use This Trick!!!

大概意思是在Gecko核心 (Firefox) 和 WebKit核心 (Chrome)的浏览器下,广告的展示会变为两次?我试了下,暂时没有发现异常,如果有朋友发现问题的话记得告诉我哦:-)

2011年8月26日更新

看到Aaron Peters的这篇文章又有了更新,谷歌广告已经支持非阻塞(Non-blocking)方式加载广告了:

Adsense releases non-blocking Adsense! Yes, it happened, finally: Google has released a new version of the Adsense show_ads.js file that loads in a non-blocking way. Per today, March 18 2011, Google serves it to Chrome, Firefox and IE8 browsers and support for more browsers is coming. As a bonus: publishers do not have to change their code! Read the Google Code blog post about the new Adsense code (注:由于特殊原因,这里的链接我就不放了,大家可以到 作者那篇文章 上去找下。)

我试了一下,确实不再卡住页面了,看来谷歌的技术还是比较强大的!

Posted in:
  • 前端开发与用户体验
  • Web开发及相关
Tagged
  • 网站优化
  • 广告营销

改变图片大小的缩略图生成软件

以前电脑是Windows XP系统的,记得在 Microsoft PowerToys for Windows XP 里面找过一个叫 Image Resizer 下载地址 )的改变图像大小的缩略图软件,这里我们不叫压缩图片,因为这里压缩是指图片体积(即所占磁盘大小)的改变,而改变图像大小,是指尺寸的改变,通常叫缩略图,当然,尺寸改变了体积就相应变小了。

好吧,言归正传,下面就谈谈 Image Resizer 这个小工具吧,然后我会推荐另外一款功能更强大的缩略图软件。

安装完成后会自动集成到Windows Explorer的右键菜单中去。

Image Resizer集成右键菜单

对你所要改变大小的图片或者图片目录右击选择Resize,然后选择合适的大小,点击OK,这样就自动生成了,是不是很方便?

Image Resizer

后来电脑升级换代了,杯具的XP老爷爷被抛弃了,我们满怀欣喜的迎接了Windows 7时代,但是与此同时我们杯具的发现,有些软件不能用了,很不幸, Image Resizer 正好在此之列,幸好,我们有另外一款替代软件,那就是 Prish Image Resizer ,貌似原作者博客打不开了,要下载的就 访问这里 或者 谷歌一下 吧。

同样的安装完成后会集成到Windows Explorer的右键菜单中去。

Prish Image Resizer Prish Image Resizer

可见 Prish Image Resizer 的功能要比 Image Resizer 丰富很多,尤其是右键的Copy Picture更为方便,可以将图片按指定的大小复制到剪切板上。

Posted in:
  • 软件推荐及相关资讯
Tagged
  • 图片与图像
  • 图像压缩

谈新窗口打开链接的合理方式

如果标题换做“用户体验”,感觉大了些,自己毕竟不是这方面的专家,在这里只是谈谈自己的感受。

我还记得很早的时候自己学做网页制作,那时不晓得链接如何从新窗口打开,也不关心这些,因为网页只是起到一个宣传简介的作用,后来多了友情链接这个东东,是的,那时还没有多标签多选项卡的浏览器出现,大家都用着IE6之类的窗口浏览器,于是那时候大家养成了个习惯,就是打开一个页面,等浏览结束后下意识的去关浏览窗口,岂不知这个页面的上一页自己也需要,或者网站作者并不希望浏览者点了外部链接后就脱离自己的网站,因为站长们认为自己网站还有更精彩的浏览者并没有发现……

正是由于这些原因,于是广大站长纷纷采用了外部链接的新窗口打开的模式,新窗口打开,无非就是采用JavaScript的 window.open 办法或者 target="_blank" 的方法,由于后者不需要脚本支持所以实际采用多一些。这样以来似乎已经很完美了,真的是这样吗?这些网站继续培养了浏览者盲目按×关闭窗口的习惯,或许他们应该尝试着新的方式那就是按Shift加鼠标左键新窗口打开网页。

终于有一天新的标准XHTML 1.0出现了,广大站长纷纷发现原来的 target="_blank" 不能通过标准了,于是大家开始思考:“我们到底做错了什么?”。我们到底做错了什么?大家可以参考阿捷的这篇 《_blank开新窗口不符合标准?》 大家应该知道是怎么回事了,不加限制的开新窗口说到底是剥夺了用户的选择权,用户有权利选择是原窗口打开还是新窗口打开,我们必须将设计由以自我为中心转变为以用户为中心,为用户考虑,但是话又说回来了,在中国这种新窗口打开的模式挺符合国情的,大家都默认并习惯了,当你把选择权交给用户时,用户突然变得不知所措,甚至会怪罪于你的设计,你明明是为用户想的,偏偏用户不领情。

那我们究竟还要不要新开窗口,有没有比较好的做法?至少我认为MSDN的做法是值得我们借鉴的,MSDN在外部链接的旁边放置了个小图标标示着这个链接是个外部链接,但是实际还是本窗口打开的。

MSDN新窗口打开.png

我们何不把这个小图标利用起来,也就是说点击链接是本窗口打开,点击旁边的小图标就新窗口打开,这样貌似这个问题到这里就合理解决了,这个解决方案很早就有了,也是我认为比较好的一个办法,当然大家如果有什么更好的方法可以和我讨论。

附加贴上自动识别并加上外部链接图标的JavaScript代码:

(function (){
var window = this, undefined;

function addListener(element, e, fn) {
    if (element.addEventListener) {
        element.addEventListener(e, fn, false);
    } else {
        element.attachEvent("on" + e, fn);
    }
}

var outlinks =  {
  protocol : /^(?:http|https|ftp|mms):(?:\/\/|\\\\)/i,
  local_url : location.hostname, // 获取本地域名
  icon : 'outlink.png', // 请改成自己的图标路径
  
  set : function(obj, list) {
    for (var i = 0; i < list.length; i++) {
      obj.setAttribute(list[i][0], list[i][1]);
    }
  },
  create : function(anchor) {
    var space = document.createTextNode(' '),
      link = document.createElement('a'),
      img = document.createElement('img'),
      text = '新窗口打开';
    
    outlinks.set(link, [['href', anchor.href],
              ['target', '_blank'],
              ['title', text]]);
    outlinks.set(img, [['alt', text],
              ['src', outlinks.icon],
              ['height', 13],
              ['width', 13],
              ['border', 0]]);
    img.style.verticalAlign='middle';
    link.style.background = 'none';
    link.style.margin = '0';
    link.style.padding = '0';
    img.style.margin = '0';
    img.style.padding = '0';
    link.appendChild(img);
    anchor.parentNode.insertBefore(space,
                    anchor.nextSibling);
        anchor.parentNode.insertBefore(link,
                    anchor.nextSibling
                    .nextSibling);
  },
  
  init : function() {
    try {
      var anchor,
        anchors = document.getElementsByTagName('a');
      for (var i=0; i<anchors.length; i++) {
        anchor = anchors[i];
        if (
          anchor.href &&
          // 跳过加了链接的图片
          !anchor.getElementsByTagName('img')[0] &&
          outlinks.protocol.test(anchor.href) &&
          !anchor.getAttribute('target') &&
          anchor.href.indexOf(outlinks.local_url) < 0) {
            outlinks.create(anchor);
        }
    }
    }catch(e) { alert(e.message);}
  }
}

addListener(window, 'load', outlinks.init);

})();
Posted in:
  • 前端开发与用户体验
  • Web开发及相关
Tagged
  • 用户体验

WScript脚本打开文件夹选择对话框

最近在弄一些WScript脚本,有段功能需求就是弹出个打开文件夹的对话框,之前老是在" MSComDlg.CommonDialog "上纠结,后来才发现原来那个只能摆弄出文件选择对话框,后来在查阅了一些资料后才知道,要调用" Shell.Application "这个组件,哎,微软也应该把这些组件组合组合了,要不还真不容易找到。

文件夹浏览对话框

贴出部分代码,后来根据需要我还改写了JavaScript版本,话说JS的对象引用很是方便,不用像VBS那样Set对象了。

Const SHELL_MY_COMPUTER = &H11
Const SHELL_WINDOW_HANDLE = 0
Const SHELL_OPTIONS = 0
Function GetOpenDirectory(title)
	Dim ShlApp,ShlFdr,ShlFdrItem
	
	Set ShlApp = WSH.CreateObject("Shell.Application")
	Set ShlFdr = ShlApp.Namespace(SHELL_MY_COMPUTER)
	Set ShlFdrItem = ShlFdr.Self
	GetOpenDirectory = ShlFdrItem.Path
	Set ShlFdrItem = Nothing
	Set ShlFdr = Nothing
	
	Set ShlFdr = ShlApp.BrowseForFolder _
				(SHELL_WINDOW_HANDLE, _
				title, _
				SHELL_OPTIONS, _
				GetOpenDirectory)
	If ShlFdr Is Nothing Then
		GetOpenDirectory = ""
	Else
		Set ShlFdrItem = ShlFdr.Self
		GetOpenDirectory = ShlFdrItem.Path
		Set ShlFdrItem = Nothing
	End If
	Set ShlApp = Nothing
End Function
var SHELL_MY_COMPUTER = 0x11;
var SHELL_WINDOW_HANDLE = 0;
var SHELL_OPTIONS = 0;
	
function openDir(title) {
  var shlfdr,
  shlapp = WSH.CreateObject("Shell.Application");

  shlfdr = shlapp.BrowseForFolder(
			SHELL_WINDOW_HANDLE,
			title,
			SHELL_OPTIONS,
			shlapp.Namespace(SHELL_MY_COMPUTER).Self.Path);
  if (shlfdr == null)
     return "";
  return shlfdr.Self.Path;
}
Posted in:
  • VBScript/JavaScript/Python
  • 系统应用程序开发
Tagged
  • wscript

巧用htaccess客户端网页缓存实现网站加速

网站加快访问速度的一个基本原则就是减少HTTP请求数,在我们实现了合并CSS和脚本,使用了图片CSS Sprites后,发现 YSlow PageSpeed 的评分并没有提高(当然淘宝UED团队给了我们一个新的优化思路,不必拘泥于这两个工具,详细请见 这里 ),仔细研究后才发现原来我们没有很好的利用客户端缓存,仔细分析了 淘宝 等大网站的HTTP反馈信息如下。

淘宝网

Date: Tue, 22 Feb 2011 14:02:56 GMT
Expires: Tue, 22 Feb 2011 15:02:56 GMT
Cache-Control: max-age=3600

腾讯QQ

Date: Tue, 22 Feb 2011 14:04:26 GMT
Expires: Tue, 22 Feb 2011 14:19:26 GMT
Cache-Control: max-age=900

网易163

Date: Tue, 22 Feb 2011 14:07:35 GMT
Expires: Tue, 22 Feb 2011 14:08:21 GMT
Cache-Control: max-age=80

都可以看到这些网站有个共同点就是使用了Cache-Control控制了客户端的网页缓存,这样,客户端在频繁访问网站时不必每次都向服务器发出请求,大大提高访问的速度和减轻了服务器的负担。

Cache-Control的关键部分就在于max-age,其值代表缓存的时间,单位为秒,对于较快更新的网站这个时间应该短一些,对于更新较慢的网站,这个时间应该长一些,对于个人博客,我认为这个值可以设定为600(10分钟),当然如果时间过长的话,可能评论文章需要刷新或等待指定时间过后才能看见。

对于客户端缓存控制,还有Pragma和ETag值得注意,一般情况下Param: no-cache,代表不缓存文件,当然我们要缓存就必须去掉这项,有关ETag,在查询HTTP反馈后发现是一个标识符,也就是说客户端在收到这个页面的时候会记下这个ETag标识,当再次访问时,客户端将把这个ETag发回给服务器,服务器在收到这个ETag后,会与当前的ETag进行对比,如果一致,代表页面没有改动,直接反馈304 Not Modified的消息,这样浏览器就直接在本地取出缓存页面。实际考察下来发现大多数Web应用均没有实现对ETag的管理控制,所以保留这个信息对于这些应用来说纯属浪费,完全可以去掉,去掉Pragma和ETag头信息可以在.htaccess输入下面两行。

<FilesMatch ".(html|htm|php|txt)$">
Header unset Pragma
Header unset ETag
FileETag None
</FilesMatch>

其中 html|htm|php|txt 对应的是要处理的文件类型扩展名。再解决了这两项后,下面可以添加Cache-Control信息了,这里我们设定为10分钟。原来的.htaccess配置如下。

<FilesMatch ".(html|htm|php|txt)$">
Header unset Pragma
Header unset ETag
FileETag None
Header set Cache-Control "max-age=600"
</FilesMatch>

同样的道理,我们知道一般网站上图片、样式表、脚本文件等等都是基本上不改动的,我们可以通过下面的代码将其缓存时间设定长一些。

<FilesMatch ".(gif|jpg|jpeg|png|ico|css|js)$">
Header unset Pragma
Header unset ETag
FileETag None
Header set Cache-Control "max-age=315360000"
</FilesMatch>

怎么样,是不是觉得时间太长了,假如我要改个样式,客户端可能需要刷新才能看见,那怎么办?我们知道,前面对于网页设置了个比较短的时间,也就是说网页在那个时间过后就需要重新到服务器上获取最新版。我们可以在引用的样式表style.css的后面加上style.css?t=20110222这样的时间戳,当然为了照顾一些特殊的浏览器,一般建议这样写style.css?t=20110222.css,当你改动了样式表后,你只需要对网页里的link引用的样式表时间戳进行修改即可。

<link rel="stylesheet" href="style.css?t=20110222.css" type="text/css" />

好吧,做完这些,我们可以歇口气喝杯咖啡了?等等,你会发现把配置好的.htaccess文件上传到网站根目录下,然后你登录博客后台时一些后台操作变得不正常了,比如我们删掉一条记录,系统提示删除成功,但是当你返回的时候,发现那条记录仍然存在,真的是这样吗?当你再刷新下该页,才发现那条记录已经没了,聪明的你应该晓得是怎么回事了,对!就是缓存在作怪。

所以我们需要去掉后台管理页面的缓存,假设后台管理路径是/admin/,我们可以针对该文件夹单独配置个.htaccess,内容如下。

<FilesMatch ".(html|htm|php|txt)$">
Header unset ETag
FileETag None
Header set Cache-Control "no-cache, no-store, max-age=0, must-revalidate"
Header set Pragma "no-cache"
</FilesMatch>

好了,就是这么简单,做完这一切,现在访问你的网站看看,是不是感觉不错:-)

另外还有种设置缓存的方法可以参考 《How to Set an Expires Header in Apache》 这篇文章。

Posted in:
  • 前端开发与用户体验
  • Web开发及相关
Tagged
  • htaccess
  • Web缓存
  • 网站优化

ASP连接MSSQL数据库的两种方式

原文发表于2008年12月8日

一个是sa验证,一个是Windows本地验证,自己升级数据库用到的,先记录这里。

下面是sa验证,Data Source指明的是数据库所在的服务器地址,如果是本地服务器这里就为local,User ID指明登录数据库的用户名,Password指明的是登录密码,database指明要使用的数据库名。

Dim objConnect   
Set objConnect = Server.CreateObject( _
		   "ADODB.Connection")   
With objConnect   
    .ConnectionString = "Provider=SQLOLEDB;" &_
	"Data Source=(local);" &_
	"User ID=sa;" &_
	"Password=123;" &_
	"database=master;"  
    .Open   
    .Close   
End With  
Set objConnect = Nothing

下面是Windows本地验证的方式登录,Initial Catalog指明要使用的数据库名,Data Source指明服务器地址,本地服务器即为localhost,对于SQL Express系列数据库,本地服务器 Data Source=.\SQLEXPRESS

Dim objConnect  
Set objConnect = Server.CreateObject( _
		 "ADODB.Connection")   
With objConnect   
    .ConnectionString = "Provider=SQLOLEDB.1;" &_
	"Integrated Security=SSPI;" &_
	"Initial Catalog=master;" &_
	"Data Source=localhost"  
    .Open   
    .Close   
End With  
Set objConnect = Nothing

另外 这里有个网站 可以供查询各种数据库的连接字符串,值得推荐!

Posted in:
  • 网络编程与数据库
  • Web开发及相关
Tagged
  • asp
  • 连接字符串
  • sqlserver

几个值得推荐的开源库

使用现成的第三方成熟的开发库有利于整个项目的稳定,减少不必要的软件测试,缩短开发时间,可以达到事半功倍的效果。下面介绍几款我所熟悉的开源库,有些已经较稳定的应用在我的程序项目中了。

SQLite3
http://www.sqlite.org/
很小很强大的数据库,是遵守ACID的关联式数据库管理系统,也是我非常喜欢的小型数据库之一,目前我的大部分C语言项目在小型数据库方面均采用这款数据库了。

TinyXML
http://www.grinninglizard.com/tinyxml/
优秀的C++ XML解析器,可以让你非常方便的调用操作XML文件。

libpng
http://www.libpng.org/pub/png/libpng.html
一款PNG图像处理的开源库。

zlib
http://zlib.net/
很多软件包里会看到它的影子,这个是用来进行文件压缩的开源库,zlib使用抽象化的DEFLATE算法,最初是为libpng函式库所写的。

bzip2
http://bzip.org/
又是一款压缩库,比传统的gzip或者ZIP的压缩效率更高,但是它的压缩速度较慢。

libcurl
http://curl.haxx.se/libcurl/
用不同的协议连接和沟通不同的服务器的开源库。

以上开源库均是跨平台的,下面介绍一个之前本人在移植项目到Windows环境下用到的关于多线程的库。

pthreads-win32
http://sources.redhat.com/pthreads-win32/
一款Windows下的POSIX多线程实现接口的库,非常好用,在移植其他系统的多线程程序到Windows下可能会用得到。

Posted in:
  • 软件推荐及相关资讯
Tagged
  • 开源库

简单介绍编程中位运算的使用

原文发表于2008年11月22日

在我刚刚接触C语言时,对于10进制转2进制这种数学运算很是反感,记得某次实验课上老师要求写一段10进制转换为2进制的C语言程序,我竟然忙活了半天没有搞定,本来以为很简单的,不就是除以二判断余数吗?但偏偏弄不好,后来接触到数据结构课知道每次余数判断需要将结果进栈,然后输出结果时出栈即可,代码后来自己搞定了。后来上过汇编课后了解了位运算。于是我写了如下代码,对,这就是进制转换,很简单。当然,如果你有更好的欢迎共同交流。

#include <stdio.h>   
int main(void)   
{ 
    int usr_input;   
    short i;   
    puts("Enter a number:");   
    scanf("%d", &usr_input);   
    for(i = ((sizeof(usr_input) << 3) - 1);
	i > -1; i--)   
    {   
        printf("%d", ((usr_input &
		     (0x1 << i)) == 0 ?
				0 : 1));   
        if((i & 3) == 0)   
            putchar(' ');    /* 这个if也可以省掉 */  
    }   
    putchar('\n');   
    return 0;   
}

位操作的魅力就在这里,代码简洁,当然最重要的一点还是位操作的效率比较高。缺点就是代码不易理解,不过我认为你对二进制位有深刻了解并且经常写一些位操作的代码的话这些代码你也会很容易理解的。

下面解释下这段进制转换的代码。

((sizeof(usr_input) << 3) - 1) 获取数据的位数,这里是int型,sizeof后为4,左移3位,左移1位即乘以2,这里即乘以8,结果是32,也就是说int型为32位(注:不同的机器可能sizeof的值是不同的,这里仅仅以Intel x86机型为例)。一般情况下二进制我们从右向左读,第1位也就是我们这里说的第0位,那么输出这个二进制,需要先输出最高的一位,也就是输出第31位。怎么判断这一位呢?这是我们下面要做的工作,学过汇编的知道,使用TEST指令即可判断位,而TEST指令做的是不写原值的按位与操作,所以要判断哪一位我们需要将那一位与1与,其余位与0与即可,比如这里的判断需要与的是 1000 0000 0000 0000 0000 0000 0000 0000 ,如果结果是0,说明这一位是0,反之若不为0则这一位为1。但如何实现判断下一位和下下位的循环判断呢?其实我们可以设定一个初始值 0000 0000 0000 0000 0000 0000 0000 0001 即0x1,让其随循环次数进行左移即可。i & 3 其实这句是 i % 4,主要是为了美观,每四位输出空格。求余(模)一般对于求的是2的倍数的余数都可以用类似的按位与实现。

这段代码理解后可以看看下面的代码:

/* 转化为大写 */  
char *UCase(char *Source)   
{   
 long i=0;   
 do  
  if(*(Source+i) <= 'z' &&
	*(Source+i) >= 'a')   
   *(Source+i) &= 223; /* 将二进制第六位置为0 */  
 while(*(Source+i++));   
  return Source;   
}   
  
/* 转化为小写 */  
char *LCase(char *Source)   
{   
 long i=0;   
 do  
  if(*(Source+i) <= 'Z' &&
	*(Source+i) >= 'A')   
   *(Source+i) |= 32; /* 将二进制第六位置为1 */  
 while(*(Source+i++));   
  return Source;   
}

这段代码应该是比较好理解的,其实你只要用心观察过ASCII码表,分析其二进制后你就会发现一定的规律,然后也可以像上面的代码一样轻松的用位操作实现常用的功能。

如果我要让你写一段判断奇偶数的代码呢?很多人肯定认为,这还不简单,直接与2求余即可,学过汇编后,我才知道有比这个还方便的位操作方法,即直接判断最后一位是否为1,为1即为奇数,反之为偶数。怎么判断呢,上面说过了,用按位与即可,对0x1按位与。你会发现和刚才提到的求余的位操作简化有着相同之处,即模2。

再介绍个我较早接触的位操作,即交换两个整形变量。老师在授课时绝大多会和你讲,交换两个数需要临时变量什么的,然后要你写一个swap函数,其实在书上位操作那章介绍了一个不需要临时变量的整形交换方法。即异或。下次老师再要求你写交换两个整形的函数你就可以这样去写:

void swap(int *a, int *b)   
{   
    *a ^= *b;   
    *b ^= *a;   
    *a ^= *b;   
}

不相信吗?自己调试看看。这段代码类似与使用位运算的简单应用实现的密钥加密解密的功能。

下面提供一些,我写的用来操作位的宏:

#define BIT_TEST(src, pos) \
	((((src) & (0x1 << (pos))) == 0) ? 0 : 1)   
#define BIT_SET(src, pos) \
	((src) | (0x1 << (pos)))   
#define BIT_CLEAR(src, pos) \
	((src) & (~(0x1 << (pos))))   
#define BIT_TURN(src, pos) \
	((src) ^ (0x1 << (pos)))   
#define BIT_SIZE(type)     \
	(sizeof((type)) << 3)   
#define BIT_MOD(src0, src1) \
	((src0) & ((src1) - 1)) /* src1 must be 2*n */

解释:

BIT_TEST 输出src的pos位是0还是1。
BIT_SET 设置src的pos位为1。
BIT_CLEAR 设置src的pos位为0。
BIT_TURN 翻转src的pos位,即0变成1,1变成0。
BIT_SIZE 输出type型的位数。
BIT_MOD 求余(模),即将src0 % src1,特别提醒的是 src1必须是2的倍数。

最后,我想说的是,这里提到的位操作均适用于整形数,最好不要尝试在浮点型上应用,以避免意想不到的后果。

Posted in:
  • 数据结构及算法理论
  • 计算机学习与研究
Tagged
  • 位运算

Windows下程序开发较常用的工具

原文发表于2009年8月17日 标题是《介绍几个程序开发中较常用的工具》

编程老手可能都用过,那这篇文章可以略过了^_^

Dependency Walker
http://www.dependencywalker.com/
附加检查EXE依赖项的,可以查看导出导入函数,了解一个程序所调用的API。

Microsoft Spy++
写过Windows窗体程序的人对这个都比较熟悉,我常常用来查看窗体样式以及消息事件等等。

UPX - the Ultimate Packer for eXecutables
http://upx.sourceforge.net/
可以通过这个小程序压缩你的EXE或者DLL文件,同时也为你的程序加上了一个外壳。当然使用upx -d命令也可以解压使用UPX压缩加壳的应用程序。貌似这个加的壳会被少数杀毒软件报毒,如果胆小的话就不要给自己的应用程序压缩加壳了。

WinHex
http://www.winhex.com/
这款工具很强大啦,不过我经常用来查看编辑二进制文件。

好了,先写这么多,如果你有些想要分享的话欢迎评论。

Posted in:
  • 软件推荐及相关资讯
Tagged
  • 开发工具

© Wang Ye / 王 晔. All rights reserved.