文檔流是文檔中可顯示對象在排列時所占用的位置。比如網頁的div標簽它默認占用的寬度位置是一整行,p標簽默認占用寬度也是一整行,因為div標簽和p標簽是塊狀對象。
網頁中大部分對象默認是占用文檔流,也有一些對象是不占文檔流的,比如表單中隱藏域。當然我們也可以讓占用文檔流的元素轉換成不占文檔流,這就要用到CSS中屬性position來控制。
看看CSS 2.0對position的定義:檢索對象的定位方式。共有4種取值。
static:默認值,無特殊(靜態)定位。對象遵循HTML定位規則 。
absolute:絕對定位。將對象從文檔流中拖出,使用left,right,top,bottom等屬性相對于其最接近的一個最有定位設置的父對象進行絕對定位。如果不存在這樣的父對象,則依據body對象。而其層疊通過z-index屬性定義 。當對象定位在瀏覽器窗口以外,瀏覽器因此顯示滾動條。
fixed:固定定位。對象定位遵從絕對(absolute)方式。但是要遵守一些規范。當對象定位在瀏覽器窗口以外,瀏覽器不會因此顯示滾動條,而當滾動條滾動時,對象始終固定在原來位置。
relative:相對定位。對象不可層疊,但將依據left,right,top,bottom等屬性在正常文檔流中偏移位置。當對象定位在瀏覽器窗口以外,瀏覽器因此顯示滾動條。
inherit:繼承值,對象將繼承其父對象相應的值
posted @
2009-10-13 16:56 華夢行 閱讀(908) |
評論 (0) |
編輯 收藏
發現一個不錯的養生網站 養生之道 www.yszd.org ,希望大家喜歡。
posted @
2009-09-25 22:25 華夢行 閱讀(270) |
評論 (0) |
編輯 收藏
hessian
posted @
2009-08-24 09:26 華夢行 閱讀(230) |
評論 (0) |
編輯 收藏
http://xstream.codehaus.org/json-tutorial.html
posted @
2009-08-12 08:55 華夢行 閱讀(270) |
評論 (0) |
編輯 收藏
/*
CSS Reset for Taobao
注意:這里是 ONLY for Taobao 的 reset rules
維護:玉伯(lifesinger@gmail.com), 正淳(ragecarrier@gmail.com)
*/
/* require(reset.css) */
html {
color: #404040; /* 淘寶文字默認色 */
background: #fff; /* 覆蓋掉用戶在不知情的情況下,設置的頁面背景 */
}
/* 淘寶鏈接默認色 */
a { color: #404040; }
a:hover { color: #f60; }
/* 重置 hr */
hr {
color: #ccc;
background-color: #ccc;
}
/* misc */
html {
/* 讓非ie瀏覽器默認也顯示垂直滾動條,防止因滾動條引起的閃爍 */
overflow-y: scroll;
}
posted @
2009-07-29 18:09 華夢行 閱讀(509) |
評論 (0) |
編輯 收藏
javascript的繼承機制并不是明確規定的,而是通過模仿實現的,意味著繼承不是由解釋程序處理,開發者有權決定最適合的繼承方式. 下面我給出幾種常用的方法:
1 .對象冒充
原理: 構造函數使用this關鍵字給所有屬性和方法賦值, 因為構造函數只是一個函數,所以可以使ClassA的構造函數成為classB的方法,然后調用它.這樣classB就會收到classA的構造函數中定義的屬性和方法.例子:
function classA(name)
{
this.name=name;
this.showName=function(){alert(this.name);}
}
function classB(name)
{
this.newMethod = classA;
this.newMethod(name);
}
obj = new classA("hero");
objB = new classB("dby");
obj.showName(); // print hero
objB.showName(); // print dby 說明classB 繼承了classA的方法.
對象冒充可以實現多重繼承 例如
function classz(){
this.newMethod = classX;
this.newMethod();
delete this.newMethod;
this.newMethod=classY;
this.newMethod():
delete this.newMethod;
}
但是如果classX和classY有相同的屬性或者方法,classY具有高優先級.
2.call()方法
call方法使與經典的對象冒充法就相近的方法,它的第一個參數用作this的對象,其他參數都直接傳遞給函數自身.
function sayName(perfix)
{
alert(perfix+this.name);
}
obj= new Object();
obj.name="hero";
sayName.call(obj,"hello," );
function classA(name)
{
this.name=name;
this.showName=function(){alert(this.name);};
}
function classB(name)
{
classA.call(this,name);
}
objB = new classB("bing");
objB.showName();////說明classB繼承classA的showName方法
3.apply()方法
aplly()方法有2個參數,一個用作this對象,一個使傳遞給函數的參數數組.
function sayName(perfix)
{
alert(perfix+this.name);
}
obj= new Object();
obj.name="hero";
sayName.aplly(obj,new Array("hello,") );
4. 原型鏈
prototype對象的任何屬性和方法都會被傳遞給對應類的所有實例,原型鏈就是用這種方式來顯現繼承.
function classA (){}
classA.prototype.name="hero";
classA.prototype.showName=function(){alert(this.name)}
function classB(){}
classB.prototype=new classA();
objb = new classB()
objb.showName();//print hero 說明b繼承了a的方法
這里需要注意 調用classA的構造函數時,沒有給它傳遞參數,這是原型鏈的標準做法,確保函數的構造函數沒有任何參數.
并且 子類的所有屬性和方法,必須出現在prototype屬性被賦值后,應為在它之前賦的值會被刪除.因為對象的prototype屬性被替換成了新對象,添加了新方法的原始對象將被銷毀.
5 混和方式
就是用冒充方式 定義構造函數屬性,用原型法定義對象方法.
function classA(name)
{
this.name=name;
}
classA.prototype.showName=function(){alert(this.name)}
function classB(name)
{
classA.call(this,name);
}
classB.prototype = new classA();
classB.prototype.showName1=function(){alert(this.name+"*****");};
obj = new classB("hero");
obj.showName();
obj.showName1();
在classB的構造函數中通過調用call方法 繼承classA中的name屬性,用原型鏈來繼承classA的showName方法.
posted @
2009-07-16 13:47 華夢行 閱讀(120) |
評論 (0) |
編輯 收藏
1)Sun的JVM在實現Selector上,在Linux和Windows平臺下的細節。
2)Selector類的wakeup()方法如何喚醒阻塞在select()系統調用上的細節。
先給大家做一個簡單的回顧,在Windows下,Sun的Java虛擬機在Selector.open()時會自己和自己建立loopback的TCP鏈接;在Linux下,Selector會創建pipe。這主要是為了Selector.wakeup()可以方便喚醒阻塞在select()系統調用上的線程(通過向自己所建立的TCP鏈接和管道上隨便寫點什么就可以喚醒阻塞線程)
我們知道,無論是建立TCP鏈接還是建立管道都會消耗系統資源,而在Windows上,某些Windows上的防火墻設置還可能會導致Java的Selector因為建立不起loopback的TCP鏈接而出現異常。
而在我的另一篇文章《用GDB調試Java程序》中介紹了另一個Java的解釋器——GNU的gij,以及編譯器gcj,不但可以比較高效地運行Java程序,而且還可以把Java程序直接編譯成可執行文件。
GNU的之所以要重做一個Java的編譯和解釋器,其一個重要原因就是想解釋Sun的JVM的效率和資源耗費問題。當然,GNU的Java編譯/解釋器并不需要考慮太多復雜的平臺,他們只需要專注于Linux和衍生自Unix System V的操作系統,對于開發人員來說,離開了Windows,一切都會變得簡單起來。在這里,讓我們看看GNU的gij是如何解釋Selector.open()和Selector.wakeup()的。
同樣,我們需要一個測試程序。在這里,為了清晰,我不會例出所有的代碼,我只給出我所使用的這個程序的一些關鍵代碼。
我的這個測試程序中,和所有的Socket程序一樣,下面是一個比較標準的框架,當然,這個框架應該是在一個線程中,也就是一個需要繼承Runnable接口,并實現run()方法的一個類。(注意:其中的s是一個成員變量,是Selector類型,以便主線程序使用)
//生成一個偵聽端
ServerSocketChannel ssc = ServerSocketChannel.open();
//將偵聽端設為異步方式
ssc.configureBlocking(false);
//生成一個信號監視器
s = Selector.open();
//偵聽端綁定到一個端口
ssc.socket().bind(new InetSocketAddress(port));
//設置偵聽端所選的異步信號OP_ACCEPT
ssc.register(s,SelectionKey.OP_ACCEPT);
System.out.println("echo server has been set up ......");
while(true){
int n = s.select();
if (n == 0) { //沒有指定的I/O事件發生
continue;
}
Iterator it = s.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey key = (SelectionKey) it.next();
if (key.isAcceptable()) { //偵聽端信號觸發
…… …… ……
…… …… ……
}
if (key.isReadable()) { //某socket可讀信號
…… …… ……
…… …… ……
}
it.remove();
}
}
而在主線程中,我們可以通過Selector.wakeup()來喚醒這個阻塞在select()上的線程,下面是寫在主線程中的喚醒程序:
new Thread(this).start();
try{
//Sleep 30 seconds
Thread.sleep(30000);
System.out.println("wakeup the select");
s.wakeup();
}catch(Exception e){
e.printStackTrace();
}
這個程序在主線程中,先啟動一個線程,也就是上面那個Socket線程,然后休息30秒,為的是讓上面的那個線程有阻塞在select(),然后打印出一條信息,這是為了我們用strace命令查看具體的系統調用時能夠快速定位。之后調用的是Selector的wakeup()方法來喚醒偵聽線程。
接下來,我們可以通過兩種方式來編譯這個程序:
1)使用gcj或是sun的javac編譯成class文件,然后使用gij解釋執行。
2)使用gcj直接編譯成可執行文件。
(無論你用那種方法,都是一樣的結果,本文使用第二種方法,關于gcj的編譯方法,請參看我的《用GDB調試Java程序》)
編譯成可執行文件后,執行程序時,使用lsof命令,我們可以看到沒有任何pipe的建立。可見GNU的解釋更為的節省資源。而對于一個Unix的C程序員來說,這意味著如果要喚醒select()只能使用pthread_kill()來發送一個信號了。下面就讓我們使用strace命令來驗證這個想法。
下圖是使用strace命令來跟蹤整個程序運行時的系統調用,我們利用我們的輸出的“wakeup the select”字符串快速的找到了wakeup的實際系統調用。
posted @
2009-06-16 14:50 華夢行 閱讀(567) |
評論 (0) |
編輯 收藏
很早就聽說tomcat6使用nio了,這幾天突然想到一個問題,使用nio代替傳統的bio,ThreadLocal豈不是會存在沖突?
如果讀者有socket的編程基礎,應該會接觸過堵塞socket和非堵塞socket,堵塞socket就是在accept、read、write等IO操作的的時候,如果沒有可用符合條件的資源,不馬上返回,一直等待直到有資源為止。而非堵塞socket則是在執行select的時候,當沒有資源的時候堵塞,當有符合資源的時候,返回一個信號,然后程序就可以執行accept、read、write等操作,這個時候,這些操作是馬上完成,并且馬上返回。而windows的winsock則有所不同,可以綁定到一個EventHandle里,也可以綁定到一個HWND里,當有資源到達時,發出事件,這時執行的io操作也是馬上完成、馬上返回的。一般來說,如果使用堵塞socket,通常我們時開一個線程accept socket,當有socket鏈接的時候,開一個單獨的線程處理這個socket;如果使用非堵塞socket,通常是只有一個線程,一開始是select狀態,當有信號的時候馬上處理,然后繼續select狀態。
按照大多數人的說法,堵塞socket比非堵塞socket的性能要好。不過也有小部分人并不是這樣認為的,例如Indy項目(Delphi一個比較出色的網絡包),它就是使用多線程+堵塞socket模式的。另外,堵塞socket比非堵塞socket容易理解,符合一般人的思維,編程相對比較容易。
nio其實也是類似上面的情況。在JDK1.4,sun公司大范圍提升Java的性能,其中NIO就是其中一項。Java的IO操作集中在java.io這個包中,是基于流的阻塞API(即BIO,Block IO)。對于大多數應用來說,這樣的API使用很方便,然而,一些對性能要求較高的應用,尤其是服務端應用,往往需要一個更為有效的方式來處理IO。從JDK 1.4起,NIO API作為一個基于緩沖區,并能提供非阻塞O操作的API(即NIO,non-blocking IO)被引入。 BIO與NIO一個比較重要的不同,是我們使用BIO的時候往往會引入多線程,每個連接一個單獨的線程;而NIO則是使用單線程或者只使用少量的多線程,每個連接共用一個線程。
這個時候,問題就出來了:我們非常多的java應用是使用ThreadLocal的,例如JSF的FaceContext、Hibernate的session管理、Struts2的Context的管理等等,幾乎所有框架都或多或少地應用ThreadLocal。如果存在沖突,那豈不驚天動地?
后來終于在Tomcat6的文檔(http://tomcat.apache.org/tomcat-6.0-doc/aio.html)找到答案。根據上面說明,應該Tomcat6應用nio只是用在處理發送、接收信息的時候用到,也就是說,tomcat6還是傳統的多線程Servlet,我畫了下面兩個圖來列出區別:
tomcat5:客戶端連接到達 -> 傳統的SeverSocket.accept接收連接 -> 從線程池取出一個線程 -> 在該線程讀取文本并且解析HTTP協議 -> 在該線程生成ServletRequest、ServletResponse,取出請求的Servlet -> 在該線程執行這個Servlet -> 在該線程把ServletResponse的內容發送到客戶端連接 -> 關閉連接。
我以前理解的使用nio后的tomcat6:客戶端連接到達 -> nio接收連接 -> nio使用輪詢方式讀取文本并且解析HTTP協議(單線程) -> 生成ServletRequest、ServletResponse,取出請求的Servlet -> 直接在本線程執行這個Servlet -> 把ServletResponse的內容發送到客戶端連接 -> 關閉連接。
實際的tomcat6:客戶端連接到達 -> nio接收連接 -> nio使用輪詢方式讀取文本并且解析HTTP協議(單線程) -> 生成ServletRequest、ServletResponse,取出請求的Servlet -> 從線程池取出線程,并在該線程執行這個Servlet -> 把ServletResponse的內容發送到客戶端連接 -> 關閉連接。
從上圖可以看出,BIO與NIO的不同,也導致進入客戶端處理線程的時刻有所不同:tomcat5在接受連接后馬上進入客戶端線程,在客戶端線程里解析HTTP協議,而tomcat6則是解析完HTTP協議后才進入多線程,另外,tomcat6也比5早脫離客戶端線程的環境。
實際的tomcat6與我之前猜想的差別主要集中在如何處理servlet的問題上。實際上即使拋開ThreadLocal的問題,我之前理解tomcat6只使用一個線程處理的想法其實是行不同的。大家都有經驗:servlet是基于BIO的,執行期間會存在堵塞的,例如讀取文件、數據庫操作等等。tomcat6使用了nio,但不可能要求servlet里面要使用nio,而一旦存在堵塞,效率自然會銳降。
所以,最終的結論當然是tomcat6的servlet里面,ThreadLocal照樣可以使用,不存在沖突
posted @
2009-06-16 14:30 華夢行 閱讀(214) |
評論 (0) |
編輯 收藏
我就拿一個房子來做一個比方吧,服務器好比就是一幢房子,黑客最直接的方式就是帶著一些撬鎖的工具,去把房子的鎖給撬掉,然后奪門而入,這種方式被稱為服務器入侵。還有一類就是它直接撬大門鎖撬不開,它就把這個房子的窗打破,從窗子里面鉆進去,來進行破壞,這種方式叫做網站入侵。還有一類就是黑客帶著一只訓練有素的小猴子,讓小猴子爬到房子的房頂,從煙囪里面鉆進去,然后把大門打開,這種方式叫做特洛伊木馬入侵。還有一類就是我們前面講到那個事件的DDOS攻擊這個技術,這個相當于黑客帶著一大幫人過來把房子的大門給堵住了,讓房子里面的人出不來,讓外面的人也進不去,這就是DDOS攻擊。
posted @
2009-06-10 10:40 華夢行 閱讀(145) |
評論 (0) |
編輯 收藏
SELECT DATEADD(mm,DATEDIFF(mm,0,getdate()),0)
//首先選出當前月,然后把他轉換為日期
select (2009-1900)*12
select DATEDIFF(mm,0,getdate())
posted @
2009-06-08 14:39 華夢行 閱讀(182) |
評論 (0) |
編輯 收藏
?#define ? WINVER ? 0x0050??
#define ? WINVER ? 0x0500,這個表示是為Windows ? 2000編譯,不保證Windows ? 98/NT4可以正常運行??
Windows ? Server ? 2003 ?
? WINVER>=0x0502 ?
? ? ?
? Windows ? XP ? ?
? WINVER>=0x0501 ?
? ? ?
? Windows ? 2000 ?
? WINVER>=0x0500 ?
? ? ?
? Windows ? NT ? 4.0 ?
? WINVER>=0x0400 ?
? ? ?
? Windows ? Me ?
? WINVER>=0x0500 ?
? ? ?
? Windows ? 98 ?
? WINVER>=0x0410 ?
? ? ?
? Windows ? 95 ?
? WINVER>=0x0400???
?????
posted @
2009-03-26 22:15 華夢行 閱讀(180) |
評論 (0) |
編輯 收藏
?// TODO: Add your message handler code here and/or call default
?/*HDC hdc;
?hdc=::GetDC(m_hWnd);
?MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL);
?LineTo(hdc,point.x,point.y);
?::ReleaseDC(m_hWnd,hdc);*/
?/*CDC *pDC=GetDC();
?pDC->MoveTo(m_ptOrigin);
?pDC->LineTo(point);
?ReleaseDC(pDC);*/
?//CClientDC dc(this);
?/*CClientDC dc(GetParent());
?dc.MoveTo(m_ptOrigin);
?dc.LineTo(point);*/
?//CWindowDC dc(this);
?//CWindowDC dc(GetParent());
?/*CWindowDC dc(GetDesktopWindow());
?dc.MoveTo(m_ptOrigin);
?dc.LineTo(point);*/
?/*CPen pen(PS_DOT,1,RGB(0,255,0));
?CClientDC dc(this);
?CPen *pOldPen=dc.SelectObject(&pen);
?dc.MoveTo(m_ptOrigin);
?dc.LineTo(point);
?dc.SelectObject(pOldPen);*/
//?CBrush brush(RGB(255,0,0));
?/*CBitmap bitmap;
?bitmap.LoadBitmap(IDB_BITMAP1);
?CBrush brush(&bitmap);*/
?/*CClientDC dc(this);
?//dc.FillRect(CRect(m_ptOrigin,point),&brush);
?CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
?CBrush *pOldBrush=dc.SelectObject(pBrush);
?dc.Rectangle(CRect(m_ptOrigin,point));
?dc.SelectObject(pOldBrush);*/
?m_bDraw=FALSE;
?CView::OnLButtonUp(nFlags, point);
posted @
2009-03-24 16:25 華夢行 閱讀(168) |
評論 (0) |
編輯 收藏
#include <iostream.h>
#include <string>
char* strToBinary(int x);
char* strToHex(int i);
char* transToGKB(char *t);
int main ()
{
char *p=strToBinary(233);
//cout<<p;
//cout<<strToHex(233);
cout<<transToGKB("商");
return 0;
}
char* transToGKB(char *t){
?int res=0;
?? int intlen;
?? intlen=strlen(t);
?? if(intlen>1){
??? char *result=new char[5];
?? int i=0;
?if(0>t[0]){
??? res=256+t[0];
? }
?char *p1=strToHex(res);
?if(0>t[1]){
??res=256+t[1];
?}
?char *p2=strToHex(res);
?result=p1;
?result[2]=p2[0];
?result[3]=p2[1];?
?result[4]='\0';?
?return result;
?}
?? else{
??? //if(t[0]>64)
??? char * p=new char[3];
??? p=strToHex(t[0]);
??? p[2]='\0';
??? return? p;
?? }
}
?
//數字轉為二進制(255以內的正數)
char* strToBinary(int i){
?char *result=new?? char[9];
?int n=1;
?int m;
?int c=0;
?int j=8;
?for(c=0;c<8;c++){
??m=i%2;
??j=j-1;
??i=n=i/2;
??if(n>=0){
???if (m>0){
????result[j]='1';
???}else
???{
????result[j]='0';
???}?
??}
??
?}
?result[8]='\0';
?
//?cout<<result;
?return result;
}
//數字轉為十六進制(255以內的正數)
char* strToHex(int i){
?char *result=new?? char[3];
?int n=1;
?int m;
?int c=0;
?int j=2;
?for(c=0;c<2;c++){
??m=i%16;
??j=j-1;
??i=n=i/16;
??if(n>=0){
???if (m>0){
????if (m==1){
????????????????? result[j]='1';
????}
????else if (m==2){
?????result[j]='2';
????}
????else if (m==3){
?????result[j]='3';
????}
????else if (m==4){
?????result[j]='4';
????}
????else if (m==5){
?????result[j]='5';
????}
????else if (m==6){
?????result[j]='6';
????}
????else if (m==7){
?????result[j]='7';
????}
????else if (m==8){
?????result[j]='8';
????}
????else if (m==9){
?????result[j]='9';
????}
????else if (m==10){
?????result[j]='A';
????}
????else if (m==11){
?????result[j]='B';
????}
????else if (m==12){
?????result[j]='C';
????}
????else if (m==13){
?????result[j]='D';
????}
????else if (m==14){
?????result[j]='E';
????}
????else if (m==15){
?????result[j]='F';
????}
???}else
???{
????result[j]='0';
???}?
??}
?}
?result[2]='\0';
?return result;
}
posted @
2009-03-19 16:37 華夢行 閱讀(186) |
評論 (0) |
編輯 收藏
#include <iostream.h>
#include <string>
void yihuo(char *t,int n, int m);
void? myToBinary();
void transToGKB(char *t);
void? myToHex();
int main(){
//cout<<"GOOD";
int i=122;
int j=233;
int m=j^i;
?char t[128]={0xC9,0xCC,0xC9,0xCC,0xC9,0xCC,'\0',0xC9,0xCC,0xC9,0xCC};
yihuo(t,0, 2);
//?transToGKB(t);
//cout<<m;
//yihuo(2, 3);
//myToHex();
// myToBinary();
cout<<endl;
return 0;
}
//進制之間的轉換
? // 字符串傳為16進制
void? myToHex(){
?char c[] = "CC";
?unsigned long tt= strtoul(c, NULL, 16);
cout<<strtol(c, NULL, 16);
}
// 字符串傳為16進制
void? myToBinary(){
?char c[] = "10000000";
//?unsigned long tt= strtoul(c, NULL, 2);
?cout<<strtol(c, NULL, 2);
?
?
}
//漢字的轉換, 16進制轉換為漢字
void transToGKB(char *t){
?
?//?char *t="商戶";
?//?CharN
?//如果是負數,則轉為正整數
?//?if(0>t[0]){
?//??? res=256+t[0];
?//?}
?int j=t[0];
?cout<<t<<endl;
}
void yihuo(char *t,int n, int m) {
?char *tt="商戶說的算";
??? //轉成數字并且保存到數組,然后求異或
?//求的長度
const int mylen=strlen(tt)+1;
char mysplit[1000];
//循環對這個整形數組進行賦值
int i=0;
for(i<0;i<mylen-1;i++){
?if (tt[i]<0){
mysplit[i]=256+tt[i];
?}else
?{
mysplit[i]=tt[i];
?}
}
int result=mysplit[n-1];
int j;
for(j=n;j<n+m;j++){
?result=result^mysplit[n];
?cout<<"L"<<endl;
cout<<mysplit[n];
?cout<<"M"<<endl;
}
//進行遍歷求異或
mysplit[mylen-1]='\0';
cout<<mysplit;
cout<<"ee";
if(result<0)
result=256+result;
cout<<result;
?//int j=t[0];
//?cout<<t<<endl;
?}
?
posted @
2009-03-17 17:47 華夢行 閱讀(456) |
評論 (0) |
編輯 收藏
Integer.parseInt(String.valueOf(o));
posted @
2009-03-14 15:21 華夢行 閱讀(274) |
評論 (0) |
編輯 收藏
Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
?Text1.Text = PropBag.ReadProperty("RecordSource", _
?????? m_def_recordSource)
? Text2.Text = PropBag.ReadProperty _
?? ("ConnectionString", m_def_connectionString)
End Sub
posted @
2009-03-11 22:27 華夢行 閱讀(133) |
評論 (0) |
編輯 收藏
int main(void)
{
?? int m=4;
?? int nn;
?? int? *n;
?? int *s;
?? int *p;
?? int *q;
?? n=&m;
??
? nn=n;
?? q=n;
? s=nn;
?? printf("%08x",*s);
?? return 0;
}
posted @
2009-03-10 21:45 華夢行 閱讀(138) |
評論 (0) |
編輯 收藏
0xFFFFFF20? 數據輸入緩沖區
0xFFFFFF24? 輸出數據緩沖區???
0xFFFFFF28? 控制寄存器
posted @
2009-03-10 16:51 華夢行 閱讀(238) |
評論 (0) |
編輯 收藏
1.程序段:程序段為程序代碼在內存中的映射.一個程序可以在內存中多有個副本.
2.初始化過的數據:在程序運行值初已經對變量進行初始化的
3.未初始化過的數據:在程序運行初未對變量進行初始化的數據
4.堆(stack):存儲局部,臨時變量,在程序塊開始時自動分配內存,結束時自動釋放內存.存儲函數的返回指針.
5.棧(heap):存儲動態內存分配,需要程序員手工分配,手工釋放.
?
#
include
<stdio.h>
int g1=0, g2=0, g3=0;
intmax(int i)
{
????int m1=0,m2,m3=0,*p_max;
????static n1_max=0,n2_max,n3_max=0;
????p_max =(int*)malloc(10);
????printf("打印max程序地址\n");
????printf("in max: 0x%08x\n\n",max);
????printf("打印max傳入參數地址\n");
????printf("in max: 0x%08x\n\n",&i);
????printf("打印max函數中靜態變量地址\n");
????printf("0x%08x\n",&n1_max);//打印各本地變量的內存地址
????printf("0x%08x\n",&n2_max);
????printf("0x%08x\n\n",&n3_max);
????printf("打印max函數中局部變量地址\n");
????printf("0x%08x\n",&m1);//打印各本地變量的內存地址
????printf("0x%08x\n",&m2);
????printf("0x%08x\n\n",&m3);
????printf("打印max函數中malloc分配地址\n");
????printf("0x%08x\n\n",p_max);//打印各本地變量的內存地址
????if(i)return 1;
????elsereturn 0;
}
int main(int argc,char**argv)
{
staticint s1=0, s2, s3=0;
int v1=0, v2, v3=0;
int*p;????
p =(int*)malloc(10);
printf("打印各全局變量(已初始化)的內存地址\n");
printf("0x%08x\n",&g1);//打印各全局變量的內存地址
printf("0x%08x\n",&g2);
printf("0x%08x\n\n",&g3);
printf("======================\n");
printf("打印程序初始程序main地址\n");
printf("main: 0x%08x\n\n", main);
printf("打印主參地址\n");
printf("argv: 0x%08x\n\n",argv);
printf("打印各靜態變量的內存地址\n");
printf("0x%08x\n",&s1);//打印各靜態變量的內存地址
printf("0x%08x\n",&s2);
printf("0x%08x\n\n",&s3);
printf("打印各局部變量的內存地址\n");
printf("0x%08x\n",&v1);//打印各本地變量的內存地址
printf("0x%08x\n",&v2);
printf("0x%08x\n\n",&v3);
printf("打印malloc分配的堆地址\n");
printf("malloc: 0x%08x\n\n",p);
printf("======================\n");
????max(v1);
printf("======================\n");
printf("打印子函數起始地址\n");
printf("max: 0x%08x\n\n",max);
return 0;
}
?
這個程序可以大致查看整個程序在內存中的分配情況:
可以看出,傳入的參數,局部變量,都是在棧頂分布,隨著子函數的增多而向下增長.
函數的調用地址(函數運行代碼),全局變量,靜態變量都是在分配內存的低部存在,而malloc分配的堆則存在于這些內存之上,并向上生長
posted @
2009-03-10 15:40 華夢行 閱讀(224) |
評論 (0) |
編輯 收藏
#include <stdio.h>
#include <string.h>
hello(){
char *hello="dddd大點的";
int i;
for(i=0;i<strlen(hello);i++){
printf("%s\n",&hello[i]);
}
}
void testStr(){
int i=0;
?for(i=0;i<128;i++)
?{
printf("%c",(char)i);
?}
}
void testmy(){
?char *hello="??大點的";
?char hellodd[]={hello};
?unsigned char test= hellodd[2];
?if(test>137){
?printf("大于%u",test);
?}else
?{
??printf("小于");
?}
//putchar((char)hello[5]);
printf("字符:%d \n",hellodd[2]);
printf("%d",strlen( hellodd));
}
//相當于substring
teststrcopy(){
char *s="到的得到";
char d[]={"? "};
//strncpy(d,s+0,2);
strncpy(d,s,2);
printf("%s\n",d);
}
int main(void){
//testmy();
?//teststrcopy();
?return 0;
}
?
posted @
2009-03-10 15:23 華夢行 閱讀(85) |
評論 (0) |
編輯 收藏