2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
In C/C++, there are a large number of variables, functions, and classes that you will learn later. The names of these variables, functions, and classes will exist in the world.
The purpose of using namespaces is to localize the names of identifiers to avoid naming
Conflict or name pollution, the namespac keyword appears to address this problem.
Naming conflicts are common problems in C language projects, such as the following program. C++ introduces namespac to better solve them.
Such a problem: (because the variable rand we set conflicts with the rand function in stdlib.h, so an error is reported)
#include <stdio.h>
#include <stdlib.h>
int rand = 10;
int main()
{
// 编译报错:error C2365: “rand”: 重定义;以前的定义是“函数”
printf("%dn", rand);
return 0;
}
1. To define a namespace, you need to use the namespace keyword, followed by the namespace name, and then a pair of {}.
It is a member of a namespace. Variables/functions/types can be defined in a namespace.(Note that there is no “;” after {})。
2. The essence of namespace is to define a domain. This domain is independent of the global domain. Different domains can define variables with the same name. Therefore,
The rand on the surface no longer conflicts.
#include<iostream>
#include <stdio.h>
#include <stdlib.h>
namespace tmp
{
int rand = 0;
}
int main()
{
printf("%dn", rand);
return 0;
}
3. In C++, there are function local scope, global scope, namespace scope, and class scope. The scope affects the syntax of looking up a variable/function/
The logic of type origin (declaration or definition), so with domain isolation, name conflicts are resolved.
Compilation search logic also affects the variable declaration cycle, while namespace scope and class scope do not affect the variable declaration cycle.
4. Namespace can only be defined globally, but it can also be nested.
#include<iostream>
#include <stdio.h>
#include <stdlib.h>
namespace tmp
{
int rand = 0;
namespace tmp1
{
int Add(int left, int right)
{
return left + right;
}
struct Node
{
struct Node* next;
int val;
};
}
}
int main()
{
printf("%dn", rand);
return 0;
}
5. Namespaces with the same name defined in multiple files in a project will be considered as one namespace and will not conflict.
test.c file
#include<iostream>
#include <stdio.h>
#include <stdlib.h>
#include"test.h"
namespace tmp
{
int rand = 0;
namespace tmp1
{
int Add(int left, int right)
{
return left + right;
}
struct Node
{
struct Node* next;
int val;
};
}
}
int main()
{
printf("%dn", tmp::d);
return 0;
}
test.h file
#pragma once
namespace tmp
{
int d = 0;
}
It can be found that the d variable in the tmp space can be used in the .c file.
6. The C++ standard library is placed in a namespace called std (standard).
7. If we want to use variables in the global scope, we can do this:
int a = 3;
int main()
{
int a = 0;
printf("%dn", ::a);
return 0;
}
In this way, printf prints 3 first.
When the compiler searches for a variable declaration/definition, it will only search locally or globally by default, and will not search in the namespace.
The following program will compile and report an error.
namespace tmp
{
int d = 0;
namespace tmp1
{
int Add(int left, int right)
{
return left + right;
}
struct Node
{
struct Node* next;
int val;
};
}
}
int main()
{
int a = 0;
printf("%dn", d);//未定义标识符d
return 0;
}
So we have three ways to use variables/functions defined in a namespace:
1. Specify namespace access, which is recommended in the project.
tmp::d
2. Using expands a member in the namespace.This approach is recommended for members of the project who frequently visit and do not have conflicts.
namespace tmp
{
int d = 0;
namespace tmp1
{
int Add(int left, int right)
{
return left + right;
}
struct Node
{
struct Node* next;
int val;
};
}
}
using tmp::d;
int main()
{
int a = 0;
printf("%dn", d);//未定义标识符d
return 0;
}
3. Expand all members in the namespace.It is not recommended for projects as the risk of conflict is very high. It is recommended for daily practice programs for convenience.
namespace tmp
{
int d = 0;
namespace tmp1
{
int Add(int left, int right)
{
return left + right;
}
struct Node
{
struct Node* next;
int val;
};
}
}
using namespace tmp;
int main()
{
int a = 0;
printf("%dn", d);//未定义标识符d
return 0;
}
1. It is the abbreviation of Input Output Stream, which is the standard input and output stream library.
Out object.
2. std::cin is an object of the istream class, which is mainly oriented towards the standard input of narrow characters (of type char).
Enter the stream.
3. std::cout is an object of the ostream class, which is mainly oriented towards the standard output stream of narrow characters.
4. std::endl is a function that is equivalent to inserting a newline character and refreshing the buffer when the stream is inserted into output.
5. << is the stream insertion operator, and >> is the stream extraction operator. (C language also uses these two operators to perform bitwise left/right shifts)
6. It is more convenient to use C++ for input and output. You don't need to manually specify the format like printf/scanf input and output.
Output can automatically identify variable types(It is essentially achieved through function overloading). In fact, the most important thing is that C++ streams can better support customization.
Type object input and output.
#include<iostream>
#include <stdio.h>
#include <stdlib.h>
namespace tmp
{
int a = 0;
double b = 0.0;
char c = '0';
namespace tmp1
{
int Add(int left, int right)
{
return left + right;
}
struct Node
{
struct Node* next;
int val;
};
}
}
using namespace tmp;
using namespace std;
int main()
{
cin >> a >> b >> c;
cout << a << b << c;
return 0;
}
7. cout/cin/endl etc. all belong to the C++ standard library. The C++ standard library is placed in a namespace called std (standard).
Use them by using namespaces.
8、In general daily practice, we can use namespace std, but it is not recommended to use namespace std in actual project development.
Default parameters are default values specified for function parameters when declaring or defining a function. When calling the function, if no actual parameters are specified
If the parameter is set to the default value, the default value of the formal parameter is used. Otherwise, the specified actual parameter is used. Default parameters are divided into full default and semi-default parameters.
Default parameters are also called default parameters).
Full default means that all parameters are given default values, and semi-default means that some parameters are given default values.C++ stipulates that semi-default parameters must be from right to left
The default values are set consecutively, and there cannot be any jumps between them.
When calling a function with default parameters, C++ stipulates that the actual parameters must be given in sequence from left to right and cannot be jumped to.
When a function is declared and defined separately, default parameters cannot appear in both the function declaration and definition.
value.
#include <iostream>
using namespace std;
void Func(int a = 0)
{
cout << a << endl;
}
int main()
{
Func(); // 没有传参时,使⽤参数的默认值
Func(10); // 传参时,使⽤指定的实参
return 0;
}
#include <iostream>
using namespace std;
// 全缺省
void Func1(int a = 10, int b = 20, int c = 30)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl << endl;
}
// 半缺省
void Func2(int a, int b = 10, int c = 20)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl << endl;
}
int main()
{
Func1();
Func1(1);
Func1(1, 2);
Func1(1, 2, 3);
Func2(100);
Func2(100, 200);
Func2(100, 200, 300);
return 0;
}
Semi-default cannot be written like this:
void Func2(int a = 10, int b, int c = 20)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl << endl;
}
//或者
void Func2(int a = 10, int b, int c)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl << endl;
}
Must strictly abide by:
Semi-default parameters must be set to default values consecutively from right to left, and cannot skip between default values.
Before we learned C++, we implemented stack initialization and insertion like this:
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
// 栈顶
void STInit(ST* ps, int n)
{
assert(ps);
ps->a = (STDataType*)malloc(n * sizeof(STDataType));
ps->top = 0;
ps->capacity = n;
}
void STPush(ST* ps, STDataType x)
{
assert(ps);
// 满了, 扩容
if (ps->top == ps->capacity)
{
printf("扩容n");
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity
* 2;
STDataType* tmp = (STDataType*)realloc(ps->a,
newcapacity * sizeof(STDataType));
if (tmp == NULL)
{
perror("realloc fail");
return;
}
ps->a = tmp;
ps->capacity = newcapacity;
}
ps->a[ps->top] = x;
ps->top++;
}
If we want to insert 100 data, we need to continuously expand the capacity, which is efficient. However, after learning the default parameters, we can write it like this:
// 栈顶
void STInit(ST* ps, int n = 4)
{
assert(ps);
ps->a = (STDataType*)malloc(n * sizeof(STDataType));
ps->top = 0;
ps->capacity = n;
}
void STPush(ST* ps, STDataType x)
{
assert(ps);
// 满了, 扩容
if (ps->top == ps->capacity)
{
printf("扩容n");
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity
* 2;
STDataType* tmp = (STDataType*)realloc(ps->a,
newcapacity * sizeof(STDataType));
if (tmp == NULL)
{
perror("realloc fail");
return;
}
ps->a = tmp;
ps->capacity = newcapacity;
}
ps->a[ps->top] = x;
ps->top++;
}
int main()
{
ST a;
STInit(&a, 100);//这里不传100也可以,因为规定必须从左到右依次给实参,不能跳跃给实参。刚好和缺省参数确定位置互补
for (int i = 0; i < 100; i++)
{
STPush(&a, i);
}
return 0;
}
This effectively avoids the problem of duplicate space creation.
C++ supports the same-name functions in the same scope, but requires that the parameters of these functions be different, which can be different in number or
Different types. In this way, C++ function calls show polymorphic behavior and are more flexible to use. (However, different return values cannot be used as overloading conditions.
Because they cannot be distinguished during the call, if the return value and parameter type or number change at the same time, it is also an overloading condition).
#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;
}
// 2、参数个数不同
void f()
{
cout << "f()" << endl;
}
void f(int a)
{
cout << "f(int a)" << endl;
}
In particular, if the above function uses default parameters, an error will be reported when it is called without passing parameters, because the compiler does not know who to call.
// 下⾯两个函数构成重载
// f()但是调⽤时,会报错,存在歧义,编译器不知道调⽤谁
void f1()
{
cout << "f()" << endl;
}
void f1(int a = 10)
{
cout << "f(int a)" << endl;
}
// 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;
}
#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;
}
// 2、参数个数不同
void f()
{
cout << "f()" << endl;
}
void f(int a)
{
cout << "f(int a)" << endl;
}
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()
{
Add(10, 20);
Add(10.1, 20.2);
f();
f(10);
f(10, 'a');
f('a', 10);
return 0;
}
`#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;
}
// 2、参数个数不同
void f()
{
cout << "f()" << endl;
}
void f(int a)
{
cout << "f(int a)" << endl;
}
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()
{
Add(10, 20);
Add(10.1, 20.2);
f();
f(10);
f(10, 'a');
f('a', 10);
return 0;
}``
result: