[C++] Detailed explanation of getting started with C++ I [Getting started with C++, this article is enough]




Preface

C++ is an improvement on the defects and deficiencies encountered in the use of C language.

C++ is based on C, incorporating object-oriented programming ideas, and adding many useful libraries, programming paradigms, etc.. After becoming familiar with C language, it will be helpful to learn C++.

The main goals of this chapter:

  1. Supplement the shortcomings of C language syntax, and how C++ optimizes the unreasonable design of C language, such as: scope, IO, function, pointer aspects, macro aspects, etc.

  2. Lay the foundation for subsequent class and object learning


1. C++ keywords (C++98)

C++Total 63 keywords (covering 32 keywords in C language)

Insert image description here


2. Namespace namespace

(1) The emergence of namespace

Problems that arise in C/C++:

  1. Variables, functions and the classes to be learned later all exist in large numbers. These variables , function and class nameswill all exist inglobal scope, which may cause< a i=7>Many conflicts.
  2. The variable name written conflicts with the name in the library.
  3. When the project proceeds asynchronously, it can easily lead to many naming conflicts (renaming) when the final project is merged.

Such as the following example

#include <stdio.h>

#include <stdlib.h>        //包含rand()函数
int rand = 10;             //全局变量中也有 命名为rand的变量

// C语言没办法解决类似这样的命名冲突问题,所以C++提出了namespace来解决
int main()
{
    
    
 printf("%d\n", rand);
return 0;
}
// 编译后后报错:error C2365: “rand”: 重定义;以前的定义是“函数”
  • C++ namespace [keyword] optimizes this:
    During normal program operation, variables in global variables are accessed by default. The namespace is equivalent to a wall, will usually be bypassed, and will not enter the wall to find domain access by default a> can you have permission to access the variables stored in the namespace. expand the namespace . Only

After using namespace

#include <stdio.h>

#include <stdlib.h>        //包含rand()函数

namespace nini{
    
    
int rand = 10;             
}
// C语言没办法解决类似这样的命名冲突问题,所以C++提出了namespace来解决
int main()
{
    
    
 printf("%d\n",nini::rand);   // :: 域作用限定符 
return 0;
}

The purpose of using namespaces isto localize identifier names to avoid naming conflicts or name pollution.
namespace The emergence of keywords is aimed at this problem.



(2) Definition of namespace

(1) Normal definition of namespace

namespace[keyword] + namespace name + {} + (inside {}) members of the namespace

  1. In general development, project name is used as namespace name.
  2. Can be defined in the namespaceVariables / Functions / Type (such as structure, etc.)

[Note:A namespace defines a new scope, and all content in the namespace is limited to this namespace Medium]

namespace nini
{
    
    
 // 命名空间中可以定义变量/函数/类型
 int rand = 10;                        //变量
 
 int Add(int left, int right)          //函数
 {
    
    
 return left + right;
 }

struct Node                            //类型
 {
    
    
 struct Node* next;
 int val;
 };
 
}


(2) Functional characteristics of namespace

1. Namespace can be nested
// test.cpp
namespace N1
{
    
    
int a;
int b;
int Add(int left, int right)
 {
    
    
     return left + right;
 }
 
namespace N2
 {
    
    
     int c;
     int d;
     int Sub(int left, int right)
     {
    
    
         return left - right;
     }
 }
 
}
2. Multiple namespaces with the same name are allowed to exist in the same project, and the compiler will eventually synthesize them into the same namespace.

ps: test.h in a project and the two N1s in test.cpp above will be merged into one

// test.h
namespace N1
{
    
    
int Mul(int left, int right)
 {
    
    
     return left * right;
 }
}


Use of namespaces

(1) Add namespace name and :: scope qualifier [specify namespace each time]

int main()
{
    
    
    printf("%d\n", N::a);    // :: 作用域限定符 【指定命名空间】
    return 0;    
}

☆ (2) using introduces a member in the namespace [partial expansion]

using N::b;
int main()
{
    
    
    printf("%d\n", N::a);
    printf("%d\n", b);
    return 0;    
}

(3) using namespace namespace name introduction [full expansion]

using namespce N;
int main()
{
    
    
    printf("%d\n", N::a);
    printf("%d\n", b);
    Add(10, 20);
    return 0;    
}

  • Discussion onfull expansion and partial expansion:
    Expand the namespace [namespace full expansion] (3) In fact, it is a very dangerous thing. Direct expansion will expose everything, and there is a risk of conflict. And it is very inconvenient to specify the namespace (1) every time.
    Specifying expansion (2) can solve the problem. Specifies expansion commonly used.
using std::cout;
using std::endl;

int main(){
    
    
cout<<"hello world\n";

int a=10;
double b=11.11;

cout << a << endl << b << endl;
cout << a << endl << b << endl;
cout << a << endl << b << endl;
}


三、using namespace std

Usage conventions of std namespace:

std is the namespace of C++ standard library. How to expand std and use it more reasonably?

  1. In daily practice, it is recommended to use namespace std directly, which is very convenient.

  2. Using namespace std is expanded, and the standard library is fully exposed. If we define a type/object/function with the same name as the library, there will be a conflict problem. This problem rarely occurs in daily practice, but when there is a lot of code and a large scale in project development, it can easily occur. Therefore, it is recommended to use it in project development. When using it like std::cout, specify the namespace + using std::cout to expand commonly used library objects/types.



4. C++ input & output [IO stream]

(1) Code implementation

(1) Include header files# include<iostream>

  1. Abbreviation of io _ int & out + stream stream => iostream input and output stream

When using cout and cin later, you mustinclude the < iostream >header file and The namespace usage method uses std.
As shown below


(2)cout cin endl

c (console console) out, cin

  • cout standard output object (console) [linux calls it terminal ]
    Insert image description here

  • cin standard input object (keyboard)

cout and cin are global stream objects.

  • endl [ endline ends this line ] is a special C++ symbol (C++ newline character), Indicatesnewline output.

They are included in the < iostream > header file.


(3)<< _ stream insertion operator, >> _ stream extraction operator


Actuallycout and cin are objects of ostream and istream types respectively,>> and << also involves operator overloading and other knowledge ,
. We will learn these knowledge later, so we will just briefly learn their use here. We will have a chapter later to learn more in depthIO stream usage and principles.


(2) Characteristics of C++ input and output: variable types can be automatically identified

It is more convenient to use C++ input and output, and there is no need to do the same as printf/scanf input and output, Requires manual control of format.
C++’s input and output can automatically identify variable types.

#include <iostream>
using namespace std;

int main()
{
    
        
   //IO流
   // 可以自动识别变量的类型
   // << 流插入
   std::cout << "hello world";
   int a = 10;
   double b = 11.11;
   
            //int //字符串 //double //字符
   std::cout << a << "\n"<< b << '\n';
   std::cout << a << std::endl << b << std::endl;
   
   return 0;
}


(3) More complex usage of cout and cin

There are many more complex uses of cout and cin, such asControlling the precision of floating point output,Control the integer output format and so on.

BecauseC++ is compatible with the usage of C language[So, this kind of complex usage in C++, It can be implemented in C using its basic syntax]

int main(){
    
    
cout << "hello world\n";

int a = 10;
double b = 11.11

cout << a << endl << b << endl;
printf("%.1lf\n",b);      //C++兼容C语言的用法,这种在C++的复杂用法,可以在C中用其基本语法来实现
}

These are not used very much, so we will not study them here. If necessary, we will study the documentation later.


(3) .h header file and std namespace

Note:The early standard library implemented all functions in the global scope, and was declared in .h In the suffix header file , only needs to include the corresponding header file when using it.

Later it was placed instd namespace in order to distinguish from C header files. <iostream.h> + std stipulates that the C++ header file does not contain .h< /span> is recommended; The old compiler (vc 6.0) also supports the <iostream.h> format, but subsequent compilers no longer support it, so , use the namespace correctly, and in order to



5. Default parameters

(1) Default parameter concept

The default parameter isWhen declaring or defining a function specify a default value for the function's parameter .
When calling this function, if no actual parameter is specified, the default value of the formal parameter is used, otherwise the specified actual parameter is used.

void Func(int a = 0)
{
    
    
 cout<<a<<endl;
}
int main()
{
    
    
 Func();     // 没有传参时,使用参数的默认值
 Func(10);   // 传参时,使用指定的实参
return 0;
}


(2) Default parameter classification

  • All default parameters
void Func(int a = 10, int b = 20, int c = 30)
 {
    
    
     cout<<"a = "<<a<<endl;
     cout<<"b = "<<b<<endl;
     cout<<"c = "<<c<<endl;
 }
  • Semi-default parameters
    Semi-default parameters must be given in orderfrom right to left, Cannot be given at intervals
void Func(int a, int b = 10, int c = 20)
 {
    
    
     cout<<"a = "<<a<<endl;
     cout<<"b = "<<b<<endl;
     cout<<"c = "<<c<<endl;
 }

Notice:

  1. Default parameters cannot appear simultaneously infunction declarations and definitions
    if< a i=4>The declaration and definition positions appear at the same time. If the values ​​provided by the two positions are different, the compiler cannot determine which default value should be used.
//a.h
  void Func(int a = 10);
  
  // a.cpp
  void Func(int a = 20)
 {
    
    }
  1. The default value must be constant or global variable
  2. C language is not supported (the compiler does not support it)


6. Function overloading

C does not support functions with the same name. C relies on function names to identify functions, but the functions are similar, just because formal parameter list (number of parameters or type or type order) Different, so many different function names need to be opened. This is cumbersome and inefficient.

In this regard, C++ has made improvements and proposed the concept offunction overloading.



(1) Concept of function overloading

Function overloading: It is a special case of functions. C++ allows several declarationsin the same scope a i=3>functions similar tofunctions with the same name, these functions with the same name The formal parameter list (parameter number or type or type order) is different and is often used to process data that implements similar functions Questions of different types.

  • [ The return value is available but not needed ]
    You will not know who to call.


(2) Function overloading

(1) Different parameter types

#include<iostream>
using namespace std;

// 1、参数类型不同
int Add(int left, int right)
{
    
    
 cout << "int Add(int left, int right)" << endl;
 return left + right;
}

double Add(double left, double right)
{
    
    
 cout << "double Add(double left, double right)" << endl;
 return left + right;
}

int main(){
    
    
 Add(10, 20);
 Add(10.1, 20.2);
}

(2) The number of parameters is different

// 2、参数个数不同
void f()
{
    
    
 cout << "f()" << endl;
}
void f(int a)
{
    
    
 cout << "f(int a)" << endl;
}

int main()
{
    
     
 f();//f()则不知道该调用 f()还是f(int a)  
 f(10);     //f(10)可以很明确的是传给f(int a);
}

(3) The order of parameter types is different

// 3、参数类型顺序不同
void f(int a, char b)
{
    
    
 cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{
    
    
 cout << "f(char b, int a)" << endl;
}

int main()
{
    
    
 f(10, 'a');
 f('a', 10);
 return 0;

}


(3) Function overloading underlying principle_name mangling (name mangling)

Why does C++ support function overloading, but the C language does not support function overloading?

In C/C++, in order for a program to run, it needs to go through the following stages: Preprocessing, < a i=3>Compile, Assemble, Link< a i=8>.
Insert image description here

Insert image description here
Insert image description here

  1. Preprocessing (.i file)
    Preprocessing instructions, header file expansion


  1. Compilation (.s file)
    Syntax analysis, lexical analysis, semantic analysis, symbol summary

(Syntax bundle) Check syntax and generate assembly code [instruction level code] (shown to us)


2.1 Function call In the compilation phase, call (address)
[ only declares (but the compiler Let it pass), there is no address ]
[Will be generated during the link phase by generating according to the assembly phase.o ]The file symbol table (find the address corresponding to the function name) links the address in call()
Insert image description here


2.2 andbring parameters in for modificationproduce [ Function name modification rules ]
Since the modification rules of vs under Windows are too complicated, while the modification rules of g++ under Linux are simple and easy to understand, below we use g++ to demonstrate the modified name.

We can see from the following that the name of the function of gcc (C) remains unchanged after modification. After modification, the function of g++ (C++) becomes [_Z+function length+function name+type initial letter< /span>

  • Result after compilation using C language compiler
    Insert image description here
    Conclusion: Under Linux, after compilation using gcc, the modification of the function name has not changed.

  • Result after compilation using C++ compiler
    Insert image description hereConclusion: Under Linux, after compilation using g++, the modification of the function name changes, and the compiler adds function parameter type information to the modified in the last name.

  • Name modification rules under Windows
    Insert image description here

Comparing Linux, you will find that the function name modification rules of the VS compiler under Windows are relatively complicated and difficult to understand, but the principles are similar, so we will not do a detailed study.

[Extended learning: C/C++ function calling conventions and name modification rules – interested students can take a look, which explains the function name modification rules under VS]
C /C++ function calling convention

You will understand through this C language cannot support overloading, because functions with the same name cannot be distinguished . C++ is distinguished by function modification rules. As long as the parameters are different, the modified names are different, and overloading is supported.

If two functionsfunction names and parameters are the same,the return values ​​are different is does not constitute an overload, because the compiler cannot distinguish it when calling.
The return value is available but not required. There may be situations where you don’t know who to call.



  1. Assembly ( Relocatable object file .o file)
    3.1 Form a symbol table. (The call address will only be called when the function is called in assembly, so the symbol table is generated at this time)

    Symbol table:
    Form " Function name address " [Mapping of function name and address]
    Insert image description here
    3.2 Assembly instructions-> Binary instructions [converted into binary machine code (can be understood by the CPU)] -> test.o



  1. Link
    Merge segment table
    Merge symbol table and relocate symbol table
    Merge together, Link some undetermined function addresses etc. [Use function names to find addresses (function name modification rules)]

Actual projects usually consist of multiple header files and multiple source files. Through the compilation links learned in the C language stage, we can know that [when the Add function defined in b.cpp is called in the current a.cpp], after compilation Before linking, there is no Add function address in the target file of a.o, because Add is defined in b.cpp, so the address of Add is in b.o. So what to do?

Sothe linking stage is specifically designed to deal with this problem. The linker sees thata.o calls Add, But if there is no Add address, the Add address will be found in the symbol table of b.o, and then linked together.

So when linking, when facing the Add function, which name will the linker use to find it? Here we can find it through what we mentioned in the previous compilation stage: each compiler has its own function name modification rules.

Guess you like

Origin blog.csdn.net/NiNi_suanfa/article/details/134259727