孤獨是什麼...
一九四六年諾貝爾文學獎得主,以《玻璃珠遊戲》、《流浪者之歌》
等著作聞名於世的赫曼‧赫塞說:
我們必須孤獨,全然孤獨,才能退回到自我深處。這是一種痛苦的
經驗,但唯有如此我們才能克服孤獨感,才不再感到寂寞,因為我
們發現最深沉的自我乃是與天地一體,與萬物不分。突然之間,我
們發現自己處於世界的中心,卻不為其萬象所擾,因為我們已經與
萬物合而為一了。
曾經 我也孤獨的與黑夜為友 , 那是一種說不出的滋味 ; 不習慣孤獨的
人會害怕它 , 孤獨了一陣子的人會習慣它 , 離開孤獨的人會想念它 ...
對我而言 , 孤獨是與自己聊天 傾聽自己聲音的時刻 , 特別是在凌晨破
曉時分一個人走在工學院到停車場的路上時~~
孤獨的我 是為了等待 讓我不孤獨的妳
妳是讓我離開孤獨的唯一理由
Issaac
...
read more
2007年7月26日 星期四
2007年7月24日 星期二
[+/-] : [ 久違的全家出遊 ~ 2007.07.22(日)非常熱 ]
話說一大早 就被持續不停的電話吵起來
逸 : '' 喂~~ 你們的服務我知道很好 但我沒叫morning call阿(累...) ''
某位胖胖的劉太太: '' 早起的鳥兒有蟲吃 你們再不起來 我就要去騷擾你們嚕(興奮樣)~~''為了保全學生我寶貴的貞操 , 也只好趕快起床了
十分鐘後 某帥哥就在帝寶的2樓享用起豐盛的早餐
話說這家餐廳的早餐 , 真的很不賴 , c/p值極高
最特別的是他們提供了四種口味的包子和水餃 , 柳橙汁飄散著鮮美的微小果粒 ,
以及又香又甜的楓糖可頌 ,再再的叫人很難不滿意 ^_____^
用過早餐後 , 我們便前往東海大學遊玩 , 儘管天氣很熱 , 但在著名的東海大教堂
前一點也不影響我們的興致 , 藍色的天空擁著壯麗的教堂 , 在環繞的群綠裡 ,
帶著親切的莊嚴 , 附近恰巧有著一群小朋友的營隊 , 一點小吵鬧的他們 , 讓我
眼前的畫面 , 補足了原本不足的活潑 ; 風兒徐徐吹來 , 讓人精神一振 , 這就是我
們家庭出遊要追求的目標 , 輕鬆寫意自由自在的與最熟悉的人聚在一起 ,
儘管我的小瑤瑤不在身邊 , 但我相信這只是遲早的事 , 相伴一生的浪漫約定 , 用
一點短暫的分離當作提味 , 只會讓未來的我們在回憶過去交往時每次相聚的畫面 ,
都帶著最徹底的感動 ~~
之後, 我們又跟著精通台中市好吃好玩的導遊老弟四處吃透透 , 吃了東海附近出名的雞腳凍 + 芋圓 + 春水堂奶茶, 最後逛了一下附近著名的藝術街 , 才趟上歸途.
==========================================================
~ 人生就是要 努力的工作 努力的玩 還有努力的珍惜與身邊人的緣分 ~ 逸...
read more
逸 : '' 喂~~ 你們的服務我知道很好 但我沒叫morning call阿(累...) ''
某位胖胖的劉太太: '' 早起的鳥兒有蟲吃 你們再不起來 我就要去騷擾你們嚕(興奮樣)~~''為了保全學生我寶貴的貞操 , 也只好趕快起床了
十分鐘後 某帥哥就在帝寶的2樓享用起豐盛的早餐
話說這家餐廳的早餐 , 真的很不賴 , c/p值極高
最特別的是他們提供了四種口味的包子和水餃 , 柳橙汁飄散著鮮美的微小果粒 ,
以及又香又甜的楓糖可頌 ,再再的叫人很難不滿意 ^_____^
用過早餐後 , 我們便前往東海大學遊玩 , 儘管天氣很熱 , 但在著名的東海大教堂
前一點也不影響我們的興致 , 藍色的天空擁著壯麗的教堂 , 在環繞的群綠裡 ,
帶著親切的莊嚴 , 附近恰巧有著一群小朋友的營隊 , 一點小吵鬧的他們 , 讓我
眼前的畫面 , 補足了原本不足的活潑 ; 風兒徐徐吹來 , 讓人精神一振 , 這就是我
們家庭出遊要追求的目標 , 輕鬆寫意自由自在的與最熟悉的人聚在一起 ,
儘管我的小瑤瑤不在身邊 , 但我相信這只是遲早的事 , 相伴一生的浪漫約定 , 用
一點短暫的分離當作提味 , 只會讓未來的我們在回憶過去交往時每次相聚的畫面 ,
都帶著最徹底的感動 ~~
之後, 我們又跟著精通台中市好吃好玩的導遊老弟四處吃透透 , 吃了東海附近出名的雞腳凍 + 芋圓 + 春水堂奶茶, 最後逛了一下附近著名的藝術街 , 才趟上歸途.
==========================================================
~ 人生就是要 努力的工作 努力的玩 還有努力的珍惜與身邊人的緣分 ~ 逸...
read more
2007年7月22日 星期日
[+/-] : [ 久違的全家出遊 ~ 2007.07.21(六)超熱 ]
台中 -> 美術館 -> 逢甲夜市 -> 金樺飯店 -> 東海大學 -> 家
多麼美妙的組合阿 呵呵
如果能扣去 汽車冷氣壞調的維修
還有那兇猛的大太陽
還真是一趟完美的兩天一夜之旅呢
自金樺飯店步行至美術館的路上
走的是綠蔭小徑
途中順道造訪了台中市文化中心 欣賞了個人畫展
看到了正在發功,水柱神功護體的小孩
還有那些美麗的造景和為數眾多的魚兒
終於走到美術館嚕
合照留念是一定要的啦 畢竟人生能有幾次 是自己傻傻的從飯店走一個小時多到美術館的經驗呢
館內目前正在展示 妮基˙德˙桑法勒的異想世界 , 一個從名模到藝術家的傳奇的法國女性, 她的作品前半期以寫實主義的射擊藝術(以來福槍射擊懸掛在畫布前的顏料袋之後,在畫布上所形成的圖案)出名 , 後期以頭小小身體很巨大的混凝紙漿製作-NANA(法文中意味的粗俗女人)為主, 說實在的我認為她是一個瘋子 , 不過有時也只有瘋子才會有超脫一般人的藝術表現 , 是瘋子造就了藝術 , 抑或是藝術製造出瘋子 , 沒有人知道 ,我唯一能用眼睛看出來的只有獨自去看展的正妹不少 , 這點我弟跟我英雄所見略同 ,事實又再一次的證明了我們果然都是真男人 ,不要亂叫我們東亞病夫,俗俗可是有練過的唷
到了晚上 肯定要去吃吃喝喝
但是, 假日的逢甲夜市, 真是個恐怖的沙丁魚地獄阿~~~~
停車找不到地方
夜市中擠到暴
揮汗成雨 比肩接踵 還有莫名其妙的橫走喔巴桑
所以沒照片是很正常的事 哈哈
總而言之 言而總之
星期六是個奇妙的一天
看到正妹露的肉比吃的肉還多
雙腳移動距離比上班一周走的路還多很多
期待明天的到來
ps: 不過看著正妹 心理還是想著我專屬的正妹 所謂身在異邦心在漢
所以我也是勉為其難的讓眼睛吃冰淇淋唷(好險我突然想到補充這句...挖哈哈)...
read more
多麼美妙的組合阿 呵呵
如果能扣去 汽車冷氣壞調的維修
還有那兇猛的大太陽
還真是一趟完美的兩天一夜之旅呢
自金樺飯店步行至美術館的路上
走的是綠蔭小徑
途中順道造訪了台中市文化中心 欣賞了個人畫展
看到了正在發功,水柱神功護體的小孩
還有那些美麗的造景和為數眾多的魚兒
終於走到美術館嚕
合照留念是一定要的啦 畢竟人生能有幾次 是自己傻傻的從飯店走一個小時多到美術館的經驗呢
館內目前正在展示 妮基˙德˙桑法勒的異想世界 , 一個從名模到藝術家的傳奇的法國女性, 她的作品前半期以寫實主義的射擊藝術(以來福槍射擊懸掛在畫布前的顏料袋之後,在畫布上所形成的圖案)出名 , 後期以頭小小身體很巨大的混凝紙漿製作-NANA(法文中意味的粗俗女人)為主, 說實在的我認為她是一個瘋子 , 不過有時也只有瘋子才會有超脫一般人的藝術表現 , 是瘋子造就了藝術 , 抑或是藝術製造出瘋子 , 沒有人知道 ,我唯一能用眼睛看出來的只有獨自去看展的正妹不少 , 這點我弟跟我英雄所見略同 ,事實又再一次的證明了我們果然都是真男人 ,不要亂叫我們東亞病夫,俗俗可是有練過的唷
到了晚上 肯定要去吃吃喝喝
但是, 假日的逢甲夜市, 真是個恐怖的沙丁魚地獄阿~~~~
停車找不到地方
夜市中擠到暴
揮汗成雨 比肩接踵 還有莫名其妙的橫走喔巴桑
所以沒照片是很正常的事 哈哈
總而言之 言而總之
星期六是個奇妙的一天
看到正妹露的肉比吃的肉還多
雙腳移動距離比上班一周走的路還多很多
期待明天的到來
ps: 不過看著正妹 心理還是想著我專屬的正妹 所謂身在異邦心在漢
所以我也是勉為其難的讓眼睛吃冰淇淋唷(好險我突然想到補充這句...挖哈哈)...
read more
2007年7月20日 星期五
[+/-] : Qos module
...
sch_ingress.c
http://bbs.chinaunix.net/viewthread.php?tid=849145&highlight=qtdszws
使用ingress的內核處理流程
tc qdisc add dev eth0 handle ffff: ingress
tc filter add dev eth0 parent ffff: pref 10 protocol ip u32
1.init_module->nf_register_hook
註冊ingress的鉤子到
static struct nf_hook_ops ing_ops =
{
{ NULL, NULL},
ing_hook,
PF_INET,// 2
NF_IP_PRE_ROUTING,//註冊到PRE_ROUTING
NF_IP_PRI_FILTER + 1
};
2.網卡接收到一個ip資料包後調用ip_input.c中的ip_rcv
NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL,ip_rcv_finish)
NF_HOOK定義如下
#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \
(list_empty(&nf_hooks[(pf)][(hook)]) \
? (okfn)(skb) \
: nf_hook_slow((pf), (hook), (skb), (indev), (outdev), (okfn)))
因此將調用nf_hook_slow,在core/netfilter.c中
nf_hook_slow->nf_iterate-> hook-> ing_hook(ingress的鉤子函數)-> ingress_enqueue(入隊)-> tc_classify(分類)
3.根據分類結果決定繼續處理該包,還是丟棄(例如被管制器管制)
======================================================================
sch_teql.c
teql原理
1.在Linux的高級路由和流量控制HOWTO.pdf有一些說明,可以參照
2.teql實現了一個簡單的多網卡負載均衡.簡單,是因為它不考慮實際的硬體情況,只是在關聯的實際設備之間輪轉轉發包,即使是一個千兆網卡和MODEM被關聯在一起.可以稱做發包數負載均衡吧.
3.insmod sch_teql.o時, init_module會註冊一個名為teql0的虛網路介面和一個名為teql0的佇列規程,他們被集成在struct teql_master結構中,彼此分不開.
可以使用一下命令綁定實設備到佇列規程teql0
tc qdisc add dev eth0 root teql0
tc qdisc add dev eth1 root teql0
然後用命令ip link set dev teql0 up啟動虛設備teql0
這樣一個teql設備就配置完成了
接下來可以再配置另一個teql設備
insmod –o sch_teql1 sch_teql.o
我這是RED HAT 7.2,由於已經載入了sch_teql.o模組,只能重命名載入了.
新版本內核已經實現一次insmod就可指定若干個teql
tc qdisc add dev eth2 root teql1
tc qdisc add dev eth3 root teql1
ip link set dev teql1 up
4.當有資料包到達teql0時先進入自己的佇列,缺省為pfifo_fast,然後內核就調用teql_master_xmit來在從設備中迴圈輪轉選擇一個設備eth*發包.如果teql*是該實設備的根佇列規程,就直接調用eth*的hard_start_xmit函數發包.如果不是就選擇下一個設備,只至成功或失敗.而配置在該設備上的teql*規程,它的行為就類似於pfifo規程.這是給那些直接通過該設備發送的包準備的規程.
teql.rar
======================================================================
sch_red.c random early detection
隨機早期探測
參考http://www.icir.org/floyd/papers/red/red.html 中的early.pdf
說明
1.qlen 為當前佇列長度
2.qave 平均佇列長度,它的計算公式是qave=qave*(1-W)+qlen*W,W為權重,W一般選得很小 ,這可以使突發包對qave不會產生太大波動
3.qmin,qmax 當qmin<=qave<=qmax時,開始隨機標記/丟包,標記/丟包的概率為 max_P * (qave- qmin)/(qmax-qmin),,隨著qave增長,概率逼近max_P 標記包是希望用戶端知道目前網路已經開始擁擠,放慢發包速度吧 如果qave>=qmax,標記/丟棄所有的包
4.如果網路空閒了一段時間,就應該相應地減少qave的大小,qave=qave*(1-W)^m,m為空閒時間段長度
sch_red.rar
路由分類器cls_route.c
路由分類器的原理很簡單,就是在路由的時候由路由規則對資料包打標記.路由分類器就用這個標記來對資料包分類.
路由規則語法如下
ip route add Host/Network via Gateway dev Device realm RealmNumber
例
ip route add 192.168.10.0/24 via 192.168.10.1 dev eth1 realm 10
至於如何打標記,我現在還不瞭解
在設置了路由規則以後,就可以使用路由分類器分類資料了
tc filter add dev eth0 protocol ip prio 100 route to 10 classid :2
tc filter add dev eth0 protocol ip prio 100 route from 10 classid :1
路由分類器參考的參數有fromdev/from,to,fromdev和from互斥,只能使用其中一個,由他們在分類器的二層hash表中索引和查找.
資源預留協議分類器cls_rsvp.h
資源預留協定分類器的原理也很簡單,就是用ip協定(也支援ipv6,此處不涉及)的目的地址,可能的目的埠,源位址,可能的源埠來索引和查找一個二層hash表.
"可能的"意思是不一定使用,由用戶決定.也就是它是基於session(會話)的.
tc filter add dev eth0 pref 10 protocol ip rsvp ipproto tcp session 10.1.1.1/80 classid :1
這條規則的意思就是,到10.1.1.1:80的資料流程分類到:1的佇列
還可以加入sender,指定發送者,或者不指定埠,而指定一個GPI,也就是在offset處的值&mask==key方式更加靈活地指定一個匹配.
route_rsvp.rar
sch_dsmark.c和cls_tcindex.c
diffserv是一個體系,需要一個有若干個路由和一定規模的網路來協作實現,就單個主機來說用處不大.在這個網路中,大家都遵守同樣的diffserv協定,例如哪個dsfield的優先順序高,哪個低,以及怎樣處理等.
這裏引入了域的概念,就是遵守某一diffserv協定的網路組成一個ds域.剩下的就是非ds域.一台域中的主機要發的包,可以在自己的出口佇列分類,或在接入的路由上分類.
1.在本機分類,出口綁定dsmark佇列規程和u32等分類器
2.在路由分類,路由入口綁定ingress佇列規程和u32等分類器
注:上面的分類器一般不用tcindex分類器,因為是從非ds域到ds域的轉換,而tcindex實用於使用已有ds field來分類流(見3)和不同ds域之間的轉換,不同域之間的轉換一般發生在入口上,例如上面的2,如果資料是從另外一個ds域來的話.
這樣所有的流就被區分開了.
3.然後路由器就可以在自己的出口綁定dsmark佇列規程(和一些內部佇列,例如cbq)和tcindex分類器,讓tcidnex分類來對不同級別的流(只根據ds field)進行整形和qos.
上面都是我的理解,化了我很長時間,不對之處,請大家指正.大家參考lartc上的說明.
下面的例子也是摘之lartc
tc qdisc add dev eth0 handle 1:0 root dsmark indices 64 set_tc_index#綁定dsmark佇列規程
tc filter add dev eth0 parent 1:0 protocol ip prio 1 tcindex mask 0xfc shift 2#建立tcindex分類器
tc qdisc add dev eth0 parent 1:0 handle 2:0 cbq bandwidth 10Mbit cell 8 avpkt 1000 mpu 64 # EF traffic class內部佇列
tc class add dev eth0 parent 2:0 classid 2:1 cbq bandwidth 10Mbit rate 1500Kbit avpkt 1000 prio 1 bounded isolated allot 1514 weight 1 maxburst 10 # Packet fifo qdisc for EF traffic子類
tc qdisc add dev eth0 parent 2:1 pfifo limit 5 #子類的佇列規程
tc filter add dev eth0 parent 1:0 protocol ip prio 1 handle 0x2e tcindex classid 2:1 pass_on #例子中是parent 2:0,我認為是parent 1:0,把EF流分類到2:1子類,不懂EF流是怎麼回事,半桶水^_^
sch_gred.c Generic Random Early Detection
這個演算法是在red的基礎上擴展引入virtual queue的概念形成的.
在gred中最多可以引入16個vq,其中至少有一個缺省vq.
每個vq都基本按red演算法來操作(有區別),但所有的這些vq都公用一個實際的佇列
sch->q.
gred演算法有四種模式,由參數eqp和grio控制(不知道是什麼的縮寫)
(注意是否開始隨機丟包由qave+q->qaveqth_min控制)
eqp grio
0 0 每個vq一個獨立red (qave=0),但共用一個實佇列
0 1 每個vq和比它優先順序高的vq構成一個部分相關red,保證優先順序高的vq優先發包
qave+q->qave的值是按照相關的每個vq自己計算的ave的總和
1 0 每個vq一個部分相關red,和sch->backlog相關 (qave=0)
q->qave的值是把sch->backlog按本vq的方式計算ave的值
1 1 每個vq一個全部相關red (qave=0)
q->qave的值是把sch->backlog按本vq的方式計算ave的累計總和
我認為比較有用的是(0,0)(有點類似於sfq)和(0,1)(有點類似於prio)
gred實際上和red一樣都比較難配置,主要應用于路由器上
因為它是採用skb->tc_index來選擇vq的,可以和dsmark規程和tcindex分類器協作
gred.rar
estimator.c和police.c
--------------------------------------------------------------
estimator用於估計包的速度,包括bps(每秒位元組數)和pps(每秒包數).
estimator的調用獨立於qos架構,每個estimator一個內核計時器,可以每1/4s,1/2s,1s,2s,4s,8s被調用一次,定時計算
它可以應用在佇列規程上和分類器上.
1.在佇列規程上,它把計算結果放在qdisc->stats中,到目前為止我還沒有看到誰在使用這個結果,不過這可以讓用戶監視和評估該規程上的流量
2.在分類器上,在分類器的每個策略中都有一個tcf_police結構,估計結果就放入該結構的stats成員中.在策略被命中後,將調用tcf_police,如果使用了估計器,tc_police就根據估計結果決定通過該策略的資料流程量是否超限,是的話就執行規定的動作,ok,drop,reclassify,unspec.
Usage: ... estimator INTERVAL TIME-CONST
interval為定時間隔,time-const的計算方法是w=interval/time-const,w為加權比,例est 1s 8s,則定時間隔為1s,w=1/8=0.125
------------------------------------------------------------------
police用於分類器上,前面已經提到,策略被命中就會調用tcf_police,對通過該策略資料的進行管制
除了使用可選的estimator的結果進行管制以外,police主要使用tbf(權杖桶篩檢程式)對流進行管制操作.tbf的理論在前面已經敍述過了.tbf使用常規桶和峰值桶來控制流量.對於超限的包執行規定的動作.
Usage: ... police rate BPS burst BYTES[/BYTES] [ mtu BYTES[/BYTES] ]
[ peakrate BPS ] [ avrate BPS ]
[ ACTION ]
Where: ACTION := reclassify drop continue
avrate用於estimator,判斷流量是否超限
lartc上有一個"防護SYN洪水攻擊例子"用到police
iptables -A PREROUTING -i $INDEV -t mangle -p tcp --syn -j MARK --set-mark 1
$TC qdisc add dev $INDEV handle ffff: ingress
$TC filter add dev $INDEV parent ffff: protocol ip prio 50 handle 1 fw
police rate 1kbit burst 40 mtu 9k drop flowid :1
read more
[+/-] : XML RPC簡單上手
1. 基本精神與使用,內含簡單的Server+Client程式範例
http://xmlrpc-c.sourceforge.net/doc/#clibrariese
2. C API for XML-RPC
http://xmlrpc-epi.sourceforge.net/main.php?t=php_api...
read more
http://xmlrpc-c.sourceforge.net/doc/#clibrariese
2. C API for XML-RPC
http://xmlrpc-epi.sourceforge.net/main.php?t=php_api...
read more
2007年7月18日 星期三
[+/-] : C語言中陣列與指標的結合(二)
[轉錄自 http://blog.chinaunix.net/u1/36619/showart_335038.html]
C語言中陣列與指標的結合(二)
4.C語言中函數對陣列的傳遞
實際上,在C語言中沒有辦法把陣列本身傳遞給一個函數,
如果將陣列作為函數的實參,它將自動被改為指向陣列的指標。
C語言中函數參數的傳遞採用的是值傳遞的方式,除了陣列之外
的所以資料類型在傳遞時,都是使用複製一份完整的新拷貝的方式。
出於效率的考慮,C在傳遞陣列時,沒有將整個陣列複製,而是把陣列的位址壓入棧中傳遞給被調用函數,被調用函數從棧中獲取位址值,由此訪問被傳遞的陣列。因此,實際上被傳遞的參數是一個指向陣列的指標,而原本陣列大小的資訊則被丟失了。所以無論傳入的是陣列還是指標,被調用函數實際上得到的都只是指標。因此,C標準規定,在用作函數的形參時,以陣列形式定義的形參被編譯器當作指向該陣列的指標類型。
陣列參數自動改寫為指標的規則並不遞迴,二維陣列被改成的類型是指向陣列的指標,而不是指標的指標。所以,
char c[5][6];
對應的形參類型是
char (*p)[6];
而指標陣列
char *c[];
對應的形參類型才是
char **c;
5.向函數傳遞陣列
對於固定長度的陣列傳遞,情況比較簡單,如上面所說:
傳遞類型為
char c[5][6];
的陣列給函數,只需要把函數的形參類型聲明為
char (*p)[6];
或
char c[5][6];
即可。
但是要注意的是,被調用函數得到的只是指標,所以需要某種途徑把陣列的長度告訴被調用函數。一種方式是用某種特定的數值來表示陣列的結尾,比如對於字串,C語言定義了'\0',當檢索到結尾標誌時,函數就知道陣列結束了。另一種方式是,使用一個額外的參數來傳遞陣列長度,比如大家的老朋友,
int main(int argc, char *argv[]);
如果希望函數能接受的陣列參數更靈活一些,能具有可變長度,就需要比較曲折的方法了。因為陣列的第一維將被改為指標類型,陣列形參定義中最左邊的一維中的數字沒有效果。可以定義為,
char c[];
或者
char c2[][5];
這部分的解決了我們的問題,但如果希望c2的兩維都可變,就不能通過這種方式的參數傳遞了,需要使用的是指標陣列。
6.指標陣列
指標陣列的是以指標為元素的陣列。它的訪問方式和二維陣列很像,定義
char c[5][6];
char *cp[];
都可以用連續下標的方式訪問,
c[2][3] = cp[2][3];
但是它們實際上的訪問方式並不一樣:
先看c[2][3],它是取符號表中記錄的c位址,加上2*sizeof(char [6]),再加上3*sizeof(char),得到元素的位址。
而cp[2][3]則是取指針cp的值,加上2乘以指標寬度,得到指標cp[2]的地址;然後從位址取得內容,再以此內容為位址加上偏移量3*sizeof(char),得到元素的位址。
傳遞可變二維陣列的方法就是逐個把陣列第n行第一個元素的位址,賦予指標陣列的第n個元素,然後以指標陣列為參數,傳遞給被調用函數。
當然,也可以不把指標陣列作為二維陣列的載體,而把它作為多個不連續的不定長一維陣列的載體,不過記住,在傳遞時需要找到一種方法告知被調用函數所有的這些一維陣列的長度,對於字串這會比較容易。
7.使用動態陣列
在ANSI C中,不允許在運行時動態指定陣列的長度(C99中允許,參考C99 6.7.5)。為了突破這個限制,可以使用malloc()動態分配記憶體,(在cast為合適的類型後)以陣列下標的形式訪問這塊記憶體。更進一步,為了讓陣列的大小能真正的動態變化,可以根據陣列元素的實際數目,使用realloc()為你的陣列重新分配合適大小的記憶體。
...read more
[+/-] : C語言中陣列與指標的結合(一)
[轉錄自 http://blog.chinaunix.net/u1/35100/showart_338097.html]
對於C語言中指標和陣列的認識和看法
1. 指標變數也只是普通的變數
很多C語言的初學者都將指標變數看的很神秘,實際上,就像其他的普通變數
(比如int類型的),指標變數也是一種普通變數,他具有其他變數的一切特徵。
例如:int main(){int q=10;int *pi=0;pi = &q;printf ("%d\n", *pi);}
main中聲明並定義了一個自動變數p,他的類型是pointer-to-int.一旦定義了p,
編譯器就要給p分配記憶體空間。main結束後,p被自動釋放。
pi和q在這些方面沒有絲毫不同。
結論:指標變數沒有那麼神秘,指標變數只是一個普通變數
2. 指標變數與其他變數的關係
那麼,指針的特殊性表現在什麼地方呢?
指標特殊就特殊在對他所存儲的值的解釋上和對他的使用上。
在上例中,pi的值會被解釋成記憶體中的一個位址,
以這個位址開始的一塊記憶體則表示一個int型的數.
但是,即使在執行了pi = &q之後,pi和q也沒有什麼直接的關係:
改變pi的值不會影響q,改變q的值也不會影響pi,
他倆是兩個獨立的變數,有各自的存儲空間。
C語言賦予了指標特殊的本領就是:可以存儲別的變數的記憶體位址,
也可以利用指標變數本身的值去間接的操作別的變數.
這兩種能力是通過兩個操作符來完成的 : &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;和*。
pi = &q;
//利用q的記憶體位址對pi進行賦值printf ("%d\n", *pi); //利用pi的值去間接的讀q的值
sizeof(pi)跟sizeof(q)根本就是兩碼事. pi不會自動根據自己去尋找q的,只有你顯示的使用*pi才可以.
結論:假設指標pi存儲的是q的位址。pi和q沒有任何直接的關係。只有*pi才和q有直接的關係。
3. C語言中的函數參數傳遞方式
很多人的另外一種誤解是,C語言中有兩種函數傳遞方式:按值傳遞和按地址傳遞。
造成這種誤解的原因就是對上面所說的兩點理解的不夠。
void swap1( int a, int b){int temp;temp = a;a = b;b = temp;}
void swap2( int* pa, int* pb){int temp;temp = *pa;*pa = *pb;*pb = temp;}
int main(){
int i=10, j=5;
int *pi, *pj;
pi = &i;
pj = &j;
swap1(i, j);printf("i=%d, j=%d\n", i, j);
swap2(pi, pj);printf("i=%d, j=%d\n", i, j);
}
很多人會認為swap1是按值傳遞,而swap2是按指針傳遞。
其實,C語言只有一種函數參數傳遞方式:按值傳遞。
swap1大家都明白,我說一下swap2。
實際上,我在第一點中已經指出,指標只是一個普通變數而已。
在對swap2的調用swap2(pi, pj)中, pi和pj的值分別被copy到swap2中的pa和pb中。
現在,i,pi和pa是3個完全不同的變數,但pi和pa的值相同,他們存的都是i的地址。
在swap2中,利用*pa就可以讀寫i了,同樣利用*pb就可以讀寫j了,
所以swap2就可以完成i和j的交換了。但是,pi和pj的值通過 swap2是無法改變的。
也就是說, swap2使用的參數傳遞方式仍然是按值傳遞,只不過傳遞的是指標的值,
然後利用指標有可以間接訪問其他變數而已.
結論:C語言只有一種函數參數傳遞方式:按值傳遞.
4. 指標與陣列
4.1 陣列名稱的類型
在C語言中,指標與陣列千絲萬縷的聯繫.看下面的例子:
int a[5];int b[3][5];int *pa1[5];int (*pa2)[5];
那麼a,b,pa1,pa2的類型到底是什麼呢?
很多人將a的類型誤解成為一級指標,即const pointer to int,
而將b的類型誤解成為二級指標,即const pointer to the pointer to int;
a不是const pointer to int類型的,我們是可以從下面這個事實推出來的:
sizeof(a)跟sizeof(int*)是不同的.
只能說,a是array of 5 ints類型的
而b則是array of 3 arrays of 5 ints類型的
這裏之所以把pa1和pa2列出來,主要是給大家區別一下:
pa1是array of 5 int pointers類型的,
而pa2是pointer to array of 5 ints類型的
4.2 陣列名稱的運算
大家經常會遇到關於陣列名稱的運算問題,比如
int a[5]={1, 2, 3, 4, 5};
int b[3][5]={{1,2,3,4,5}, {6,7,8,9,10}, {11,12,13,14,15}};
printf("%d", *(a+2));
printf("%d, %d\n", **(b+2), *(*b+2));
在進行上面的運算時,有下面的似非而是的結論:
&a可以看作是pointer to array of 5 ints類型的所以&a+1,這裏的“1”是指5*sizeof(int)
a是array of 5 ints類型的,但是a的值是什麼呢?
a的值其實是一個pointer to int
*a的值則是一個int,即a[0];
&b可以看作是pointer to array of 3 arrays of 5 ints類型的
所以&b+1, 這裏的“1”是指3*5*sizeof(int)
b 是array of 3 arrays of 5 ints類型的,
但是b的值卻是一個pointer to array of 5 ints
*b是array of 5 ints類型的,
但是*b的值卻是pointer to int類型的
**b的值則是int類型的,即b[0][0];
推而廣之,則對於 int c[n1][n2]...[nm]的m維陣列(m後面的數位為下標),
有下面的結論(或者說計算方法):
先將c擴展為int c[n1][n2]...[nm][1]; (最後一個是數位1,不是字母l)
1.&c的單位“1”為n1*n2*...*nm*1*sizeof(int)
sizeof(&c)等於存儲一個指標的大小,
其值與sizeof(int*)相同;
2.令c1代表*...*c,共有 i 個 (0< color="#3333ff">則他的單位“1”為n(i+2)*...*nm*1*sizeof(int),
其中(i+2)等是下標sizeof(c1)=n(i+1)*...*nm*sizeof(int) 3.令c2代表*...*c,共有m個*,
表示陣列中第一個整數sizeof(c2)=sizeof(int)
例如:int c[3][4][5][6];先轉換成int c[3][4][5][6][1];
&c+1 相當於地址加3*4*5*6*1*sizeof(int), sizeof(&c)的值等於sizeof(int*);
c+1 相當於地址加4*5*6*1*sizeof(int), sizeof(c)=3*4*5*6*1*sizeof(int);
**c+1 相當於地址加6*sizeof(int), sizeof(**c)=5*6*1*sizeof(int);
****c 就是陣列中第一個整數
4.3 一種常見錯誤
int b[3][5];int **p=b;
有些人誤認為p+1的值和b+1是相同的,其實不然
類似於
T1 b1;T2* b2=(T2*)(&b1); //T1,T2為兩種不同的類型
這樣的話,b2+1是按sizeof(T2)進行增加的而&b1+1
是按照sizeof(T1)進行增加的指標進行類型轉換後,
其運算跟他自身的類型有關,而與他指向的東東無關
...
read more
對於C語言中指標和陣列的認識和看法
1. 指標變數也只是普通的變數
很多C語言的初學者都將指標變數看的很神秘,實際上,就像其他的普通變數
(比如int類型的),指標變數也是一種普通變數,他具有其他變數的一切特徵。
例如:int main(){int q=10;int *pi=0;pi = &q;printf ("%d\n", *pi);}
main中聲明並定義了一個自動變數p,他的類型是pointer-to-int.一旦定義了p,
編譯器就要給p分配記憶體空間。main結束後,p被自動釋放。
pi和q在這些方面沒有絲毫不同。
結論:指標變數沒有那麼神秘,指標變數只是一個普通變數
2. 指標變數與其他變數的關係
那麼,指針的特殊性表現在什麼地方呢?
指標特殊就特殊在對他所存儲的值的解釋上和對他的使用上。
在上例中,pi的值會被解釋成記憶體中的一個位址,
以這個位址開始的一塊記憶體則表示一個int型的數.
但是,即使在執行了pi = &q之後,pi和q也沒有什麼直接的關係:
改變pi的值不會影響q,改變q的值也不會影響pi,
他倆是兩個獨立的變數,有各自的存儲空間。
C語言賦予了指標特殊的本領就是:可以存儲別的變數的記憶體位址,
也可以利用指標變數本身的值去間接的操作別的變數.
這兩種能力是通過兩個操作符來完成的 : &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;和*。
pi = &q;
//利用q的記憶體位址對pi進行賦值printf ("%d\n", *pi); //利用pi的值去間接的讀q的值
sizeof(pi)跟sizeof(q)根本就是兩碼事. pi不會自動根據自己去尋找q的,只有你顯示的使用*pi才可以.
結論:假設指標pi存儲的是q的位址。pi和q沒有任何直接的關係。只有*pi才和q有直接的關係。
3. C語言中的函數參數傳遞方式
很多人的另外一種誤解是,C語言中有兩種函數傳遞方式:按值傳遞和按地址傳遞。
造成這種誤解的原因就是對上面所說的兩點理解的不夠。
void swap1( int a, int b){int temp;temp = a;a = b;b = temp;}
void swap2( int* pa, int* pb){int temp;temp = *pa;*pa = *pb;*pb = temp;}
int main(){
int i=10, j=5;
int *pi, *pj;
pi = &i;
pj = &j;
swap1(i, j);printf("i=%d, j=%d\n", i, j);
swap2(pi, pj);printf("i=%d, j=%d\n", i, j);
}
很多人會認為swap1是按值傳遞,而swap2是按指針傳遞。
其實,C語言只有一種函數參數傳遞方式:按值傳遞。
swap1大家都明白,我說一下swap2。
實際上,我在第一點中已經指出,指標只是一個普通變數而已。
在對swap2的調用swap2(pi, pj)中, pi和pj的值分別被copy到swap2中的pa和pb中。
現在,i,pi和pa是3個完全不同的變數,但pi和pa的值相同,他們存的都是i的地址。
在swap2中,利用*pa就可以讀寫i了,同樣利用*pb就可以讀寫j了,
所以swap2就可以完成i和j的交換了。但是,pi和pj的值通過 swap2是無法改變的。
也就是說, swap2使用的參數傳遞方式仍然是按值傳遞,只不過傳遞的是指標的值,
然後利用指標有可以間接訪問其他變數而已.
結論:C語言只有一種函數參數傳遞方式:按值傳遞.
4. 指標與陣列
4.1 陣列名稱的類型
在C語言中,指標與陣列千絲萬縷的聯繫.看下面的例子:
int a[5];int b[3][5];int *pa1[5];int (*pa2)[5];
那麼a,b,pa1,pa2的類型到底是什麼呢?
很多人將a的類型誤解成為一級指標,即const pointer to int,
而將b的類型誤解成為二級指標,即const pointer to the pointer to int;
a不是const pointer to int類型的,我們是可以從下面這個事實推出來的:
sizeof(a)跟sizeof(int*)是不同的.
只能說,a是array of 5 ints類型的
而b則是array of 3 arrays of 5 ints類型的
這裏之所以把pa1和pa2列出來,主要是給大家區別一下:
pa1是array of 5 int pointers類型的,
而pa2是pointer to array of 5 ints類型的
4.2 陣列名稱的運算
大家經常會遇到關於陣列名稱的運算問題,比如
int a[5]={1, 2, 3, 4, 5};
int b[3][5]={{1,2,3,4,5}, {6,7,8,9,10}, {11,12,13,14,15}};
printf("%d", *(a+2));
printf("%d, %d\n", **(b+2), *(*b+2));
在進行上面的運算時,有下面的似非而是的結論:
&a可以看作是pointer to array of 5 ints類型的所以&a+1,這裏的“1”是指5*sizeof(int)
a是array of 5 ints類型的,但是a的值是什麼呢?
a的值其實是一個pointer to int
*a的值則是一個int,即a[0];
&b可以看作是pointer to array of 3 arrays of 5 ints類型的
所以&b+1, 這裏的“1”是指3*5*sizeof(int)
b 是array of 3 arrays of 5 ints類型的,
但是b的值卻是一個pointer to array of 5 ints
*b是array of 5 ints類型的,
但是*b的值卻是pointer to int類型的
**b的值則是int類型的,即b[0][0];
推而廣之,則對於 int c[n1][n2]...[nm]的m維陣列(m後面的數位為下標),
有下面的結論(或者說計算方法):
先將c擴展為int c[n1][n2]...[nm][1]; (最後一個是數位1,不是字母l)
1.&c的單位“1”為n1*n2*...*nm*1*sizeof(int)
sizeof(&c)等於存儲一個指標的大小,
其值與sizeof(int*)相同;
2.令c1代表*...*c,共有 i 個 (0< color="#3333ff">則他的單位“1”為n(i+2)*...*nm*1*sizeof(int),
其中(i+2)等是下標sizeof(c1)=n(i+1)*...*nm*sizeof(int) 3.令c2代表*...*c,共有m個*,
表示陣列中第一個整數sizeof(c2)=sizeof(int)
例如:int c[3][4][5][6];先轉換成int c[3][4][5][6][1];
&c+1 相當於地址加3*4*5*6*1*sizeof(int), sizeof(&c)的值等於sizeof(int*);
c+1 相當於地址加4*5*6*1*sizeof(int), sizeof(c)=3*4*5*6*1*sizeof(int);
**c+1 相當於地址加6*sizeof(int), sizeof(**c)=5*6*1*sizeof(int);
****c 就是陣列中第一個整數
4.3 一種常見錯誤
int b[3][5];int **p=b;
有些人誤認為p+1的值和b+1是相同的,其實不然
類似於
T1 b1;T2* b2=(T2*)(&b1); //T1,T2為兩種不同的類型
這樣的話,b2+1是按sizeof(T2)進行增加的而&b1+1
是按照sizeof(T1)進行增加的指標進行類型轉換後,
其運算跟他自身的類型有關,而與他指向的東東無關
...
read more
[+/-] : Google 自訂桌面功能
很方便的自訂桌面功能
可以把 其他比較常看的東西放到首頁(像是新聞 小時鐘...)
這樣以後開啟首頁就可以一目了然嚕
另外可以自訂個人標籤
放一些比較私人的玩意(像是gmail , picasa...)
Google series 真是創意多多.......
read more
可以把 其他比較常看的東西放到首頁(像是新聞 小時鐘...)
這樣以後開啟首頁就可以一目了然嚕
另外可以自訂個人標籤
放一些比較私人的玩意(像是gmail , picasa...)
Google series 真是創意多多.......
read more
2007年7月17日 星期二
2007年7月16日 星期一
[+/-] : [ 寧靜的午後 ]
我喜歡靜靜的午後 ,
喜歡帶著慵懶神情的妳 ,
陽光細灑在參差不齊的葉縫 ,
悠閒漫佈在我倆的周圍 ,
草地傳來滿是夏天的味道 ,
Simple Life is the best
I like it ^^
...喜歡帶著慵懶神情的妳 ,
陽光細灑在參差不齊的葉縫 ,
悠閒漫佈在我倆的周圍 ,
草地傳來滿是夏天的味道 ,
Simple Life is the best
I like it ^^
read more
2007年7月15日 星期日
2007年7月14日 星期六
[+/-] : [ 放空之旅 ]
今天是2007.07.09星期一
一個本來該在辦公室工作吹冷氣的平淡日子
但是現在
淡藍的薰衣草 高山上的美好空氣 以及 我最愛的小女人 瑤
都圍繞在我伸手可及之處
讓我暫離那煩悶的生活
一切都是這麼美好
感覺非常的舒適
身體也再度充滿了活力
來時路上剛開始的制熱大太陽
接著又下起跟瀑布沒兩樣的大雨
接著是到達薰衣草森林前最後的好漢波
考驗一波接著一波
雖然不是趟輕鬆的旅程
卻也讓我欣賞到 來自瑤堅毅個性下的美麗
無入而不自得
是這趟旅程中我最深的體驗
...
read more
2007年7月12日 星期四
2007年7月11日 星期三
訂閱:
文章 (Atom)