C ++ STL programming (2)

Source: Internet
Author: User

As an indispensable part of the C ++ standard, STL should penetrate into the corners of the C ++ program. STL is not the darling of the lab, nor the decoration on the programmer's desk. Her excitement is not a flash. This tutorial aims to spread and popularize the basic knowledge of STL. If you can take this opportunity to do something as far as you can for STL promotion, it is also a pleasant thing.

2 Cool test: And look at a simple routine

2.1 intro

If you are a purely pragmatic, you may start to look at it from the very beginning, because it provides a sample program, which can bring you the most direct feeling about using STL. Yes, it is better to go straight into the system than to talk on paper. However, it should be noted that it would be great if you can combine the previous chapters as a meal when enjoying the content of this chapter with high spirits. You will find that the advantages of STL mentioned above have been proved exactly here. The second part of this chapter will show you the specific operation methods for running the preceding sample program on some mainstream C ++ compilers and the precautions.

2.2 routine implementation

Unfortunately, I have to discard the "Hello World" classic example. Although it is cited by many textbooks that introduce computer languages more than once, it has almost become a default "standard ". The reason is that it is too simple to present the charm of STL without being representative. I used a slightly more complex example. Its general function is to read some integer data from a standard input device, typically a keyboard, and then sort them, the final result is output to the standard output device, generally the display screen ). This is a typical processing method. The program itself has almost all the basic features that a system should have: Input + Processing + output.

You will see three different versions of the program.

The first is a general C ++ program that does not use STL. You will see how much effort is needed to complete such seemingly simple tasks, and it may not be a problem ).

The main part of the second program uses the STL feature. The problems encountered in the first program can be basically solved. At the same time, you will find that after using STL, the program becomes concise, clear, and easy to read.

In the third program, the STL function is realized. You can see that almost every line of code in the program is related to STL. This opportunity is not always everywhere. It shows almost all the basic components in STL, although it seems a little too much.

Note the following points:

The purpose of this routine is to demonstrate how to use STL in a C ++ program, and to prove the practical benefits of STL. Some basic STL components used in the program, such as vector, a container) and sort, you only need to have a general concept, this does not affect reading the code and understanding the meaning of the program.

Many people are very interested in the running mode of GUI. It is no wonder that beautiful interfaces are always pleasing to the eye. However, unfortunately, these functions are not added here. This is easy to explain. For the simple sample program provided, adding the GUI feature is a bit out of the box. This will suddenly increase the amount of code in the program, the core part of the problem is indeed drowned in the middle of a lot of irrelevant code. You need to spend a lot of effort to handle the tedious and standardized response of the keyboard or mouse messages). Even if you have a tool like Borland C ++ Builder Based on IDE integrated development environment), the interface processing becomes simpler and the Framework Code is automatically generated ). Note that the first letter of STL, part of the C ++ standard, indicates this.) It does not involve a specific development tool, it is code that can be compiled in almost any C ++ compiler. After all, the GUI processing code is different in Microsoft Visual C ++ and Borland C ++ Builder. If you want to know the details of these guis, I am afraid there is no answer you want. You can look for other related books.

2.2.1 first version: prehistoric times -- Turning to wood for fire

In the "Dark Age" That STL has not yet been born, C ++ programmers need to do many things to complete the functions mentioned above, but it seems better than C Programs ), the program looks like this:

 
 
  1. // Name: example2_1.cpp
  2. // Alias: Rubish
  3. # Include
  4. # Include
  5. Int compare (const void * arg1, const void * arg2 );
  6. Void main (void)
  7. {
  8. Const int max_size = 10; // The maximum number of elements allowed in the array
  9. Int num [max_size]; // integer Array
  10. // Read an integer from the standard input device and accumulate the input quantity,
  11. // Until the input is non-integer data
  12. Int n;
  13. For (n = 0; cin> num [n]; n ++ );
  14. // Quick-sort function in C standard library
  15. Qsort (num, n, sizeof (int), compare );
  16. // Output the sorting result to the standard output device.
  17. For (int I = 0; I <n; I ++)
  18. Cout <num [I] <"\ n ";
  19. }
  20. // Compare the two numbers,
  21. // If * (int *) arg1 is smaller than * (int *) arg2,-1 is returned.
  22. // If * (int *) arg1 is greater than * (int *) arg2, 1 is returned.
  23. // If * (int *) arg1 is equal to * (int *) arg2, 0 is returned.
  24. Int compare (const void * arg1, const void * arg2)
  25. {
  26. Return (* (int *) arg1 <* (int *) arg2 )? -1:
  27. (* (Int *) arg1> * (int *) arg2 )? 1: 0;
  28. }

This is a traditional C ++ program that has nothing to do with STL. Because the program annotations are very detailed, I do not need to explain them more. In general, this program does not seem very complicated, and there is not much functionality in it ). However, the compare function seems a little difficult. The function pointer pointing to it is passed into the qsort function as the last real parameter. qsort is a function in stdlib. h of the C library. The following is the prototype of the qsort function:

 
 
  1. void qsort(void *base, size_t num, size_t width, int (__cdecl *compare )
  2. (const void *elem1, const void *elem2 ) );  

It looks a bit disgusting, especially the last parameter. The first parameter indicates the array to be sorted, for example, num in the program ), the second parameter gives the size of the array. qsort does not have enough intelligence to predict the actual size of the array you pass to it.) The third parameter gives the size of each element in the array in bytes. Finally, the long guy gave a way to compare elements during sorting, because of qsort's IQ problem ).

The following is the result of a running task:

Input: 0 9 2 1 5

Output: 0 1 2 5 9

There is a problem that this program is not as Robust as it looks ). If the number of numbers entered exceeds the upper limit set by max_size, the array out-of-bounds problem occurs. If you run this program on the console in the Visual C ++ IDE environment, an invalid memory access error dialog box is displayed. This problem is serious enough for you to review the code of the program. To make up for this defect in the program. We have to consider one of the following three solutions:

  • Large-capacity static array allocation is adopted.
  • Limit the number of input data.
  • Dynamic memory allocation is used.

The first solution is relatively simple. All you have done is to increase max_size, for example, 1000 or 10000. However, strictly speaking, this does not ultimately solve the problem, and the hidden risks still exist. If someone is patient enough, it will crash your corrected program. In addition, allocating a large array is usually a waste of space, because in most cases, part of the space in the array is not used.

Let's take a look at the second solution. By adding a condition to the first for loop, we can solve the problem.

For example:

 
 
  1. for (int n = 0; cin >> num[n] && n < max_size; n ++);  

However, this solution is equally unsatisfactory. Although it won't crash the program, it loses flexibility and you cannot enter more numbers.

It seems that only the third solution is selected. Yes, you can use pointers and dynamic memory allocation to properly solve the above problems and make the program flexible. This requires the new, delete operators, or the old malloc (), realloc (), and free () functions. But to this end, you will sacrifice the simplicity of the program, so that the program code increases sharply, and the code processing logic is no longer as clear as it seems.

A compare function may have made you impatient. What's more, what about implementing these complex processing mechanisms? It is hard to ensure that you will not encounter errors when dealing with this issue. Many program bugs are often generated in this way. At the same time, you should also thank stdlib. h, which provides you with the qsort function. Otherwise, you also need to implement the Sorting Algorithm by yourself. If you use the Bubble sorting method, the efficiency will not be very satisfactory ......., The problem is getting a headache!

The discussion of the first program ends here. If you are interested in the third solution, you can try to write your own program as a question. There is no need to waste the ink to implement such an unpleasant program.

2.2.2 version 2: the industrial age -- componentized Production

We should be glad to live in our age. In the industrial age, the great convenience brought by the development of science and technology has affected every detail in our lives. If you are still living in the way of primitive humans, I should doubt whether you belong to a member of a primitive tribe that lives in Africa or the South American jungle, is it the re-occurrence of the Maya civilization?

STL is the product of this era. Just like other scientific and technological achievements, C ++ programmers should try to adapt themselves to and make full use of this "high-tech achievements ". Let's review the first version of the tattered program. Try to use STL to see how it works.

 
 
  1. // Name: example2_2.cpp
  2. // Alias: The first STL program
  3. # Include
  4. # Include
  5. # Include
  6. Using namespace std;
  7. Void main (void)
  8. {
  9. Vector num; // vector container in STL
  10. Int element;
  11. // Read the integer from the standard input device,
  12. // Until the input is non-integer data
  13. While (cin> element)
  14. Num. push_back (element );
  15. // Sorting Algorithm in STL
  16. Sort (num. begin (), num. end ());
  17. // Output the sorting result to the standard output device.
  18. For (int I = 0; I <num. size (); I ++)
  19. Cout <num [I] <"\ n ";
  20. }

The main part of this program is changed to STL, which looks a little simpler than the first program. You can't find the annoying compare function. Can it really run well? You can try it. Because the running result of the program is roughly the same as the previous one, you can skip it here. I can assure you that this program is robust enough. However, you may not fully understand the program code, so I need to explain it for you. After all, this trick has become too fast. Compared with the first program, the code that old C ++ programmers are familiar with is gone in a twinkling of an eye, instead of some new things.

The first three lines of a program are included header files. They provide all the C ++ features required by the program, including input/output processing, STL containers, and algorithms ). Don't worry about that. h. It's not my negligence. The program can be compiled, as long as your C ++ compiler supports the relevant part of the standard C ++ specification. You only need to regard them as some common C ++ header files. As a matter of fact, if you are interested in the details of this change, you can pay attention to your side's meal.

The existence of Row 4 can also be ignored. Add the Declaration to indicate that the program references the standard namespace named std), because all the things in STL are included in it. Only through this line of declaration can the compiler allow you to use interesting features.

Vector is used in the program. It is a standard container in STL and can be used to store some elements. You can understand the vector as int [?], An integer array. The unknown size is because the vector is a container that can dynamically adjust the size. when the container is full, if it is placed into an element, the vector will quietly expand its capacity. Push_back is a class member function of the vector container. It is used to insert an element at the end of the container. The first while loop in the main function is to constantly insert integer data into the tail end of the vector container and automatically maintain the size of the container space.

Sort is a standard algorithm in STL used to sort elements in containers. It requires two parameters to determine which range of elements in the container can be used for sorting. The other two class member functions of vector are used here. Begin () is used to point to the first end of the vector, while end () points to the end of the vector. There are two problems here: what are the returned values of begin () and end? This involves another important part of STL-Iterator), but it does not need to be detailed here. You only need to treat it as a pointer, a pointer to the integer data. The corresponding sort function declaration can also be considered as void sort (int * first, int * last), although this is actually not accurate.

Another problem is that it is related to the end () function. Although the returned value points to the end of the vector, this statement is not correct. In fact, its return value points to the next position of the final element in the vector, that is, the so-called pass-the-end value. This may sound a bit confusing, but you don't have to worry about it. Here is just a bit of a note. In general, what the sort function does is to sort the elements in the quasi-integer array, just like the qsort In the first program. However, compared with qsort, sort seems much simpler.

The final part of the program is the output part. Here, the vector can be completely distorted. It provides the same access method to elements as the ordinary C ++ built-in array. The size function is used to return the number of elements in the vector, which is equivalent to the variable n in the first program. The two lines of code do not need to be explained.

I think my patience should help you understand the above program. In fact, the use of STL makes the logic of the program clearer and the code easier to read. Who will not understand the meaning of the word "begin", "end", and "size" unless he does not understand English )? Run the command to check the effect. Try inputting a few more numbers to see if the array is out of bounds. Practice has proved that the program runs well. Yes, because the vector container maintains its own size, C ++ programmers don't have to worry about dynamic memory allocation. The incorrect usage of pointers will cause a lot of trouble after all, at the same time, the program will become extremely lengthy. This is the disadvantage of the third solution.

Let's take a closer look at your first C ++ program for STL, and review the advantages of STL mentioned in Chapter 1: ease of use, industrial strength ......, Compare the first version of the program. I think you should have some experience!

2.2.3 Third Edition: the masterpiece of Aesthetics

The development of events sometimes tends to be extreme, which is still the case among the beautiful people. First, I declare that I am not a perfectionist. I provide the ultimate version of the second edition of the program to make you feel the charm of STL more deeply. After reading the third edition, you will feel this point. Maybe you will become an aesthetic, at least in STL. This should not be my fault, because you have the right to decide. Let's take a look at this out-of-the-box C ++ program.

 
 
  1. // Name: example2_3.cpp
  2. // Alias: aesthetic version
  3. # Include
  4. # Include
  5. # Include
  6. # Include
  7. Using namespace std;
  8. Void main (void)
  9. {
  10. Typedef vector int_vector;
  11. Typedef istream_iterator istream_itr;
  12. Typedef ostream_iterator ostream_itr;
  13. Typedef back_insert_iterator <int_vector> back_ins_itr;
  14. // Vector container in STL
  15. Int_vector num;
  16. // Read the integer from the standard input device,
  17. // Until the input is non-integer data
  18. Copy (istream_itr (cin), istream_itr (), back_ins_itr (num ));
  19. // Sorting Algorithm in STL
  20. Sort (num. begin (), num. end ());
  21. // Output the sorting result to the standard output device.
  22. Copy (num. begin (), num. end (), ostream_itr (cout, "\ n "));
  23. }

Almost every line of code in this program is related to STL except for the main and the curly braces, and of course there are annotations), and it contains almost all the major component containers in STL, iterator, algorithm, adapter adaptor), The only pity is that the function object functor is missing.

Do you still remember the basic features of a typical system mentioned at the beginning? -- Input + Processing + output. All of these functions are implemented through three-line statements in the preceding program. each row of statements corresponds to one operation. The data operations are highly abstract, and the combination of algorithms and containers is as easy as building blocks, and the coupling degree of the system is reduced to a very low. This is the great power of STL that shines with the light of generics. So concise, so clever, so amazing! It's like magic, so that you can never be confused again. How to implement it? Why are you so clear when you look at the second edition of the program, and you are in the dark ).

Please pay attention to the title of the masterpiece of aesthetics), in the actual environment, you do not need to do so perfectly. After all, the destruction of good wishes often happens in life. Being too idealistic is not a good thing, at least I think so. As mentioned above, this program is just to show the unique charm of STL, you have to be impressed by its outstanding performance, maybe only those who are well versed in STL will come up with such a thing. If you only use STL in general, you can do the second version.

It is because this program is too "simple" that I cannot be sure whether I can understand three lines of code in this area through my explanation before you fully master STL, I will do my best.

The iterator mentioned above can locate and access any element in the container. In STL, this feature has been promoted. A cin represents a piece of data stream from the input device. In terms of concept, its access to the data stream function is similar to the iterator in the general sense, however, the cin operation in C ++ is not like an iterator in many places, because its interface is inconsistent with that in the iterator. For example, you cannot perform ++ operations on cin, you cannot perform value operations-that is, * operations ). To solve this problem, we need to introduce the concept of adapter. Istream_iterator is an adapter that encapsulates cin to make it look like a common iterator, so that we can pass it as a real parameter to some algorithms, such as the copy algorithm here ).

Because the algorithm only recognizes the iterator and does not accept cin. For the first copy function in the above program, the first parameter is expanded in the form of istream_iterator (cin), and the second parameter is expanded in the form of istream_iterator () if you are not clear about the syntax of typedef, you can refer to the relevant c ++ language books ). The result is to generate a temporary object for two iterators. the first one points to the beginning of the integer input data stream, and the last one points to "pass-the-end value ". This function is used to copy the integer input data streams one by one from the beginning to the end to the quasi-integer array of vector. The first iterator starts from the start position and enters each time, finally, it reaches the position pointed to by the second iterator. Maybe you want to ask, if the copy function acts like I said, why not write it as follows?

 
 
  1. copy(istream_iterator(cin), istream_iterator(), num.begin()); 

You can do this, but there is a little trouble. Do you still remember that array in the first version of the program is out of bounds? If you do this, you will encounter similar troubles. The reason is that when the copy function is "copying" data, if the number of input data exceeds the range of the vector container, the data will be copied outside the container. At this time, the container will not automatically increase the capacity, because it is simply copying, not inserting from the end.

To solve this problem, another adapter, back_insert_iterator, appeared. Its function is to guide the copy algorithm to insert a data at the end of the container each time. The back_ins_itr (num) in the program is expanded to back_insert_iterator (num), and the effect is to generate such an overlay object. It's really not easy to finish 1/3 !), Fortunately, there is no difference between the second sentence and the previous version of the program. It is skipped here.

As for the third sentence, ostream_itr (cout, "\ n") is expanded in the form of ostream_iterator (cout, "\ n "), the result is to generate an iterator object that processes the output data stream. Its position points to the starting position of the data stream and uses "\ n" as the delimiter. The second copy function will "copy" the content in the vector to the output device from the beginning to the end. The iterator represented by the first parameter will carry in from the start position each time, finally, it reaches the position pointed to by the iterator represented by the second parameter.

This is all content.

2.3 Historical Review

The wheel of history is always rolling forward. Civilization in the industrial age is certainly advanced and developed compared with that in the Prehistoric Age. Looking back at the C ++ programs in those two eras, you will really feel this difference. Simple and easy to use, with industrial strength, good portability, and high efficiency, coupled with the high abstraction, high flexibility and componentization of the third stunning out-of-band program, this gives you some slight feelings about the general idea behind STL.

Fortunately, you have the opportunity to witness the difference in civilization across two eras. At the same time, this should make you more and more strengthen your faith and adapt yourself to the trend of the times.

2.4 how to run

Before you start running the first two programs, you 'd better read this section. This section briefly introduces some details about how to run STL programs in a specific compiler environment, and provides some possible solutions.

Here, I have selected Microsoft Visual C ++ 6.0 and Borland C ++ Builder 6.0, which are common on Windows. Although Visual C ++ 6.0 does not support the latest ANSI/iso c ++ standard. However, it is said that Visual C ++. NET, or VC7.0, has improved its performance in this regard.

You can run the preceding program in multiple ways. For example, in Visual C ++, You can compile and run the program in the doscommand line status, you can also run the Console Application in the vc ide. For C ++ Builder, the situation is similar.

For Visual C ++, if it is in the doscommand line state, you first need to find its compiler. Assume that your Visual C ++ is installed under C: \ Program Files \ Microsoft Visual Studio \ VC98, the path of the compiler should be C: \ Program Files \ Microsoft Visual Studio \ VC98 \ bin, where you can find the cl.exe file. Add the/GX and/MT parameters during compilation. If everything is normal, an executable file is generated. As follows:

Cl/GX/MT example2_2.cpp

The previous parameter is used to inform the compiler to allow Exception Handling ). Exception Handling Mechanism (try…) is used in many places in P. J. Plauger STL... Throw... Catch syntax), so this parameter should be added, otherwise there will be the following warning:

Warning C4530: C ++ exception handler used, but unwind semantics are not enabled.

The next parameter is used to make the program support multithreading. It needs to use the LIBCMT. LIB library file when linking. However, P. J. Plauger STL is NOT thread-safe ). If you use STL implementation versions like STLport in the VC environment, you need to add this parameter because STLport is thread-safe.

In the IDE environment, you can select the console application when creating a project.

For setting those parameters, you can set the compilation options in the Settings function Alt + F7 in the Project function menu.

Sometimes, when compiling STL programs in the IDE environment, the following warning may occur ):

Warning C4786 :'...... ': Identifier was truncated to '000000' characters in the debug information

This is because the compiler limits the length of identifiers in the program to 255 characters during debugging. If the maximum length is exceeded, these identifiers cannot be viewed and computed during the debugging phase. A large number of template functions and template classes are used in STL programs. When the compiler instantiates these content, the identifier generated after expansion is often very long and may contain more than one thousand characters !). If you want to know this warning, it's easy to add the following line of code to the program:

 
 
  1. Vector string_array; // similar to a string array variable

Of course, we can ignore such warning, but there are also solutions. You can add the following line at the beginning of the file: # pragma warning (disable: 4786 ). It forces the compiler to ignore this warning message, which is a bit rude but effective.

For C ++ Builder, the running mode in the doscommand line state is as follows. Assume that your C ++ Builder is installed in C: \ Program Files \ Borland \ CBuilder6. Then the path of the compiler should be C: \ Program Files \ Borland \ CBuilder6 \ bin. you can find the bcc32.exe file and enter the following command, which means the success is achieved:

Bcc32 example2_2.cpp

In the IDE environment, you can select Console Wizard when creating an application ).

Now you can run the previous sample program on your machine. However, please forgive me for talking too much and I have to draw your attention to some details. Be careful with the traps left by the compiler. For example, the third program contains the following code:

 
 
  1. typedef back_insert_iterator< int_vector > back_ins_itr; 

Please note that the space in front of ">" should not be omitted. If you are sorry for the disk space occupied by this space, it would be too easy. The reason is the defects of the C ++ compiler. The above code is equivalent to the following code compiler's translation work ):

 
 
  1. typedef back_insert_iterator< vector > back_ins_itr; 

If you do not add spaces, the compiler will mistake ">" as a single identifier that looks like the data stream input operator "> "). To avoid this problem, C ++ requires that a space be inserted between two right angle brackets. Therefore, you 'd better follow my instructions to avoid unnecessary troubles. However, it is interesting that the compiler will not report errors even if you do not add spaces in Visual C ++ for the code before the above line is expanded. The same Code is not so lucky in C ++ Builder. However, it is better not to be lucky. If you adopt the expanded writing method, neither compiler will show you mercy.

Now, you can feel the unique charm that STL brings to you. Good luck!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.