Feed on
Posts
Comments

[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 可以快點推出。

Google Chrome 推出 4.0 穩定版 & Mozilla 推出 FireFox 3.6

Mozilla 在上禮拜 (2010.01.22) 推出了 FireFox 3.6,大家可以下載測試效能如何,也可以 follow 狐耳摩莎的 Plurk 來收到 MozTW 的最新資訊,這篇重點不是在 FireFox,而是 Google 正式推出 Windows 版本 new Chrome 4.0 stable release,4.0 版本已經可以正式使用 Google Extensions,之前在3.0版本,只能安裝 Chrome Beta 版本才可以使用 extension,現在只要將 Windows Google Chrome 升級成 Stable 版本,就可以全面使用 Extensions,可以使用手動升級,或者是在下禮拜就會自動 update 到最新版本。

Google Chrome 4.0 (by appleboy46)

最後可以參考 ericsk 大大所寫的從開發者角度看 Chrome 4 的推出

Reference:
Extensibility + new HTML and JavaScript APIs for Google Chrome
More Resources for Developers

How to change run levels and init.d scripts in Ubuntu & Debian

Ubuntu 6.10 (Edgy Eft) 之後使用 Upstart 代替原來的 sysinit,而 init 是用來管理 Upstart 的 Daemon,本來系統預設的 runlevel 可以在 /boot/menu.list 或者是 /etc/inittab,可是現在這檔案已經移除了,取而代之的就是 Upstart 管理,可以利用 telinit 來改變系統 runlevel,然而現在 runlevel 的定義跟以前不太一樣了,原先 Ubuntu 跟 Fedora 系列 runlevel 代表意義如下:

0:系統關機 (to halt the system)
1:單一使用者模式 (single-user mode)
2:尚未使用(可由使用者定義)
3:多使用者模式 (文字介面登入)
4:尚未使用 (可由使用者定義)
5:多使用者模式 (含有一個X介面的登入畫面)
6:重新開機 (reboot the system)

轉換成 Upstart 的話,就會變成底下

0:系統關機 (to halt the system)
1:單一使用者模式 (single-user mode)
2:多使用者模式 (含有一個X介面的登入畫面)
3:多使用者模式 (含有一個X介面的登入畫面)
4:多使用者模式 (含有一個X介面的登入畫面)
5:多使用者模式 (含有一個X介面的登入畫面)
6:重新開機(reboot the system)

上面資訊可以在 man telinit 裡面找到,寫得很詳細,現在 Ubuntu 9.10 系統,預設啟用是在 runlevel 2,只要執行 runlevle 指令,就可以查出先前跟目前所設定的 runlevel 值,這些數值是存放在 /var/run/utmp,這是一個 UTMP File,你會發現,現在只要安裝好 Ubuntu Desktop 系統,就會自動啟動,所以常常會看到 Linux 使用者會來詢問如何關閉 gdm 桌面程式,其實有很多手動的方式,init 也管理了開機所需執行的程式,如果是跑 runlevel 2,就會去執行 /etc/rc2.d/* 底下所有的 script 檔案,所以大家可以發現會有 /etc/rcX.d/ (X:0,1,2,3,4,5,6,S),其中的 S 代表 single user mode,我們用 rc2.d 底下的檔案來說明:
/ect/rcX.d/ all script (by appleboy46)
大家可以看到,每個檔案命名方式:[S|K]\d{2}script_name,S 代表開機會啟動,K 代表開機不啟動,後面接兩位數字,代表開機優先權順序,這些檔案都是利用 Soft link 方式連接到 /etc/init.d/ 底下,所以修改 /etc/init.d/ 資料夾檔案內容,就可以自動更新 /etc/rc[0-6].d/ 檔案,相當方便吧,那該如何產生對應檔案到 /etc/rc[0-6].d/ 資料夾底下,可以利用 update-rc.d 這指令,update-rc.d 是用來產生或移除 init script links,可以參考 Debian Policy Manual

如何使用 update-rc.d 管理 init script links

利用系統預設值來新增 script links,預設值啟動 runlevels 2-5 跟停止於 runlevels 0, 1 and 6

update-rc.d script_name defaults

或者是可以自行設定執行優先順序跟自訂啟動 runlevel (ps. 請注意後面都有 . 符號)

update-rc.d script_name start 20 2 3 4 5 . stop 20 0 1 6 .

移除這些 script links (-f 參數代表強制移除)

update-rc.d -f script_name remove

2010-01-28 11 52 06 (by appleboy46)
可以看到在 runlevel 0126 是不啟動,345 是啟動 gdm 狀態,在 Ubuntu 9.10 底下,如果不想要開機就執行桌面程式,那就是必須要把 gdm 關閉,可以用下面兩種 command line 關閉

/etc/init.d/gdm stop
service gdm stop

但是這兩種方式只會在開機後手動執行,大家需要的是開機不會啟動,當然可以寫到 /etc/rc.local,因為在 rcX.d 底下會有 S99rc.local 執行,底下分享一下如何修改開機 runlevel,預設值是 2,但是之前都是另用 /etc//inittab 方式來修改,那其實現在這檔案消失了,您也可以自行新增喔,請先看 /etc/init/rc-sysinit.conf

# Default runlevel, this may be overriden on the kernel command-line
# or by faking an old /etc/inittab entry
env DEFAULT_RUNLEVEL=2

在這裡就可以修改系統 runlevel,註解也有說明,可以新增 /etc/inittab 來讓系統讀取其內容

id:2:initdefault:

最後也是會讀取 /etc/inittab

# Check for default runlevel in /etc/inittab
if [ -r /etc/inittab ]
then
    eval "$(sed -nre 's/^[^#][^:]*:([0-6sS]):initdefault:.*/DEFAULT_RUNLEVEL="\1";/p' /etc/inittab || true)"
fi

所以最後還是會依照 /etc/inittab 寫入的資訊來判斷系統 runlevel,最後才會去執行 rcX.d 所有 script 檔案。不想執行桌面程式,會在網路上找到利用

update-rc.d gdm stop 20 0 1 2 3 4 5 6 .

這樣正常來說不會去啟動 gdm 才對,可是實驗結果,還是會繼續啟動,後來找到 /etc/init/gdm.conf 底下這段程式碼:

start on (filesystem
          and started hal
          and tty-device-added KERNEL=tty7
          and (graphics-device-added or stopped udevtrigger))
stop on runlevel [016]

把 stop on runlevel [016] 改成 stop on runlevel [0123456] 這樣就可以了

參考網站:
Choosing different run level in Ubuntu
upstart 和ubuntu启动过程原理介绍
[Linux]ubuntu下修改服務的執行等級
[ubuntu] Need to disable gdm

遲來的 jQuery 1.4 Released

為了慶祝 jQuery 四週年慶,官方網站終於 Release 1.4 版本了,也大幅度修改了 jQuery API 網站,跟以往一樣,jQuery 提供兩種版本讓大家測試跟下載:jQuery Minified (23kb Gzipped),這版本是利用 Google Closure Compiler 去壓縮,以往好像是用 YUI Compressor,另一版本就是沒經過壓縮:jQuery Regular (154kb),當然 Google 也提供了 host 來讓 jQuery 有 cache 檔案作用,增加網站速度:

http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js

1.4 版本的出來,最主要就是效能的改善,以及整個 Code Base 翻修,可以參考 John Resig 寫的 JavaScript Function Call Profiling,看到底下的圖,就大致上知道 1.4 的效能改善
4271690739_f0bced3a78 (by appleboy46)

.css() and .attr() 效能改善圖:
4271691147_fd72853fa4 (by appleboy46)

整篇都在說明 jQuery 效能的部份,真的是改善很多,Media Temple 主機商也贊助 jQuery 14天的徵文活動,大家可以上去看看有很多影片都是在介紹 jQuery,最後得獎的人可以獲得 13″ MacBook Pro,真是太吸引人了。

最後可以參考 黑暗執行緒大大寫的:jQuery 1.4 小閱兵

How to install Google Web Toolkit with Eclipse

Google Web Toolkit (簡稱:GWT)是先以 Java 語言編寫 AJAX 應用程式網頁,然後在編譯成最佳化 Javascript,不但幫助了剛入門 Javascrit,然後又需要撰寫 AJAX 應用程式的工程師很大的幫助,不僅如此,Google App Engine 也提供了 Java 跟 Python 環境,整合了 GWT,讓您可以上傳到 GAE 的空間進行測試,GWT 目的是產生具有高效能性的 Web 應用程式,您不需要是 Javascript 專家也可以做到,GWT 用在 Google 相當多的服務,例如 Google Wave, 新版的 Google AdWords 可以參考這裡更多實際範例。它是開放姓原始碼(open source),完全免費,您也可以參與 GWT 的開發。

Google Plugin for Eclipse 支援 Google Web Toolkit 跟 Google App Engine 開發,我們可以直接安裝此 Plugin 就可以開始上手 GWT,當製作完成之後,就可以上傳到 GAE,直接打開提供的網址就可以看到成果了。

首先安裝 Google Plugin for Eclipse,先去下載 Eclipse 3.5 (Galileo) 最新版,打開 Eclipse

1. 選擇 Help -> Install New Software
Google Web Toolkit (by appleboy46)
2. 在 Work With: 填入 http://dl.google.com/eclipse/plugin/3.5
Google Web Toolkit (by appleboy46)
3. 將 Plugin 跟 SDKS 全部選取,接下來按下一步就可以完成

[FreeBSD] Fanout and Fanterm Tool to run commands on multiple machines

在 Linux 或 FreeBSD 系統底下,如何下達 command 來達到多方控管機器,在網路上找到 Fanout and fanterm 這兩套軟體,可以實現我想要的目的,在 FreeBSD 有把 sysutils/fanout 進到 ports 裡面,安裝方式很簡單,就直接 make install clean 就可以了,用法也很簡易:

Usage:
  /usr/local/bin/fanout "MACHINES" "commands and parameters to run on each machine"
  /usr/local/bin/fanout -h      #Show this help
  /usr/local/bin/fanout --noping        # Do not ping before running command

當然事情沒有這麼簡單,因為是透過 SSH 方式去對其他機器下 command,所以作者都把預設 port 設定成 22,沒有完整考慮到其他環境,管理重要的 Server 怎麼會設定 22 阿,一定會改掉的阿,後來檢查一下 /usr/local/bin/fanout 這隻程式,並非編譯過的 binary 檔案,所以打開來看,就是利用 bash shell script 所寫的程式,網路上 Google 也找到一篇 Does anyone know how to specify a ssh port number with fanout? 文章,但是最後我是自己把 bash 改成支援可調整 port,也就是 MACHINES 可以放入:ip:portt or hostname:port

patch 檔案:需要的就拿去 patch 就可以用了

--- /usr/local/bin/fanout   2010-01-08 15:06:47.000000000 +0800
+++ fanout  2010-01-08 15:00:04.000000000 +0800
@@ -53,13 +53,22 @@
 STARTTIME=`date`
 for ONETARGET in $TARGETS ; do
    case $ONETARGET in
-   *@*)                                    #user@machine form
+   *@*)                                    #user@machine:port form
        ONEUSER="-l ${ONETARGET%%@*}"
-       ONEMACH=${ONETARGET##*@}
-       HEADER="==== As ${ONETARGET%%@*} on $ONEMACH ===="
+       SERVER=${ONETARGET##*@}
+       HOST=`echo $SERVER | awk -F: '{ printf $1 }'`
+       PORT=`echo $SERVER | awk -F: '{ printf $2 }'`
+       if [ "$PORT" != "" ]; then
+           ONEPORT="-p ${PORT}"
+       else
+           ONEPORT=""
+       fi
+       ONEMACH=${HOST}
+       HEADER="==== As ${ONEUSER} on $ONEMACH port: ${PORT}===="
        ;;
    *)                                  #just machine form
        ONEUSER=""
+       ONEPORT=""
        ONEMACH=$ONETARGET
        HEADER="==== On $ONEMACH ===="
        ;;
@@ -74,7 +83,7 @@
    if [ "$PING" = "NO" ] || ping -c 3 $ONEMACH >/dev/null 2>/dev/null ; then
        echo Starting $ONETARGET >/dev/stderr               #Machine is reachable
        #Show machine name header, show command output, indented two spaces, save all to a temp file.
-       ( echo $HEADER ; ssh -n $ONEUSER $ONEMACH "$*" | sed -e 's/^/  /' ; echo ) >$TMPFILE &
+       ( echo $HEADER ; ssh $ONEPORT -n $ONEUSER $ONEMACH "$*" | sed -e 's/^/  /' ; echo ) >$TMPFILE &
    else
        echo $ONETARGET unavailable >/dev/stderr            #Machine not responding
        echo $HEADER ; echo "==== Machine unreachable by ping" ; echo >$TMPFILE

Using firebug for firefox 除錯 javascript

在 Web 程式設計,不管是 html 或者是 CSS、甚至 javascript,都可以利用 FireFox Plugin: firebug 來除錯,順便推薦另一套 Web Develper 工具:Web Developer 1.1.8,這兩套都可以玩看看,在網路看自己東華電機學長 gasolin 寫過一篇:3 分鐘學會用 firebug 除錯 ,裡面有一個影片,建議大家看看:影片,如何利用 firebug 來對 javaascript 除錯,介紹了 firebug 優點。底下整理我看到的內容

1. 利用 console.log() 來針對變數除錯

以往都是利用 window.alert() 的方式來看看變數是否正確,現在只要在 javascript 裡面加入 console.log() 針對不同變數取值出來觀看

<script type="text/javascript">
function doThis()
{
  var a = "test";
  var b = [1, 2, 3, 4];
  var c = document.getElementById("li");
  console.log("a is %s ", a);
  console.log(b);
}
</script>

輸出會顯示:

a is test
[1, 2, 3, 4]

2. 印出有圖示的訊息 console.info/console.warn/console.error

<script type="text/javascript">
  function doThis()
  {
    var a = "test";
    var b = [1, 2, 3, 4];
    var c = document.getElementById("li");
    console.log("a is %s ", a);
    console.info(b);
    console.warn(b);
    console.error(b);
  }
</script>

這功能跟 console.log 差不多,只有差在前面有圖示符號,請看下圖:
firebug_01 (by appleboy46)

3. 使用 firebug 除錯 debugger;

<script type="text/javascript">
  function doThis()
  {
    debugger;
    var a = "test";
    var b = [1, 2, 3, 4];
    var c = document.getElementById("li");
    console.log("a is %s ", a);
    console.info(b);
    console.warn(b);
    console.error(b);
  }
</script>

只要在 js 裡面加入 debugger; 就會進行逐步除錯,我想如果寫過 Window form 的使用者,C# ASP.net 最常用的就是逐步徵測錯誤,這功能相當方便,每一行跑了哪些變數,都可以逐一在旁邊顯示喔
firebug_02 (by appleboy46)
大家看到逐步偵錯到第19行,前面變數都會在旁邊顯示喔,原本都是 null。

4. 計算 js 花費時間 console.time/console.timeEnd

<script type="text/javascript">
  function doThis()
  {
    console.time("do this");
    var a = "test";
    var b = [1, 2, 3, 4];
    var c = document.getElementById("li");
    console.timeEnd("do this");
  }
</script>

只要加上 console.time(”do this”); 跟最後 console.timeEnd(”do this”); 就可以在 console 看到執行時間喔,很方便吧。Firebug 還有很多除錯功能,像 CSS 可以直接註解馬上看到結果,這都是 Web 工程師必備的工具。

[PHP Framework] How to implement Plurk API in CodeIgniter

ci_logo2 (by appleboy46)
很開心在12月看到 Plurk Release API 出來,而自己也跟網路上一些朋友合作開發 PHP implementation of Plurk API,Plurk (簡稱噗浪)在台灣這一兩年紅了起來,網路高手分別針對噗浪研究產生非官方的 API,現在官網 Release 出來,提供了 JavaPython 的 Example,我想因為 Plurk 是用 Python 寫出來的,所以提供了範例,但是 API 出來沒多久,roga 就集合了網路一些強者,一起開發了 PHP Plurk API,我也拿了此 API 在實作到 CodeIgniter Framework,讓在使用此套 open source 的使用者可以享用 Plurk API。不過從2009.12.29日之後,Plurk 官網有限制每天只能 call 50.000 次,已經蠻多了,不要操掛 Plurk 的機器阿。
Continue Reading »

 Page 1 of 41  1  2  3  4  5 » ...  Last »