现在的位置: 首页 > 综合 > 正文

菜鸟学C++

2013年08月07日 ⁄ 综合 ⁄ 共 9022字 ⁄ 字号 评论关闭

2004/7/2
------------------------------------------------------------------------------------------
how to debug register?here is a example:

typedef struct regs_t
{
 DWORD eax;
 DWORD ebx;
 DWORD ecx;
 DWORD edx;
 DWORD esp;
 DWORD ebp;
 DWORD esi;
 DWORD edi;
} REGS;

#define SHOW_REGS(x) REGS __regs;/
 __asm {mov __regs.eax, eax}/
 __asm {mov __regs.ebx, ebx}/
 __asm {mov __regs.ecx, ecx}/
 __asm {mov __regs.edx, edx}/
 __asm {mov __regs.esp, esp}/
 __asm {mov __regs.ebp, ebp}/
 __asm {mov __regs.esi, esi}/
 __asm {mov __regs.edi, edi}/
 char __regs_text[128];/

2004/8/20
------------------------------------------------------------------------------------------
int* p,q;
第一眼看去,好像是p和q都是int*类型的,但事实上,只有p是一个指针,而q是一个最简单的int型变量。
int (*p)[4]=RollNum;
int *q[5];

这里,p被声明为一个指向一个4元素(int类型)数组的指针,而q被声明为一个包含5个元素(int类型的指针)的数组。

另外,我们还可以在同一个声明中混合实用*和&,如下:

int **p1; // p1 is a pointer to a pointer to an int.
int *&p2; // p2 is a reference to a pointer to an int.
int &*p3; // ERROR: Pointer to a reference is illegal.
int &&p4; // ERROR: Reference to a reference is illegal.

注:p1是一个int类型的指针的指针;p2是一个int类型的指针的引用;p3是一个int类型引用的指针(不合法!);p4是一个int类型引用的引用(不合法!)。
const int *p;
int const *q;

他们当中哪一个代表const int类型的指针(const直接修饰int),哪一个代表int类型的const指针(const直接修饰指针)?实际上,p和q都被声明为const int类型的指针。

2004/9/1
------------------------------------------------------------------------------------------
1 for_each和表达式模板(expression template)??????10么dd
2 纯虚拟私有函数?

2004/9/2
------------------------------------------------------------------------------------------
微软风格就是if(0==i)这种,因为可以防止出现写成if(i=0)这样if后的语句肯定被执行的情况

2004/9/2
------------------------------------------------------------------------------------------
from csdn
假设 
int  a[10] 
p1=a; 
 
那么 
*p++=1; 
*++p=2; 
++*p=3; 
(*p)++=4; 
 
分别应该怎么按照优先级别运算? 
按照书上的说法++  (后置)  >++(前置)  >*  解引用用  >  =  等于 
*p++  是否应该是  现算(p++)  在算*  最后  赋值? 
求所有的正确的算法  和解答 
--------------------------------------------------------------- 
 
++(后缀)属于“后缀操作符”,其优先级高于“前缀操作符”。 
*  和++(前缀)都属于“前缀操作符”,优先级相同,按从左到右结合的顺序。都高于赋值运算符。 
 
所以: 
*p++=1  相当于  (*(p++))  =  1,也就是说++操作于p上,结果为p原来的值,再作*运算,去除引用,再赋为1。总的作用就是把p引用的对象赋值为1,并把p加1。 
 
*++p=2  相当于(*(++p))  =  2,也就是说++操作于p上,结果为p加1后的值,再作*运算,去除引用,再赋值为1。总的作用就是把p加1,然后对其引用的对象赋值为2。 
 
++*p=3  相当于(++(*p))  =  3,也就是说先对p作*运算去除引用,其结果为p引用的对象,再把这个对象+1,结果还是这个对象,再把它赋值为3。这个表达式要求对象的前缀++操作符的返回值为左值。 
 
(*p)++=4  这里有一个强制优等级(括号),它的级别最高,结果就是((*p)++)  =  4,也就是先对p作*运算去除引用,其结果为它引用的对象,然后对这个对象作后缀++操作符,结果为这个对象操作前的值(一般是一个临时变量),然后把它赋值为4,这个表达式要求对象的后缀++操作符的返回值为左值(整数类型是不符合要求的,只对定义了这个操作符的对象类型才有可能符合要求)。 
 
这个问题以C中很难试验出来,在C++中可以用操作符重载的方法看清楚(操作符重载不会改变优先级): 
 
#include  <iostream> 
 
class  test 

public: 
   test(){} 
   test(int){} 
   test&  operator  =  (const  test&){std::cout<<"Assignment  of  test"  <<  std::endl;  return  *this;} 
   test&  operator  ++  (){std::cout  <<  "Prefix  ++  of  test"  <<  std::  endl;  return  *  this;} 
   test&  operator  ++  (int)  {std::cout  <<  "Suffix  ++  of  test"  <<  std::endl;  return  *this;} 
}; 
class  testptr 

   test  Value; 
public: 
   testptr&  operator  =  (const  test&){std::cout<<"Assignment  of  testptr"  <<  std::endl;  return  *this;} 
   testptr&  operator  ++  (){std::cout  <<  "Prefix  ++  of  testptr"  <<  std::  endl;  return  *  this;} 
   testptr&  operator  ++  (int)  {std::cout  <<  "Suffix  ++  of  testptr"  <<  std::endl;  return  *this;} 
   test&  operator  *(){std::cout<<  "Operator  *  of  testptr"<<std::endl;  return  Value;} 
}; 
 
#define  TRACK(X)  std::cout  <<std::endl<<"*****    "<<  #X  <<  "  *****"  <<std::endl;  X 
int  main() 

       testptr  p; 
       TRACK(*p++=1); 
       TRACK(*++p=2); 
       TRACK(++*p=3); 
       TRACK((*p)++=4); 
       std::cin.get(); 

 
输出为 
*****    *p++=1  ***** 
Suffix  ++  of  testptr 
Operator  *  of  testptr 
Assignment  of  test 
 
*****    *++p=2  ***** 
Prefix  ++  of  testptr 
Operator  *  of  testptr 
Assignment  of  test 
 
*****    ++*p=3  ***** 
Operator  *  of  testptr 
Prefix  ++  of  test 
Assignment  of  test 
 
*****    (*p)++=4  ***** 
Operator  *  of  testptr 
Suffix  ++  of  test 
Assignment  of  test 
 
 
int  p  =  1; 
int  a  =  p++; 
结果a=1,并不是因为后缀++优先级低(我记得有一本C教材就是这样写的,真是误人子弟),而是由后缀++的语义决定的。标准的后缀++应该是“对操作对象做+1操作,并返回操作前的值”,它在赋值运算前运算了,但它的返回值并不是p,而是p在做+1运算前的值。因此我们还可以知道,p++的返回值应该不是一个左值,p++=a是无法编译通过的。而前缀++则不一样,++p的含义就是“对p做+1运算,并返回p”,其返回值就是p本身(引用),是一个左值,++p  =  a是可以编译的(但没什么意义)。 
 
如果用代码描述一下这两个操作符,应该是这样的: 
 
const  int  int::operator  ++(int)//后缀++ 

   int  temp  =  *this; 
   *this  =  *this  +1; 
   return  temp; 

 
int&  int::operator  ++()//前缀++ 

   *this  =  *this  +  1; 
   return  *this; 

 
 
补充: 
在C中,上述语句含义分别是: 
*p++=1; -->  temp  =  p  +  1;  *temp  =  1; 
*++p=2;  -->  p  =  p  +1;  *  p  =  1; 
++*p=3;  -->  *p  =  *p  +  1;  *p  =  3; 
(*p)++=4;//语法错误,无法写出对应的语句。 
 
由于后缀增/减量操作符的特殊性,导致初学者很难理解“为什么后缀的++优先级高却后对变量加1呢?”事实上,事实上,“后缀++”并不是后对变量加1,而是先做了,只是它的返回值并不是这个变量,而是这个变量改变前的值。如果对它很难理解,建议不要使用这几个操作符,而改用普通的加/减法操作符: 
*p++=1; -->  *p  =  1;  p  =  p  +  1; 
*++p=2;  -->  p  =  p  +  1;  *p  =  2; 
++*p=3;  -->  *p  =  *p  +  1;  *p  =  3; 
(*p)++=4;//语法错误,无法写出对应的语句。 
 
由于在C++中这几个操作符不再是整数和指针类型特有的,而是可以为类定义的,并且它们可以和+/-1操作语义不同或根本没有加/减法操作符(如双向迭代器),不能简单地用加/减法代替。不过C++程序员们可以通过看比较好的类的操作符重载函数(如迭代器的)代码真正明白后缀增/减量操作符的语义,不会因为它“优先级高却后对变量加1”的问题糊涂。不过,仅管如此,我还是认为使用增/减量操作符时最好让一个表达式中或者没有增/减量操作符,或者只有一个增/减量操作符,如:++p;*p  =  1;(相当于*++p  =  1)或*p  =  1;++p;(相当于*p++=1),这样也不用去区分前缀和后缀的区别了。 

2004/9/2
------------------------------------------------------------------------------------------
我已经包含了objbase.h并调用了CoInitialize(0), 
报错如下: 
'CoCreateInstanceEx'  :  undeclared  identifier 
 
--------------------------------------------------------------- 
 
do  you  have  defined  _WIN32_DCOM  or  defined  _WIN32_DCOM  larger  than  or  equal    0x400? 
--------------------------------------------------------------- 
 
stdfax.h加上这个 
#define  _WIN32_WINNT  0x0500

 

afxDump是一个CDumpContext类型的全局变量

2004/11/20
------------------------------------------------------------------------------------------
结构编译对齐方式
VC c1 /Zp1 (or Porject->Settings->C/C++->Code Generation->Struct menber alignment)
BCB bcc32 -a1

2004/11/21
------------------------------------------------------------------------------------------
1 try
 {
  throw("dsfsdfsdf");
 }
 catch(float x)
 {
  printf("Hello World!/n");
 }
 catch(char* x)
 {
  printf("Hello World!/n");//执行这句
 }
2  try
 {
  throw("dsfsdfsdf");
 }
 catch(float x)
 {
  printf("Hello World!/n");//执行这句
 }
3 try
 {
  throw(1);
 }
 catch(float x)
 {
  printf("Hello World!/n");
 }
 catch(int x)
 {
  printf("Hello World!/n");//执行这句
 }
4 try
 {
  throw(1);
 }
 catch(float x)
 {
  printf("Hello World!/n");//执行这句
 }
看来C中catch各子句并不像CPP中对象一样。
5 try
 {
  throw(1);
 }
 catch(...)
 {
  printf("Hello World!/n");
 }
 catch(int x)
 {
  printf("Hello World!/n");
 }
编译出错!catch(...)必须在最后

2004/11/23
------------------------------------------------------------------------------------------
《凌波微步》
打开速度优化开关的指令:
VC c1 /O2
Linux g++ -O2

优化后的指令
1 将for循环的实现改成了do while结构
2 更多的利用系统寄存器
3 优化开关必一定久必不用快!参见P140,系统函数strlen()的实现(VC98/CRT/SRC/Intel/STRLEN.ASM)。每次比较4字节vs每次比较1字节

2006/1/12
------------------------------------------------------------------------------------------
虚拟继承的测试:
class Point { public: int x;};
class Point3d : public Point {};
class Vertex : virtual public Point {};
class Vertex3d : public Point3d, public Vertex {};
class pVertex : public Vertex3d {};

int main ()
{
    Vertex3d v;
    v.Point3d::x = 1;
    v.Vertex::x = 2;
    printf("%d %d/n",v.Point3d::x, v.Vertex::x);
    getchar();
    return 0;
}

输出 1 2
如果是class Point3d : virtual public Point {};输出2 2

1/18/2006

------------------------------------------------------------------------------------------

It's one of the classic basic forms for malloc arguments:

1    object_ptr = malloc(N * sizeof *object_ptr);
2    string_ptr = malloc(STRING_LENGTH + 1);
3      void_ptr = malloc(sizeof variable);

Notes: 1 the parenthesis is not necessory for sizeof; 2 the * position

 

------------------------------------------------------------------------------------------

1/26/2006

foo * and const foo * are different types but are nevertheless similar
enough that you can use const_cast to cast between them. Where two types are
used as template arguments, however, the similarity of the types is
irrevant. Consider:

template<class T>
class Test
{
    T t;

 

};

template<>
class Test<const int>
{
    char array[1000];

};

Thus Test<const int> contains an array of chars, whereas Test<int> contains
a single int.

#include <iostream>
using namespace std;

int main()
{
    Test<int> t1;
    Test<const int> t2;
    cout << sizeof(t1) << endl; // gives 4
    cout << sizeof(t2) << endl; // gives 1000
    return 0;

 

}

In reality vector<foo *> and vector<const foo *> may hardly differ at
all --- in particular, they may have the same size. However, the possibility
of explicit template specialization means that they could differ
spectacularly, hence the reluctance of the compiler to allow conversion.

------------------------------------------------------------------------------------------
1/27/2006

You should not pass temporary objects by reference unless the reference
is a const. Because by the time the code gets to look at the non const
temporary object that was referenced, the temporary object may or may
not exists.

 

2/9/2006 about stream
------------------------------------------------------------------------------------------

There's an idiom (and a supporting member function) for checking
the state of a stream, which allows a stream object to be used
in a boolean context.  But converting it to a boolean value
doesn't 'just happen'.  To do so requires the use of a boolean
logical operator (a stream's 'value' itself is not boolean).
(The member function is 'operator void*', you can research it
if you like).

Try this

if(!outFile)
   // stream in is error state
else
   // stream is in 'good' state

If you want the first test to be for 'good' state, you
can write:

if(!!outFile)

or:

if(outFile.good())

BTW if you only need output, you should use 'std::ofstream'.
'std::fstream' is intended for streams which are both read
from and written to.

抱歉!评论已关闭.