30 questions (21-30)

1. Why does Delete fail?

class CBase
{
public:
         CBase() { cout <<"CBase" << endl; }
         virtual ~CBase() { cout <<"~CBase" << endl;}
};
 
classCDerived : public CBase
{
public:
         CDerived() { cout <<"CDerived" << endl; }
         ~CDerived() { cout <<"~CDerived"<< endl; }};int main(a)
{
         CBase base;
         CBase* pBase = new CBase;
         pBase = &base;
         delete pBase; // Run error!
}
Copy the code

\

[Analysis as follows] :

1. PBase refers to stack memory, which is system managed space and cannot be freed by DELETE.

2. The program was not released at the end of new in the heap, causing a memory leak.

3. It is better not to point the pointer to the applied heap space anywhere, but at least one pointer to the applied heap space. So that the last release is the piece of memory they applied for.

[Modified practice] :

int main(a)
{
    CBase base;
    CBase* pBase = new CBase;
    CBase* pBase2 = pBase;   // There must be at least one pointer to the requested space
    pBase = &base;
    delete pBase2;  // So that the last memory to be freed is the allocated memory.
} // No more errors at runtime!
Copy the code

[Further] : There are two problems with the program:

1. Memory leaks, and new files are not deleted.

2. Two destructions; Base is not new, it is automatically released at the end of the life cycle (when your function ends), you call delete to destruct it, and the system destructs it again at the end of the function, which is why you get an error. And the error should be reported when the program exits.

 

2. Class static constant variable definition?

#include<iostream>
usingnamespace std;
// The class variable of a constant can be assigned in a class declaration
//VS2008 works, VC6.0 does not. It has to do with the compiler.
class myclass
{
public:
         static const int i=20; // Only static constant data members of a class can be initialized in a class.
};
const int myclass::i = 10;
int main(a)
{
         cout<<myclass::i<<endl;
         return 0;
}
Copy the code

3. The relationship between overloading and polymorphism?

The difference between Reloading the phrase” Covering the override
1. Is polymorphism supported? Does not support support
2. Form of existence? This can be done in a class or in C++ Exists between the parent and subclass of a class.
3. Parameter list and return value Different argument lists or return values, or both. Parameter lists and returned indicators must be the same.

 

 

4. Output format: printf use!

%a(%A)     Floating-point, hexadecimal, and P- (p-) notation (C99)
%c            character
%d             Signed decimal integer
%f              Floating point numbers (including float and doulbe)
%e(%E)     Floating-point exponent output [e-(e-) notation]
%g(%G)     Floating point number not meaningless zero “0”
%i              Signed decimal integer (same as %d)
%u             An unsigned decimal integer
%o             Octal integers e.g. 0123
%x(%X)      Hex integer 0f(0f) e.g. 0x1234
%p             Pointer to the
%s             string

     

5. Can a parameter or pointer be both const and volatile?

Volatile prevents the compiler from optimizing it to read from the register. A variable defined as volatile says that it can be changed unexpectedly so that the compiler does not assume its value. To be precise, the optimizer must carefully re-read the value of the variable each time it is used, rather than using a backup stored in a register.

A parameter can be both const and volatile. Const is not subject to program modification. Volatile is unexpected change, not program modification. A pointer can also be volatile, and the interrupt service subroutine modifies a pointer to buffer.

Low Endian (low – > high byte storage); The computer default is low byte order.

High Endian High byte order (stored by High – > low bytes);

typedef struct bitstruct
{
         int b1:5;
         int b2:2;
         int b3:2;
}bitstruct;
 
int main(a)
{
         bitstruct b;
         memcpy(&b,"EMCEXAMINATION".sizeof(b));
 
         cout << sizeof(b) << endl;
 
         printf("%d,%d\n",b.b1,b.b2);/ / 5, 2
         return 0;
}
Copy the code

1. Sizeof (b)=4; That’s four bytes in size.

2. EMC memcpy will “…” Put it in B.

3. There are only 5+2+2 in substance B. The ASCII code of E is 0X45, and the ASCII code of M is 0X4D.

The high – > low – byte storage 0X4D0X45 corresponds to the binary bit 01001101 0100 0101.

4. Corresponding to B1, it meets the 5-bit 0 0101 of the low address after obtaining (low bytes are stored in the low level). The first digit 0 represents a positive number and the size is 5.

The corresponding b2, let’s take 10, and the first digit is a negative number, and then we get b2=-2.

27. Output?

int main(a)
{
         int a[5] [2] = {0.1.2.3.4.5.6.7.8.9};
        
         int *p = a[0];
         int (*p2)[2] = &a[1];
         ++p;
         ++p2;
        
         printf("%d\n",*p); //1 p is an integer pointer that starts at element 0 and adds 1 to element 1
         printf("%d\n",**p2); //4 p2 is a pointer to an array of two elements, initially pointing to element 2. The pointer is moved backwards by 2, so it points to 4
         printf("%d \n",p2[1] [2]); // How to interpret? See the interpretation.
         return 0;
}
Copy the code

\

  0 1
0 0 (p) 1 (after ++ P)
1 2 (P2 pointing) 3
2 4 (after ++ P2) 5
3 After six (p2 + 1) 7
4 8  (p2[1][2]) 9

 

P2 is a pointer to a variable that points to an array of two elements. Different from a normal pointer it points to length 2. (*p2)[2] is equivalent to a.

For p2[1][2], p2 points to 4, the previous subscript 1 is p2 plus 1 to 6, and the last subscript plus 2 moves 2 elements to 8.

\

28. Copy construct output?

class A
{
    static int objectCount;
public:
    A()
    {
        objectCount++;
        cout << "A():" <<objectCount << endl;
    }
   
    A(const A& r)
    {
        objectCount++;
        cout << "A(const A&r):" << objectCount << endl;
    }
        
    ~A()
    {
        objectCount--;
        cout << "~A():"<< objectCount << endl; }}; intA::objectCount =0;
 
A f(A x)        
{
    cout << endl <<  "Begin: f(A x)" << endl;
    return x;   Call the default copy constructor A(const a&r):3
}                //~A():2
 
int main(a)
{
    A h;        //A():1
    A h2 = f(h); // Call the default copy constructor A(consta&r):2
    cout << endl <<"End(main): f(A x)" << endl << endl;
        
    return 0;   
}               / / ~ (A) : 1 destructor h2
/ / ~ (A) : 0 structure letter h
Copy the code

29. Four types of casts

type schematic For example,
static_cast 1. Type conversion. Any type implicitly executed by the compiler can be displayed as static_cast; 2. Use type information to perform conversion, and perform necessary detection (out of bounds detection, type check) during conversion, so that the operation is relatively safe; Int – > doubleint ival. double result = static_cast<double> ival
const_cast Converts the const property of an object For example, under
dynamic_cast Runtime type checking for the top-down transformation downcast under inheritance. For example, under
reinterpret_cast 1. Only the bit model of the given object is recompiled without binary conversion; 2. Provide low-level reinterpretation of operands. For example, under

For example:

/ / const_cast instance.
class B
{
public:
         int m_num;
};
 
int main(a)
{
         B b0;
         b0.m_num = 100;
         const B b1 = b0;
         cout << b0.m_num<< "" << b1.m_num << endl;
// It is an error to modify the value of a const object below.
// b1.m_num = 355;
// cout << b1.m_num <
 
// The following uses const_cast as the positive solution.
         const_cast<B&>(b1).m_num =355;
         cout<< b1.m_num << endl;
         return 0;
}
 
/ / reinterpret_cast instance
int main(a)
{
         int n = 9;
         double dval =reinterpret_cast<double& >(n);
         double dval_new =static_cast<double>(n); / / success.
         //[just copy n bits to d, without necessary analysis]
         cout << dval << endl;/ / 2.64214 e-308
         cout << dval_new << endl;/ / 9
         return 0;
}
/ / dynamic_cast instance
class B
{
public:
         B() { cout << "B()"<< endl; }
         ~B() { cout << "~B()"<< endl; }};class C :public B
{
public:
         C() { cout << "C()"<< endl; }
         ~C() { cout << "~C()"<< endl; }};class D :public C
{
public:
         D(){ cout << "D()"<< endl; }
         ~D(){ cout << "~D()"<< endl; }};void f(D* pd)
{
         C* pc =dynamic_cast<C*>(pd);   // ok: C isa direct base class
         // pc points to C subobject of pd
 
         B* pb =dynamic_cast<B*>(pd);   // ok: B isan indirect base class
         // pb points to B subobject of pd    
}
 
int main(a)
{
         D objd;
         f(&objd);
         return 0;
}
Copy the code

\

30. Continuously updated at……

How to display the file name and line number of the current program in C/C++.

— This did not answer at that time, have seen have not remembered. Today I checked MSDN as follows:

__FILE__, // The macro %s used to display file names in the format [F:\NeuSoftDemo\NeuSoftDemo. CPP]; __LINE__, // display line number macro %d, format [12];

Extension “__DATE__, // used to display the current date, such as [Sep 18 2012] %s; __TIME__, // Displays the current time in the format of [09:45:01] %s;

__TIMESTAMP__, // Displays the current date and time in the format of [Tue Sep 18 09:48:07 2012] %s.

31. Program error correction:

[cpp] view plain copy print ?

  1. int main(int argc,char* argv[])

  2. {

  3. char str[5][] = {

    “First”,”Second”,”Thrid”,”Four”,”Five”};

  4. char* p[] = {str[4],str[3],str[2],str[1],str[0]};

  5. for(int i = 0; i < 5; i++)

  6. {

  7. printf(“%c\n”,*(p+i));

  8. }

  9. return 0;

  10. }

int main(int argc, char* argv[])
{
	char str[5] [] = {"First"."Second"."Thrid"."Four"."Five"};
	char* p[] = {str[4],str[3],str[2],str[1],str[0]};
	
	for(int i = 0; i < 5; i++)
	{
		printf("%c\n",*(p+i));
	}

	return 0;
}
Copy the code

My personal feelings are as follows:

Char STR [][5] : char STR [][5] : char STR [] But strings like “Second” have six characters and ‘\0’. Alter: char* STR [5] is safer;

Error 2: printf(“%c\n”,*(p+ I)); Obviously *(p+ I) is equivalent to p[I] storing a string, so %c should be changed to %s. %c prints a single character, %s prints a string.

Revised as follows:

[cpp] 

  1. int main(int argc,char* argv[])

  2. {

  3. char *str[5] = {

    “First”,”Second”,”Thrid”,”Four”,”Five”};

  4. char* p[] = {str[4],str[3],str[2],str[1],str[0]};

  5. for(int i = 0; i < 5; i++)

  6. {

  7. printf(“%s\n”,*(p+i));

  8. }

  9. return 0;

  10. }

Recursive and non-recursive binary search.

// Non-recursive implementation –

[cpp] view plain copy print ?

  1. void binarySearchUncycle(int nArr[],int nSize,int nSearchVal)
  2. {
  3. int nLow = 0;
  4. int nHigh = nSize-1;
  5. int nMid = 0;
  6. bool bFound = false;
  7. while(nLow <= nHigh)
  8. {
  9. nMid = (nLow + nHigh)/2;
  10. cout << “nMid =” << nMid << endl;
  11. if(nArr[nMid] == nSearchVal)
  12. {
  13. bFound = true;
  14. break;
  15. }
  16. else if(nArr[nMid] > nSearchVal)
  17. {
  18. nHigh = nMid-1;
  19. }
  20. else
  21. {
  22. nLow = nMid+1;
  23. }
  24. }//end while
  25. if(bFound)
  26. {
  27. cout << “The Elem ” << nSearchVal << ” is Exist in the array!” << endl;
  28. }
  29. else
  30. {
  31. cout << “The Elem ” << nSearchVal << ” is Not Exist in the array!” << endl;
  32. }
  33. }
Copy the code

[cpp]

  1. // Recursive binary search
  2. void binarySearchCycle(int nArr[],int low, int high, int nSearchVal)
  3. {
  4. int nLow = low;
  5. int nHigh = high;
  6. int nMid = 0;
  7. bool bFound = false;
  8. nMid = (nLow + nHigh)/2;
  9. if(nArr[nMid] == nSearchVal)
  10. {
  11. bFound = true;
  12. cout << “The Elem ” << nSearchVal << ” is Exist in the array!” << endl;
  13. return;
  14. }
  15. else if(nArr[nMid] > nSearchVal)
  16. {
  17. nHigh = nMid-1;
  18. binarySearchCycle(nArr,nLow,nHigh,nSearchVal);
  19. }
  20. else
  21. {
  22. nLow = nMid+1;
  23. binarySearchCycle(nArr,nLow,nHigh,nSearchVal);
  24. }
  25. }