Tuesday, November 27, 2012

開放式課程網站


以下是個人花不少時間蒐集的數位學習網站. 上面有非常大量的數位學習內容, 相信未來還會有能互動的數位學習網站/內容興起.
 
]
### WorldWide
MYOOPS
 
Berkeley
 
MIT
 
Standford 
 
Harvard
 
Utah
 
Washington
 
JHSPH
 
Coursera
 
CodeSchool
 
OCWConsortium
 
### Taiwan
TOCWC
 
NTU
 
NTHU
 
NCTU
 
NCKU
 
NCU
 
KMU

Saturday, November 17, 2012

透過 VPN 買 Android apps FX Plus

本來想要用免費軟體玩 Android, 沒想到還是刷了第一筆 USD 2.99 買個免費軟體(File Explorer)的 sshfs 模組(FX Plus). 這個軟體不只是可以 sshfs 還可以掛雲端硬碟(Google Drive, Dropbox, Box, SkyDrive, SugarSync 前三個測試過). 其實之前用 NFS 掛伺服器的目錄就很好用了, 但是遇到伺服器(Ubuntu)的硬碟是 NTFS|FAT|FAT16 目錄權限會限縮到只有 Owner 可以看, 從 NFS client (Android)看到的就是 Permission denied. 有了 sshfs 就可以遨遊自己的個人目錄(連 symbolic link 也可以進去).

使用 VPN 繞過官商打架.

FX Plus

在 Windows (2003 不可用, XP以上) 上可以使用 win-sshfs.(symbolic link : OK)
http://code.google.com/p/win-sshfs/
接下來就是找windows server 2003 的 sshfs 解法, 對於使用者就可以不一定要用 SAMBA 了. 讓 SAMBA 變成公用目錄或暫存用目錄, 就可以不用 ACL 在那邊傷腦筋.

其實本來是想用 BlueStacks (http://www.pigo.idv.tw/archives/1641) 突破的. 但是在Win XP VM搞半天 BlueStacks 就是看到黑畫面. 才放棄這個方法改用上述的方法(VPN連線不能使用加密還真是 OOXX). 

在 FreeBSD 建立樣版功能的 jail 環境


0. 準備步驟 :
0.0. 準備 Host 的網路環境
0.0.0. 綁 IP 到 Host : 編輯 /etc/rc.conf 加上 IP alias 設定
ifconfig_em0_alias1="192.168.66.66 netmask 255.255.255.255"

0.0.1. 設定 natd (如果是只有一片網卡的機器就可以不用, 此步驟適用機器有跨在兩個網路(一內一外)上)
Edit /etc/rc.conf

gateway_enable="YES"

firewall_enable="YES"
firewall_type="/etc/my.firewall"
firewall_script="/etc/my.firewall"
firewall_logging="YES"

natd_enable="YES"
natd_interface="re0"
natd_flags="-l -f /etc/natd.conf"


Edit /etc/my.firewall (請依照實際需求更改)

#!/bin/sh -

fwcmd="/sbin/ipfw"                                                                                               
INTIF="re0"
LANIF0="em0"


${fwcmd} -f flush                                                                                              
#For NATD                                                                                                      
${fwcmd} add 00030 divert natd all from any to any via ${INTIF}
...
${fwcmd} add 65000 pass all from any to any

Edit /etc/natd.conf

use_sockets yes
same_ports yes
dynamic yes

Edit /etc/services
natd            8668/divert # Network Address Translation


接著 Host 重新啟動.

0.1. 在 /usr/src 編譯整個環境.
# cd /usr/src; make buildworld

1. 設定樣板存放位置且安裝樣板

# zfs create storage/jail
# zfs set mountpoint=/storage/jail storage/jail
# zfs set dedup=on storage/jail
# zfs set quota=300G storage/jail
# zfs create storage/jails
# zfs set mountpoint=/storage/jails storage/jails
# zfs set dedup=on storage/jails
# zfs set quota=300G storage/jails
# mkdir -p /storage/jail/mroot

# cd /usr/src
# make installworld DESTDIR=/storage/jail/mroot

2. 複製 src 及 ports 
# cd /storage/jail/mroot
# mkdir usr/ports
# portsnap -p /storage/jail/mroot/usr/ports fetch extract
# cpdup /usr/src /storage/jail/mroot/usr/src

3. 建立樣板環境
# mkdir /storage/jail/skel /storage/jail/skel/home /storage/jail/skel/usr-X11R6 /storage/jail/skel/distfiles /storage/jail/skel/packages
# mv etc /storage/jail/skel
# mv usr/local /storage/jail/skel/usr-local
# mv tmp /storage/jail/skel
# mv var /storage/jail/skel
# mv root /storage/jail/skel

4. 產生設定檔
# mergemaster -t /storage/jail/skel/var/tmp/temproot -D /storage/jail/skel -i
# cd /storage/jail/skel
# rm -R bin boot lib libexec mnt proc rescue sbin sys usr dev

5. 建立個別環境可寫入的目錄
#cd /storage/jail/mroot
#mkdir s
#ln -s s/etc etc
#ln -s s/home home
#ln -s s/root root
#ln -s ../s/usr-local usr/local
#ln -s ../s/usr-X11R6 usr/X11R6
#ln -s ../../s/distfiles usr/ports/distfiles
#ln -s ../../s/packages usr/ports/packages
#ln -s s/tmp tmp
#ln -s s/var var

6. 建立 jailed O.S. 的 make.conf
# Add /storage/jail/skel/etc/make.conf
# WRKDIRPREFIX?=  /s/portbuild

以下是每個 jailed O.S. 都要做一次

7. 設定 Host 每次開機為 jailed O.S. 掛上目錄
[FreeBSD 9 labdata2] (Why: 開機時因 ZFS 來不及掛載而無法在 /etc/fstab 處理)
Edit /etc/rc.local
### For jail
/sbin/mount -t nullfs -r /storage/jail/mroot /storage/jail/labdata2
/sbin/mount -t nullfs -rw /storage/jails/labdata2 /storage/jail/labdata2/s

[FreeBSD 8 localdata2]
Edit /etc/fstab

#/storage/jail/mroot   /storage/jail/localdata2     nullfs  ro  0   0
#/storage/jails/localdata2     /storage/jail/localdata2/s   nullfs  rw  0   0


8. 編輯 Host 的 /etc/rc.conf
###20121004
jail_enable="YES"
jail_set_hostname_allow="NO"
### 以下是清單, 有幾台 jailed O.S. 就登記幾台
jail_list="localdata2"
### 以下是每一台 jailed O.S. 的設定記得每一台都要有一組設定.(前四行是必要的)
jail_localdata2_hostname="localdata2.DOMAIN_NAME"
jail_localdata2_ip="192.168.66.66"
jail_localdata2_interface="em0"
jail_localdata2_rootdir="/storage/jail/localdata2"
jail_localdata2_devfs_enable="YES"
### 20121113 解決 netstat -rn 查詢問題
#jail_localdata2_devfs_ruleset="devfsrules_jail"
jail_localdata2_devfs_ruleset="devfsrules_jail2"
jail_localdata2_exec_start="/bin/sh /etc/rc"
jail_localdata2_exec_stop="/bin/sh /etc/rc.shutdown"
jail_localdata2_fdescfs_enable="YES"
jail_localdata2_procfs_enable="YES"

9. 建立系統目錄
mkdir /storage/jail/localdata2
mkdir /storage/jails/localdata2
cpdup /storage/jail/skel /storage/jails/localdata2
mkdir /storage/jail/localdata2/s

10. [Optional] 在 Host 編輯 /etc/sysctl.conf 開放 jailed O.S. 使用 ping.
Edit /etc/sysctl.conf
###20121113 For jail to fix ping icmp socket: Operation not permitted
security.jail.allow_raw_sockets=1

11. [Optional] 在 Host 編輯 /etc/default/devfs.rules 開放 jailed O.S. 使用 pts pty mem bpf
11.1. Edit /etc/default/devfs.rules
[devfsrules_unhide_login=3]
...
add path pts unhide
add path 'pts/*' unhide
add path pty unhide
add path 'pty/*' unhide

11.2. Edit /etc/devfs.rules
###
### http://forums.freebsd.org/archive/index.php/t-24581.html
### http://forums.freebsd.org/archive/index.php/t-5693.html
###
###

[devfsrules_unhide_mem=5]
add path mem unhide
add path kmem unhide

[devfsrules_unhide_bpf=6]
add path bpf unhide

# Devices usually found in a jail.
#
[devfsrules_jail2=7]
add include $devfsrules_hide_all
add include $devfsrules_unhide_basic
add include $devfsrules_unhide_login
add include $devfsrules_unhide_mem
add include $devfsrules_unhide_bpf

12. 掛載目錄
[FreeBSD 9]

/sbin/mount -t nullfs -r /storage/jail/mroot /storage/jail/labdata2
/sbin/mount -t nullfs -rw /storage/jails/labdata2 /storage/jail/labdata2/s


[FreeBSD 8]
mount /storage/jail/localdata2
mount /storage/jail/localdata2/s

13. 啟動 jail
# /etc/rc.d/jail start
查詢啟動的 jailed O.S.
# jls
進入 jailed O.S.
# jexec #JID tcsh (或 jexec #JID /ur/bin/su -)

14. 編輯 jailed O.S. 的系統設定
Edit /etc/rc.conf
Edit /etc/resolv.conf
...


參考資料
1. FreeBSD 使用手冊  15.6 Jail 的應用
2. Forums.freebsd.org :  [Solved] jails with vnet in rc.conf
3. Forums.freebsd.org : jail nat route

Thursday, November 08, 2012

C範例程式 : 浮點數及雙精度浮點數轉換二進位字串

浮點數紀錄數字的格式如下 :
x = 1.yyyy * 2 ^ z

_ ________ _______________________
1     8              23
+  127+z    0.yyyy 用 *2 轉換為 binary 
-

_ ___________ ____________________________________________________
1      11                            52
+    1023+z    0.yyyy 用 *2 轉換為 binary
-


程式碼 : include stdio.h stdlib.h string.h limits.h

#define BTSIZE 256

void dec2bin(int);
void float2bin(float);
void double2bin(double);

int main()
{
	int i;
	float f;
	double d = 1.0;

	printf("%d\t",2);
	dec2bin(2);
	printf("\n%d\t",-2);
	dec2bin(-2);
	printf("\n%d\t",10);
	dec2bin(10);
	printf("\n%d\t",172);
	dec2bin(172);
	printf("\n%d\t",192);
	dec2bin(192);
	printf("\n%d\t",65535);
	dec2bin(65535);
	printf("\n%d\t",-65535);
	dec2bin(-65535);

	printf("\n");

	printf("\n%f\t",2.0);
	float2bin(2.0);
	printf("\n%f\t",-2.0);
	float2bin(-2.0);

	printf("\n%f\t",1.2);
	float2bin(1.2);
	printf("\n%f\t",-1.2);
	float2bin(-1.2);

	printf("\n%f\t",1.0);
	float2bin(1.0);
	printf("\n%f\t",-1.0);
	float2bin(-1.0);

	printf("\n%f\t",0.5);
	float2bin(0.5);
	printf("\n%f\t",-0.5);
	float2bin(-0.5);

	printf("\n%f\t",0.25);
	float2bin(0.25);
	printf("\n%f\t",0.75);
	float2bin(0.75);
	printf("\n%f\t",0.125);
	float2bin(0.125);
	printf("\n%f\t",0.1);
	float2bin(0.1);
	printf("\n%f\t",0.01);
	float2bin(0.01);

	printf("\n");

	printf("\n%lf\t",1.0);
	double2bin(1.0);
	printf("\n%lf\t",-1.0);
	double2bin(-1.0);

	printf("\n%lf\t",1.2);
        double2bin(1.2);
        printf("\n%lf\t",-1.2);
        double2bin(-1.2);

	printf("\n%lf\t",0.5);
	double2bin(0.5);
	printf("\n%lf\t",-0.5);
	double2bin(-0.5);

	printf("\n");

	return 0;
}

void dec2bin(int data)
{
	unsigned int t = (unsigned int)data;

	int b = sizeof(t) * CHAR_BIT;
	char bt[BTSIZE];

	for(int i = 0; i < b; i++)
	{
		bt[i] = (t & 0x01) ? '1' : '0';
		t>>=1;
	}

	for(int i = b-1; i >= 0; i--)
	{
		putchar(bt[i]);
		if(!(i%8) && i)
			printf(" ");
	}
}

void float2bin(float f)
{
	long l;
	int b;
	char bt[BTSIZE];

	memcpy(&l, &f, sizeof(f));

	b= sizeof(f) * CHAR_BIT;

	for(int i = 0; i < b; i++)
	{
		bt[i] = (l & 0x01) ? '1' : '0';
		l>>=1;
	}

	for(int i = b-1; i >= 0; i--)
	{
		putchar(bt[i]);
		if(!(i%8) && i)
			printf(" ");
	}
}

void double2bin(double d)
{
	int l;
	int *iptr;

	iptr = &d;

	memmove(&l, iptr+1, sizeof(l));
	dec2bin(l);
	printf(" ");
	memmove(&l, iptr, sizeof(l));
	dec2bin(l);
}


實際執行結果 :
$ ./show_data

2       00000000 00000000 00000000 00000010
-2      11111111 11111111 11111111 11111110
10      00000000 00000000 00000000 00001010
172     00000000 00000000 00000000 10101100
192     00000000 00000000 00000000 11000000
65535   00000000 00000000 11111111 11111111
-65535  11111111 11111111 00000000 00000001

2.000000        01000000 00000000 00000000 00000000
-2.000000       11000000 00000000 00000000 00000000
1.200000        00111111 10011001 10011001 10011010
-1.200000       10111111 10011001 10011001 10011010
1.000000        00111111 10000000 00000000 00000000
-1.000000       10111111 10000000 00000000 00000000
0.500000        00111111 00000000 00000000 00000000
-0.500000       10111111 00000000 00000000 00000000
0.250000        00111110 10000000 00000000 00000000
0.750000        00111111 01000000 00000000 00000000
0.125000        00111110 00000000 00000000 00000000
0.100000        00111101 11001100 11001100 11001101
0.010000        00111100 00100011 11010111 00001010

1.000000        00111111 11110000 00000000 00000000 00000000 00000000 00000000 00000000
-1.000000       10111111 11110000 00000000 00000000 00000000 00000000 00000000 00000000
1.200000        00111111 11110011 00110011 00110011 00110011 00110011 00110011 00110011
-1.200000       10111111 11110011 00110011 00110011 00110011 00110011 00110011 00110011
0.500000        00111111 11100000 00000000 00000000 00000000 00000000 00000000 00000000
-0.500000       10111111 11100000 00000000 00000000 00000000 00000000 00000000 00000000

C++, Java運算子優先權列表

C++
::	範圍解析	-
::	全域範圍解析	-
------      ------      ------
()	呼叫函數	左
[]	陣列標註	左
.	成員選擇	左
->	成員選擇(指標)	左
++	後置遞增	左
--	後置遞減	左
------      ------      ------
!	邏輯 NOT	右
~	位元補數	右
+	正		右
-	負		右
sizeof	型別大小	右
++	前置遞增	右
--	前置遞減	右
&	位址		右
*	間接參照	右
new	建立新物件	右
delete	刪除物件	右
------      ------      ------
()	成員(cast)	右
------      ------      ------
%	取餘數		左
*	乘		左
/	除		左
------      ------      ------
+	加		左
-	減		左
------      ------      ------
<<	位元左移	左
>>	位元右移	左
>	大於		左
>=	大於等於	左
<	小於		左
<=	小於等於	左
------      ------      ------
==	相等		左
!=	不等於		左
------      ------      ------
&	AND位元運算	左
------      ------      ------
|	OR位元運算	左
------      ------      ------
^	XOR位元運算	左
------      ------      ------
&&	邏輯AND		左
------      ------      ------
||	邏輯OR		左
------      ------      ------
?:	條件式		右
------      ------      ------
=	指定		右
------      ------      ------
,	逗號		左
------      ------      ------

Java
()	引數		左
[]	陣列存取	左
.	成員存取	左
++	後置遞增	左
--	後置遞減	左
------      ------      ------
!	邏輯 NOT	右
~	位元補數	右
+	正		右
-	負		右
++	前置遞增	右
--	前置遞減	右
------      ------      ------
new	建立新物件	右
()	強制轉型(cast)	右
------      ------      ------
%	取餘數		左
*	乘		左
/	除		左
------      ------      ------
+	加		左
-	減		左
------      ------      ------
<<	位元左移	左
>>	位元右移	左
>>>	無符號位元右移	左
------      ------      ------
>	大於		左
>=	大於等於	左
<	小於		左
<=	小於等於	左
instanceof	資料型態比較	左
------      ------      ------
==	相等		左
!=	不等於		左
------      ------      ------
&	AND位元運算	左
------      ------      ------
^	XOR位元運算	左
------      ------      ------
|	OR位元運算	左
------      ------      ------
&&	邏輯AND		左
------      ------      ------
||	邏輯OR		左
------      ------      ------
?:	條件式		右
------      ------      ------
=	指定		右
複合指定運算子		右
+= -= *= /= %=
&= |= ^= <<= >>= >>>=
------      ------      ------

C++ 範例程式 : 類別, 物件, 繼承, 類別成員, 類別函式, 多載, 覆載

類別 : Car, RacingCar
物件 : car1, mcar1, ...
類別成員 : sum
類別函式 : showSum()
多載 : Car(), RacingCar()
覆載 : show()

程式碼 include iostream

using namespace std;

#define ASIZE 3

class Car {
	protected:
		int num;
		double gas;

	public:
		static int sum;
		Car();
		Car(int);
		Car(int,double);
		int setNum(int);
		int setGas(double);
		void setCar(int,double);
		int getNum(){ return num; }	//inline function
		double getGas(){ return gas; }	//inline function
		virtual void show();
		static void showSum();
};

class RacingCar : public Car {
	private:
		int course;

	public:
		static int sum;
		RacingCar();
		RacingCar(int);
		RacingCar(int,double,int);
		void setCourse(int);
		int getCourse(){ return course; }	//inline function
		void show();
		static void showSum();
};

// For class Car
int Car::sum=0;

Car::Car()
{
	sum++;
	cout << "製造一輛車" << endl;
	num = 0;
	gas = 0.0;
}

Car::Car(int n)
{
	sum++;
	cout << "製造一輛車" << endl;
	setNum(n);
	gas = 0.0;
}

Car::Car(int n, double g)
{
	sum++;
	cout << "製造一輛車" << endl;
	setNum(n);
	setGas(g);
}

int Car::setNum(int n)
{
	if(n > 0)
	{
		num = n;
		cout << "設定車輛編號 " << num << endl;
		return 0;
	}
	else
	{
		cout << "無法設定車輛編號, 數值必須大於 0." << endl;
		return -1;
	}
}

int Car::setGas(double g)
{
	if(g > 0)
	{
		gas = g;
		cout << "設定油量 " << gas << endl;
		return 0;
	}
	else
	{
		cout << "無法設定油量, 數值必須大於 0." << endl;
		return -1;
	}
}

void Car::setCar(int n, double g)
{
	setNum(n);
	setGas(g);
}

void Car::show()
{
	cout << "車輛編號 " << num << " 油量 " << gas << endl;
}

void Car::showSum()
{
	cout << "一共生產 " << sum << " 輛車" << endl;
}

// For class RacingCar
int RacingCar::sum = 0;

RacingCar::RacingCar()
{
	sum++;
	cout << "改造成一輛賽車" << endl;
	course = 0;
}

RacingCar::RacingCar(int c)
{
	sum++;
	cout << "改造成一輛賽車" << endl;
	setCourse(c);
}

RacingCar::RacingCar(int n, double g, int c) : Car(n, g)
{
	sum++;
	cout << "改造成一輛賽車" << endl;
	setCourse(c);
}

void RacingCar::setCourse(int c)
{
	if(c > 0)
	{
		course = c;
		cout << "設定賽車跑道 " << course << endl;
	}
	else
	{
		cout << "設定賽車跑道號碼必須大於零 " << endl;
	}
}

void RacingCar::show()
{
	cout << "車輛編號 " << num << " 油量 " << gas << endl;
	cout << "賽車跑道 " << course << endl;
}

void RacingCar::showSum()
{
	cout << "一共生產 " << sum << " 輛賽車" << endl;
}

// main function
void buy(Car&);

int main()
{
	Car car1;

	cout << "設定 car1 資訊" << endl;
	car1.setNum(1);
	car1.setGas(5168.88);
	cout << "已設定車輛編號 " << car1.getNum() << " 油量 " << car1.getGas() << endl;

	cout << "查詢 car1 資訊" << endl;
	car1.show();

	cout << endl;
	Car cara[ASIZE];

	cout << "設定 cara 資訊" << endl;
	for(int i = 0; i < ASIZE; i++)
	{
		cara[i].setNum(i+2);
		cara[i].setGas(1000*(i+1)+688);
		cout << "已設定車輛編號 " << cara[i].getNum() << " 油量 " << cara[i].getGas() << endl;
	}

	cout << "查詢 cara 資訊" << endl;
	for(int i = 0; i < ASIZE; i++)
	{
		cara[i].show();
	}

	cout << endl;
	Car *pCar;
	pCar = new Car;

	cout << "設定 pCar 資訊" << endl;
	pCar->setNum(5);
	pCar->setGas(3600);
	cout << "已設定車輛編號 " << pCar->getNum() << " 油量 " << pCar->getGas() << endl;

	cout << "查詢 pCar 資訊" << endl;
	pCar->show();

	cout << endl;
	cout << "肌肉車 mcar 生產資訊" << endl;
	Car mcar1(6);
	mcar1.setGas(6000);
	Car mcar2 = Car(7, 6800);

	cout << "查詢肌肉車 mcar 資訊" << endl;
	mcar1.show();
	mcar2.show();

	Car::showSum();

	cout << "\n購買汽車" << endl;
	buy(car1);
	buy(cara[0]);
	buy(*pCar);

	//
	// RacingCar
	//
	cout << "\n\n生產賽車 racar1" << endl;
	RacingCar racar1;
	racar1.setCar(8, 3600.0);
	racar1.setCourse(5);

	cout << "查詢賽車 racar1 資訊" << endl;
	racar1.show();

	RacingCar::showSum();
	Car::showSum();

	cout << "\n\n生產賽車 racar2" << endl;
	RacingCar racar2 = RacingCar(9, 3000.0, 6);

	cout << "查詢賽車 racar2 資訊" << endl;
	racar2.show();

	RacingCar::showSum();
	Car::showSum();

	cout << "\n\n賽車指標 pRacar1" << endl;
	Car* pRacar1;
	pRacar1 = &racar1;

	pRacar1->show();

	RacingCar::showSum();
	Car::showSum();

	cout << "\n\n車輛指標陣列 pCarArr" << endl;
	Car* pCarArr[3];
	cout << "車輛指標陣列 pCarArr[0] 指向 racar1" << endl;
	pCarArr[0] = &racar1;
	cout << "車輛指標陣列 pCarArr[1] 指向 racar2" << endl;
	pCarArr[1] = &racar2;
	cout << "車輛指標陣列 pCarArr[2] 生產一輛賽車" << endl;
	pCarArr[2] = new RacingCar(10, 3000.0, 7);

	RacingCar::showSum();
	Car::showSum();

	cout << "\n\n查詢車輛指標陣列 pCarArr" << endl;
	for(int i = 0; i < 3; i++)
	{
		pCarArr[i]->show();
	}

	RacingCar::showSum();
	Car::showSum();

	cout << "\n\n賽車指標陣列 pRaCarArr" << endl;
	RacingCar* pRaCarArr[3];
	cout << "車輛指標陣列 pRaCarArr[0] 指向 racar1" << endl;
	pRaCarArr[0] = &racar1;
	cout << "車輛指標陣列 pRaCarArr[1] 指向 racar2" << endl;
	pRaCarArr[1] = &racar2;
	cout << "車輛指標陣列 pRaCarArr[2] 生產一輛賽車" << endl;
	//pRaCarArr[2] = pCarArr[2];
	//car_class_inheritence_protected-baseptr.cpp:282:26: error: invalid conversion from ‘Car*’ to ‘RacingCar*’
	pRaCarArr[2] = new RacingCar(11, 5000.0, 8);

	RacingCar::showSum();
	Car::showSum();

	cout << "\n\n查詢賽車指標陣列 pRaCarArr" << endl;
	for(int i = 0; i < 3; i++)
	{
		pRaCarArr[i]->show();
	}

	RacingCar::showSum();
	Car::showSum();

	return 0;
}

void buy(Car& c)
{
	cout << "購買了車輛編號 " << c.getNum() << " 油量 " << c.getGas() << endl;
}

C++ 範例程式 : try-catch

程式隨機產生整數, 並判斷是奇數或偶數.
程式碼 include iostream cstdlib ctime

using namespace std;

void func(int);
void errHandle(int);

int main()
{
	char choice;
	int num;

	srand(time(0));

	while(choice != 'N' && choice != 'n')
	{
		try{
			num = rand()%100+1;
			cout << "###  " << num << "  ";
			func(num);
		}
		catch(int errValue){
			errHandle(errValue);
		}

		cout << endl << "想要繼續玩嗎? ( Y / N ) ";
		cin >> choice;
		cout << endl;
	}

	return 0;
}

void func(int a)
{
	if(a%2)
		throw 7777777;
	else
		throw 5168888;
}

void errHandle(int e)
{
	switch(e)
	{
		case 7777777:	cout << "發現奇數" << endl;	break;
		case 5168888:	cout << "發現偶數" << endl;	break;
		default:	cout << "不明狀態碼" << endl;	break;
	}
}

C++ 範例程式: 排序程式 (一)

包含三種排序方法 : 插入排序, 氣泡排序(一般, 崗哨法), 選擇排序.

標頭檔(Header)
void insertion_sort(int *, int);
void bubble_sort(int *, int);
void bubble_sort_sentinel(int *, int);
void selection_sort(int *, int);

程式碼實作
void insertion_sort(int *a, int size)
{
	// From left to right : sorted position
	for(int i = 0; i < size; i++)
	{
		// From right to left : move small number to left
		for(int j = i; j > 0; j--)
		{
			if(*(a+j-1) > *(a+j))
			{	// a = a^b; b = a^b; a = a^b;
				*(a+j-1) = *(a+j-1) ^ *(a+j);
				*(a+j)   = *(a+j-1) ^ *(a+j);
				*(a+j-1) = *(a+j-1) ^ *(a+j);
			}
		}
	}
}

void selection_sort(int *a, int size)
{
	// Define min number of each run
	int minpos;
	// Find the x-th small number
	for(int i = 0; i < size-1; i++)
	{
		// Suppose first number is the small number
		minpos = i;

		// From left to right : find the x-th small number
		for(int j = i; j < size; j++)
		{
			if(*(a+j) < *(a+minpos))
				minpos = j;
		}
		// Because using XOR exchange, you must skip this condition.
		// Otherwise you will get 0. The first line of XOR exchange will do it.
		if(minpos == i)
		{
			continue;
		}
		*(a+i)      = *(a+i) ^ *(a+minpos);
		*(a+minpos) = *(a+i) ^ *(a+minpos);
		*(a+i)      = *(a+i) ^ *(a+minpos);
	}
}

void bubble_sort(int *a, int size)
{
	for(int i = size - 1; i > 0; i--)
	{
		for(int j = 0; j < i; j++)
		{
			if(*(a+j) > *(a+j+1))
			{
				*(a+j) = *(a+j) ^ *(a+j+1);
				*(a+j+1) = *(a+j) ^ *(a+j+1);
				*(a+j) = *(a+j) ^ *(a+j+1);
			}
		}
	}
}

void bubble_sort_sentinel(int *a, int size)
{
	// Define the last swap position : sentinel
	int lastswap;
	// Define the position of x-th big number
	for(int i = size - 1; i > 0;)
	{
		// Reset last swap position
		lastswap = 0;
		// From left to right : check each pair of numbers
		for(int j = 0; j < i; j++)
		{
			if(*(a+j) > *(a+j+1))
			{
				*(a+j) = *(a+j) ^ *(a+j+1);
				*(a+j+1) = *(a+j) ^ *(a+j+1);
				*(a+j) = *(a+j) ^ *(a+j+1);
				lastswap = j;
			}
		}
		// Set the last swap position as the border
		// Because numbers at right head had been sorted
		i = lastswap;
	}
}

C範例程式 : 堆疊與佇列

堆疊(stack) : 先進後出(First In Last Out, FILO), 可以將容器想像成桶子, 放進去的東西一層一層疊上去. 拿出來時自然就是後來進去的東西先拿出來.
佇列(queue) : 先進先出(First In First Out, FIFO),可以將容器想像成水管, 只從一頭放東西進去, 且只能從另一頭取出. 所以自然是先進入的東西先拿出來.
以上兩種資料結構都將以陣列及鍊結串列實現.

堆疊
陣列 include stdio.h

#define ASIZE 5

int stack[ASIZE]={0};
int top=-1;

void push();
void pop();
void display();
void release();

int main()
{
	int choice;

	printf("陣列堆疊測試程式(可儲存資料筆數%d)\n", ASIZE+1);

	while(1)
	{
		printf("1) 新增\t2) 刪除\t3) 顯示\t0) 結束 : ");
		scanf("%d",&choice);

		if(!choice)
			break;

		switch(choice)
		{
			case 1:		push();		break;
			case 2:		pop();		break;
			case 3:		display();	break;
			default:	display();	break;
		}
	}
	printf("清空堆疊\n");
	release();

	return 0;
}

void push()
{
	int d;

	if(top < ASIZE)
	{
		printf("請輸入資料(整數) : ");
		scanf("%d",&d);
		top++;
		stack[top] = d;
	}
	else
	{
		printf("堆疊滿了\n");
	}
}


void pop()
{
	if(top >= 0)
	{
		printf("%3d\n",stack[top]);
		top--;
	}
	else
	{
		printf("堆疊是空的\n");
	}
}

void display()
{
	int pos = top;
	while(pos >= 0)
	{
		printf("%3d ",stack[pos]);
		pos--;
	}
	printf("\n");
}

void release()
{
	while(top >= 0)
		pop();
}

鍊結串列 include stdio.h malloc.h

typedef struct _node * pnode;

struct _node{
	int data;
	pnode next;
}node;

pnode head;

void init();
void push();
void pop();
void display();
void release();

int main()
{
	int choice;

	init();

	printf("串列堆疊測試程式\n");

	while(1)
	{
		printf("1) 新增\t2) 刪除\t3) 顯示\t0) 結束 : ");
		scanf("%d",&choice);

		if(!choice)
			break;

		switch(choice)
		{
			case 1:		push();		break;
			case 2:		pop();		break;
			case 3:		display();	break;
			default:	display();	break;
		}
	}
	printf("清空堆疊\n");
	release();

	return 0;
}

void init()
{
	head = NULL;
}

void push()
{
	int d;
	pnode p = (pnode)malloc(sizeof(node));

	printf("請輸入資料(整數) ");
	scanf("%d",&d);

	p->data = d;
	p->next = head;
	head = p;
}


void pop()
{
	pnode p;

	if(head)
	{
		p = head;
		head = head->next;
		printf("刪除 %d \n",p->data);
		free(p);
	}
	else
	{
		printf("堆疊是空的\n");
	}
}

void display()
{
	pnode p = head;

	while(p)
	{
		printf("%d ",p->data);
		p = p->next;
	}
	printf("\n");
}

void release()
{
	pnode p;
	while(head)
	{
		p = head;
		head = head->next;
		free(p);
	}
}

佇列
陣列 include stdio.h

#define QSIZE 5

int queue[QSIZE];
int head, tail;

void init();
int isFull();
int isEmpty();
void enqueue();
void dequeue();
void display();
void release();

int main()
{
	int choice;

	printf("陣列佇列測試程式(可儲存資料筆數%d)\n", QSIZE+1);

	while(1)
	{
		printf("1) 新增\t2) 刪除\t3) 顯示\t0) 結束 : ");
		scanf("%d",&choice);

		if(!choice)
			break;

		switch(choice)
		{
			case 1:		enqueue();	break;
			case 2:		dequeue();	break;
			case 3:		display();	break;
			default:	display();	break;
		}
	}
	printf("清空串列\n");
	release();

	return 0;
}

void init()
{
	head = tail = 0;
}

int isFull()
{
	if((tail+1)%QSIZE == head)
	{
		printf("佇列已滿\n");
		return 1;
	}
	return 0;
}

int isEmpty()
{
	if(head%QSIZE == tail%QSIZE)
	{
		printf("佇列已空\n");
		return 1;
	}
	return 0;
}

void enqueue()
{
	int d;

	if(!isFull())
	{
		printf("請輸入資料 ");
		scanf("%d",&d);
		tail++;
		tail%=QSIZE;
		queue[tail] = d;
	}
}


void dequeue()
{
	if(!isEmpty())
	{
		head++;
		head%=QSIZE;
		printf("刪除資料 %d\n",queue[head]);
	}
}

void display()
{
	for(int i = (head+1)%QSIZE; i != (tail+1)%QSIZE;)
	{
		printf("%d ",queue[i]);
		i++;
		i%=QSIZE;
	}
	printf("\n");
}

void release()
{
	for(int i = (head+1)%QSIZE; i != (tail+1)%QSIZE;)
	{
		queue[i]=-1;
		i++;
		i%=QSIZE;
	}
}

鍊結串列 include stdio.h malloc.h string.h

#define MAXSTR 50

typedef struct _node * pnode;

struct _node{
	char name[MAXSTR];
	char phone[MAXSTR];
	pnode next;
}node;

pnode head, tail;

void init();
void enqueue();
void dequeue();
void display();
void release();

int main()
{
	int choice;

	printf("鍊結串列佇列測試程式\n");

	while(1)
	{
		printf("1) 新增\t2) 刪除\t3) 顯示\t0) 結束 : ");
		scanf("%d",&choice);

		if(!choice)
			break;

		switch(choice)
		{
			case 1:		enqueue();	break;
			case 2:		dequeue();	break;
			case 3:		display();	break;
			default:	display();	break;
		}
	}
	printf("清空串列\n");
	release();

	return 0;
}

void init()
{
	head = tail = NULL;
}

void enqueue()
{
	pnode p = (pnode)malloc(sizeof(node));

	if(p)
	{
		printf("請輸入姓名 ");
		scanf("%s", p->name);
		printf("請輸入電話 ");
		scanf("%s", p->phone);
		p->next = NULL;
		if(head)
		{
			tail->next = p;
			tail = p;
		}
		else
		{
			head = tail = p;
		}
	}
	else
	{
		printf("無法取得記憶體空間新增資料\n");
	}
}


void dequeue()
{
	pnode p;

	if(head)
	{
		p = head;
		if(head->next)
			head = head->next;
		else
			head = tail = NULL;
		printf("刪除資料姓名 %s 電話 %s\n", p->name, p->phone);
		free(p);
	}
	else
	{
		printf("串列已空\n");
	}
}

void display()
{
	pnode p;
	p = head;

	while(p)
	{
		printf("姓名 %s 電話 %s\n", p->name, p->phone);
		p = p->next;
	}
}

void release()
{
	pnode p;

	tail = NULL;
	while(head)
	{
		p = head;
		head = head->next;
		free(p);
	}
}

C範例程式 : 鍊結串列 linked list

使用結構(struct)實作節點(node). 串列建立在主程式中, 使用 nodep * 型態傳進函式進行 push 及 pop.
程式碼 include stdio.h stdlib.h

#define DIRTYPE 8

// Define structure pointer
typedef struct node * nodep;

// Define structure
struct node {
	int x;
	int y;
	int dir;
	nodep next;
};

// Add new node to linked list : addr. of head, addr. of tail, new node
void pushnode(nodep*,nodep*,nodep);
// Pop end node of linked list : addr. of head, addr. of tail
void popendnode(nodep*,nodep*);
// Pop begin node of linked list : addr. of head, addr. of tail
void popheadnode(nodep*,nodep*);
// Show linked list from begin to end
void show(nodep);

int main()
{
	nodep head = NULL;
	nodep tail = NULL;
	nodep tmp  = NULL;
	int tx, ty, td, nc = 0;
	int clean = 0;

	while(1)
	{
		tmp = (nodep)malloc(sizeof(struct node));

		printf("請輸入三個正整數 X座標 Y座標 方向 (輸入 0 0 0 結束程式) ");

		scanf("%d %d %d", &tx, &ty, &td);

		if(!tx && !ty && !td)
		{
			printf("選擇結束程式.\n");
			break;
		}

		tmp->x=tx;
		tmp->y=ty;
		tmp->dir=td%DIRTYPE;
		tmp->next=NULL;

		pushnode(&head, &tail, tmp);
		nc++;

		printf("======   串列成員如下   ======\n");
		show(head);
		printf("======      ======      ======\n");
	}

	if(!nc)
		exit(0);

	printf("======  串列最終成員如下 ======\n");
	show(head);
	printf("======      ======      ======\n");

	printf("請問如何清除串列 : \n 1) 從尾端清除 \n 2) 從頭端清除 ");
	scanf("%d", &clean);

	if(clean != 1 && clean != 2)
	{
		clean = 1;
		printf("選項錯誤 使用預設 從尾端清除 \n");
	}

	printf("\n清除串列\n");
	for(int i = nc; i > 0; i--)
	{
		if(clean == 1)
			popendnode(&head, &tail);
		else
			popheadnode(&head, &tail);

                printf("\n======   串列成員如下   ======\n");
                show(head);
                printf("======      ======      ======\n\n");

		//if(!tail)
		//	head = tail;

		//if(!head)
		//	tail = head;
	}
	printf("清除串列完畢\n");

	printf("\n======  串列最終成員如下 ======\n");
	show(head);
	printf("======      ======      ======\n");

	return 0;
}

void pushnode(nodep *h, nodep *t, nodep n)
{
	//printf(" push node \n");

	if(!*h)
	{
		//printf(" add to empty list \n");
		*h = n;
		*t = n;
	}
	else
	{
		//printf(" add to non-empty list \n");
		(*t)->next = n;
		*t = n;
	}

/*	printf("h   = %x\n", h);
	printf("t   = %x\n", t);
        printf("&h   = %x\n", &h);
        printf("&t   = %x\n", &t);*/

	//return t;
}

void show(nodep h)
{
	while(h)
	{
		printf("( %d, %d )(dir = %d)\n", h->x, h->y, h->dir);
		h = h->next;
	}
}

void popendnode(nodep *h, nodep *t)
{
	nodep p, out;

	if(*h && *t)
	{
		p = *h;
		while(p != *t && p->next != *t)
			p = p->next;

		if(p->next)
		{
			out = p->next;
			*t = p;
			p->next = NULL;
		}
		else
		{
			out = p;
			*h = NULL;
			*t = NULL;
		}

		printf("倒出最後一個 node ( %d, %d )(dir = %d)\n", out->x, out->y, out->dir);
		free(out);
	}
}

void popheadnode(nodep *h, nodep *t)
{
	nodep out;

	if(*h && *t)
	{
		out = *h;
		printf("倒出第一個 node ( %d, %d )(dir = %d)\n", out->x, out->y, out->dir);
		if(out->next)
		{
			*h = out->next;
		}
		else
		{
			*h = NULL;
			*t = NULL;
		}
		free(out);
	}
}

C 語言範例程式

範例一 插入排序 include stdio.h stdlib.h time.h conio.h

// 定義排序陣列大小 
#define ASIZE 5

// 主程式 開始 
int main()
{
    // 初始化排序陣列 
	int a[ASIZE];
    // 定義變數 : 已排序位置, 比較大小的位置, 輸出陣列的位置 
	int i, j, k, tmp;
    // 判斷是否繼續使用程式的變數 
    char choice;
    
	// 程式重複執行區塊 開始
	while(1)
	{
        printf("亂數產生陣列元素\n");
		srand(time(NULL));

        // 亂數產生陣列元素
		for(i = 0; i < ASIZE; i++)
		{
			a[i] = rand() % 100;
		}

        // 輸出排序前陣列
        printf("排序前陣列 : ");
        for(k = 0; k < ASIZE; k++)
            printf("%2d ", a[k]);

        printf("\n\n排序\n");
    
        // 排序的外層迴圈 : 已排序
    	for(i = 1; i<=ASIZE; i++)
    	{
            // 輸出目前已完成排序的位置 
    		printf("i:%d, ",i);
    
    		// 輸出排序中陣列
    		for(k = 0; k < ASIZE; k++)
    			printf("%2d ", a[k]);
    		//printf("\n");
    		getchar();
    
            // 由右往左比大小排序 
    		for(j = i; j > 0; j--)
    		{
                // 若比左方大, 代表一定比左方所有已排序的數字大. 不需繼續比較直接跳離此回合排序.
                // 若比左方小, 則需要交換位置. 並繼續向左方比大小, 直到比左方數字大為止. 
    			if(a[j-1] < a[j]){
    				break;
    			}else{
    				tmp = a[j];
    				a[j] = a[j-1];
    				a[j-1] = tmp;
    			}
    		}
    	}
    
        // 輸出排序後陣列
        printf("\n排序後陣列 : ");
        for(k = 0; k < ASIZE; k++)
            printf("%2d ", a[k]);
        printf("\n");

        printf("\n請問是否要繼續排序陣列 ? (按任意鍵繼續, 輸入 N / n 離開) ");
        choice=getche();
        if(choice == 'N' || choice == 'n')
            break;
        printf("\n\n");

    // 程式重複執行區塊 結束 
    }

	printf("\n感謝您的使用.\n");

    // 暫停畫面 (For Windows) 
	system("pause");
	return 0;
// 主程式 結束 
}

範例二 計算 LCM include stdio.h stdlib.h conio.h

// 計算 GCD 函式原型 
int gcd(int,int);
// 計算 LCM 函式原型
int lcm(int,int);

// 主程式 開始
int main()
{
    // 定義存放使用者輸入數字的變數 
	int x, y;
    // 定義是否繼續的變數 
    char choice;

	// 程式重複執行區塊 開始
	while(1)
	{
        // 使用者輸入 
    	printf("請輸入兩個整數 : ");
    	scanf("%d %d", &x, &y);

        // 呼叫 LCM 函式並且 
    	printf("LCM(%d, %d) = %d\n", x, y, lcm(x,y));

        printf("\n請問是否要繼續計算 LCM ? (按任意鍵繼續, 輸入 N / n 離開) ");
        choice=getche();
        if(choice == 'N' || choice == 'n')
            break;
        printf("\n\n");

    // 程式重複執行區塊 結束 
    }

	printf("\n感謝您的使用.\n");

    system("pause");

	return 0;

// 主程式 結束 
}

// 計算 GCD 函式 開始
int gcd(int x, int y)
{
    // 定義暫存數字 
	int z;
	if(x<0)	x=-x;

    // 輾轉相除法 
	while(z=x%y)
	{	x=y;	y=z;	}

	return y;
// 計算 GCD 函式 結束 
}

// 計算 LCM 函式 開始
int lcm(int x, int y)
{
	int rx, ry, gcdnum;

    // 呼叫計算 GCD 函式 
	gcdnum = gcd(x,y);

    // 計算個別數字為 GCD 的倍數 rx ry
	rx = x/gcdnum;
	ry = y/gcdnum;

    // 數學公式 : LCM = GCD * (X/GCD) * (Y/GCD)
	return gcdnum * rx * ry;
// 計算 LCM 函式 結束 
}

範例三 計算費氏級數 include stdio.h stdlib.h

// 計算費氏數列函式原型 - 遞迴 
int rfib(int);

// 計算費氏數列函式原型 - 非遞迴
int fib(int);

// 主程式 開始
int main()
{
    // 定義存放使用者輸入數字的變數 
	int x;
    // 定義是否繼續的變數 
    char choice;

    printf("費伯納數列計算程式 : ");

	// 程式重複執行區塊 開始
	while(1)
	{
        // 使用者輸入 
    	printf("請輸入一個正整數 : ( 輸入 0 離開程式 ) ");
    	scanf("%d", &x);

	if(x == 0)
	{
		printf("結束使用程式.\n");
		break;
	}

        printf("\n  遞迴計算 Fib(%d) = %d\n", x, rfib(x));
        printf("\n非遞迴計算 Fib(%d) = %d\n", x, fib(x));

        //printf("\n請問是否要繼續計算費伯納數列 ? (按任意鍵繼續, 輸入 N / n 離開) ");
        //choice=getche();
        //if(choice == 'N' || choice == 'n')
        //    break;
        printf("\n\n");

    // 程式重複執行區塊 結束 
    }

	printf("\n感謝您的使用.\n");

    //system("pause");

	return 0;

// 主程式 結束 
}

// 計算費氏數列函式原型 - 遞迴 開始 
int rfib(int n)
{
    // fib(0) = 0
    if(n == 0)
        return 0;
    // fib(1) = 1
    else if(n == 1)
        return 1;
    // 數學公式 fib(n) = fib(n-1) + fib(n-2)
    else
        return rfib(n-1)+rfib(n-2);
// 計算費氏數列函式原型 - 遞迴 結束 
}

int fib(int n)
{
    // 定義變數 fib(n-2)  fib(n-1) 
    int x = 0, y = 1, tmp;
    // fib(0) = 0
    if(n == 0)
        return 0;
    if(n == 1)
        return 1;
    else
    {
        for(int i = 2; i <= n; i++)
        {
            tmp = y;
            y+=x;
            x = tmp;
        }
        return y;
    }
}

範例四 尋找質數 include stdio.h stdlib.h stdbool.h

// 定義每發現多少個質數就擴大陣列 
#define PSTEPNUM 100

// 主程式 開始
int main()
{
    // 定義質數陣列指標及暫存用陣列指標 
	int *prime, *tmp;
    // 定義使用者輸入的最大數字, 已找到質數個數, 舊的質數陣列最大數字, 質數陣列最大數字
	int unum, pc, oldpcmax, pcmax;
    // 是否為質數的旗標 
	bool pflag;
    // 判斷是否繼續使用程式的變數 
    char choice;

    printf("找質數程式 : \n\n");

	// 程式重複執行區塊 開始
	while(1)
	{
        // 初始化變數 
        unum = -1;
        pc = 0;
        // 質數陣列最大數字(預設值為 PSTEPNUM)
        pcmax = PSTEPNUM;

		printf("請輸入一個正整數, 找比它小的質數 : (輸入 0 離開程式)");
        scanf("%d", &unum);

        // 使用者輸入數字錯誤處理 
    	if(unum == 0)
    	{
    		printf("正常關閉程式.\n");
    		break;
    	}
    	else if(unum < 0)
    	{
    		printf("輸入數字不合規定.\n");
    		exit(0);
    	}

        // 動態取得質數陣列空間 
    	prime = (int*)malloc(sizeof(int)*pcmax);

        // 從 2 開始找質數 
    	for(int i = 2; i < unum; i++)
    	{
            // 2 就是第一個質數 
    		if(i == 2)
    		{
    			prime[pc] = 2;
    			pc++;
                printf("p");
    		}
    		else
    		{
                // 質數已放滿質數陣列 
    	   		if(pc >= pcmax)
    			{
                    // 動態取得暫存用陣列
    				oldpcmax = pcmax;
    				tmp = (int*)malloc(sizeof(int)*oldpcmax);

                    // 複製質數陣列到暫存用陣列 
    				for(int j = 0; j < oldpcmax; j++)
    				{
    					tmp[j] = prime[j];
    				}

                    // 清除質數陣列 
    	   			free(prime);

                    // 動態取得新的質數陣列 
    				pcmax+=PSTEPNUM;
    				prime = (int*)malloc(sizeof(int)*pcmax);

                    // 複製暫存用陣列到新的質數陣列 
    				for(int j = 0; j < oldpcmax; j++)
    				{
    					prime[j] = tmp[j];
    				}

                    // 清除暫存用陣列
    				free(tmp);
    				printf("+");
    			}
    			else
    			{
                    // 預設數字是質數 
    				pflag = true;

                    // 找質數迴圈 : 逐一檢查是否為已發現質數的倍數 
    				for(int k = 0; k < pc; k++)
    				{
    					if(!(i%prime[k]))
    					{
                            // 發現為質數的倍數, i 就不是質數. 跳出找質數迴圈 
    						pflag = false;
    						break;
    					}
    				}

                    // 若發現質數則記錄質數 
    				if(pflag)
    				{
    					prime[pc] = i;
    					pc++;
    					printf("p");
    				}
    			}
    		}
    	}

    	printf("\n\n發現質數個數 : %d\n", pc);

        // 輸出質數陣列 
    	for(int i = 0; i < pc; i++)
    	{
    		printf("%6d ", prime[i]);
    		if(!((i+1)%10))
    			printf("\n");
    	}

    	printf("\n");

        // 清除質數陣列 
    	free(prime);

        //printf("\n請問是否要繼續找質數 ? (按任意鍵繼續, 輸入 N / n 離開) ");
        //choice=getche();
        //if(choice == 'N' || choice == 'n')
        //    break;
        //printf("\n\n");

    // 程式重複執行區塊 結束 
    }

	printf("\n感謝您的使用.\n");

    system("pause");

   	return 0;

// 主程式 結束 
}

範例五 單字排序 include stdio.h stdlib.h string.h

// 定義單字最長的長度
#define MAXWLEN 512

// 排序單字函式原型
void sortWordCard(char**,int,int);

// 主程式 開始
int main()
{
	// 定義單字個數, 使用者輸入單字個數結果, 排序方式
	int word_count, uin, sort_type;
	// 定義二維單字陣列指標, 暫存用一維單字陣列
	char **wordcard, tmpword[MAXWLEN];

	printf("單字排序程式\n");

	// 程式重複執行區塊 開始
	while(1)
	{
		// 初始化單字個數, 使用者輸入單字個數結果
		word_count = uin = 0;

		// 使用者輸入單字個數
		printf("\n1. 請輸入要排序的單字(長度需小於 %d)個數 ? (輸入 0 離開程式)", MAXWLEN);
		uin = scanf("%d", &word_count);

		// 單字個數錯誤處理, 結束程式
		if(uin == 0 || word_count < 0 )
		{
			printf("輸入個數不合規定.\n");
			break;
		}
		else if( word_count == 0)
		{
			// 結束程式
			break;
		}

		// 輸入排序方式
		printf("   請輸入排序方式\n   1) 按字母大小排序(大寫字母排在最前面).\n   2) 按字母大小反向排序(小寫字母排在最前面). 請選擇 : ");
		uin = scanf("%d", &sort_type);

		// 排序方式錯誤處理
		if(uin == 0)
		{
			printf("輸入排序方式不合規定.使用預設排序:按字母大小排序(大寫字母排在最前面).\n");
			sort_type = 1;
		}

		// 排序方式對應傳遞參數
		switch(sort_type)
		{
			case 1:         sort_type = 1;  break;	// 大寫字母排在最前面且按字母大小排序
			case 2:         sort_type = -1; break;	// 小寫字母排在最前面且按字母大小反向排序
			default:        printf("輸入排序方式不合規定.使用預設排序:按字母大小排序(大寫字母排在最前面).\n");
					sort_type = 1;  break;	// 預設排序方式
		}

		// 動態取得二維單字陣列第一層陣列, 儲存第二層單字陣列第一個元素的位址
		wordcard = (char**)malloc(sizeof(char*)*word_count);

		// 接收使用者輸入的單字
		printf("\n2. 請輸入要排序的單字(使用空白分隔)\n");
		for(int i = 0; i < word_count; i++)
		{
			// 先使用暫存用一維單字陣列
			scanf("%s",tmpword);
			// 動態取得二維單字陣列第二層陣列, 儲存單字
			wordcard[i] = (char*)malloc(sizeof(char)*strlen(tmpword));
			// 複製暫存用一維單字陣列到單字陣列
			strcpy(wordcard[i],tmpword);
			//scanf("%s",wordcard[i]);
		}

		// 清掉所有尚未使用的輸入
		fflush(stdin);

		printf("\n3. 排序單字\n");
		// 呼叫排序程式
		sortWordCard(wordcard, word_count, sort_type);

		// 顯示排序結果
		printf("\n\n4. 依序顯示輸入單字\n");
		for(int i = 0; i < word_count; i++)
		{
			printf("%s\n",wordcard[i]);
		}

	// 程式重複執行區塊 結束
	}

	printf("\n感謝您的使用.\n");

    system("pause");
	return 0;

// 主程式 結束
}

// 排序單字函式實作 開始
void sortWordCard(char** w, int l, int st)
{
	char *tmp;

	// 預設排序 : 依照字母順序
	if(st != 1 && st != -1)
		st = 1;

	/* 除錯使用
	for(int i=0; i0; j--)
		{
			// 使用 strcmp() 比較是否需要交換位置
			if(strcmp(*(w+(j-1)),*(w+j)) == st)
			{
				// 將 w 視為一個儲存字串起點的陣列, 使用一個 tmp 指標交換指向位址
				tmp = w[j];
				w[j] = w[j-1];
				w[j-1] = tmp;
			}
		}
		printf(".");
	}

// 排序單字函式實作 結束
}

範例六 蝸牛方陣 include stdio.h stdlib.h

// 主程式 開始
int main()
{
	// 判斷是否繼續使用程式的變數 
	char choice;
	// 定義陣列指標, 方陣大小, X軸位置, Y軸位置, 順時針/逆時針方向, 起點位置, 由小到大或由大到小, 輸入檢查
	int **snail, size, x, y, clock, dir, start, sob, uin;

	printf("蝸牛矩陣產生程式 : \n\n");

	while(1)
	{
		fflush(stdin);
		printf("請輸入方陣大小 : (輸入 0 離開程式) ");
		uin = scanf("%d", &size);

		// 使用者輸入數字錯誤處理
		if(size == 0)
		{
			printf("正常關閉程式.\n");
			break;
		}
		else if(size < 0 || uin == 0)
		{
			printf("輸入數字不合規定.\n");
			exit(0);
		}

		fflush(stdin);
		printf("請問要 1) 順時針 / 2) 逆時針方向走 : ");
		uin = scanf("%d", &clock);

		if(uin == 0)
		{
			clock = 1;
			printf("輸入方向不合規定. 使用預設值 順時針\n");
		}

		//起點位置
		switch(clock)
		{
			case 1:
			case 2:		x = -1;	y = 0;	dir = 0;	break;
			default:	x = -1;	y = 0;	dir = 0;	clock = 1;
					printf("輸入方向不合規定. 使用預設值 順時針\n");	break;
		}

		fflush(stdin);
		printf("請問起點在 1) 左上 2) 左下 3) 右上 4) 右下 : ");
		uin = scanf("%d", &start);

		if(start < 1 || start > 4 || uin == 0)
		{
			start = 1;
			printf("起點選擇錯誤, 使用預設值 左上起點\n");
		}

		fflush(stdin);
		printf("請問要 1) 由小到大 / 2) 由大到小 : ");
		uin = scanf("%d", &sob);

		if(sob != 1 && sob !=2 || uin == 0)
		{
			sob = 1;
			printf("大小排序選擇錯誤, 使用預設值 由小到大\n");
		}

		/// For Debug ///
		//printf("(%d)(%d)(%d)\n", dir, clock, size);

		// 動態取得質數陣列空間
		snail = (int **)malloc(sizeof(int *)*size);
		for(int i = 0; i < size; i++)
		{
			snail[i] = (int *)malloc(sizeof(int)*size);
		}

		// 初始化方陣
		for(int i = 0; i < size; i++)
		{
			for(int j = 0; j < size; j++)
			{
				snail[i][j] = 0;
			}
		}

		/// For Debug ///
		//printf("(%d)(%d)(%d)\n", dir, clock, size);

		// 使用老鼠走迷宮方式探測方陣
		for(int i = 1; i <= size*size; i++)
		{
			// 順時針 右 0 下 1 左 2 上 3   逆時針 下 3 右 2 上 1 左 0
			// 先按照既定方向走一格
			/// For Debug ///
			//printf("(%d)(x=%d)(y=%d)\n", dir, x, y);
			switch(dir%4)
			{
				case 0:		x++;	break;
				case 1:		y++;	break;
				case 2:		x--;	break;
				case 3:		y--;	break;
			}
			// 檢查 X 軸是否越界, 越界就退回並轉向
			if(x >= size)
			{
				x--;	dir++;	y++;
			}
			else if(x < 0)
			{
				x++;	dir++;	y--;
			}

			// 檢查 Y 軸是否越界, 越界就退回並轉向
			if(y >= size)
			{
				y--;	dir++;	x--;
			}
			else if(y < 0)
			{
				y++;	dir++;	x++;
			}

			// 下一站已經填了數字 : 回頭 -> 轉向 -> 定位
			if(snail[x][y])
			{
				switch(dir%4)
				{
					case 0:         x--;	dir++;	y++;	break;
					case 1:         y--;	dir++;	x--;	break;
					case 2:         x++;	dir++;	y--;	break;
					case 3:         y++;	dir++;	x++;	break;
				}
			}

			snail[x][y] = (sob%2) ? i : size*size-i+1;
		}

		printf("\n");

		// 輸出方陣

		if(start == 1)
		{
			for(int i = 0; i < size; i++)
			{
				for(int j = 0; j < size; j++)
				{
					if(clock == 1)
						printf("%3d ", snail[j][i]);
					else
						printf("%3d ", snail[i][j]);

					if(j == size - 1)
						printf("\n");
				}
			}
		}
		else if(start == 2)
		{
			for(int i = size -1; i >= 0; i--)
			{
				for(int j = 0; j < size; j++)
				{
					if(clock == 1)
						printf("%3d ", snail[i][j]);
					else
						printf("%3d ", snail[j][i]);

					if(j == size - 1)
						printf("\n");
				}
			}
		}
		else if(start == 3)
		{
			for(int i = 0; i < size; i++)
			{
				for(int j = size - 1; j >= 0; j--)
				{
					if(clock == 1)
						printf("%3d ", snail[i][j]);
					else
						printf("%3d ", snail[j][i]);

					if(j == 0)
						printf("\n");
				}
			}
		}
		else if(start == 4)
		{
			for(int i = size-1; i >= 0; i--)
			{
				for(int j = size-1; j >= 0; j--)
				{
					if(clock == 1)
						printf("%3d ", snail[j][i]);
					else
						printf("%3d ", snail[i][j]);

					if(j == 0)
						printf("\n");
				}
			}
		}

		//printf("\n請問是否要繼續產生蝸牛矩陣 ? (按任意鍵繼續, 輸入 N / n 離開) ");
		//choice=getche();
		//if(choice == 'N' || choice == 'n')
		//	break;
		printf("\n");

	// 程式重複執行區塊 結束 
	}


// 主程式 結束
}

範例七 魔方陣 include stdio.h stdlib.h

int main()
{
	int size = 0, uin, x, y, nx, ny;
	int **magicmatrix;

	while(1)
	{
		size = uin = 0;
		printf("請輸入方陣大小, 必須為奇數的正整數 ( 輸入 0 結束程式 ) ");
		uin = scanf("%d", &size);
		if(size == 0)
		{
			printf("結束使用程式.\n");
			break;
		}
		else if(size < 0 || !(size%2))
		{
			continue;
		}
		else if(uin == 0)
		{
			printf("方陣大小不符規定.\n");
			exit(0);
		}

		printf("產生空的方陣\n");
		magicmatrix = (int **)malloc(sizeof(int*)*size);
		for(int i = 0; i < size; i++)
		{
			magicmatrix[i] = (int *)malloc(sizeof(int)*size);
		}
		for(int i = 0; i < size; i++)
		{
			for(int j = 0; j < size; j++)
			{
				magicmatrix[i][j] = 0;
			}
		}

		printf("開始填方陣\n");
		//起點
		x = size/2;
		y = 0;
		magicmatrix[x][y] = 1;
		//
		for(int i = 2; i <= size*size; i++)
		{
			// 先往右上
			nx = (x + 1) % size;
			ny = (y+size-1) % size;

			if(magicmatrix[nx][ny])
			{
				// 碰壁填下方
				nx = x;
				ny = (y+1) % size;
			}

			/// For Debug ///
			//printf("x=%d y=%d nx=%d ny=%d\n", x, y, nx, ny);

			// 開始填方陣
			x = nx;
			y = ny;
			magicmatrix[x][y] = i;
		}

		printf("輸出結果\n");
		for(int i = 0; i < size; i++)
		{
			for(int j = 0; j < size; j++)
			{
				printf("%3d ", magicmatrix[j][i]);
			}

			printf("\n");
		}

		printf("\n");
	}

	printf("感謝使用.\n");

	return 0;
}