2. What is "reference "? What should I pay attention to when declaring and using "reference?
A: A reference is the "alias" (alias) of a target variable. operations on an application are identical to operations on a variable. When declaring a reference, remember to initialize it. After the reference declaration is complete, the target variable name has two names, that is, the original name and reference name of the target, and the reference name cannot be used as the alias of other variable names. Declaring a reference is not a new variable. It only indicates that the reference name is an alias of the target variable name. It is not a data type, so the reference itself does not occupy the storage unit, the system does not allocate storage units to references. You cannot create an array reference.
3. What are the features of using "Reference" as a function parameter?
(1) passing a reference to a function has the same effect as passing a pointer. In this case, the parameter of the called function becomes an actual parameter variable or an alias of the object in the original main function, therefore, the operations on the parameters in the called function are the operations on the corresponding target object (in the main function.
(2) using the reference parameter to pass the function does not generate a copy of the real parameter in the memory, it is directly to operate on the real parameter; while using the general variable to pass the function parameter, when a function call occurs, you need to allocate storage units to the parameters. The parameters are copies of the real variables. if the object is passed, the copy constructor will also be called. Therefore, when the data transmitted by a parameter is large, it is better to use reference than to transmit a parameter using a common variable.
(3) Although using pointers as function parameters can achieve the same effect as using references, in the called function, storage units must be allocated to the parameters, you must use the "* pointer variable name" format to perform operations again, which can easily produce errors andProgramOn the other hand, the variable address must be used as the real parameter at the call point of the main call function. References are easier to use and clearer.
4. When do I need to use "regular reference "?
If you want to use references to improve program efficiency and protect the data transmitted to the function from being changed in the function, you should use regular references. Common Reference declaration method: const type identifier & reference name = target variable name;
Example 1
Int; Const Int & RA =; Ra = 1; // Error A = 1; // correct |
Example 2
String Foo (); Void bar (string & S ); The following expression is invalid: Bar (FOO ()); Bar ("Hello World "); |
The reason is that both the Foo () and "Hello World" strings generate a temporary object. In C ++, these temporary objects are of the const type. Therefore, the above expression tries to convert a const type object to a non-const type, which is invalid.
The referenced parameter should be defined as const if it can be defined as Const.
5. Use "Reference" as the format, benefits, and rules of the function return value type?
Format: type identifier & function name (parameter list and type description) {// function body} benefit: no copies of returned values are generated in the memory. (Note: this is the reason for this, therefore, it is not advisable to return a reference to a local variable. As the survival of the local variable ends, the corresponding reference will also become invalid, resulting in a runtime error!
Note:
(1) References to local variables cannot be returned. For details, refer to item 31 of Objective C ++ [1. the main reason is that local variables will be destroyed after the function returns, so the returned reference becomes a reference of "no finger", and the program enters the unknown state.
(2) You cannot return a reference to the memory allocated by the new function. For details, refer to item 31 of Objective C ++ [1. although there is no passive destruction of local variables, this situation (returning a reference to the memory allocated by the new function) faces other embarrassing situations. For example, if a reference returned by a function only appears as a temporary variable and is not assigned to an actual variable, the space pointed to by the reference (allocated by new) cannot be released, cause memory leak. (3) can return the reference of the class member, but it is better to be const. this principle can be referred to item 30 of Objective C ++ [1. the main reason is that when an object attribute is associated with a business rule, its value assignment is often related to some other attributes or the state of the object, therefore, it is necessary to encapsulate the value assignment operation in a business rule. If other objects can obtain the non-constant reference (or pointer) of this attribute, a simple value assignment to this attribute will damage the integrity of business rules.
(4) The function of declaring the returned values of stream operators as "references": stream operators <and>. These two operators are often used consecutively. For example: cout <"hello" <Endl; therefore, the return value of these two operators should be a stream reference that still supports these two operators. Other optional solutions include returning a stream object and returning a stream object pointer. However, for a returned Stream object, the program must re-(copy) to construct a new stream object. That is to say, two consecutive <operators are actually for different objects! This is unacceptable. If a stream pointer is returned, the <operator cannot be used consecutively. Therefore, returning a stream object reference is the only choice. This unique choice is critical. It illustrates the importance of reference and is irreplaceable. Maybe this is why the concept is introduced in C ++. Value assignment operator =. this operator can be used continuously like a stream operator, for example, x = J = 10; or (x = 10) = 100; the return value of the value assignment operator must be a left value, so that the value can be assigned. Therefore, it is referenced as the only return value choice of this operator.
Example 3
# I nclude <iostream. h> Int & put (int n ); Int Vals [10]; Int error =-1; Void main () { Put (0) = 10; // use the put (0) function value as the left value, equivalent to Vals [0] = 10; Put (9) = 20; // use the put (9) function value as the left value, which is equivalent to Vals [9] = 20; Cout <Vals [0]; Cout <Vals [9]; } Int & put (int n) { If (n> = 0 & n <= 9) return Vals [N]; Else {cout <"subscript error"; Return Error ;} } |
(5) among other operators, the reference: +-*/four Arithmetic Operators cannot be returned. They cannot return references. The Objective C ++ [1] item23 discusses this issue in detail. The main reason is that these four operators do not have side effect. Therefore, they must construct an object as the return value. Optional solutions include: returning an object and returning a reference to a local variable, returns the reference of a newly assigned object and a static object reference. According to the preceding three rules that reference the returned value, both the 2nd and 3 schemes are rejected. Static object reference is caused by errors because (a + B) = (C + D) is always true. Therefore, only one object is returned.
6. What is the relationship between "reference" and polymorphism?
References are another method that can produce polymorphism effects except pointers. This means that a base class reference can point to its derived class instance.
Example 4
Class A; Class B: Class A {...}; B; A & ref = B; |
7. What is the difference between "reference" and pointer?
After a pointer variable points to an object, it indirectly operates on the variable it points. When pointers are used in a program, the program has poor readability. The reference itself is the alias of the target variable, and the reference operation is the operation of the target variable. In addition, it is the difference between the ref passed to the function and the pointer mentioned above.
8. When do I need to "Reference "?
Stream operators <and>, return values of the value assignment operator =, parameters of the copy constructor, parameters of the value assignment operator =, and references are recommended in other cases.
For more information, see:Http://blog.csdn.net/wfwd/archive/2006/05/30/763551.aspx
18. What is the difference between overload and overried?
Common Questions. In terms of definition: Overload: multiple functions with the same name are allowed, and the parameter tables of these functions are different (maybe the number of parameters is different, or the parameter types are different, or both are different ).
Rewrite: it refers to the method for the subclass to redefine the complex class virtual function.
Implementation principle: overloading: the compiler modifies the name of a function with the same name based on different parameter tables of the function, then these functions with the same name become different functions (at least for the compiler ). For example, there are two functions with the same name: function func (P: integer): integer; and function func (P: string): integer ;. The modified function names of the compiler may be like this: int_func and str_func. The call to these two functions has been confirmed between the compilers and is static. That is to say, their addresses are bound during compilation (early binding). Therefore, overloading is irrelevant to polymorphism!
Rewriting: It is really related to polymorphism. When the subclass redefined the virtual function of the parent class, the parent class pointer dynamically calls the function of the subclass according to the different subclass pointer assigned to it, such a function call cannot be determined during compilation (the virtual function address of the called subclass cannot be provided ). Therefore, such function addresses are bound at runtime (late binding ).
19. What is the role of polymorphism?
There are two main reasons: 1. Hiding Implementation Details makesCodeModular; extends the code module to achieve code reuse; 2. interface reuse: This ensures that a class is called correctly when using a certain attribute of an instance of any class in the family during class inheritance and derivation.
24. Is C ++ type safe?
Answer: No. Two different types of pointers can be forcibly converted (reinterpret cast ). C # is type-safe.
25. What code will be executed before the main function is executed?
Answer: The constructor of the global object is executed before the main function.
26. describes the memory allocation methods and their differences?
1) distributed from the static storage area. The program has been allocated when it is compiled, and the program exists throughout the entire runtime. For example, global variables and static variables.
2) create a stack. When a function is executed, the storage units of local variables in the function can be created on the stack. When the function is executed, these storage units are automatically released. Stack memory allocation operations are embedded in the processor's instruction set.
3) distributed from the stack, also known as dynamic memory allocation. When the program runs, it uses malloc or new to apply for any amount of memory. The programmer is responsible for releasing the memory with free or delete. The lifetime of the dynamic memory is determined by the programmer. It is very flexible to use, but the problem is also the most.
27. What is the difference between struct and class? The struct members are public by default, while the class members are private by default. Struct and class are quite functional in other aspects.
Emotionally, most developers feel that classes and structures are very different. It seems that the structure is just like a bunch of open memory spaces that lack encapsulation and functionality, and the class is like a living and reliable social member. It has smart services, it has a strong encapsulation barrier and a well-defined interface. Since most people think so, there are only a few methods in your class and public data (this kind of thing exists in a well-designed system !) You should use the struct keyword. Otherwise, you should use the class keyword.
29. In the 8086 assembly, how is the logical address and physical address converted? (Intel)
Answer: The address provided by the general register is the intra-range offset address. The corresponding segment register address * 10 h + the intra-range address in the General Register gets the address to be accessed.
30. How do I compare the four types of conversion methods in C ++?
See:Http://blog.csdn.net/wfwd/archive/2006/05/30/763785.aspxFocuses on the differences and applications between static_cast, dynamic_cast, and reinterpret_cast.
32. What are the advantages of const compared with # define?
Answer: 1) const constants have data types, while macro constants do not. The compiler can perform type security checks on the former. However, only character replacement is performed for the latter, and there is no type security check, and unexpected errors may occur during character replacement.
2) some integrated debugging tools can debug const constants, but cannot debug macro constants.
34. What are the differences between Overloading, overwriting, and hiding of class member functions?
Answer:
A. Features of member functions being overloaded:
(1) the same range (in the same class); (2) the function name is the same; (3) the parameter is different; (4) the virtual keyword is dispensable.
B. Override refers to the function of the derived class that overwrites the base class function. The features are as follows:
(1) different scopes (derived classes and base classes respectively); (2) function names; (3) parameters are the same; (4) Base-class functions must have virtual keywords.
C. "hide" means that the function of the derived class shields the base class functions with the same name as it. The rules are as follows:
(1) If the function of the derived class has the same name as the function of the base class, but the parameter is different. In this case, functions of the base class will be hidden regardless of whether there is any virtual keyword (Be sure not to confuse them with overload ).
(2) If the function of the derived class has the same name and parameter as the function of the base class, but the base class function does not have the virtual keyword. At this time, the base class functions are hidden (Be sure not to confuse with overwrite)
37. After the main function is executed, is it possible to execute another piece of code to explain it?
Answer: Yes. You can use _ onexit to register a function. It will execute int fn1 (void), FN2 (void), fn3 (void), and FN4 (void) after main );
Void main (void) { String STR ("Zhanglin "); _ Onexit (fn1 ); _ Onexit (FN2 ); _ Onexit (fn3 ); _ Onexit (FN4 ); Printf ("this is executed first. \ n "); } Int fn1 () { Printf ("next. \ n "); Return 0; } Int FN2 () { Printf ("executed "); Return 0; } Int fn3 () { Printf ("is "); Return 0; } Int FN4 () { Printf ("this "); Return 0; } The _ onexit function is passed the address of a function (func) to be called when the program terminates normally. successive callto _ onexit create a register of functions that are executed in LIFO (last-in-first-out) Order. the functions passed to _ onexit cannot take parameters. |
44. Multi-inheritance memory allocation problem: for example, if there is Class A: Public Class B, public class c {}, what is the memory structure of?
This is compiler-dependent. Different implementations may have different details.
If you do not consider virtual functions or virtual inheritance, it is quite simple; otherwise, it is quite complicated.
You can refer to exploring the C ++ Object Model in depth, or:Http://blog.csdn.net/wfwd/archive/2006/05/30/763797.aspx
45. How can I determine whether a single-chain table has loops? (Do not use a flag. You can use up to two additional pointers)
Struct node {char val; node * Next ;}
Bool check (const node * head) {}// return false: no ring; true: Ring
An O (n) method is (two pointers, one increment step at a time, and one increment step at a time. If there is a ring, the two will inevitably overlap, and vice versa ):
Bool check (const node * head) { If (Head = NULL) return false; Node * low = head, * fast = head-> next; While (fast! = NULL & fast-> next! = NULL) { Low = low-> next; Fast = fast-> next; If (Low = fast) return true; } Return false; } |
1. Is a parent class having written a virtual function? Can a sub-class overwrite its function without the virtual function realize polymorphism?
Virtual modifiers are implicitly inherited.
Private is also integrated. Only when the derived class does not have access permissions, all variables of the parent class can be added to the space without subclass (except static)
Only one entity exists in the same function (except inline)
The sub-class can also implement polymorphism without adding virtual to its function.
In the subclass space, there are private variables of the parent class. Private variables cannot be accessed directly.
3. Briefly describe the Windows Memory Management Method.
Memory Management is an important part of the operating system. I am afraid no one can make it clear in two or three sentences ~~ Let me start with a rough idea. I hope you can give me some advice. When the program is running, you need to read the code of this program from the memory. The location of the Code must be in the physical memory before it can be run. Because there are a lot of programs running in the operating system, the memory cannot be completely put down, so the concept of virtual memory is introduced. Puts unused program fragments into the virtual memory. When you need to use them, load them into the primary memory (physical memory. This is what memory management needs to do. Another thing needs to be done for memory management: the physical location of the computing program fragment in the primary memory for CPU scheduling.
Memory Management includes block-Based Management, page-based management, and segment-based page management. Currently, block-based management is commonly used for segment-and-Page Management: The primary storage is divided into one block and one block. When the required program fragments are not in the primary storage, a primary storage space is allocated and the parts are loaded into the primary storage, even if only a few bytes are needed, the program can only be allocated to it. This will cause a lot of waste, with an average waste of 50% of the memory space, but it is easy to manage.
Page Management: The primary storage is divided into one page and one page. The space on each page is much smaller than one page. Obviously, the space utilization of this method is much higher than that of block management.
Segment management: the primary storage is divided into segments. The space of each segment is much smaller than that of one page. This method is much higher than page management in terms of space utilization, however, it also has another disadvantage. A program segment may be divided into dozens of segments, so much time will be wasted on computing the physical address of each segment (I/O is the most time-consuming computer ).
Segment-and-Page Management: combines the advantages of segment-And page-based management. The primary storage is divided into several pages, each of which is divided into several sections. The benefits are obvious. I don't need to say more.
Various memory management methods are used to calculate the physical addresses of program fragments in the primary memory. In fact, they are similar.
This is just a rough idea. It is not enough to explain the knowledge of memory management. No matter which operating system book has a detailed explanation
2. Are there any problems with the usage of the two sizeof in the following code? [C ease]
Void uppercase (char STR []) // converts lowercase letters in STR to uppercase letters. { For (size_t I = 0; I <sizeof (STR)/sizeof (STR [0]); ++ I) If ('A' <= STR [I] & STR [I] <= 'Z ') STR [I]-= ('A'-'A '); } Char STR [] = "ABCDE "; Cout <"str character length:" <sizeof (STR)/sizeof (STR [0]) <Endl; Uppercase (STR ); Cout <STR <Endl; |
A: There is a problem with sizeof in the function. According to the syntax, sizeof, for example, is used as an array, can only measure the size of a static array, and cannot detect the dynamically allocated or external array size. The STR outside the function is a static defined array, so its size is 6. The STR in the function is actually a pointer to a string without any additional array-related information, therefore, when siz EOF acts on it, it only acts as a pointer, and a pointer is 4 bytes, SO 4 is returned.
3. Where can B be implicitly converted to a for non-C ++ built-in types A and B? [C ++ medium]
A:
A. Class B: Public {......} // The Public B inherits from a and can be indirectly inherited.
B. Class B {operator A ();} // B implements implicit conversion to
C. Class A {A (const B &) ;}// a constructor that implements the non-explicit parameter as B (other parameters with default values can be available)
D. A & operator = (const A &); // value assignment operation. Although it is not an authentic implicit type conversion operation, it can barely calculate
4. What is the problem with the following code? [C ++ ease]
Struct Test { Test (INT ){} Test (){} Void fun (){} }; Void main (void) { Test A (1 ); A. Fun (); Test B (); B. Fun (); } |
A: An error occurred while defining variable B. Define Objects Based on the default constructor. No parentheses are required.
5. What is the problem with the following code? [C ++ ease]
Cout <(true? 1: "1") <Endl; |
A: The ternary expression "? : "The two operands after the question mark must be of the same type.
6. Can the following code be compiled? Why? [C ++ ease]
Unsigned int const size1 = 2; Char str1 [size1]; Unsigned int temp = 0; Cin> temp; Unsigned int const size2 = temp; Char str2 [size2]; |
A: The str2 definition has an error. size2 is a non-compiler constant, while the array definition requires that the length be a compilation constant.
7. What are the following error methods for reverse traversing array? [STL ease]
Vector Array; Array. push_back (1 ); Array. push_back (2 ); Array. push_back (3 ); For (vector: size_type I = array. Size ()-1; I> = 0; -- I) // reverse traversal of the array { Cout <array [I] <Endl; } |
A: The array definition is incorrect. Add the type parameter: vector <int> array. second, vector: size_type is defined as unsigned int, that is, the unsigned number. In this way, if I is 0 as a loop variable, then 1 minus it will become the largest integer, leading to loop loss of control.
8. Is the output statement in the following code 0? Why? [C ++ ease]
Struct CLS { Int m_ I; CLS (int I): m_ I (I ){} CLS () { CLS (0 ); } }; Cls obj; Cout <obj. m_ I <Endl; |
A: No. Within the default constructor, the constructor with parameters is called for user behaviors rather than compiler behaviors. That is, only function calls are executed, and subsequent initialization expressions are not executed. The initialization expression is called along with the corresponding constructor only when the object is generated.
9. Which class member functions are generated by default for empty classes in C ++? [C ++ ease]
A:
Class empty { Public: Empty (); // default constructor Empty (const empty &); // copy the constructor ~ Empty (); // destructor Empty & operator = (const empty &); // value assignment operator Empty * operator & (); // address fetch Operator Const empty * operator & () const; // address fetch operator const }; |
10. What are the outputs of the following two output statements? [C ++ difficulties]
Float a = 1.0f; Cout <(INT) A <Endl; Cout <(Int &) A <Endl; Cout <boolalpha <(INT) A = (Int &) a) <Endl; // What is output? Float B = 0.0f; Cout <(INT) B <Endl; Cout <(Int &) B <Endl; Cout <boolalpha <(INT) B = (Int &) B) <Endl; // What is output? |
A: outputs false and true respectively. Pay attention to the conversion application. (INT) A actually constructs an integer with the floating point A as the parameter. The value of this integer is 1, (Int &) A tells the compiler to regard a as an integer (no substantial conversion is made ). Because 1 is stored as an integer and its memory data is stored as a floating point, the two are not the same.
The two conversions of B are the same, but the integer form of 0 is the same as that of floating point, so in this special case, the two are equal (only in numerical sense ).
Note: the output of the program will show (Int &) A = 1065353216. How does this value come from? As mentioned above, 1 is stored in the memory as a floating point number. According to ieee754, the content of 1 is 0x0000803f (Bytes reverse order has been considered ). This is the value of the memory unit occupied by the variable. When (Int &) A appears, it is equivalent to telling its context: "treat this address as an integer! Don't worry about what it was ." In this way, the content 0x0000803f is interpreted as an integer, and its value is exactly 1065353216 (decimal number ).
By viewing the assembly code, we can confirm that "(INT) A is equivalent to re-constructing an integer number with a value equal to a", and (in T &) the function is only to express a type information, meaning that the correct Heavy Load version is selected for cout <and =.
11. What is the problem with the following code? [STL ease]
Typedef vector intarray; Intarray array; Array. push_back (1 ); Array. push_back (2 ); Array. push_back (2 ); Array. push_back (3 ); // Delete all 2 in the array For (intarray: iterator itor = array. Begin (); itor! = Array. End (); ++ itor) { If (2 = * itor) array. Erase (itor ); } |
A: The type parameter is also missing. In addition, each call of "array. erase (itor); ", the content after the deleted element is automatically moved forward, leading to iteration leakage. After deleting an item, let the itor --, to continue traversing from the next element that has been moved forward.
12. Write a function to copy data between memories. [Whether the problem is comprehensive]
A:
void * mymemcpy (void * DEST, const void * SRC, size_t count) {< br> char * pdest = static_cast (DEST); const char * psrc = static_cast (SRC ); If (pdest> psrc & pdest {< br> for (size_t I = count-1; i! =-1; -- I) pdest [I] = psrc [I]; }< br> else {< br> for (size_t I = 0; I pdest [I] = psrc [I]; }< br> return DEST; } |