When I write a lot in C language, I naturally like C ++-C ++ (1)

Source: Internet
Author: User

[Mac 10.7.1 Lion x64 Intel-based gcc4.2.1 xcode4.2]

Q: Explain the title.
A: I vaguely remember that when I wrote A function with the absolute value of A value, it was really painful to write it to the third one. After repeating so many times, I immediately realized the significance of heavy load and STL.
[Cpp]
1. int abs (int n)
2 .{
3. return n <0? -N: n;
4 .}
5.
6. long abs_long (long n)
7 .{
8. return n <0? -N: n;
9 .}
10.
11. double abs_double (double n)
12 .{
13. return n <0? -N: n;
14 .}
When I wrote the third function, I felt really uncomfortable. The heavy loading in c ++ was so realistic that I knew the pain points of c programmers. for basic types, many absolute value operations are similar, why write so many functions? Writing code is not more concise and stable than writing code. STL understands the pain of writing the above Code better.
[Cpp]
1. template <class T>
2. T abs (T)
3 .{
4. return a <0? -A:;
5 .}
Of course, it can also be implemented using macros, but it is not very recommended:
[Cpp]
1. # define ABS (a) <0? (-A): ())
An error may occur when you are not careful:
[Cpp]
1. std: cout <ABS (-12.4) <std: endl;
Compilation prompt:
[Cpp]
1. error C2105: '-- 'needs l-value
Oh, the original ABS (-12.4) was replaced by a macro -- 12. 4. Be careful when there is a macro...
[Cpp]
1. # define ABS (a) <0? -(A): ())
In this way, the compilation is OK.
In addition, when using the C language, it is often written to a struct and operations on the struct. You must apply for a space to construct a structure and write N malloc, until every time I write malloc, I feel that I want to vomit. c ++ understands this pain point. The constructor allows programmers who write malloc to vomit to quickly fall in love with c ++.
There are also many improvements to c ++, which are not described here.

Q: What is the difference between using the cstring header file and string. h In c ++?
A: Let's look at two examples:
[Cpp]
1. # include <stdio. h>
2. # include <stdlib. h>
3. # include <string. h>
4.
5. # define PRINT_D (intValue) printf (# intValue "is % d \ n", (intValue ));
6. # define PRINT_STR (str) printf (# str "is % s \ n", (str ));
7. # define FOR_EVER () {while (1 );}
8.
9. int main ()
10 .{
11. size_t len =: strlen ("hello ");
12. return 0;
13 .}
Save as std_strlen.c. Compile:
[Cpp]
1. error: expected expression [1]
2. size_t len =: strlen ("hello ");
3. ^
4. 1 error generated.
It can be seen that there is no scope operator in the C language. Compilation error here;
[Cpp]
1. # include <iostream>
2. # include <cstring>
3.
4. int main ()
5 .{
6. size_t len =: strlen ("hello ");
7. return 0;
8 .}
Save it as main. cpp, compile it, and there is no problem.
Cstring and string. h: c ++ supports the scope OPERATOR: The functions in the original c library are regarded as global scope functions in c ++ by default, and of course they are also std scope functions. As follows:
[Cpp]
1. len = std: strlen ("hello ");
The above code can still be compiled. Now let's take a look at the content in the header files cstring and string. h:
Cstring header file (partial ):
[Cpp]
1. _ GLIBCXX_BEGIN_NAMESPACE (std)
2.
3. using: memcpy;
4. using: memmove;
5. using: strcpy;
6. using: strncpy;
7. using: strcat;
8. using: strncat;
9. using: memcmp;
10. using: strcmp;
11. using: strcoll;
12. using: strncmp;
13. using: strxfrm;
14. using: strcspns;
15. using: strspns;
16 .......
17 .......
18.
19. _ GLIBCXX_END_NAMESPACE

String. h header file (partial ):
[Cpp]
1. _ BEGIN_DECLS
2. void * memchr (const void *, int, size_t );
3. int memcmp (const void *, const void *, size_t );
4. void * memcpy (void *, const void *, size_t );
5. void * memmove (void *, const void *, size_t );
6. void * memset (void *, int, size_t );
7. char * strcat (char *, const char *);
8. char * strchr (const char *, int );
9. int strcmp (const char *, const char *);
10. int strcoll (const char *, const char *);
11. char * strcpy (char *, const char *);
12. size_t strcspn (const char *, const char *);
13. char * strerror (int) _ DARWIN_ALIAS (strerror );
14. size_t strlen (const char *);
15. char * strncat (char *, const char *, size_t );
16. int strncmp (const char *, const char *, size_t );
17. char * strncpy (char *, const char *, size_t );
18. char * strpbrk (const char *, const char *);
19. char * strrchr (const char *, int );
20. size_t strspn (const char *, const char *);
21. char * strstr (const char *, const char *);
22. char * strtok (char *, const char *);
23. size_t strxfrm (char *, const char *, size_t );
24. _ END_DECLS

Q: What is the difference between references in c ++ and pointers of similar functions?
A: basically, there is no difference. In terms of usage, there are differences. Example:
[Cpp]
1. # include <iostream>
2. # include <cstring>
3.
4. # define COUT_ENDL (str) std: cout <# str <"is" <(str) <std: endl;
5.
6. void swap (int & a, int & B)
7 .{
8. int temp =;
9. a = B;
10. B = temp;
11 .}
12.
13. void swap (int * pa, int * pb)
14 .{
15. int temp = * pa;
16. * pa = * pb;
17. * pb = temp;
18 .}
19.
20.
21. int main ()
22 .{
23. int a = 1, B = 2;
24. swap (a, B );
25. COUT_ENDL ()
26. COUT_ENDL (B)
27.
28. a = 1, B = 2;
29. swap (& a, & B );
30. COUT_ENDL ()
31. COUT_ENDL (B)
32.
33. return 0;
34 .}
Save as main. cpp.
Void swap (int & a, int & B); function compilation is as follows:
[Cpp]
1. 0x0000000100000c00 <_ Z4swapRiS _ + 0>: push % rbp
2. 0x0000000100000c01 <_ Z4swapRiS _ + 1>: mov % rsp, % rbp
3. 0x0000000100000c04 <_ Z4swapRiS _ + 4>: mov % rdi,-0x8 (% rbp)
4. 0x0000000100000c08 <_ Z4swapRiS _ + 8>: mov % rsi,-0x10 (% rbp)
5. 0x0000000100000c0c <_ Z4swapRiS _ + 12>: mov-0x8 (% rbp), % rsi
6. 0x0000000100000c10 <_ Z4swapRiS _ + 16>: mov (% rsi), % eax
7. 0x0000000100000c12 <_ Z4swapRiS _ + 18>: mov % eax,-0x14 (% rbp)
8. 0x0000000100000c15 <_ Z4swapRiS _ + 21>: mov-0x10 (% rbp), % rsi
9. 0x0000000100000c19 <_ Z4swapRiS _ + 25>: mov (% rsi), % eax
10. 0x0000000100000c1b <_ Z4swapRiS _ + 27>: mov-0x8 (% rbp), % rsi
11. 0x0000000100000c1f <_ Z4swapRiS _ + 31>: mov % eax, (% rsi)
12. 0x0000000100000c21 <_ Z4swapRiS _ + 33>: mov-0x14 (% rbp), % eax
13. 0x0000000100000c24 <_ Z4swapRiS _ + 36>: mov-0x10 (% rbp), % rsi
14. 0x0000000100000c28 <_ Z4swapRiS _ + 40>: mov % eax, (% rsi)
15. 0x0000000100000c2a <_ Z4swapRiS _ + 42>: pop % rbp
16. 0x0000000100000c2b <_ Z4swapRiS _ + 43>: retq

Void swap (int * pa, int * pb); the function compilation is as follows:
[Cpp]
1. 0x0000000100000c30 <_ Z4swapPiS _ + 0>: push % rbp
2. 0x0000000100000c31 <_ Z4swapPiS _ + 1>: mov % rsp, % rbp
3. 0x0000000100000c34 <_ Z4swapPiS _ + 4>: mov % rdi,-0x8 (% rbp)
4. 0x0000000100000c38 <_ Z4swapPiS _ + 8>: mov % rsi,-0x10 (% rbp)
5. 0x0000000100000c3c <_ Z4swapPiS _ + 12>: mov-0x8 (% rbp), % rsi
6. 0x0000000100000c40 <_ Z4swapPiS _ + 16>: mov (% rsi), % eax
7. 0x0000000100000c42 <_ Z4swapPiS _ + 18>: mov % eax,-0x14 (% rbp)
8. 0x0000000100000c45 <_ Z4swapPiS _ + 21>: mov-0x10 (% rbp), % rsi
9. 0x0000000100000c49 <_ Z4swapPiS _ + 25>: mov (% rsi), % eax
10. 0x0000000100000c4b <_ Z4swapPiS _ + 27>: mov-0x8 (% rbp), % rsi
11. 0x0000000100000c4f <_ Z4swapPiS _ + 31>: mov % eax, (% rsi)
12. 0x0000000100000c51 <_ Z4swapPiS _ + 33>: mov-0x14 (% rbp), % eax
13. 0x0000000100000c54 <_ Z4swapPiS _ + 36>: mov-0x10 (% rbp), % rsi
14. 0x0000000100000c58 <_ Z4swapPiS _ + 40>: mov % eax, (% rsi)
15. 0x0000000100000c5a <_ Z4swapPiS _ + 42>: pop % rbp
16. 0x0000000100000c5b <_ Z4swapPiS _ + 43>: retq

It can be seen that the two pieces of assembly code are completely consistent. In fact, it can also be understood that the compiler regards reference as passing a pointer by default. Of course, this depends on the compiler. It cannot be determined that all the Assembly codes using the reference and pointer methods are consistent, but at least their final functions are consistent.

Q: For the same swap function as the above Code, how does the compiler ultimately separate them?
A: Since there are differences, the compiler can naturally separate them. As shown in the Assembly above, the name of the first swap function in the compiler is _ Z4swapRiS _, and the name of the second swap function is _ Z4swapPiS _.
Run the nm command to view the symbol table in the generated executable file (testForCpp is generated by default in this project ):
 

We can see that these two names exist. For such a name, only one common naming rule can be provided. Generally, "Return Value + (namespace) + function name + parameter form" is used ", the processing varies with compilers.

Q: What is the difference between the input and output, cout and cin in c ++ and printf and scanf functions?
A: from one perspective, cout and cin are objects; printf and scanf are functions; from another perspective, cout is probably less efficient than printf functions, because it encapsulates many functions internally, printf is relatively direct for security reasons or modular considerations. Whether or not cout calls the printf function should be completely determined. Although there is a saying that this is true, it may be the reason for compatibility. different platforms should have different considerations.
The declaration of variables such as cout is as follows:
[Cpp]
1. extern istream cin; // <Linked to standard input
2. extern ostream cout; // <Linked to standard output
3. extern ostream cerr; // <Linked to standard error (unbuffered)
4. extern ostream clog; // <Linked to standard error (buffered)

Q: Can virtual functions be dynamically bound? Can c ++ be considered as a dynamic language?
A: According to the basic concept of Dynamic Language, standard c ++ is not enough. It is still A strict compiling language. For dynamic binding, c ++ only uses static methods to implement slightly dynamic features. Dynamic binding is generally supported by virtual tables. The Compiler assembles a virtual table based on the name of the virtual function in the class and inheritance system, then, based on the specific meaning of the calling code, you can simply call the function corresponding to the location of the virtual table. Although the surface looks simple, in fact, the compiler can calculate what is actually called (except for a single function with parameters as the base class pointer, of course, this is one of the reasons why virtual tables exist ).
If this feature can be viewed as dynamic, c ++ is a language with a little dynamic features.

Xichen

 

 

From Chen Xi's sharing

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.