※天道酬勤※

§水至清则无鱼,人至察则无徒§
posts - 63, comments - 6, trackbacks - 0, articles - 0
  IT博客网 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

2007年1月23日

AppFace For VC 支持Win9X/NT/2K/XP,UNICODE/ANSI,能够对目标进程里的所有Widows标准控件,系统菜单,通用对话框等实现换肤,对非商业用途而言,它是完全免费的。关键的是AppFace的使用非常简单,很容易添加到已有的工程中。可以到它的网站 http://www.appface.com 去下载最新版本 。


AppFace 支持三种皮肤加载方式,从磁盘文件加载,从资源加载,从内存加载。下面我就说说如何从资源加载URF皮肤文件:

首先,要确保你下载了AppFace for VC 开发包,我们要用到其中的三个文件: "appface.h", "appface.dll" ,"gtclassic.urf" 。

接着,创建一个 VC 可执行文件工程, MDI/SDI/DIALOG/WIN32 类型的都可以,我以创建一个DIALOG 工程 ResSkin 进行说明 。将"appface.h" 拷贝到该工程目录下,将"Appface.dll"拷贝到该工程的输出目录下,例如:"debug\",将"gtclassic.urf"拷贝到资源所在目录下 。在VC 的项目管理器中进入资源管理项,在右键菜单中选择"Import",将"gtclassic.urf"添加进工程,资源类型设定为: "MYRESTYPE",资源ID设定为"IDR_MY_URF"。注意:资源ID 前面一定要加双引号 。


准备工作全部完成了,现在进入正题:
1.在ResSkin.cpp 中加入: #include "appface.h"
2.在CResSkinApp::InitInstance() 成员函数中添加如下代码

CResSkinApp::InitInstance()
{
...
CAppFace af ; //line 1
af.Start(_T("IDR_MY_URF"),GTP_LOAD_RESOURCE,NULL,_T("MYTYPE"),NULL) ; //line 2

CResSkinDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();

...
af.Remove() ; //line 3

}

编译... 一切搞定 !

3. 上面是官方的做法,由于appface 也支持从内存中加载urf,所以您也可以这样做:

CResSkinApp::InitInstance()
{
...
CAppFace af ; //Init

//Load
if(HRSRC hr = ::FindResource(NULL,"IDR_MY_URF","MYTYPE"))
{
ULONG nResSize = ::SizeofResource(NULL,hr) ;
if(HGLOBAL hz = ::LoadResource(NULL,hr))
{
char* p = (char*)LockResource(hz);
if(p)
af.Start(p,GTP_LOAD_MEMORY,nResSize,NULL,NULL) ;
}
}

CResSkinDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();

...
af.Remove() ; //Release

}
你可以使用这种方法从资源中加载其它数据。


需要注意的是: 如果将URF添加进资源时,资源ID没有用双引号括起来, 加载时必须这样写:
af.Start(_T("IDR_MY_URF"),GTP_LOAD_RESOURCE,NULL,MAKEINTRESOURCE(_T("MYTYPE")),NULL)) ; //line 2



添加“换皮肤“按钮
添加一个Button,消息响应函数如下:

void CChatDlg::OnButton2()
{
    x++;    //全局变量,static int x=3;
    int x1;
    x1=x%3;
    if(x1==1)
    {
    CAppFace af ; 
    af.Start(_T("IDR_MY_URF1"),GTP_LOAD_RESOURCE,NULL,_T("MYTYPE"),NULL) ;
    this->MoveWindow(81,75,870,602);
    }
    if(x1==2)
    {
    CAppFace af ; 
    af.Start(_T("IDR_MY_URF2"),GTP_LOAD_RESOURCE,NULL,_T("MYTYPE"),NULL) ;
    this->MoveWindow(81,75,854,595);
    }
    if(x1==0)
    {
    CAppFace af ;
    af.Start(_T("IDR_MY_URF"),GTP_LOAD_RESOURCE,NULL,_T("MYTYPE"),NULL) ;
    this->MoveWindow(81,75,865,602);
    }
}

posted @ 2007-01-23 11:38 五指魅力 阅读(1261) | 评论 (1)编辑 收藏

2007年1月17日

使用位域的主要目的是压缩存储,其大致规则为:
1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;
2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,Dev-C++采取压缩方式;
4) 如果位域字段之间穿插着非位域字段,则不进行压缩;
5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。

测试:
struct test
 {
  char a:1;
  char :2;
  long b:3;
  char c:2;
 };
 test t1;
 int len=sizeof(t1);   //len=12

struct test
 {
  char a:1;
  char :2;
  char b:3;
  long c:2;
 };
 test t1;
 int len=sizeof(t1);   //len=8

struct test
 {
  char a:1;
  char :2;
  char b:3;
  char c:2;
 };
 test t1;
 int len=sizeof(t1);   //len=1

posted @ 2007-01-17 11:18 五指魅力 阅读(620) | 评论 (0)编辑 收藏

2006年12月5日

首先声明,简单的比较前缀自增运算符和后缀自增运算符的效率是片面的,因为存在很多因素影响这个问题的答案。  
   
   
  首先考虑内建数据类型的情况:  
   
  如果自增运算表达式的结果没有被使用,而仅仅简单的用于增加一员操作数,答案是明确的,前缀法和后缀法没有任何区别,编译器的处理都应该是相同的,很难想象得出有什么编译器实现可以别出心裁在二者之间制造任何差异。  
  测试C++源代码如下:  
  //test1.cpp  
  void   test()  
  {  
  int   i=0;  
  i++;  
  ++i;  
  }  
  Gnu   C/C++   2编译的汇编中间代码如下:  
                  .file       "test1.cpp"  
  gcc2_compiled.:  
  ___gnu_compiled_cplusplus:  
  .text  
                  .align   4  
  .globl   _test__Fv  
                  .def         _test__Fv;             .scl         2;             .type       32;           .endef  
  _test__Fv:  
                  pushl   %ebp  
                  movl   %esp,%ebp  
                  subl   $24,%esp  
                  movl   $0,-4(%ebp) ;i=0  
                  incl   -4(%ebp) ;i++  
                  incl   -4(%ebp) ;++i  
                  jmp   L3  
                  jmp   L2  
                  .p2align   4,,7  
  L3:  
  L2:  
                  leave  
                  ret  
  很显然,不管是i++还是++i都仅仅是一条incl指令而已。  
   
  如果表达式的结果被使用,那么情况要稍微复杂一些。  
  测试C++源代码如下:  
  //test2.cpp  
  void   test()  
  {  
  int   i=0,a,b;  
  a=i++;  
  b=++i;  
  }  
  Gnu   C/C++   2编译的汇编中间代码如下:  
  .file "test2.cpp"  
  gcc2_compiled.:  
  ___gnu_compiled_cplusplus:  
  .text  
  .align   4  
  .globl   _test__Fv  
  .def _test__Fv; .scl 2; .type 32; .endef  
  _test__Fv:  
  pushl   %ebp  
  movl   %esp,%ebp  
  subl   $24,%esp  
  movl   $0,-4(%ebp) ;i=0  
  movl   -4(%ebp),%eax ;i   -->   ax  
  movl   %eax,-8(%ebp) ;ax   -->   a(a=i)  
  incl   -4(%ebp) ;i++  
  incl   -4(%ebp) ;++i  
  movl   -4(%ebp),%eax ;i   -->   ax  
  movl   %eax,-12(%ebp) ;ax   -->   b(b=i)  
  jmp   L3  
  jmp   L2  
  .p2align   4,,7  
  L3:  
  L2:  
  leave  
  ret  
  有差别吗?显然也没有,同样是一条incl指令,再加上两条movl指令借用eax寄存器复制调用栈内容。  
   
  让我们再加上编译器优化,重新编译后的汇编代码如下:  
  .file "test2.cpp"  
  gcc2_compiled.:  
  ___gnu_compiled_cplusplus:  
  .text  
  .align   4  
  .globl   _test__Fv  
  .def _test__Fv; .scl 2; .type 32; .endef  
  _test__Fv:  
  pushl   %ebp  
  movl   %esp,%ebp  
  leave  
  ret  
  好了,优化的过火了,由于i,a,b三个变量没有被使用,所以干脆全都被优化了,结果成了一个什么都不做的空函数体。  
   
  那么,让我们再加上一点代码使用a和b的结果吧,这样i的结果也不能够忽略了,C++源代码如下:  
  //test3.cpp  
  int   test()  
  {  
  int   i=0,a,b;  
  a=i++;  
  b=++i;  
  return   a+b;  
  }  
  此时汇编代码如下:  
  .file "test3.cpp"  
  gcc2_compiled.:  
  ___gnu_compiled_cplusplus:  
  .text  
  .align   4  
  .globl   _test__Fv  
  .def _test__Fv; .scl 2; .type 32; .endef  
  _test__Fv:  
  pushl   %ebp  
  movl   %esp,%ebp  
  movl   $2,%eax  
  leave  
  ret  
  你还是没有想到吧,答案仅仅是编译器计算了返回值,常量展开(constant-unwinding)启动,变成了直接返回常量结果。  
   
  怎么办?我们把i变成参数,避免这种预期以外的结果,C++源代码如下:  
  //test4.cpp  
  int   test1(int   i)  
  {  
  int   a=i++;  
  return   a;  
  }  
   
  int   test2(int   i)  
  {  
  int   a=++i;  
  return   a;  
  }  
  好了,很辛苦,终于得到了不一样的汇编代码:  
  .file "test4.cpp"  
  gcc2_compiled.:  
  ___gnu_compiled_cplusplus:  
  .text  
  .align   4  
  .globl   _test1__Fi  
  .def _test1__Fi; .scl 2; .type 32; .endef  
  _test1__Fi:  
  pushl   %ebp  
  movl   %esp,%ebp  
  movl   8(%ebp),%eax  
  leave  
  ret  
  .align   4  
  .globl   _test2__Fi  
  .def _test2__Fi; .scl 2; .type 32; .endef  
  _test2__Fi:  
  pushl   %ebp  
  movl   %esp,%ebp  
  movl   8(%ebp),%eax  
  incl   %eax  
  leave  
  ret  
  和你接触到的教条正相反吧,++i反而增加了一条汇编指令incl,而i++却没有,这就是编译器优化的魅力。  
  因为不管i有没有增加,都不影响a的值,而函数仅仅返回i的值,所以i的自增运算就根本不必进行了。  
  所以,为了更客观一些,我们将i参数改为按照引用传递,C++源代码如下;  
  //test5.cpp  
  int   test1(int   &i)  
  {  
  int   a=i++;  
  return   a;  
  }  
   
  int   test2(int   &i)  
  {  
  int   a=++i;  
  return   a;  
  }  
  这一次的结果加入了指针的运算,稍微复杂一些:  
  .file "test5.cpp"  
  gcc2_compiled.:  
  ___gnu_compiled_cplusplus:  
  .text  
  .align   4  
  .globl   _test1__FRi  
  .def _test1__FRi; .scl 2; .type 32; .endef  
  _test1__FRi:  
  pushl   %ebp  
  movl   %esp,%ebp  
  movl   8(%ebp),%eax  
  movl   (%eax),%edx  
  incl   (%eax)  
  movl   %edx,%eax  
  leave  
  ret  
  .align   4  
  .globl   _test2__FRi  
  .def _test2__FRi; .scl 2; .type 32; .endef  
  _test2__FRi:  
  pushl   %ebp  
  movl   %esp,%ebp  
  movl   8(%ebp),%eax  
  movl   (%eax),%edx  
  leal   1(%edx),%ecx  
  movl   %ecx,(%eax)  
  movl   %ecx,%eax  
  leave  
  ret  
  惊讶吗?还是a=i++的代码更高效一些,不知道这会让你有什么想法。反正,我得出的结论,对于内建数据类型来说,i++和++i孰优孰劣,是编译器实现相关的,实在不必太可以关心这个问题。  
   
   
  最后让我们再回到起点,对于自定义数据类型(主要是指类)说,不需要再做很多汇编代码的分析了,我很清楚的知道为什么会有人循循善诱。  
  因为前缀式可以返回对象的引用,而后缀式必须返回对象的值,所以导致了在大对象的时候产生了较大的复制开销,引起效率降低,因此会有劝告尽量使用前缀式,尽可能避免后缀式,除非从行为上真的需要后缀式。  
  这也就是More   Effective   C++/Term   7中的原文提到的,处理使用者自定义类型(注意不是指内建类型)的时候,应该尽可能的使用前缀式地增/递减,因为他天生体质较佳。  
  同时,为了保证前缀和后缀对递增/递减的语义的实现保持一致,设计上的一般原则是后缀式的实现以前缀式为基础,这样,后缀式往往多了一次函数调用,这也许也是一个需要考虑的效率因素,不过相比之下,就有点微乎其微了。  
  重申一点关于这个问题的进一步叙述,可以在Scott   Mayer的<<More   Effective   C++>>一书的条款7中获得,大约在原书的P31-34上。

posted @ 2006-12-05 14:38 五指魅力 阅读(230) | 评论 (1)编辑 收藏

2006年8月21日

1:程序设计或软件设计就是程序体系结构的规范,要实现这个规范来满足程序的功能和性能需求。以设计文档来体现。

设计文档包含的内容:
(1):将程序部分划为多个子系统,包括子系统间的接口和依赖关系,子系统间的数据流,在各子系统之间来回的输入和输出,以及总的线程模式。

(2):各子系统的具体细节,包括进一步细分的类,类层次关系,数据结构,算法,特定的线城模型和错误处理细节。

2:C++设计的两个原则:抽象(abstraction)和重用(reuse)

posted @ 2006-08-21 16:56 五指魅力 阅读(138) | 评论 (0)编辑 收藏

五大内存分区

C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。

栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。

堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。

自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。

全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。

常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改,而且方法很多)

明确区分堆与栈

bbs上,堆与栈的区分问题,似乎是一个永恒的话题,由此可见,初学者对此往往是混淆不清的,所以我决定拿他第一个开刀。

首先,我们举一个例子:

void f() { int* p=new int[5]; }

这条短短的一句话就包含了堆与栈,看到new,我们首先就应该想到,我们分配了一块堆内存,那么指针p呢?他分配的是一块栈内存,所以这句话的意思就是:在栈内存中存放了一个指向一块堆内存的指针p。在程序会先确定在堆中分配内存的大小,然后调用operator new分配内存,然后返回这块内存的首地址,放入栈中,他在VC6下的汇编代码如下:

00401028push14h

0040102Acalloperator new (00401060)

0040102Faddesp,4

00401032movdword ptr [ebp-8],eax

00401035moveax,dword ptr [ebp-8]

00401038movdword ptr [ebp-4],eax

这里,我们为了简单并没有释放内存,那么该怎么去释放呢?是delete p么?澳,错了,应该是delete []p,这是为了告诉编译器:我删除的是一个数组,VC6就会根据相应的Cookie信息去进行释放内存的工作。

好了,我们回到我们的主题:堆和栈究竟有什么区别?

主要的区别由以下几点:

1 、管理方式不同;

2 、空间大小不同;

3 、能否产生碎片不同;

4 、生长方向不同;

5 、分配方式不同;

6 、分配效率不同;

管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生memory leak

空间大小:一般来讲在32位系统下,堆内存可以达到4G的空间,从这个角度来看堆内存几乎是没有什么限制的。但是对于栈来讲,一般都是有一定的空间大小的,例如,在VC6下面,默认的栈空间大小是1M(好像是,记不清楚了)。当然,我们可以修改:

打开工程,依次操作菜单如下:Project->Setting->Link,在Category 中选中Output,然后在Reserve中设定堆栈的最大值和commit

注意:reserve最小值为4Bytecommit是保留在虚拟内存的页文件里面,它设置的较大会使栈开辟较大的值,可能增加内存的开销和启动时间。

碎片问题:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出,在他弹出之前,在他上面的后进的栈内容已经被弹出,详细的可以参考数据结构,这里我们就不再一一讨论了。

生长方向:对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;对于栈来讲,它的生长方向是向下的,是向着内存地址减小的方向增长。

分配方式:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。

分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。

从这里我们可以看到,堆和栈相比,由于大量new/delete的使用,容易造成大量的内存碎片;由于没有专门的系统支持,效率很低;由于可能引发用户态和核心态的切换,内存的申请,代价变得更加昂贵。所以栈在程序中是应用最广泛的,就算是函数的调用也利用栈去完成,函数调用过程中的参数,返回地址,EBP和局部变量都采用栈的方式存放。所以,我们推荐大家尽量用栈,而不是用堆。

虽然栈有如此众多的好处,但是由于和堆相比不是那么灵活,有时候分配大量的内存空间,还是用堆好一些。

无论是堆还是栈,都要防止越界现象的发生(除非你是故意使其越界),因为越界的结果要么是程序崩溃,要么是摧毁程序的堆、栈结构,产生以想不到的结果,就算是在你的程序运行过程中,没有发生上面的问题,你还是要小心,说不定什么时候就崩掉,那时候debug可是相当困难的

posted @ 2006-08-21 16:29 五指魅力 阅读(668) | 评论 (0)编辑 收藏

1、什么是static?
  static 是c++中很常用的修饰符,它被用来控制变量的存储方式和可见性。

 2、为什么要引入static?
  函数内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,大家知道,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题: 如果想将函数中此变量的值保存至下一次调用时,如何实现? 最容易想到的方法是定义一个全局的变量,但定义为一个全局变量有许多缺点,最明显的缺点是破坏了此变量的访问范围(使得在此函数中定义的变量,不仅仅受此函数控制)。

3、什么时候用static?
  需要一个数据对象为整个类而非某个对象服务,同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部,对外不可见。

 4、static的内部机制:
  静态数据成员要在程序一开始运行时就必须存在。因为函数在程序运行中被调用,所以静态数据成员不能在任何函数内分配空间和初始化。

  这样,它的空间分配有三个可能的地方,一是作为类的外部接口的头文件,那里有类声明;二是类定义的内部实现,那里有类的成员函数定义;三是应用程序的main()函数前的全局数据声明和定义处。

   静态数据成员要实际地分配空间,故不能在类的声明中定义(只能声明数据成员)。类声明只声明一个类的“尺寸和规格”,并不进行实际的内存分配,所以在类声明中写成定义是错误的。它也不能在头文件中类声明的外部定义,因为那会造成在多个使用该类的源文件中,对其重复定义。

  static被引入以告知编译器,将变量存储在程序的静态存储区而非栈上空间,静态数据成员按定义出现的先后顺序依次初始化,注意静态成员嵌套时,要保证所嵌套的成员已经初始化了。消除时的顺序是初始化的反顺序。

5、static的优势:
  可以节省内存,因为它是所有对象所公有的,因此,对多个对象来说,静态数据成员只存储一处,供所有对象共用。静态数据成员的值对每个对象都是一样,但它的值是可以更新的。只要对静态数据成员的值更新一次,保证所有对象存取更新后的相同的值,这样可以提高时间效率。

 6、引用静态数据成员时,采用如下格式:
         <类名>::<静态成员名>
  如果静态数据成员的访问权限允许的话(即public的成员),可在程序中,按上述格式来引用静态数据成员。

7、注意事项:
  (1)类的静态成员函数是属于整个类而非类的对象,所以它没有this指针,这就导致了它仅能访问类的静态数据和静态成员函数。

   (2)不能将静态成员函数定义为虚函数。

   (3)由于静态成员声明于类中,操作于其外,所以对其取地址操作,就多少有些特殊,变量地址是指向其数据类型的指针 ,函数地址类型是一个“nonmember函数指针”。

   (4)由于静态成员函数没有this指针,所以就差不多等同于nonmember函数,结果就产生了一个意想不到的好处:成为一个callback函数,使得我们得以将c++和c-based x window系统结合,同时也成功的应用于线程函数身上。

   (5)static并没有增加程序的时空开销,相反她还缩短了子类对父类静态成员的访问时间,节省了子类的内存空间。

   (6)静态数据成员在<定义或说明>时前面加关键字static。

   (7)静态数据成员是静态存储的,所以必须对它进行初始化。

   (8)静态成员初始化与一般数据成员初始化不同:
                  初始化在类体外进行,而前面不加static,以免与一般静态变量或对象相混淆;

     初始化时不加该成员的访问权限控制符private,public等;

     初始化时使用作用域运算符来标明它所属类;

     所以我们得出静态数据成员初始化的格式:
        <数据类型><类名>::<静态数据成员名>=<值>

   (9)为了防止父类的影响,可以在子类定义一个与父类相同的静态变量,以屏蔽父类的影响。这里有一点需要注意:我们说静态成员为父类和子类共享,但我们有重复定义了静态成员,这会不会引起错误呢?不会,我们的编译器采用了一种绝妙的手法:name-mangling 用以生成唯一的标志。

posted @ 2006-08-21 15:43 五指魅力 阅读(178) | 评论 (0)编辑 收藏

1:构建 C++ 程序的步骤:首先,代码通过一个预处理器运行。这个预处理器会识别出代码的元信息。其次,代码经过编译或翻译为机器可读的对象文件。最后,单个的对象文件链接到一起,构成一个应用。

2:声明(declaration)只是告诉编译器如何调用一个函数,定义(definition)则包含了函数的实际代码。

3:命名空间(namespace)可以解决不同代码之间的命名冲突问题。但如果命名空间使用不恰当,仍然会造成命名冲突,如:两个命名空间都含有相同的名字。

4:C++ 在计算表达式时使用一种“短路逻辑”,这说明,一旦能够确认最后结果,表达式的余下部分就不必再计算了。

5:动态分配一个数组,首先需要声明一个指针。
int *myArr;
myArr=new int[arraySize];
分配了内存后就可以把myArr当作一个常规数组使用。
myArr[3]=2;
delete [] myArr;

6:
int *myInt=new int;
myInt = 8;          //指针的地址指向地址为8的内存空间,可能产生垃圾
*myInt = 8; //给指针赋值为8

7:字符串
C风格: char *str="this is a test";
 char str[20]="this is a test";
C++风格:
include <string>
string str="this is a test"; //可直接使用 =,==,+等运算符

8:const常量,保护变量不被修改,
const引用,好处:提交效率。免去建立副本的开销,也防止被修改。

posted @ 2006-08-21 11:11 五指魅力 阅读(228) | 评论 (0)编辑 收藏

2006年8月18日

ASCII表

ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符
0 NUT 32 (space) 64 @ 96
1 SOH 33 65 A 97 a
2 STX 34 66 B 98 b
3 ETX 35 # 67 C 99 c
4 EOT 36 $ 68 D 100 d
5 ENQ 37 % 69 E 101 e
6 ACK 38 & 70 F 102 f
7 BEL 39 , 71 G 103 g
8 BS 40 ( 72 H 104 h
9 HT 41 ) 73 I 105 i
10 LF 42 * 74 J 106 j
11 VT 43 + 75 K 107 k
12 FF 44 , 76 L 108 l
13 CR 45 - 77 M 109 m
14 SO 46 . 78 N 110 n
15 SI 47 / 79 O 111 o
16 DLE 48 0 80 P 112 p
17 DCI 49 1 81 Q 113 q
18 DC2 50 2 82 R 114 r
19 DC3 51 3 83 X 115 s
20 DC4 52 4 84 T 116 t
21 NAK 53 5 85 U 117 u
22 SYN 54 6 86 V 118 v
23 TB 55 7 87 W 119 w
24 CAN 56 8 88 X 120 x
25 EM 57 9 89 Y 121 y
26 SUB 58 : 90 Z 122 z
27 ESC 59 ; 91 [ 123 {
28 FS 60 < 92 \ 124 |
29 GS 61 = 93 ] 125 }
30 RS 62 > 94 ^ 126 ~
31 US 63 ? 95 127 DEL

posted @ 2006-08-18 22:36 五指魅力 阅读(113) | 评论 (0)编辑 收藏

2006年8月17日

1. 请介绍一下你自己。

  这是外企常问的问题。一般人回答这个问题过于平常,只说姓名、年龄、爱好、工作经验,这些在简历上都有,其实,外企最希望知道的是求职者能否胜任工作,包括:最强的技能、最深入研究的知识领域、个性中最积极的部分、做过的最成功的事,主要的成就等,这些都可以和学习无关,也可以和学习有关,但要突出积极的个性和做事的能力,说得合情合理外企才会相信。外企很重视一个人的礼貌,求职者要尊重考官,在回答每个问题之后都说一句“谢谢”。外企喜欢有礼貌的求职者。

   2. 在学校你最不喜欢的课程是什么?为什么?

  这个问题外企不希望求职者直接回答“数学”、“体育”之类的具体课程,如果直接回答还说明了理由,不仅代表求职者对这个学科不感兴趣,可能还代表将来也会对要完成的某些工作没有兴趣。这个问题外企招聘者最想从求职者口里听到:我可能对个别科目不是特别感兴趣,但是正因为这样,我会花更多的时间去学习这门课程,通过学习对原本不感兴趣的科目也开始有了兴趣,对于本来就有兴趣的科目我自然学习得更认真,所以各门课的成绩较为平衡。通过这样的问题,外企可以找到对任何事情都很感兴趣的求职者。

   3. 说说你最大的优缺点?

  这个问题外企问的概率很大,通常不希望听到直接回答的缺点是什么等,如果求职者说自己小心眼、爱忌妒人、非常懒、脾气大、工作效率低,外企肯定不会录用你。外企喜欢求职者从自己的优点说起,中间加一些小缺点,最后再把问题转回到优点上,突出优点的部分。外企喜欢聪明的求职者。

   4. 你认为你在学校属于好学生吗?

  外企的招聘者很精明,问这个问题可以试探出很多问题:如果求职者学习成绩好,就会说:“是的,我的成绩很好,所有的成绩都很优异。当然,判断一个学生是不是好学生有很多标准,在学校期间我认为成绩是重要的,其他方面包括思想道德、实践经验、团队精神、沟通能力也都是很重要的,我在这些方面也做得很好,应该说我是一个全面发展的学生。”如果求职者成绩不尽理想,便会说:“我认为是不是一个好学生的标准是多元化的,我的学习成绩还可以,在其他方面我的表现也很突出,比如我去很多地方实习过,我很喜欢在快节奏和压力下工作,我在学生会组织过××活动,锻炼了我的团队合作精神和组织能力。” 有经验的招聘者一听就会明白,外企喜欢诚实的求职者。

   5. 说说你的家庭。

  外企面试时询问家庭问题不是非要知道求职者家庭的情况,探究隐私,外企不喜欢探究个人隐私,而是要了解家庭背景对求职者的塑造和影响。外企希望听到的重点也在于家庭对求职者的积极影响。外企最喜欢听到的是:我很爱我的家庭!我的家庭一向很和睦,虽然我的父亲和母亲都是普通人,但是从小,我就看到我父亲起早贪黑,每天工作特别勤劳,他的行动无形中培养了我认真负责的态度和勤劳的精神。我母亲为人善良,对人热情,特别乐于助人,所以在单位人缘很好,她的一言一行也一直在教导我做人的道理。外企相信,和睦的家庭关系对一个人的成长有潜移默化的影响。

   6. 说说你对行业、技术发展趋势的看法?

  外企对这个问题很感兴趣,只有有备而来的求职者能够过关。求职者可以直接在网上查找对你所申请的行业部门的信息,只有深入了解才能产生独特的见解。外企认为最聪明的求职者是对所面试的公司预先了解很多,包括公司各个部门,发展情况,在面试回答问题的时候可以提到所了解的情况,外企欢迎进入企业的人是“知己”,而不是“盲人”。

   7. 就你申请的这个职位,你认为你还欠缺什么?

  外企喜欢问求职者弱点,但精明的求职者一般不直接回答。他们希望看到这样的求职者:继续重复自己的优势,然后说:“对于这个职位和我的能力来说,我相信自己是可以胜任的,只是缺乏经验,这个问题我想我可以进入公司以后以最短的时间来解决,我的学习能力很强,我相信可以很快融入公司的企业文化,进入工作状态。”外企喜欢能够巧妙地躲过难题的求职者。

   8. 你期望的工资是多少?

  外企的工资水平是很灵活的,何种能力拿何种工资。外企喜欢直率的人,但这个问题却不能正面回答,外企希望听到:“以我的能力和我的优势,我完全可以胜任这个职位,我相信我可以做得很好。但是贵公司对这个职位的描述不是很具体,我想还可以延后再讨论”。外企欢迎求职者给其定薪的自由度,而不是咬准一个价码。

    9. 你能给公司带来什么?

  外企很想知道未来的员工能为企业做什么,求职者应再次重复自己的优势,然后说:“就我的能力,我可以做一个优秀的员工在组织中发挥能力,给组织带来高效率和更多的收益”。外企喜欢求职者就申请的职位表明自己的能力,比如申请营销之类的职位,可以说:“我可以开发大量的新客户,同时,对老客户做更全面周到的服务,开发老客户的新需求和消费。”等等。

    10. 你还有什么问题吗?

  外企的这个问题看上去可有可无,其实很关键,外企不喜欢说“没有问题”的人,因为其很注重员工的个性和创新能力。外企不喜欢求职者问个人福利之类的问题,如果有人这样问:贵公司对新入公司的员工有没有什么培训项目,我可以参加吗?或者说贵公司的晋升机制是什么样的?外企将很欢迎,因为体现出你对学习的热情和对公司的忠诚度以及你的上进心。

posted @ 2006-08-17 17:18 五指魅力 阅读(125) | 评论 (0)编辑 收藏

this.DataGrid1.Visible=false;
this.DataGrid1.DataSource=ds;
this.DataGrid1.DataBind();

Response.Clear();
Response.Buffer= true;
Response.Charset="GB2312";   
Response.AppendHeader("Content-Disposition","attachment;filename=FileName.xls");
Response.ContentEncoding=System.Text.Encoding.GetEncoding("GB2312");//设置输出流为简体中文
Response.ContentType = "application/ms-excel";//设置输出文件类型为excel文件。
this.EnableViewState = false;   
System.Globalization.CultureInfo myCItrad = new System.Globalization.CultureInfo("ZH-CN",true);
System.IO.StringWriter oStringWriter = new System.IO.StringWriter(myCItrad);
System.Web.UI.HtmlTextWriter oHtmlTextWriter = new System.Web.UI.HtmlTextWriter(oStringWriter);
this.DataGrid1.RenderControl(oHtmlTextWriter);
Response.Write(oStringWriter.ToString());
Response.End();

posted @ 2006-08-17 17:17 五指魅力 阅读(106) | 评论 (0)编辑 收藏