zhuozhuo

 

2009年4月15日

一个内存池的实现

     摘要: 自定义内存池的思想通过这个"池"字表露无疑,应用程序可以通过系统的内存分配调用预先一次性申请适当大小的内存作为一个内存池,之后应用程序自己对内存 的分配和释放则可以通过这个内存池来完成。只有当内存池大小需要动态扩展时,才需要再调用系统的内存分配函数,其他时间对内存的一切操作都在应用程序的掌 控之中。[from IBM]本人参考《C++应用程序性能优化》写出了完整的内存池实现代码,和大家交流。如...  阅读全文

posted @ 2009-04-15 20:46 卓卓 阅读(1584) | 评论 (0)编辑 收藏

2009年3月27日

[导入]双向链表C++实现

摘要: TableHead类决定使用双向链表,可快速找到其前驱。实现代码如下DBLList.h(双向链表类)CodeCode highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->1/**//* 2* 湖南大学软件学院07级5班Debugger小组 3*4* 文件名称:DBL  阅读全文

--------------------------
新闻:非接触式IC卡技术被破解 全国1.4亿IC卡存隐患
导航:博客园首页  知识库  新闻  招聘  社区  小组  博问  网摘  找找看
文章来源:http://www.cnblogs.com/minimdb/archive/2009/03/27/1423397.html

posted @ 2009-03-27 18:03 卓卓 阅读(188) | 评论 (0)编辑 收藏

2009年3月26日

[导入]上图形学的实验要用到矩阵的运算,不是很完善,但是足够用于图形变换了


//Matrix.h
//矩阵类(用来做图形学的作业)
//by 卓卓09 3 2
//可进行矩阵的加 和 乘 操作

#pragma once

#include 
<iostream>
using namespace std;
class Matrix
{
private:
    
int m_lnum;//矩阵行数
    int m_cnum;//矩阵列数
    float* m_p;
public:
    Matrix();
    Matrix(
const int& line,const int& column)//line*column矩阵
    {
        m_lnum
=line;
        m_cnum
=column;
        m_p
=new float[m_lnum*m_cnum];
    }
    Matrix(
const int& num)//num*num矩阵
    {
        m_cnum
=m_lnum=num;
        m_p
=new float[num*num];
    }
    
~Matrix()
    {
        delete[] m_p;
    }

    void Set(float sor[])//数组初始化矩阵
    {
        
int j=0;
        
for(;j<m_lnum*m_cnum;j++)
        {
            m_p[j]
=sor[j];
        }
    }
    
void Print()//打印矩阵
    {
        
int j=0;
        
for(;j<m_lnum*m_cnum;j++)
        {
            
if(j!=0&&j%m_cnum==0)
                cout
<<endl;
            cout
<<m_p[j]<<" ";
        }
        cout
<<endl;
    }
    
/*
        num为第num 行/列
        如:第一行/列 num为1
    
*/ 
    
void SetElement(int x,int y,float element)
    {
        
if(x<=0||x>m_lnum||y<=0||y>m_cnum)//判断x,y是否在范围内
            return;
        m_p[(x
-1)*m_cnum+(y-1)]=element;
    }
    
float GetElement(int x,int y)
    {

        return m_p[(x-1)*m_cnum+(y-1)];
    }
    
bool SetLine(const int& num,float line[])//设置第num行的值 
    {
        
if(num<=0||num>m_cnum)
            
return false;
        
int i=(num-1)*m_cnum;
        
int j=0;//
        for(;j<m_lnum;j++,i++)
        {
            m_p[i]
=line[j];//拷贝
        }
        
return true;
    }
    
int GetTotalNum() const//返回矩阵所有元素数目
    {
        
int tmp=m_lnum*m_cnum;
        
return tmp;
    }
    
int GetLineNum() const//返回矩阵行数
    {
        
return m_lnum;
    }
    
int GetColumnNum() const//返回矩阵列数
    {
        
return m_cnum;
    }
    
bool Add(Matrix& source,Matrix& result)//矩阵相加
    {
        
if(source.GetColumnNum()!=m_cnum||source.GetLineNum()!=m_cnum)
            
return false;
        
int i=1,j=1;
        
for(;i<=m_lnum;i++)
        {
            j
=1;
            
for(;j<=m_cnum;j++)
            {
                result.SetElement(i,j,
this->GetElement(i,j)+source.GetElement(i,j));
            }
        }
        
return true;
    }
    
bool Plus(Matrix& source,Matrix& result)//矩阵相乘
    {
        
if(source.GetLineNum()!=m_cnum)//行不等于列的话返回false
            return false;
        
int i=1,j=1,z=1;
        
float sum=0;
        
for(;i<=m_lnum;i++)//第i行
        {
            j
=1;
            
for(;j<=source.GetColumnNum();j++)//第j列
            {
                z
=1;
                sum
=0;
                
for(;z<=m_cnum;z++)//计算
                {
                    sum
+=this->GetElement(i,z)*source.GetElement(z,j);
                }
                result.SetElement(i,j,sum);
            }
        }
    }
    
bool Minus(const Matrix& source,Matrix& result)//to be continue
    {
        
return true;
    }
};


//test.cpp

#include 
"Matrix.h"

void Cal()

{

    Matrix a(
4,2);

    Matrix b(
2,1);

    Matrix r(
4,1);//存结果

    
float sor[8]={1,2,3,4,5,6,7,8};

    
float sor2[2]={1,2};

    a.Set(sor);

    b.Set(sor2);

    a.Plus(b,r);
//进行乘运算

    r.Print();

}

int main()

{

    
    Cal();

    system(
"pause");

    
return 0;

}

 



--------------------------
新闻:Linux基金会CEO:Linux是发展最快的平台
导航:博客园首页  知识库  新闻  招聘  社区  小组  博问  网摘  找找看
文章来源:http://www.cnblogs.com/minimdb/archive/2009/03/26/1422338.html

posted @ 2009-03-26 14:45 卓卓 阅读(88) | 评论 (0)编辑 收藏

2009年3月25日

[导入]const的小发现

我们都知道,在类的成员函数后加const,函数体内将不能修改类的数据成员。

今天在写TableHead的时候发现,c++是通过隐式转换把数据成员转换为const,从而达到无法修改其值的目的。



--------------------------
新闻:微软广告攻势第三波:Mac作不了游戏机
导航:博客园首页  知识库  新闻  招聘  社区  小组  博问  网摘  找找看
文章来源:http://www.cnblogs.com/minimdb/archive/2009/03/25/1421789.html

posted @ 2009-03-25 20:38 卓卓 阅读(55) | 评论 (0)编辑 收藏

[导入][转]堆和栈辨析

一、预备知识—程序的内存分配

一个由c/C++编译的程序占用的内存分为以下几个部分

1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放 
4、文字常量区—常量字符串就是放在这里的。 程序结束后由系统释放
5、程序代码区—存放函数体的二进制代码。

         例子程序 

 这是一个前辈写的,非常详细 

//main.cpp 
int a = 0; 全局初始化区 
char *p1; 全局未初始化区 
main() 

int b; 栈 
char s[] = "abc"; 栈 
char *p2; 栈 
char *p3 = "123456"; 123456"0在常量区,p3在栈上。 
static int c =0; 全局(静态)初始化区 
p1 = (char *)malloc(10); 
p2 = (char *)malloc(20); 
分配得来得10和20字节的区域就在堆区。 
strcpy(p1, "123456"); 123456"0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。 


二、堆和栈的理论知识 

2.1申请方式 

stack: 
由系统自动分配。 例如,声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间 
heap: 
需要程序员自己申请,并指明大小,在c中malloc函数 
如p1 = (char *)malloc(10); 
在C++中用new运算符 
如p2 = (char *)malloc(10); 
但是注意p1、p2本身是在栈中的。 


2.2 

申请后系统的响应 
栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。 
堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时, 
会 遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内 存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大 小,系统会自动的将多余的那部分重新放入空闲链表中。 

2.3申请大小的限制 

栈:在Windows下,栈是向低地址扩展的数据结 构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是 一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。 
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。 


2.4申请效率的比较: 

栈由系统自动分配,速度较快。但程序员是无法控制的。 
堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便. 
另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是直接在进程的地址空间中保留一快内存,虽然用起来最不方便。但是速度快,也最灵活。 

2.5堆和栈中的存储内容 

栈: 在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。 
当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。 
堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。 

2.6存取效率的比较 

char s1[] = "aaaaaaaaaaaaaaa"; 
char *s2 = "bbbbbbbbbbbbbbbbb"; 
aaaaaaaaaaa是在运行时刻赋值的; 
而bbbbbbbbbbb是在编译时就确定的; 
但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。 
比如: 

#include 
void main() 

char a = 1; 
char c[] = "1234567890"; 
char *p ="1234567890"; 
a = c[1]; 
a = p[1]; 
return; 

对应的汇编代码 

10: a = c[1]; 
00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh] 
0040106A 88 4D FC mov byte ptr [ebp-4],cl 
11: a = p[1]; 
0040106D 8B 55 EC mov edx,dword ptr [ebp-14h] 
00401070 8A 42 01 mov al,byte ptr [edx+1] 
00401073 88 45 FC mov byte ptr [ebp-4],al 

第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到edx中,在根据edx读取字符,显然慢了。 

2.7小结: 

堆和栈的区别可以用如下的比喻来看出: 
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。 
使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。



--------------------------
新闻:微软广告攻势第三波:Mac作不了游戏机
导航:博客园首页  知识库  新闻  招聘  社区  小组  博问  网摘  找找看
文章来源:http://www.cnblogs.com/minimdb/archive/2009/03/25/1421762.html

posted @ 2009-03-25 19:56 卓卓 阅读(53) | 评论 (0)编辑 收藏

[导入]内存泄露检测

最近老是感觉自己的程序会出现内存泄露的问题

上网google了一下visual studio下检测内存泄露的方法,和大家分享一下。

在需要检测的.cpp文件  头部增加以下语句

#define _CRTDBG_MAP_ALLO

#include <crtdbg.h>


在需要检测的代码后面增加以下语句

_CrtDumpMemoryLeaks();


 



--------------------------
新闻:微软广告攻势第三波:Mac作不了游戏机
导航:博客园首页  知识库  新闻  招聘  社区  小组  博问  网摘  找找看
文章来源:http://www.cnblogs.com/minimdb/archive/2009/03/25/1421236.html

posted @ 2009-03-25 12:27 卓卓 阅读(48) | 评论 (0)编辑 收藏

2009年3月21日

[导入]虚函数释义(二)

from pconline  

多态的这个概念稍微有点模糊,如果想在一开始就想用清晰用语言描述它,让读者能够明白,似乎不太现实,所以我们先看如下代码:

//例程1 
#include <iostream>     
using namespace std;   
   
class Vehicle 
{   
public:   
    Vehicle(float speed,int total) 
    { 
        Vehicle::speed=speed; 
        Vehicle::total=total; 
    } 
    void ShowMember() 
    { 
        cout<<speed<<"|"<<total<<endl; 
    } 
protected:   
    float speed; 
    int total; 
};   
class Car:public Vehicle   
{   
public:   
    Car(int aird,float speed,int total):Vehicle(speed,total)   
    {   
        Car::aird=aird;   
    } 
    void ShowMember() 
    { 
        cout<<speed<<"|"<<total<<"|"<<aird<<endl; 
    } 
protected:   
    int aird; 
};   
 
void main()   
{   
    Vehicle a(120,4); 
    a.ShowMember(); 
    Car b(180,110,4); 
    b.ShowMember(); 
    cin.get(); 
}

   在c++中是允许派生类重载基类成员函数的,对于类的重载来说,明确的,不同类的对象,调用其类的成员函数的时候,系统是知道如何找到其类的同名成员, 上面代码中的a.ShowMember();,即调用的是Vehicle::ShowMember(),b.ShowMember();,即调用的是 Car::ShowMemeber();。

 

 

  但是在实际工作中,很可能会碰到对象所属类不清的情况,下面我们来看一下派生类成员作为函数参数传递的例子,代码如下:

//例程2 
#include <iostream>     
using namespace std;   
   
class Vehicle 
{   
public:   
    Vehicle(float speed,int total) 
    { 
        Vehicle::speed=speed; 
        Vehicle::total=total; 
    } 
    void ShowMember() 
    { 
        cout<<speed<<"|"<<total<<endl; 
    } 
protected:   
    float speed; 
    int total; 
};   
class Car:public Vehicle   
{   
public:   
    Car(int aird,float speed,int total):Vehicle(speed,total)   
    {   
        Car::aird=aird;   
    } 
    void ShowMember() 
    { 
        cout<<speed<<"|"<<total<<"|"<<aird<<endl; 
    } 
protected:   
    int aird; 
};   
 
void test(Vehicle &temp) 

    temp.ShowMember(); 

 
void main()   

    Vehicle a(120,4); 
    Car b(180,110,4); 
    test(a); 
    test(b); 
    cin.get(); 
}

   例子中,对象a与b分辨是基类和派生类的对象,而函数test的形参却只是Vehicle类的引用,按照类继承的特点,系统把Car类对象看做是一个 Vehicle类对象,因为Car类的覆盖范围包含Vehicle类,所以test函数的定义并没有错误,我们想利用test函数达到的目的是,传递不同 类对象的引用,分别调用不同类的,重载了的,ShowMember成员函数,但是程序的运行结果却出乎人们的意料,系统分不清楚传递过来的基类对象还是派生类对象,无论是基类对象还是派生类对象调用的都是基类的ShowMember成员函数。

 

 

 

 

  为了要解决上述不能正确分辨对象类型的问题,c++提供了一种叫做多态性(polymorphism)的技术来解决问题,对于例程序1,这种能够在编译时就能够确定哪个重载的成员函数被调用的情况被称做先期联编(early binding),而在系统能够在运行时,能够根据其类型确定调用哪个重载的成员函数的能力,称为多态性,或叫滞后联编(late binding),下面我们要看的例程3,就是滞后联编,滞后联编正是解决多态问题的方法。

代码如下:

//例程3 
#include <iostream>     
using namespace std;   
   
class Vehicle 
{   
public:   
    Vehicle(float speed,int total) 
    { 
        Vehicle::speed = speed; 
        Vehicle::total = total; 
    } 
    virtual void ShowMember()//
虚函数 
    { 
        cout<<speed<<"|"<<total<<endl; 
    } 
protected:   
    float speed; 
    int total; 
};   
class Car:public Vehicle   
{   
public:   
    Car(int aird,float speed,int total):Vehicle(speed,total)   
    {   
        Car::aird = aird;   
    } 
    virtual void ShowMember()//
虚函数,在派生类中,由于继承的关系,这里的virtual也可以不加 
    { 
        cout<<speed<<"|"<<total<<"|"<<aird<<endl; 
    } 
public:   
    int aird; 
}; 
 
void test(Vehicle &temp) 

    temp.ShowMember(); 

 
int main()   
{   
    Vehicle a(120,4); 
    Car b(180,110,4); 
    test(a); 
    test(b); 
    cin.get(); 
}

  多态特性的工作依赖虚函数的定义,在需要解决多态问题的重载成员函数前,加上virtual关键字,那么该成员函数就变成了虚函数,从上例代码运行的结果看,系统成功的分辨出了对象的真实类型,成功的调用了各自的重载成员函数。

多态特性让程序员省去了细节的考虑,提高了开发效率,使代码大大的简化,当然虚函数的定义也是有缺陷的,因为多态特性增加了一些数据存储和执行指令的开销,所以能不用多态最好不用。

 

  虚函数的定义要遵循以下重要规则:

  1.如果虚函数在基类与派生类中出现,仅仅是名字相同,而形式参数不同,或者是返回类型不同,那么即使加上了virtual关键字,也是不会进行滞后联编的。

2.只有类的成员函数才能说明为虚函数,因为虚函数仅适合用与有继承关系的类对象,所以普通函数不能说明为虚函数。

3.静态成员函数不能是虚函数,因为静态成员函数的特点是不受限制于某个对象。

4.内联(inline)函数不能是虚函数,因为内联函数不能在运行中动态确定位置。即使虚函数在类的内部定义定义,但是在编译的时候系统仍然将它看做是非内联的。

5.构造函数不能是虚函数,因为构造的时候,对象还是一片位定型的空间,只有构造完成后,对象才是具体类的实例。

6.析构函数可以是虚函数,而且通常声名为虚函数。


说明一下,虽然我们说使用虚函数会降低效率,但是在处理器速度越来越快的今天,将一个类中的所有成员函数都定义成为virtual总是有好处的,它除了会增加一些额外的开销是没有其它坏处的,对于保证类的封装特性是有好处的。

  对于上面虚函数使用的重要规则6,我们有必要用实例说明一下,为什么具备多态特性的类的析构函数,有必要声明为virtual

代码如下:

#include <iostream>     
using namespace std;   
   
class Vehicle 
{   
public:  
    Vehicle(float speed,int total) 
    { 
        Vehicle::speed=speed; 
        Vehicle::total=total; 
    } 
    virtual void ShowMember() 
    { 
        cout<<speed<<"|"<<total<<endl; 
    } 
    virtual ~Vehicle() 
    { 
        cout<<"
载入Vehicle基类析构函数"<<endl; 
        cin.get(); 
    } 
protected:   
    float speed; 
    int total; 
};   
class Car:public Vehicle   
{   
public:   
    Car(int aird,float speed,int total):Vehicle(speed,total)   
    {   
        Car::aird=aird;   
    } 
    virtual void ShowMember() 
    { 
        cout<<speed<<"|"<<total<<"|"<<aird<<endl; 
    } 
    virtual ~Car() 
    { 
        cout<<"
载入Car派生类析构函数"<<endl; 
        cin.get(); 
    } 
protected:   
    int aird; 
};   
 
void test(Vehicle &temp) 

    temp.ShowMember(); 

void DelPN(Vehicle *temp) 

    delete temp; 

void main() 
{   
    Car *a=new Car(100,1,1); 
    a->ShowMember(); 
    DelPN(a); 
    cin.get(); 
}

   从上例代码的运行结果来看,当调用DelPN(a);后,在析构的时候,系统成功的确定了先调用Car类的析构函数,而如果将析构函数的virtual 修饰去掉,再观察结果,会发现析构的时候,始终只调用了基类的析构函数,由此我们发现,多态的特性的virtual修饰,不单单对基类和派生类的普通成员 函数有必要,而且对于基类和派生类的析构函数同样重要。

 

 



--------------------------
新闻:英特尔贝瑞特6月退休:告别者的骄傲与遗憾
导航:博客园首页  知识库  新闻  招聘  社区  小组  博问  网摘  找找看
文章来源:http://www.cnblogs.com/minimdb/archive/2009/03/21/1418632.html

posted @ 2009-03-21 21:10 卓卓 阅读(92) | 评论 (0)编辑 收藏

[导入]虚函数释义(一)

From baidu百科

一、什么是虚函数(如果不知道虚函数为何物,但有急切的想知道,那你就应该从这里开始)

简单地说,那些被virtual关键字修饰的成员函数,就是虚函数。虚函数的作用,用专业术语 来解释就是实现多态性(Polymorphism),多态性是将接口与实现进行分离;用形象的语言来解释就是实现以共同的方法,但因个体差异而采用不同的 策略。下面来看一段简单的代码
class A{
public:
void print(){ cout<<”This is A”<<endl;}
};
class B:public A{
public:
void print(){ cout<<”This is B”<<endl;}
};
int main(){ //为了在以后便于区分,我这段main()代码叫做main1
A a;
B b;
a.print();
b.print();
}

  通过class A和class B的print()这个接口,可以看出这两个class因个体的差异而采用了不同的策略,输出的结果也是我们预料中的,分别是This is A和This is B。但这是否真正做到了多态性呢?No,多态还有个关键之处就是一切用指向基类的指针或引用来操作对象。那现在就把main()处的代码改一改。

      int main(){ //main2
A a;
B b;
A* p1=&a;
A* p2=&b;
p1->print();
p2->print();
}
运行一下看看结果,哟呵,蓦然回首,结果却是两个This is A。问题来了,p2明明指向的是class B的对象但却是调用的class A的print()函数,这不是我们所期望的结果,那么解决这个问题就需要用到虚函数
class A{
public:
virtual void print(){ cout<<”This is A”<<endl;} //现在成了虚函数了
};
class B:public A{
public:
void print(){ cout<<”This is B”<<endl;} //这里需要在前面加上关键字virtual吗?
};

  毫无疑问,class A的成员函数print()已经成了虚函数,那么class B的print()成了虚函数了吗?回答是Yes,我们只需在把基类的成员函数设为virtual,其派生类的相应的函数也会自动变为虚函数。所 以,class B的print()也成了虚函数。那么对于在派生类的相应函数前是否需要用virtual关键字修饰,那就是你自己的问题了。

    现在重新运行main2的代码,这样输出的结果就是This is A和This is B了。

 



--------------------------
新闻:英特尔贝瑞特6月退休:告别者的骄傲与遗憾
导航:博客园首页  知识库  新闻  招聘  社区  小组  博问  网摘  找找看
文章来源:http://www.cnblogs.com/minimdb/archive/2009/03/21/1418610.html

posted @ 2009-03-21 20:30 卓卓 阅读(81) | 评论 (0)编辑 收藏

2009年3月15日

[导入]汇编实验 移位操作

最近在上汇编的实验,把代码贴上来和大家交流交流。

实验二     非压缩/压缩十进制码转换程序的设计与实现(必做)

1.         实验二:非压缩/压缩十进制码转换程序的设计与实现

2.         实验目的:通过上机编程,熟悉CPU内部的寄存器等部件,掌握基本的汇编语言程序结构,并掌握汇编语言中移位指令的使用。

      3.         实验要求:       对于事先设定的一个简单的十进制数,如“0506h”,通过汇编语言将其表示变为压缩表示,如变为“56h”

 

                                     高八位     低八位
思路:十六进制数0506h对应16位二进制数 00000101 00000110

          十六进制数   56h对应16位二进制数 00000000 01010110

把0506h的高八位左移四位(即变为01010000)然后和其低八位相加,构成56h的低八位

代码如下:

code segment

start:
    mov dx,0506h ;把立即数0506h赋给寄存器dx,此时寄存器dx的高八位 dh为00000101 低八位dl为00000110
    shl dh,1 ;dx高八位dh向左移 下同
    shl dh,1
    shl dh,1
    shl dh,1 ;最终dh为 01010000
    add dl,dh ;此时把dx的第八位和高八位相加,把结果赋给dl
    sub dh,dh  ;清空dx寄存器的高八位 ()
    mov ah,2 ;把ax的高八位ah赋值为2
    int 21h   ;产生中断 检测ah的值 输出字符 v   
code ends        

end start

 

 

 

 

 



--------------------------
新闻:外刊评10款最烂操作系统 微软四款上榜
导航:博客园首页  知识库  新闻  招聘  社区  小组  博问  网摘  找找看
文章来源:http://www.cnblogs.com/minimdb/archive/2009/03/15/1412479.html

posted @ 2009-03-15 16:12 卓卓 阅读(95) | 评论 (0)编辑 收藏

2009年3月14日

[导入]Column.h(属性类--字段的属性) 声明文件

/* 
 * 湖南大学软件学院07级5班Debugger小组 
 *
 * 文件名称:Column.h
 * 功能摘要:属性类 声明文件
 *
 * 作者:卓卓
 * 创建日期:2009年3月13日 
 *  修改日期:2009年3月14日
 */
#pragma once
#include <string>
#include "GlobalDefine.h"
using namespace std;
class Column
{
private:
    short m_columnSize;//字段大小
    string m_columnName;//字段名称(32个字节)
    string m_columnDes;//字段说明(256个字节)
    DB_DataType m_dataType;//数据类型
    bool m_primaryKey;//主键
    bool m_foreignKey;//外键
    bool m_index;//索引    
    bool m_required;//必填
    string m_defaultValue;//默认值
    string m_forKeyTableName;//外键相连的表名
    string m_forKeycolumnName;//外键相连的列名
public:
    Column(void);
    Column(string& name,int& size,DB_DataType dataType);//构造函数 初始化主要数据成员
    ~Column(void);
    bool SetColumn(string& name,int& size,DB_DataType& dataType,string& description,
                   bool priKey=false,bool forKey=false,bool index=false,
                   string forTableKey=NULL,string forColumnName=NULL);//各数据成员的初始化
    int GetSize() const;//返回字段大小
    string GetName() const;//返回字段名称
    string GetDescription() const;//返回字段说明
    DB_DataType GetDataType() const;//返回数据类型
    bool IsPriKey() const;//返回是否主键
    bool IsForKey() const;//返回是否外键
    bool IsIndex() const;//返回是否索引
    bool IsRequired() const;//返回是否必填
    string GetDefaultValue() const;//返回默认值
    bool SetName(string& name);//设定字段名
    bool SetDescription(string& description);//设定字段说明
    bool SetDataType(DB_DataType& dataType);//设定数据类型
    void SetPriKey(bool& priKey);//设定主键的布尔值
    void SetForKey(bool& forKey);//设定外键的布尔值
    void SetIndex(bool& index);//设定索引的布尔值
    void SetRequired(bool& required);//设定必填的布尔值
    bool SetDefualtValue(string& defualtval);//设定默认值
};

--------------------------
新闻:微软4月补丁日将发布8个安全补丁
导航:博客园首页  知识库  新闻  招聘  社区  小组  博问  网摘  找找看
文章来源:http://www.cnblogs.com/minimdb/archive/2009/03/14/1411742.html

posted @ 2009-03-14 19:25 卓卓 阅读(145) | 评论 (0)编辑 收藏

仅列出标题  下一页

导航

统计

公告

常用链接

留言簿(1)

随笔档案

文章档案

搜索

最新评论

阅读排行榜

评论排行榜