随笔-295  评论-26  文章-1  trackbacks-0
 
文档流是文档中可显示对象在排列时所占用的位置。比如网页的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 华梦行 阅读(893) | 评论 (0)编辑 收藏
发现一个不错的养生网站 养生之道 www.yszd.org ,希望大家喜欢。
posted @ 2009-09-25 22:25 华梦行 阅读(257) | 评论 (0)编辑 收藏
hessian
posted @ 2009-08-24 09:26 华梦行 阅读(224) | 评论 (0)编辑 收藏
http://xstream.codehaus.org/json-tutorial.html
posted @ 2009-08-12 08:55 华梦行 阅读(262) | 评论 (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 华梦行 阅读(499) | 评论 (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 华梦行 阅读(110) | 评论 (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 华梦行 阅读(557) | 评论 (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 华梦行 阅读(199) | 评论 (0)编辑 收藏
我就拿一个房子来做一个比方吧,服务器好比就是一幢房子,黑客最直接的方式就是带着一些撬锁的工具,去把房子的锁给撬掉,然后夺门而入,这种方式被称为服务器入侵。还有一类就是它直接撬大门锁撬不开,它就把这个房子的窗打破,从窗子里面钻进去,来进行破坏,这种方式叫做网站入侵。还有一类就是黑客带着一只训练有素的小猴子,让小猴子爬到房子的房顶,从烟囱里面钻进去,然后把大门打开,这种方式叫做特洛伊木马入侵。还有一类就是我们前面讲到那个事件的DDOS攻击这个技术,这个相当于黑客带着一大帮人过来把房子的大门给堵住了,让房子里面的人出不来,让外面的人也进不去,这就是DDOS攻击。
posted @ 2009-06-10 10:40 华梦行 阅读(135) | 评论 (0)编辑 收藏
SELECT DATEADD(mm,DATEDIFF(mm,0,getdate()),0) //首先选出当前月,然后把他转换为日期 select (2009-1900)*12 select DATEDIFF(mm,0,getdate())
posted @ 2009-06-08 14:39 华梦行 阅读(173) | 评论 (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 华梦行 阅读(162) | 评论 (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 华梦行 阅读(149) | 评论 (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 华梦行 阅读(161) | 评论 (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 华梦行 阅读(437) | 评论 (0)编辑 收藏
Integer.parseInt(String.valueOf(o));
posted @ 2009-03-14 15:21 华梦行 阅读(261) | 评论 (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 华梦行 阅读(115) | 评论 (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 华梦行 阅读(123) | 评论 (0)编辑 收藏

0xFFFFFF20  数据输入缓冲区
0xFFFFFF24  输出数据缓冲区   
0xFFFFFF28  控制寄存器

posted @ 2009-03-10 16:51 华梦行 阅读(216) | 评论 (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 华梦行 阅读(207) | 评论 (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 华梦行 阅读(77) | 评论 (0)编辑 收藏
仅列出标题
共15页: 上一页 1 2 3 4 5 6 7 8 9 下一页 Last