[C/C++] 計算二進位任意數含有多少個位元為1?

今天看到一個有趣的題目,就是計算二進位任意數值,其中包含了幾個1,這非常有趣,利用每個 bit 做&就可以解出這個問題了:
#include 
#include 
int bitcount(unsigned int);
int main(){
    int count = 0, a;
    a = 1023;
    count = bitcount(a);
    printf("%d有%d個位元為1\n\n", a, count);
    
    system("pause");
    return 0;
}
int bitcount(unsigned int n)
{
   int count = 0 ;
   while (n)
   {
      count++ ;
      n &= (n - 1) ; //關鍵演算之處
   }
   return count ;
}
關鍵解法是在 n &= (n – 1) ; 這個地方,為什麼會是這樣寫呢,大家可以想看看,為什麼要 (n-1),其實可以帶數字進去跑看看就知道程式為什麼會這樣寫,這個 case 可以分作兩種,數值可能會有兩種狀況,一種是奇數,另一種就是偶數,8 代表 1000,9 代表 1001,最右邊 bit 是 1 代表奇數,剩下的都是偶數,拿9當例子帶入 while 迴圈試試看,首先將 count + 1,接下來 1001 會跟 1000 做相乘動作,就會變成 1000,接下來跑另一次 while 會變成 1000 & 0111 就會變成 0 了,退出 while 迴圈,所以結論是 (n -1) 的用意是去掉一個 1 位元 bit,就像 [xxxx10 … 0] -1 = [xxxx01 … 1] …. 每運算一次相乘,就會少掉一個 1,原理就是這麼簡單。 這只是一種解法,歡迎大家討論看看還有無其他方法?

製作 Windows XP USB 開機系統 (模擬光碟開機)

最近幫朋友重灌一台電腦,發現他是 HP Mini 1109TU,沒有內建光碟機,然後朋友又沒買外接式光碟機,所以只好趕快上網找如何製作 Windows XP USB 系統,如果是 Linux 系列就好辦了,網路上找到一堆關於 Linux 教學文件,後來在 mobile01 找到一篇:『[教學]將USB 隨身碟 製成 XP 的安裝碟 (模擬CD-ROM)』,裡面的安裝過程我全部測試過了,可以正常運作,利用 USB 安裝 XP 真的還蠻快的,少了 CD-Rom 的讀取,USB 真的安裝相當快速,不過大家在上面下載的安裝程式,它會先將您的 USB 進行 Fat32 格式化,然後複製 XP 光碟內容到 USB 隨身碟,在設定複製內容到 USB 的同時,請不要將 USB 掛載到 D 槽,因為看了一下程式碼 usb_prep8.cmd 裡面有一段設定 USB 開機選項:
:_getusb
set _ok=
echo.
echo  Please give Target USB-Drive Letter e.g type U
ECHO.
set /p _ok= Enter Target USB-Drive Letter: 
set _ok=!_ok:~0,1!
if not exist !_ok!:\nul (
  echo.
  echo  ***** Target USB-Drive !_ok!: does NOT Exist *****
  echo.
  pause
  goto _main
)

FOR %%i IN (E F G H I J K L M N O P Q R S T U V W X Y e f g h i j k l m n o p q r s t u v w x y) DO IF "%%i" == "!_ok!" SET usbdrive=!_ok!:

if "%usbdrive%" == "" ( 
        echo.
        echo  ***** !_ok!: is not a valid Drive *****
        echo.
	pause
	goto _main
)
在 for 的迴圈裡面,並沒有寫到 D 這個代碼,所以自己把它補上去吧,這樣就可以正常複製光碟內容到 USB 裡面了。

[C/C++] 指標相加 = ?or 相減 = offset

最近看到網路上討論 C/C++ 題目,某公司主管給新進人員面試的 C/C++ 考題,如下:
int main(void)
{
     int *a,*b;
     a=1;
     b=1;
     printf("%d\n",a+b);
     return 0;
}
請問上面這個題目,哪裡有出問題,這是面試官問新進人員的題目之一,看也知道這程式丟到 Dev-C++ 是不會過的,*a *b 都是宣告為整數指標型態,可是在 a=1 或 b=1 在 Dev-C++ 裡面是編譯不過的,但是那寫法是沒有錯的,就像你設定 a=0 或者是 a=NULL 是一樣意思,不過最好是不要這樣寫,assignment 這樣寫不太好,可以改成 a = (int *)1; b = (int *)1; 這樣就可以順利編譯通過,再來 printf(“%d\n”,a+b); 這行錯很大,指標相加會爆炸吧,如果程式這樣寫,不把 OS 搞掛,那我還會覺得懷疑呢,正確寫法是指標加上 offset(位移),這樣才是可以正確執行的,所以我們把程式改成下面:
int main(void)
{
     int *a,*b;
     a = (int *)1;
     b = (int *)1;
     printf("%d\n",a+(int)b);
     return 0;
}
最後的執行結果是 5,(int) b 就相當於 sizeof(*b) 也等於 sizeof(int *) 答案都是四,所以就是 1+4 =5,指標是不能相加的,只能透過 offset 方式來讓指標指向不同 base,但是如果是指標相減,那就是求 offset 的意思喔,看一下底下例子
int main(void)
{
    int *a,*b;
    a = (int *)0x5566;
    b = (int *)0x5570;
    printf("%d %d %d %d %d\n", a, b, (int)a+(int)b, a+(int)b, sizeof(int *));
    printf("%d\n", a - b);
    printf("%d\n", ((int)b - (int)a)/sizeof(int *));
    return 0;
}
要算 offset 也非常容易,只要先轉成 10 進位相減在除以 sizeof(int *) 這樣就可以求出結果了,a-b 除以四其實 -2.5 取補數,所以是 -3,如果是 b-a 就是整數3了,只是位移 3 個 bit,其實觀念就是這樣,指標位址不能相加,但是指標位址可以相減 = Offset,觀念大致上是這樣,最後補上完整程式,大家可以 run 一次看看就知道了
#include "string.h"
#include "stdlib.h"
#include "stdio.h"

int main(void)
{
    int *a, *b;
    a = (int *)1;
    b = (int *)1;
    printf("%d %d %d\n", a + (int)b, (int)(a + (int)b), (int)a + (int)b); 
    a = (int *)0x5566;
    b = (int *)0x5570;

    printf("%d %d %d %d %d\n", a, b, (int)a+(int)b, a+(int)b, sizeof(int *));
    printf("%d\n", a - b);
    printf("%d\n", ((int)b - (int)a)/sizeof(int *));
    
    a = (int*)0x1000;
    b = a + 3;
    printf("%d %d %p %p \n", a, b, a, b);
    
    system("pause");
    return 0;
}

Google Chrome 支援超過 40,000 Extensions! with Greasemonkey

看到 Google Chrome Blog 發表的Google Chrome 支援超過 40,000 Extensions!,當 Google Chrome 瀏覽器剛出來的時候,造成 Web Developer 一些震撼,因為 Chrome 強調的是擁有快速的 Javascript 引擎,以及快速的啟動,Fast start-up、Fast loading、Fast search,也因此讓很多設計網站的工程師必須把 Chrome 的支援性考慮進去,但是由於剛推出的瀏覽器,沒有任何外掛功能,我本身用 FireFox 瀏覽器很多年了,FireFox 的附加元件讓許多程式設計師投入開發,也製造出很多方便的附加元件來讓大家使用,例如:FireBugGmail ManagerGreasemonkey…,然而 FireFox 最方便的就是 Greasemonkey 此附加元件,使用者可以撰寫簡單 Javascript 語言來跟指定網站進行元件控制,現在 Google 工程師聽到我們的聲音了,Google Chrome 4 加入 Greasemonkey user scripts 功能,大家可以到 userscripts.org 下載超過 40,000 script 安裝到 Chrome 瀏覽器。您可以在 blogger 使用 emoticons,大家可以去參考看看。 由於 Chrome 支援了 Greasemonkey,所以趕快把 FireFox 所安裝的 script,也安裝到 Chrome,可是我發現之前 DarkKiller 大神寫的 Wretch Album Expander 已經不能用了,所以我將它實做到 Chrome,可以從這裡下載安裝:Wretch Album Expander for Google Chrome or FireFox,平時自己偶而會看看無名小站,所以也是方便自己觀看照片,此 script 也可以安裝在 FireFox 喔。這樣大家就不用再看圖片還要一張一張慢慢點,只要負責按換頁就可以了 ^^。 來測試看看,隨便找一本無名相簿:馬甲‧小葵 ,畫面:點我觀看

phpBB 3.1 版本將不再支援 PHP4

phpBB 官方網站看到這篇:『phpBB 3.1 to discontinue support for PHP versions below 5.2』,內容大致上是說 phpBB 3.0 “Olympus” 系列的版本將是 phpBB 支援 php 4 最後一個版本,之後所推出的 phpBB 3.1 “Ascraeus” 版本,PHP 需要 5.2 或者是更高才可以正確執行。隨著 3.1 版本的推出,3.0 將會繼續維護 6~9 個月的時間,這版本將會繼續維持相容於 php 4 系統。 由於 phpBB 3.1 還處於開發的階段,尚未決定發佈日期,所以大家還是有很多時間可以將 php 升級到 5.2.0 或者是更高。看到 phpBB 可以捨棄 php 4 還蠻高興的,自己本身玩 phpBB 多年,看到 2.0 到 3.0 的變化蠻大的,php 4 安全姓做的非常不好,所以導致 code 非常隴長,希望 3.1 可以快點推出。