1. The purpose of this article is not to provide guidance for the job interview of C/C ++ programmers, but to analyze the connotation of interview questions technically. Most of the interview questions in this article come from major forums. Some answers to the questions also refer to the comments of netizens -.
Many interview questions seem simple, but they require profound basic skills to provide a perfect answer. Enterprises require the interviewer to write the simplest strcpy function to see what the interviewer has technically achieved.
Degree, can we really write a strcpy function? We all think we can, but the strcpy we write may only get 2 out of 10 points. Readers can see strcpy from this article
An example of a function from 2 to 10 points to see what level it belongs. In addition, there are some interview questions to examine the examinee's agile thinking ability.
The analysis of these interview questions is very interesting. As a R & D personnel, the in-depth analysis of these interview questions can further enhance their internal strength.
2. Locate the wrong question
Question 1:
Void test1 ()
{
Char string [10];
Char * str1 = "0123456789 ";
Strcpy (string, str1 );}
Question 2:
Void Test2 ()
{
Char string [10], str1 [10];
Int I;
For (I = 0; I <10; I ++)
{Str1 = 'a ';
}
Strcpy (string, str1 );}
Question 3:
Void test3 (char * str1)
{
Char string [10];
If (strlen (str1) <= 10)
{
Strcpy (string, str1 );
}
}
Answer:
Question 1 string str1 needs 11 bytes to be stored (including '/0' at the end), while string only has 10 bytes of space, strcpy will cause the array to cross-border; for Question 2, if the subject points out that the character array str1 cannot end in the array, it can give 3 points. If the subject points out strcpy (string,
Str1) The call makes the number of bytes replicated from the str1 memory to the string memory uncertain and can be given 7 points. Based on this, it is pointed out that the strcpy function works for 10
Points;
For question 3, if (strlen (str1) <= 10) should be changed to If (strlen (str1) <
10) because the strlen result does not count the 1 byte occupied by '/0.
Analysis:
Measure the test taker's knowledge about basic skills:
(1) The string ends with '/0;
(2) sensitivity to array out-of-bounds control;
(3) how the database function strcpy works. If the total score of a standard strcpy function is 10, the following are several different answers:
2 points
Void strcpy (char * strdest, char * strsrc)
{
While (* strdest ++ = * strsrc ++ )! = '/0 ');}
4-point void strcpy (char * strdest, const char * strsrc)
// Add the source string to const, indicating that it is an input parameter and adds 2 points
{
While (* strdest ++ = * strsrc ++ )! = '/0 ');}
7-point void strcpy (char * strdest, const char * strsrc)
{
// Add non-0 assertions to the source and target addresses, and add 3 points
Assert (strdest! = NULL) & (strsrc! = NULL ));
While (* strdest ++ = * strsrc ++ )! = '/0 ');}
10 points // in order to achieve chained operation, the destination address is returned, plus 3 points!
Char * strcpy (char * strdest, const char * strsrc)
{
Assert (strdest! = NULL) & (strsrc! = NULL ));
Char * address = strdest;
While (* strdest ++ = * strsrc ++ )! = '/0 ');
Return address ;}
We can clearly see from two to ten answers that the little strcpy has hidden so many xuanjicang! What a solid basic skill is required to write a perfect strcpy! (4) Master strlen, which does not include '/0' at the end of the string '.
After reading strcpy versions with different scores, you can write a strlen function with 10 points. The perfect version is:
Int strlen (const char * Str) // enter the const parameter.
{
Assert (strt! = NULL); // The asserted string address is not 0
Int Len;
While (* STR ++ )! = '/0 ')
{
Len ++;
}
Return Len ;}
Question 4: void getmemory (char * P)
{
P = (char *) malloc (100 );}
Void test (void)
{
Char * STR = NULL;
Getmemory (STR );
Strcpy (STR, "Hello World ");
Printf (STR );
}
Question 5: char * getmemory (void)
{
Char P [] = "Hello World ";
Return P ;}
Void test (void)
{
Char * STR = NULL;
STR = getmemory ();
Printf (STR );
}
Question 6: void getmemory (char ** P, int num)
{
* P = (char *) malloc (Num );}
Void test (void)
{
Char * STR = NULL;
Getmemory (& STR, 100 );
Strcpy (STR, "hello ");
Printf (STR );
}
Question 7: void test (void)
{
Char * STR = (char *) malloc (100 );
Strcpy (STR, "hello ");
Free (STR );
... // Other omitted statements}
Answer: Question 4: getmemory (char * P
) The parameter of the function is a string pointer. Modifying the parameter inside the function does not actually change the value of the input parameter.
Char * STR = NULL;
Getmemory (STR );
The subsequent STR is still NULL;
Question 5
Char P [] = "Hello World ";
Return P;
The P [] array is the partial automatic variable in the function. After the function returns, the memory has been released. This is a common mistake made by many programmers. Its root cause is that they do not understand the survival of variables.
Getmemory in question 6 avoids Question 4. The input parameter of getmemory is a pointer to the string pointer, but the request memory and value assignment statement are executed in getmemory.
* P = (char *) malloc (Num );
If the memory application is successful, add:
If (* P = NULL)
{
... // Processing failed to apply for memory}
Question 7 has the same problem as Question 6. Execute char * STR = (char *) malloc (100 );
In addition, after free (STR), STR is not set to null, which may become a "wild" pointer. The following should be added:
STR = NULL;
In the test function of question 6, the memory of malloc is not released.
Analysis:
Question 4 ~ 7. Measure the test taker's understanding about memory operations. Generally, 50-50 of the respondents with solid basic skills can answer these questions correctly ~ 60 error. However, it is not easy to answer the correct questions completely.
The memory operations are mainly focused on:
(1) pointer understanding;
(2) The survival time and scope of the variable;
(3) good dynamic memory application and release habits.
Let's take a look at the following program errors:
Swap (int * P1, int * P2)
{
Int * P;
* P = * P1;
* P1 = * P2;
* P2 = * P ;}
In the swap function, P is a "wild" pointer, which may point to the system zone, causing program running to crash. An error "access" is prompted during debug running in VC ++
Violation ". This program should be changed to: swap (int * P1, int * P2)
{
Int P;
P = * P1;
* P1 = * P2;
* P2 = P;
}
3. Question 1: Give the bool, Int, float, and pointer variables respectively.
If statement compared with "zero value" (assuming the variable name is var)
Answer:
Boolean variable: If (! VaR)
Int type variable: If (Var = 0)
Float variables:
Const float epsinon = 0.00001;
If (x> =-epsinon) & (x <= epsinon)
Pointer variable: If (Var = NULL)
Analysis:
Evaluate the "internal function" of the 0 value. If (Var = 0) can be used to determine the value 0, and if (! VaR), pointer variable judgment can also be written as I-F (! VaR), although the program can run correctly, it cannot clearly express the meaning of the program.
Generally, If you want if to determine whether a variable is "true" or "false", you should directly use if (VAR), if (! VaR), indicating that it is a "logical" judgment; if you use if to judge a numeric change
Amount (short, Int, long, etc.). If (Var = 0) should be used to compare the value with 0; however, if (Var = NULL) is suitable for pointer determination ),
This is a good programming habit.
Float variables are not accurate, so you cannot use "=" or "! = "To compare with a number, try to convert it to"> = "or" <=. If
(X = 0.0), the result is an error. The score is 0.
Question 2: Windows
Calculate the value of sizeof for 32-bit C ++ programs under NT
Void func (char STR [1, 100])
{
Sizeof (STR) =? }
Void * P = malloc (100 );
Sizeof (p) =? Answer:
Sizeof (STR) = 4
Sizeof (p) = 4
Analysis:
Func (char STR [2, 100]
) When the array name in the function is used as the function parameter, In the function body, the array name loses its meaning and is only a pointer, it also loses its constant feature and can perform auto-increment, auto-subtraction, and other operations-it can be modified.
The essence of array names is as follows:
(1) The array name represents a data structure, which is an array;
For example:
Char STR [10];
Cout <sizeof (STR) <Endl;
The output is 10. Str indicates the data structure char [10].
(2) The array name can be converted to a pointer pointing to the object. It is a pointer constant and cannot be used for auto-increment, auto-subtraction, or other operations;
Char STR [10];
STR ++; // compilation error, prompting that STR is not the left Value
(3) When the array name is used as a function parameter, it becomes a common pointer.
Windows NT
In a 32-bit platform, the pointer length (memory size occupied) is 4 bytes, so sizeof (
Str), sizeof (p) are 4.
Question 3: write a "standard" macro min, which inputs two parameters and returns a smaller one. What will happen when you write the following code?
Least = min (* P ++, B );
Answer:
# Define min (A, B) (a) <= (B )? (A): (B ))
Min (* P ++, B) produces macro side effects
Analysis:
This interview mainly examines the use of the macro definition. The macro definition can implement functions similar to the function, but it is not a function, and the "parameter" in the arc of the macro definition is not a real parameter, during macro expansion, the-"parameter" is replaced by one-to-one.
Programmers should be very careful with the use of macro definitions, and pay special attention to two problems:
(1) carefully enclose the "parameter" in the macro definition and the entire macro with an arc. Therefore, strictly speaking, the following answers:
# Define min (a, B) (a) <= (B )? (A): (B)
# Define min (a, B) (a <= B? A: B)
Both should be set to 0 points;
(2) Prevent the side effects of macros.
Macro definition # define min (A, B) (a) <= (B )? (A): (B) for Min (* P ++,
B) The result is:
(* P ++) <= (B )? (* P ++): (* P ++ ))
This expression produces side effects. The pointer P performs three ++ auto-increment operations.
In addition, the other answer that should be set to 0 is:
# Define min (A, B) (a) <= (B )? (A): (B ));
This answer is followed by the macro definition ";", indicating that the author's macro concept is vague and can only be ruthlessly scored 0 points and eliminated by the interviewer.
Question 4: Why do standard header files have a structure similar to the following?
# Ifndef _ incvxworksh
# DEFINE _ incvxworksh
# Ifdef _ cplusplus
Extern "C "{
# Endif
/*...*/
# Ifdef _ cplusplus}
# Endif
# Endif/* _ incvxworksh */answer:
Compile macro In header file
# Ifndef _ incvxworksh
# DEFINE _ incvxworksh
# Endif
To prevent repeated references.
As an object-oriented language, C ++ supports function overloading, while Procedural Language C does not. After the function is compiled by C ++, the name in the symbol library is different from that in the C language. For example, assume that the prototype of a function is:
Void Foo (int x, int y );
After the function is compiled by the C compiler, the name in the symbol library is _ Foo, while the C ++ compiler generates names such as _ foo_int_int. A name such as _ foo_int_int contains information about the number and type of function names and function parameters. c ++ uses this mechanism to implement function overloading.
In order to realize the mixed programming of C and C ++, C ++ provides the C connection to exchange the specified symbol extern.
"C" to solve the name matching problem, add extern before the function declaration
After "C", the compiler will compile the function as _ Foo in the C language, so that the C ++ function can be called in the C language.
Question 5: Write a function to shift n loops of a char string to the right. For example, if "abcdefghi" is n = 2, it should be "hiabcdefgh" after the shift"
The function header is as follows:
// Pstr is a pointer to a string ending with '/0'
// Steps is the n that requires moving
Void loopmove (char * pstr, int steps)
{
// Fill in ...}
Answer: Correct answer 1:
Void loopmove (char * pstr, int steps)
{
Int n = strlen (pstr)-steps;
Char TMP [max_len];
Strcpy (TMP, pstr + n );
Strcpy (TMP + steps, pstr );
* (TMP + strlen (pstr) = '/0 ';
Strcpy (pstr, TMP );}
Correct answer 2: void loopmove (char * pstr, int steps)
{
Int n = strlen (pstr)-steps;
Char TMP [max_len];
Memcpy (TMP, pstr + N, steps );
Memcpy (pstr + steps, pstr, N );
Memcpy (pstr, TMP, steps );}
Analysis: This question mainly examines the examinee's proficiency in the standard library functions. When necessary, referencing the library functions can greatly simplify the workload of programming.
The most frequently used library functions include:
(1) strcpy
(2) memcpy
(3) memset
Question 6: The following table lists the known WAV file formats. Open a WAV file, organize the wav file header in an appropriate data structure, and parse the information in WAV format.
Wave file format description
Offset address byte data type capacity
File Header
00 H 4 char "riff" flag
04 H 4 int32 file length
08 H 4 char "wave" flag
0ch 4 char "FMT" flag
10 H 4 transition byte (optional)
14 H 2 int16 format category
16 H 2 int16 Channels
18 h 2 int16
Sampling rate (number of samples per second), indicating the playback speed of each channel
1ch 4 int32 waveform audio data transmission rate
20 H 2 int16 data block adjustment (in bytes)
22 h 2 Data digits per sample
24 h 4 char data tag "data"
28 H 4 int32 Voice Data Length
Answer:
The WAV file format is defined as the structure waveformat:
Typedef struct tagwaveformat
{
Char criffflag [4];
Uin32 nfilelen;
Char cwaveflag [4];
Char cfmtflag [4];
Char ctransition [4];
Uin16 nformattag;
Uin16 nchannels;
Uin16 nsamplespersec;
Uin32 navgbytespersec;
Uin16 nblockalign;
Uin16 nbitnumpersample;
Char cdataflag [4];
Uin16 naudiolength;} waveformat;
Assume that the wav file content is read and stored in the memory unit starting with the pointer buffer, the code for analyzing the file format is very simple: waveformat;
Memcpy (& waveformat, buffer, sizeof (waveformat ));
You can directly access the members of The waveformat to obtain the format information of a specific WAV file.
Analysis:
Exam 6 examines the ability of the interviewer to organize data structures. experienced programmers organize a whole data member into a struct using pointer type conversion, memcpy, memset, and other functions can be directly used for the struct address to perform the overall operation of the struct.
Through this question, we can see whether the interviewer has rich experience in programming.
Question 7: Compile the constructor, destructor, and value assignment functions of the string class. It is known that the prototype of the string class is:
Class string
{
Public:
String (const char * STR = NULL); // common Constructor
String (const string & other); // copy the constructor
~ String (void); // destructor
String & operate = (const string & other); // value assignment function
PRIVATE:
Char * m_data; // used to save the string };
Answer: // common Constructor
String: string (const char * Str)
{
If (STR = NULL)
{
M_data = new char [1]; //
Score point: empty string automatically applied to store the end sign '/0'
// Extra points: determines if m_data is added with null
* M_data = '/0 ';
}
Else
{
Int length = strlen (STR );
M_data = new char [Length + 1]; // It is better if null can be added.
Strcpy (m_data, STR );
}}
// String destructor string ::~ String (void)
{
Delete [] m_data; // or delete m_data ;}
// Copy the constructor string: string (const string & Other )//
Score point: the input parameter is of the const type.
{
Int length = strlen (other. m_data );
M_data = new char [Length + 1];
// Extra points: determines if m_data is added with null
Strcpy (m_data, other. m_data );}
// Value assignment function string & string: operate = (const string & Other )//
Score point: the input parameter is of the const type.
{
If (this = & Other) // score point: Check auto-assigned values
Return * this;
Delete [] m_data;
// Score point: Release the original memory resource
Int length = strlen (other. m_data );
M_data = new char [Length + 1]; // additional points: Add null to m_data
Judgment
Strcpy (m_data, other. m_data );
Return * this;
// Score point: returns the reference of this object}
Analysis: the interviewer who can accurately write string class constructor, copy constructor, assign value function and destructor has at least 60% of the basic C ++ skills!
This class includes the pointer class member variable m_data. When the class includes pointer class member variables, you must reload the copy constructor, value assignment function, and destructor, this is not only a basic requirement for C ++ programmers, but also a special clause in Objective C ++.
Take a closer look at this class and pay special attention to the significance of adding comments to the score points and points. In this way, more than 60% of the basic C ++ skills are available!
Question 8: Tell me as many static and const keywords as possible
Answer:
The static keyword has at least N functions:
(1) The static variable in the function body applies to this function body. Unlike the auto variable, the memory of this variable is allocated only once, therefore, the value remains the value of the previous time during the next call;
(2) The static global variables in the module can be accessed by the functions used in the module, but cannot be accessed by other functions outside the module;
(3) The static function in the module can only be called by other functions in the module. The scope of use of this function is limited to the module that declares it;
(4) static member variables in the class belong to the entire class and only one copy of all objects in the class;
(5) The static member function in the class belongs to the whole class. This function does not receive the this pointer, so it can only be a static member variable of the category.
The const keyword has at least N functions:
(1) to prevent a variable from being changed, you can use the const keyword. When defining the const variable, you usually need to initialize it, because there will be no chance to change it in the future;
(2) For pointers, you can specify the pointer itself as const, or you can specify the data referred to by the pointer As const, or both of them as const;
(3) In a function declaration, const can modify the form parameter, indicating that it is an input parameter and cannot change its value within the function;
(4) If the member function of the class is specified as the const type, it indicates that it is a constant function and the member variables of the class cannot be modified;
(5) For a member function of the class, you must specify its return value as the const type so that its return value is not "left ". For example:
Const classa operator * (const classa & A1, const classa & A2 );
The return result of operator * must be a const object. If not, such abnormal code will not cause compilation errors:
Classa A, B, C;
(A * B) = C; // assign a value to the result of a * B
Operation (A * B) =
C obviously does not conform to the programmer's original intention and has no significance.
Analysis:
Surprised? What are the functions of small static and const? If you can only answer 1 ~ 2. You have to close the door and practice well.
This question can be used to check whether the subject's knowledge about programming is elementary, intermediate, or in-depth. Without a certain knowledge breadth and depth, it is impossible to give a comprehensive answer to this question. Most people can only answer some functions of the St-atic and const keywords.
4. Tips
Question 1: Write a c function. If the processor is big_endian, 0 is returned. If the processor is little_endian, 1 is returned.
Answer:
Int checkcpu ()
{
{
Union W
{
Int;
Char B;
} C;
C. A = 1;
Return (C. B = 1 );
}}
Profiling: Embedded system developers should be familiar with the little-Endian and big-Endian modes. The storage side of the operand of the CPU in little-Endian Mode
The format is from low byte to high byte, while the big-Endian mode stores the operands from high byte to low byte. For example, the number of 16-bit widths 0x1234 is in little-
Endian mode:
Memory Address storage content
0X4000 0x34
0x4001 0x12
In big-Endian mode, the CPU memory is stored as follows:
Memory Address storage content
0X4000 0x12
0x4001 0x34
32-bit-width 0x12345678 storage method in the little-Endian mode CPU memory (assuming it starts from address 0x4000:
Memory Address storage content
0X4000 0x78
0x4001 0x56
0x4002 0x34
0x4003 0x12
In big-Endian mode, the CPU memory is stored as follows:
Memory Address storage content
0X4000 0x12
0x4001 0x34
0x4002 0x56
0x4003 0x78
The order in which union members are stored is that all members are stored from low addresses. This feature is used by the interviewer's answers, it is easy to obtain that the CPU uses the little-Endian or big-en-dian mode to read and write the memory. If anyone could give this answer on the spot, it would be a talented programmer.
Question 2: Write a function and return the value of 1 + 2 + 3 +... + N (assuming that the result does not exceed the range of long integer variables)
Answer:
Int sum (int n)
{
Return (long) 1 + n) * n/2; // or return (1l + n) * n/2 ;}
Analysis: The simplest answer is the best one. The following answers may be optimized based on the following solutions. No matter how hard it is, the efficiency cannot be directly returned.
(1 L + n) * n/2!
Int sum (int n)
{
Long sum = 0;
For (INT I = 1; I <= N; I ++)
{
Sum + = I;
}
Return sum ;}
PS: http://www.yuanma.org/data/2009/1112/article_4013.htm