2015年12月23日 星期三

Broadcom BCM943142HM Bluetooth A2DP on Ubuntu15.10

Wifi:
Just install the restricted drivers

Bluetooth:(Alternative Link)
Method 1.
                a. Download Bluetooth hcd
                b. sudo cp "xxx.hcd" /lib/firmware/brcm/BCM.hcd
                c. sudo modprob -r btusb
                d. sudo modprob btusb
Method 2.
                a. Try to get BCMxxx.hex from windows OS(C:\windows\system\driver)
                b. git clone git://github.com/jessesung/hex2hcd.git
                c. cd hex2hcd
                d. make
                e. ./hex2hcd BCMxxx.hex BCM.hcd
                f. sudo cp "BCM.hcd" /lib/firmware/brcm/
                g. sudo modprob -r btusb
                h. sudo modprob btusb


PS: 12/24  測試A2DP(參考),Ubuntu建議安裝blueman, pavucontrol
由於我是使用Ubuntu gnome以及Pulseaudio因此其他DM我不確定是否也能使用步驟2,3
1. sudo apt-get install blueman, pavucontrol

2. sudo vim /var/lib/gdm/.config/pulse/client.conf (沒有的話直接新增)
    然後將以下內容貼上:
    autospawn = no                                                       
    daemon-binary = /bin/true

3. sudo chown gdm:gdm /var/lib/gdm/.config/pulse/client.conf
    (看你用哪種DM就試試看改成你使用的(把gdm改掉))

4. sudo vim /etc/pulse/default.pa
    新增:
    load-module module-switch-on-connect

完成後一定要重新開機,並且使用blueman來連線,使用pavucontrol改聲音設定


--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
另一個解法(source):
Edit the file:
/etc/pulse/default.pa
and comment out (with an # at the beginning of the line) the following line:
#load-module module-bluetooth-discover
now edit the file:
/usr/bin/start-pulseaudio-x11
and after the lines:
   if [ x”$SESSION_MANAGER” != x ] ; then
        /usr/bin/pactl load-module module-x11-xsmp “display=$DISPLAY session_manager=$SESSION_MANAGER” > /dev/null
    fi
add the following line:
    /usr/bin/pactl load-module module-bluetooth-discover
This way the Pulse audio’s Bluetooth modules will not be downloaded at boot time but after x11 is started.

2014年1月6日 星期一

使用raspberry pi與openelec打造家庭影劇中心

自從買了Raspberry Pi以後,除了想拿它來架設伺服器以外,還想用來打造家中的數位影劇中心,一個1000左右的嵌入式裝置搭配網路與XBMC絕對是最前衛的一件事。

自從安裝了Openelec系統後發現運行效率似乎不是非常流暢,感覺還是會卡卡的。從openelec的論壇發現有人把開機系統安裝在SD卡以後,將SD的保護上鎖,然後再用隨身碟當作data。加上超頻後,整個脫胎換骨,於是我躍躍欲試,以下則是操作安裝流程

準備工具:
Raspberry Pi x1
無線網卡ASUS USB-N10 x1(Openelec有支援)
SD 卡 x1
隨身碟 x1
螢幕鍵盤
PC windows or linux(prefer)

1.格式化SD卡,整個系統只需要約150MB的空間(FAT32),單一主分割、標籤設為system目前我是用class 4的SD,若要更好的效能,推薦使用class 10的

2.隨身碟格式化為ext4,標籤設為storage,可以使用整個空間

3.從openlec網站下載raspberry pi版的系統

4.下載後解壓縮到SD卡

5.將所有資料夾內的檔案全部移到SD卡的根目錄

6.將KERNEL改名為kernel.img

7.新增一個名為cmdline的純文字檔,若是在windows下面創立,則不用加上txt的附檔名,否則開機會出錯

8.在cmdline填上
boot=/dev/mmcblk0p1 disk=/dev/sda1 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 ssh
(ps1)

9.SD卡上鎖,將SD卡上做邊的小卡榫扳到相對下的位置,即可禁止系統寫入

10.將SD卡與隨身碟安裝置raspberry pi上,開機!

ps1:將系統安裝在SD並且設定成唯讀,後將資料移到隨身碟上,據說可以提高速度
然後有人說指定的開機位置應該要用UUID這樣安裝多個儲存裝置的時候才不會誤認
找出UUID必須在linux下面查詢。以我目前的SD卡UUID為6465-7197,隨身碟為b1ed9383-b10a-cf01-806d-9383b10acf01,因此將cmdline改為:
boot=UUID=6465-7197 disk=UUID= b1ed9383-b10a-cf01-806d-9383b10acf01 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 ssh

PS2: For more information
thread1
thread2


2013年12月31日 星期二

使用no-ip申請域名讓浮動IP也能架設網站

一般架設網站使用固定IP可以減少很多不便,但是一般家庭網路如果再申辦網路的時候沒有特別要求,通常都會是浮動IP,這對於想在家中架設簡單的伺服器或是網站的時候回有許多的不便。

目前有許多網路公司有提供域名的服務,可以實現DDNS,不過大部分都是要付費的,在沒有經費許可下我選擇使用no-ip提供的免費域名將就使用。

Step1. 到no-ip網站註冊http://www.noip.com/

Step2.點選Host/Redirects增加一個域名

  • Hostname隨便打
  • Host Type 一般使用第一個
  • IP Address應該會自動偵測你所在的網路對外的IP


Step3.


  • 沒有IP分享器,或套件庫有noip2
如果網路環境是望路線直接連上internet可以參考這篇的作法(安裝noip2)
http://spyker729.blogspot.tw/2011/03/ubuntu-no-ip.html


  • 使用IP分享器(使用ddclient)
你所使用的IP分享器需要有支援DDNS的功能,而且還需要有支援no-ip的登入,如果沒有的話就試試Dyndns的方式登入。(我使用的是TP-link TL-WR1043)

本機電腦安裝ddclient

  • 設定ddclient
打開 /etc/ddclient.conf



# /etc/ddclient.conf

protocol=no-ip
use=web, web=checkip.dyndns.com/
server=dynupdate.no-ip.com
login=mylogin                      #輸入noip的帳號
password='mypassword'              #輸入noip的密碼
myhost.no-ip.biz                   #輸入預先設定的HOST全名
然後在命令列下
service ddclient restart重新啟動

2013年12月25日 星期三

XBMC --- The best media center for free

前言:
XBMC (Xbox Media Center)源於XBOX的一個家庭媒體撥放中心軟體,目前已開源並且被移植到一般家用電腦,不論何種系統Windows、Mac、Linux現在均可完美執行。近期智慧型手機與平板的盛行,XBMC也可順利在其裝置上執行。此軟體有著任何格式都可撥放,以及豐富的網路資源,使我們很容易的就可以在自家中建立一個家庭多媒體中心。此篇文章將簡單描述如何在各裝置中安裝XBMC軟體,並且於安裝完成的第一時間建構豐富的資源來"免費"觀賞影音。


A. 安裝XBMC軟體
 至官方網站下載相對應軟體http://xbmc.org/download/並且按照安裝步驟即可完成安裝手續

B. 安裝各種資源外掛
XBMC有著豐富的外掛資源(Add-on),但是若要一個一個加入就太耗費精神與時間。
所幸有些網站有整理一次安裝的方法,來方便我們設定。

a.)XBMCHUB的教學文

Step 1: Navigate to the “File manager” tab under the “SYSTEM” menu heading.選擇SYSTEM下的File manager
Screen Shot 2013 12 15 at 2.54.10 PM How To Use the XBMCHUB.COM Configuration Wizard Addon for Dummies (and see Mount Rushmore from XBMC)
Step 2: Click on the “Add Source” function on the left side of the screen.點選Add Source
Screen Shot 2013 12 15 at 2.54.13 PM How To Use the XBMCHUB.COM Configuration Wizard Addon for Dummies (and see Mount Rushmore from XBMC)
Step 3: Choose the first input box which says “<None>” at the top of the popup window, under where it says the “Enter the paths or browse for the media locations” first.
Screen Shot 2013 12 15 at 2.54.16 PM How To Use the XBMCHUB.COM Configuration Wizard Addon for Dummies (and see Mount Rushmore from XBMC)
Step 4: Using the on-screen keyboard, enter “http://fusion.xbmchub.com” (without quotations) then press the “Done” button on the left side of the keyboard. If you’re having trouble finding the colon or the slashes, just click the “Symbols” button the keyboard to see them displayed.點選<None>並且輸入 http://fusion.xbmchub.com
Screen Shot 2013 12 15 at 2.54.22 PM How To Use the XBMCHUB.COM Configuration Wizard Addon for Dummies (and see Mount Rushmore from XBMC)
Step 5: Select the second input box at the bottom of the popup window under where it says “Enter the name for this media Source” next.隨便命名(fusion為例子)
Screen Shot 2013 12 15 at 2.54.25 PM How To Use the XBMCHUB.COM Configuration Wizard Addon for Dummies (and see Mount Rushmore from XBMC)
Step 6: Type in “fusion” (without quotations) on the on-screen keyboard, then press the “Done” button to save it.
Screen Shot 2013 12 15 at 2.54.28 PM How To Use the XBMCHUB.COM Configuration Wizard Addon for Dummies (and see Mount Rushmore from XBMC)
Step 7: Click on the “OK” button at the bottom of the popup window to save the source you’ve just added.
Screen Shot 2013 12 15 at 2.54.30 PM How To Use the XBMCHUB.COM Configuration Wizard Addon for Dummies (and see Mount Rushmore from XBMC)
Step 8: Verify that your “File manager” screen now looks similar to the one below, with “fusion” listed on the left side of the window, then return to the main menu.
Screen Shot 2013 12 15 at 2.54.34 PM How To Use the XBMCHUB.COM Configuration Wizard Addon for Dummies (and see Mount Rushmore from XBMC)
Step 9: Click on the “Settings” tab under the “SYSTEM” menu heading.選擇並且進入SYSTEM
Screen Shot 2013 12 15 at 2.54.38 PM How To Use the XBMCHUB.COM Configuration Wizard Addon for Dummies (and see Mount Rushmore from XBMC)
Step 10: Choose the “Add-ons” option from the left side menu bar, and click “Ok” if prompted with a first-use message.點擊Add-ons
Screen Shot 2013 12 15 at 2.54.41 PM How To Use the XBMCHUB.COM Configuration Wizard Addon for Dummies (and see Mount Rushmore from XBMC)
Screen Shot 2013 12 15 at 2.54.43 PM How To Use the XBMCHUB.COM Configuration Wizard Addon for Dummies (and see Mount Rushmore from XBMC)
Step 11: Click on the “Install from zip file” function from the listing.點擊Install from zip
Screen Shot 2013 12 15 at 2.54.45 PM How To Use the XBMCHUB.COM Configuration Wizard Addon for Dummies (and see Mount Rushmore from XBMC)
Step 12: Open the “fusion” server based folder on the right side of the screen.選擇剛剛加入的來源
Screen Shot 2013 12 15 at 2.54.48 PM How To Use the XBMCHUB.COM Configuration Wizard Addon for Dummies (and see Mount Rushmore from XBMC)
Step 13: Select the “hub-wizard” folder from the listed options.進入hub-wizard
Screen Shot 2013 12 15 at 2.54.51 PM How To Use the XBMCHUB.COM Configuration Wizard Addon for Dummies (and see Mount Rushmore from XBMC)
Step 14: Click on the “plugin.video.hubwizard-1.0.9.zip” item from the listing, then wait a few seconds for it to download.先安裝hubwizard
Screen Shot 2013 12 15 at 2.54.55 PM How To Use the XBMCHUB.COM Configuration Wizard Addon for Dummies (and see Mount Rushmore from XBMC)
Step 15: Return to the main menu, then navigate to the “PROGRAMS” menu.到主畫面點擊PROGRAM
Screen Shot 2013 12 15 at 2.55.07 PM How To Use the XBMCHUB.COM Configuration Wizard Addon for Dummies (and see Mount Rushmore from XBMC)
Step 16: Click on the “XBMCHUB.com  Wizard” addon at this point.
Screen Shot 2013 12 15 at 2.55.09 PM How To Use the XBMCHUB.COM Configuration Wizard Addon for Dummies (and see Mount Rushmore from XBMC)
Step 17: Select your desired platform, although it doesn’t really matter which one you choose, they are all pretty much universal.選擇安裝相對應的系統的選項
Screen Shot 2013 12 15 at 2.55.21 PM How To Use the XBMCHUB.COM Configuration Wizard Addon for Dummies (and see Mount Rushmore from XBMC)
Step 18: When prompted, agree to any warnings by clicking the “Yes” button to continue.
Screen Shot 2013 12 15 at 2.55.24 PM How To Use the XBMCHUB.COM Configuration Wizard Addon for Dummies (and see Mount Rushmore from XBMC)
Step 19: You’ll now have to wait about six minutes for the process to complete, don’t touch anything while this takes place, sometimes it could be a bit slow but it’s working.
Screen Shot 2013 12 15 at 2.56.31 PM How To Use the XBMCHUB.COM Configuration Wizard Addon for Dummies (and see Mount Rushmore from XBMC)
Step 20: Once returned to the main menu, click on the little power looking icon at the bottom left of the screen, next to the star icon.
Screen Shot 2013 12 15 at 2.58.42 PM How To Use the XBMCHUB.COM Configuration Wizard Addon for Dummies (and see Mount Rushmore from XBMC)
Step 21: Click on the “Exit” function once prompted, then wait a few seconds for XBMC to close.
Screen Shot 2013 12 15 at 2.58.44 PM How To Use the XBMCHUB.COM Configuration Wizard Addon for Dummies (and see Mount Rushmore from XBMC)
Step 22: Launch the “XBMC” application, this time you’ll see it configured in all its splendor.離開XBMC並且重新啟動

根據以上設定後重新進入XBMC軟體,將會發現介面有些許不同,代表已經安裝好各種網路外掛,若要欣賞影片,則點擊Videos底下的Add-ons進入,將有許多來源可以使用。(請自行探索)
PS:若想要有中文資源,對岸也有論壇可以尋找http://www.hdpfans.com/

C.更改語言介面,可以上網搜尋"XBMC 中文介面"按照教學設定

########################################################################
智慧型手機充當遙控器
假設XBMC已經安裝好,則可以更進一步將擁有的智慧型手機透過相同網域的區域網路來遠端遙控XBMC軟體。
a.)先在手機或平板安裝遙控軟體
Android:

IOS:

b.)XBMC主程式設定
1.進入XBMC的SYSTEM點擊Service
2.選擇Webserver並且致能右邊的選項,可以自行設定相對應port(預設80),與登入名稱和密碼(此兩項可空白)
3.跳回主畫面,選擇SYSTEM目錄下的system info副目錄
4.選擇Network即可得知IP
5.記住IP、port、username、password並且設定手機的遙控軟體


2013年9月6日 星期五

Raspberry PI 系統安裝+網路設定


系統安裝 (Window系統):





1.  下載 Raspberry PI 的映像檔,至 Raspberry PI的官方網站「http://www.raspberrypi.org/downloads」下載,選擇  2013-07-26-wheezy-raspbian.zip 的檔案,並解壓縮
(其中官網提供四種作業系統讓使用者下載,參考此網址介紹 http://life-of-raspberrypi.blogspot.tw/2013/01/raspberry-pi-sd-14-raspbian.html )

2.  下載 Win32DiskImage 來進行燒錄至SD卡中,可至「http://sourceforge.net/projects/win32diskimager/」下載,並解壓縮

3.  解壓縮後,開啟資料夾,找到「 Win32DiskImage 」執行檔,先不執行

4.  將SD卡插入電腦主機,並觀察SD卡在哪個磁碟機   ( 在此為「 F:\ 」)

5.  開始執行 Win32DiskImage,在「Device」為「 F:\ 」,「Image File」為「D:/gina/Raspberry Pi/2013-07-26-wheezy-raspbian.img」 ( 指向映像檔本體 ),再按下「Write」開始燒寫

6.  最後將SD卡插回 Raspberry PI ,即可開機

********************************************************************************

開機完畢後,要進入系統時,必須先須入帳號密碼
帳號:pi  密碼:raspberry  (此為原先的設置帳號密碼,之後可做更換)

每次開機後,必須下達  sudo apt-get  update  指令來進行韌體更新

********************************************************************************

網路設定:

1.  首先,進入  /etc/network/interfaces  此目錄中:

>>   sudo nano /etc/network/interfaces  

     將內文改寫成:

        iface eth0 inet static    (手動設定)
        address   120.101.9.xxx   (IP位置設定)
        netmask  255.255.255.0   (網路遮罩設定)
        gateway  120.101.9.xxx   (預設閘道設定)

    ctrl+o 存檔   ctrl+x離開檔案













2.  接著設定DNS,進入 /etc/resolv.conf  目錄中

>>   sudo nano  /etc/resolv.conf 

    新增 nameserver 120.101.0.1

    ctrl+o 存檔   ctrl+x離開檔案









3.  檢查是否確實有網路

>>   ifconfig 





2013年8月19日 星期一

指向函數的指標(pointer to function)(aka: Function Pointer) V.S. 傳回指標的函數(function return a pointer)

From: 指標的藝術

Function Pointer:(指向函數的指標)

int (*pf)(int);

在指標的藝術一書(p.87)中又名Pointer to function。目的是經過宣告後,會有一個指標是指向函數的起始位址,當我們要使用某個函數的時候,只要將此指標指向那個函數,就可使用,其實函數名稱是一個位址,因此只要將函數名稱設定給此指標即可。

使用函數指標的時候必須注意指標的引入與回傳參數是否與原函式匹配,就說原函式引入、回傳的資料型態,引入參數個數,通通要一樣才可以。

例如三個副函式:

(1) int add(int);
(2) float add2(float);
(3) int add3(int,int);

並且宣告一個函式指標:
int (*pf)(int);

則:

(a.) pf = add;     //正確
(b.) pf = add2;   //錯誤,參數資料型態不匹配
(c.) pf = add3;   //錯誤,引入參數個數不匹配

#################################################################################

Function return a pointer:(回傳指標的函數)

int *pf(int); //少了一個括號cf: int (*pf)(int);

表示pf是一個函數,這個函數會引入一個整數型態的參數,經過函數運算後會回傳一個整數型態的指標(回傳的東西是一個位址,假設回傳x,則x可以是指標(x存的內容是指向的位址),也可以是變數的位址,若x是一般變數,則回傳&x;若x是陣列則回傳x。

#################################################################################

typedef與函數指標(from wiki typedef)

Using typedef with function pointers[edit source | editbeta]

Function pointers are somewhat different than all other types because the syntax does not follow the pattern typedef <old type name> <new alias>;. Instead, the new alias for the type appears in the middle between the return type (on the left) and the argument types (on the right). Consider the following code, which does not use a typedef:
int do_math(float arg1, int arg2) {
    return arg2;
}
 
int call_a_func(int (*call_this)(float, int)) {
    int output = call_this(5.5, 7);
    return output;
}
 
int final_result = call_a_func(do_math);
This code can be rewritten with a typedef as follows:
typedef int (*MathFunc)(float, int);
 
int do_math(float arg1, int arg2) {
    return arg2;
}
 
int call_a_func(MathFunc call_this) {
    int output = call_this(5.5, 7);
    return output;
}
 
int final_result = call_a_func(do_math);
Here, MathFunc is the new alias for the type. A MathFunc is a pointer to a function that returns an integer and takes as arguments a float followed by an integer.

typedef int (*MathFunc)(float, int);是別名的宣告,就只是在最前面加上typedef則以後就可以只用MathFunc這樣的名稱來宣告同類型的函數指標。


2013年8月16日 星期五

typedef用法

typedef用法小結- -
這兩天在看程序的時候,發現很多地方都用到typedef,在結構體定義,還有一些數組等地方都大量的用到.但是有些地方還不是很清楚,今天下午,就想好好研究一下.上網搜了一下,有不少資料.歸納一下

來源一:Using typedef to Curb Miscreant Code
Typedef
聲明有助於創建平台無關類型,甚至能隱藏複雜和難以理解的語法。不管怎樣,使用typedef能為代碼帶來意想不到的好處,通過本文你可以學習用typedef避免缺欠,從而使代碼更健壯。

typedef
聲明,簡稱typedef,為現有類型創建一個新的名字。比如人們常常使用typedef來編寫更美觀和可讀的代碼。所謂美觀,意指typedef能隱藏笨拙的語法構造以及平台相關的數據類型,從而增強可移植性和以及未來的可維護性。本文下面將竭盡全力來揭示typedef強大功能以及如何避免一些常見的陷阱。

如何創建平台無關的數據類型,隱藏笨拙且難以理解的語法?
使用typedefs為現有類型創建同義字。
定義易於記憶的類型名
  typedef
使用最多的地方是創建易於記憶的類型名,用它來歸檔程序員的意圖。類型出現在所聲明的變量名字中,位於''typedef''關鍵字右邊。例如:
typedef int size;
 
此聲明定義了一個int的同義字,名字為size。注意typedef並不創建新的類型。它僅僅為現有類型添加一個同義字。你可以在任何需要int的上下文中使用size
void measure(size * psz);
size array[4];
size len = file.getlength();
std::vector vs;
  typedef
還可以掩飾符合類型,如指針和數組。例如,你不用像下面這樣重複定義有81個字符元素的數組:
char line[81];
char text[81];
定義一個typedef,每當要用到相同類型和大小的數組時,可以這樣:
typedef char Line[81];
Line text, secondline;
getline(text);
同樣,可以像下面這樣隱藏指針語法:
typedef char * pstr;
int mystrcmp(pstr, pstr);
 
這裡將帶我們到達第一個typedef陷阱。標準函數strcmp()有兩個'const char *'類型的參數。因此,它可能會誤導人們像下面這樣聲明mystrcmp()
int mystrcmp(const pstr, const pstr);
 
這是錯誤的,按照順序,'const pstr'被解釋為'char * const'(一個指向char的常量指針),而不是'const char *'(指向常量char的指針)。這個問題很容易解決:
typedef const char * cpstr;
int mystrcmp(cpstr, cpstr); //
現在是正確的
記住:不管什麼時候,只要為指針聲明typedef,那麼都要在最終的typedef名稱中加一個const,以使得該指針本身是常量,而不是對象。

代碼簡化
 
上面討論的typedef行為有點像#define宏,用其實際類型替代同義字。不同點是typedef在編譯時被解釋,因此讓編譯器來應付超越預處理器能力的文本替換。例如:
typedef int (*PF) (const char *, const char *);
 
這個聲明引入了PF類型作為函數指針的同義字,該函數有兩個const char *類型的參數以及一個int類型的返回值。如果要使用下列形式的函數聲明,那麼上述這個typedef是不可或缺的:
PF Register(PF pf);
  Register()
的參數是一個PF類型的回調函數,返回某個函數的地址,其署名與先前註冊的名字相同。做一次深呼吸。下面我展示一下如果不用typedef,我們是如何實現這個聲明的:
int (*Register (int (*pf)(const char *, const char *)))
(const char *, const char *);
 
很少有程序員理解它是什麼意思,更不用說這種費解的代碼所帶來的出錯風險了。顯然,這裡使用typedef不是一種特權,而是一種必需。持懷疑態度的人可能會問:"OK,有人還會寫這樣的代碼嗎?",快速瀏覽一下揭示signal()函數的頭文件,一個有同樣接口的函數。

typedef
和存儲類關鍵字(storage class specifier
 
這種說法是不是有點令人驚訝,typedef就像autoexternmutablestatic,和register一樣,是一個存儲類關鍵字。這並是說typedef會真正影響對象的存儲特性;它只是說在語句構成上,typedef聲明看起來象staticextern等類型的變量聲明。

下面將帶到第二個陷阱:
typedef register int FAST_COUNTER; //
錯誤
 
編譯通不過。問題出在你不能在聲明中有多個存儲類關鍵字。因為符號typedef已經佔據了存儲類關鍵字的位置,在typedef聲明中不能用register(或任何其它存儲類關鍵字)。
促進跨平台開發
  typedef
有另外一個重要的用途,那就是定義機器無關的類型,例如,你可以定義一個叫REAL的浮點類型,在目標機器上它可以i獲得最高的精度:
typedef long double REAL;
在不支持long double的機器上,該typedef看起來會是下面這樣:
typedef double REAL;
並且,在連double都不支持的機器上,該typedef看起來會是這樣:
typedef float REAL; 


  
你不用對源代碼做任何修改,便可以在每一種平台上編譯這個使用REAL類型的應用程序。唯一要改的是typedef本身。在大多數情況下,甚至這個微小的變動完全都可以通過奇妙的條件編譯來自動實現。不是嗎?標準庫廣泛地使用typedef來創建這樣的平台無關類型:size_tptrdifffpos_t就是其中的例子。此外,象std::stringstd::ofstream這樣的typedef還隱藏了長長的,難以理解的模板特化語法,例如:basic_stringallocator>basic_ofstream>


來源二:( http://www.ccfans.net/bbs/dispbbs.asp?boardid=30&;id=4455 )
C
語言中typedef用法
1.
基本解釋
  typedef
C語言的關鍵字,作用是為一種數據類型定義一個新名字。這裡的數據類型包括內部數據類型(int,char等)和自定義的數據類型(struct等)。
 
在編程中使用typedef目的一般有兩個,一個是給變量一個易記且意義明確的新名字,另一個是簡化一些比較複雜的類型聲明。

 
至於typedef有什麼微妙之處,請你接著看下面對幾個問題的具體闡述。

2. typedef &
結構的問題
 
當用下面的代碼定義一個結構時,編譯器報了一個錯誤,為什麼呢?莫非C語言不允許在結構中包含指向它自己的指針嗎?請你先猜想一下,然後看下文說明:
typedef struct tagNode
{
char *pItem;
pNode pNext;
} *pNode; 


 
答案與分析:
  1
typedef的最簡單使用
typedef long byte_4;
 
給已知數據類型long起個新名字,叫byte_4


  2
typedef與結構結合使用
typedef struct tagMyStruct
{
int iNum;
long lLength;
} MyStruct; 


 
這語句實際上完成兩個操作:
  1)
定義一個新的結構類型
struct tagMyStruct
{
int iNum;
long lLength ;
};
 
分析:tagMyStruct稱為“tag”,即標籤,實際上是一個臨時名字,struct關鍵字和tagMyStruct一起,構成了這個結構類型,不論是否有typedef,這個結構都存在。
 
我們可以用struct tagMyStruct varName來定義變量,但要注意,使用tagMyStruct varName來定義變量是不對的,因為structtagMyStruct合在一起才能表示一個結構類型。

  2) typedef
為這個新的結構起了一個名字,叫MyStruct
typedef struct tagMyStruct MyStruct;
 
因此,MyStruct實際上相當於struct tagMyStruct,我們可以使用MyStruct varName來定義變量。
 
答案與分析
  C
語言當然允許在結構中包含指向它自己的指針,我們可以在建立鍊錶等數據結構的實現上看到無數這樣的例子,上述代碼的根本問題在於typedef的應用。
 
根據我們上面的闡述可以知道:新結構建立的過程中遇到了pNext域的聲明,類型是pNode,要知道pNode表示的是類型的新名字,那麼在類型本身還沒有建立完成的時候,這個類型的新名字也還不存在,也就是說這個時候編譯器根本不認識pNode
 
解決這個問題的方法有多種:
  1)

typedef struct tagNode
{
char *pItem;
struct tagNode *pNext;
} *pNode; 


  2)

typedef struct tagNode *pNode;
struct tagNode
{
char *pItem;
pNode pNext;
};
 
注意:在這個例子中,你用typedef給一個還未完全聲明的類型起新名字。C語言編譯器支持這種做法。

  3)
、規範做法:
struct tagNode
{
char *pItem;
struct tagNode *pNext;
};
typedef struct tagNode *pNode; 



3. typedef & #define
的問題
 
有下面兩種定義pStr數據類型的方法,兩者有什麼不同?哪一種更好一點?
typedef char *pStr;
#define pStr char *;
 
答案與分析:
 
通常講,typedef要比#define要好,特別是在有指針的場合。請看例子:
typedef char *pStr1;
#define pStr2 char *;
pStr1 s1, s2;
pStr2 s3, s4;
 
在上述的變量定義中,s1s2s3都被定義為char *,而s4則定義成了char,不是我們所預期的指針變量,根本原因就在於#define只是簡單的字符串替換而typedef則是為一個類型起新名字。
  #define
用法例子:
#define f(x) x*x
main( )
{
int a=6
b=2c
c=f(a) / f(b)

printf("%d \\n"
c)
}
 
以下程序的輸出結果是: 36
 
因為如此原因,在許多C語言編程規範中提到使用#define定義時,如果定義中包含表達式,必須使用括號,則上述定義應該如下定義才對:
#define f(x) (x*x)
 
當然,如果你使用typedef就沒有這樣的問題。


  4. typedef & #define
的另一例
 
下面的代碼中編譯器會報一個錯誤,你知道是哪個語句錯了嗎?
typedef char * pStr;
char string[4] = "abc";
const char *p1 = string;
const pStr p2 = string;
p1++;
p2++;
 
答案與分析:
 
p2++出錯了。這個問題再一次提醒我們:typedef#define不同,它不是簡單的文本替換。上述代碼中const pStr p2並不等於const char * p2const pStr p2const long x本質上沒有區別,都是對變量進行只讀限制,只不過此處變量p2的數據類型是我們自己定義的而不是系統固有類型而已。因此,const pStr p2的含義是:限定數據類型為char *的變量p2為只讀,因此p2++錯誤。

  #define
typedef引申談
  1) #define
宏定義有一個特別的長處:可以使用#ifdef ,#ifndef等來進行邏輯判斷,還可以使用#undef來取消定義。

  2) typedef
也有一個特別的長處:它符合範圍規則,使用typedef定義的變量類型其作用範圍限制在所定義的函數或者文件內(取決於此變量定義的位置),而宏定義則沒有這種特性。


  5. typedef &
複雜的變量聲明
 
在編程實踐中,尤其是看別人代碼的時候,常常會遇到比較複雜的變量聲明,使用typedef作簡化自有其價值,比如:
 
下面是三個變量的聲明,我想使用typdef分別給它們定義一個別名,請問該如何做?
>1
int *(*a[5])(int, char*);
>2
void (*b[10]) (void (*)());
>3. doube(*)() (* pa)[9]; 


 
答案與分析:
 
對複雜變量建立一個類型別名的方法很簡單,你只要在傳統的變量聲明表達式裡用類型名替代變量名,然後把關鍵字typedef加在該語句的開頭就行了。

>1
int *(*a[5])(int, char*);
//pFun
是我們建的一個類型別名
typedef int *(*pFun)(int, char*);
//
使用定義的新類型來聲明對象,等價於int* (*a[5])(int, char*);
pFun a[5]; 


>2
void (*b[10]) (void (*)());
/ /
首先為上面表達式藍色部分聲明一個新類型
typedef void (*pFunParam)();
//
整體聲明一個新類型
typedef void (*pFun)(pFunParam);
//
使用定義的新類型來聲明對象,等價於void (*b[10]) (void (*)());
pFun b[10]; 


>3. doube(*)() (*pa)[9];
//
首先為上面表達式藍色部分聲明一個新類型
typedef double(*pFun)();
//
整體聲明一個新類型
typedef pFun (*pFunParam)[9];
//
使用定義的新類型來聲明對象,等價於doube(* )() (*pa)[9];
pFunParam pa;