Mi informacion de contacto
Correo[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
En C/C++, hay una gran cantidad de variables, funciones y clases que se aprenderán más adelante. Los nombres de estas variables, funciones y clases existirán en todo el mundo.
En el ámbito local, puede causar muchos conflictos.El propósito de utilizar espacios de nombres es localizar los nombres de los identificadores para evitar nombrarlos.
Conflicto o contaminación de nombres, la palabra clave Namespac parece abordar este problema.
Los conflictos de nombres como el siguiente programa en proyectos en lenguaje C son problemas comunes. C++ introduce el espacio de nombres para resolverlos mejor.
Tal problema: (El error se informa porque la variable rand que configuramos entra en conflicto con la función rand en stdlib.h)
#include <stdio.h>
#include <stdlib.h>
int rand = 10;
int main()
{
// 编译报错:error C2365: “rand”: 重定义;以前的定义是“函数”
printf("%dn", rand);
return 0;
}
1. Para definir un espacio de nombres, debe usar la palabra clave del espacio de nombres, seguida del nombre del espacio de nombres y luego conectar un par de {}, donde {}
Es decir, un miembro del espacio de nombres. Se pueden definir variables/funciones/tipos, etc. en el espacio de nombres.(Tenga en cuenta que {} no va seguido de ";")。
2. La esencia del espacio de nombres es definir un dominio. Este dominio es independiente del dominio global. Diferentes dominios pueden definir variables con el mismo nombre.
El rand anterior ya no está en conflicto.
#include<iostream>
#include <stdio.h>
#include <stdlib.h>
namespace tmp
{
int rand = 0;
}
int main()
{
printf("%dn", rand);
return 0;
}
3. Los dominios en C++ incluyen el dominio local de función, el dominio global, el dominio de espacio de nombres y el dominio de clase. El dominio afecta la sintaxis en tiempo de compilación para encontrar una variable/función/;
La lógica del origen del tipo (declaración o definición), con el aislamiento del dominio, se resuelven los conflictos de nombres.Además de afectar el dominio local y el dominio global
La compilación de la lógica de búsqueda también afectará el ciclo de declaración de variables. Los dominios de espacio de nombres y los dominios de clase no afectan el ciclo de declaración de variables.
4. El espacio de nombres solo se puede definir globalmente y, por supuesto, también se puede anidar.
#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. Los espacios de nombres con el mismo nombre definido en varios archivos del proyecto se considerarán como un espacio de nombres y no entrarán en conflicto.
archivo prueba.c
#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;
}
archivo prueba.h
#pragma once
namespace tmp
{
int d = 0;
}
Se puede encontrar que la variable d en el espacio tmp se puede usar en el archivo .c.
6. La biblioteca estándar de C++ se coloca en un espacio de nombres llamado std (estándar).
7. Si queremos utilizar variables en el dominio global, podemos hacer esto:
int a = 3;
int main()
{
int a = 0;
printf("%dn", ::a);
return 0;
}
De esta forma, printf imprime 3 primero.
Al compilar para buscar la declaración/definición de una variable, de forma predeterminada solo buscará local o globalmente, no en el espacio de nombres.entonces
El siguiente programa compilará e informará un 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;
}
Entonces tenemos que usar variables/funciones definidas en el espacio de nombres. Hay tres formas:
1. Especifique el acceso al espacio de nombres. Este método se recomienda en el proyecto.
tmp::d
2. El uso expande un miembro del espacio de nombres.Este enfoque se recomienda para miembros del proyecto a los que se accede con frecuencia y que no tienen conflictos.
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. Expanda todos los miembros en el espacio de nombres.No se recomienda el proyecto porque el riesgo de conflicto es alto. Se recomienda el programa de práctica diaria por conveniencia.
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. Es la abreviatura de Input Output Stream. Es una biblioteca de flujos de entrada y salida estándar que define la entrada y salida estándar.
fuera objeto.
2. std::cin es un objeto de la clase istream, que está orientado principalmente a la salida estándar de caracteres estrechos (de tipo char).
Afluencia.
3. std::cout es un objeto de la clase ostream, que está orientado principalmente al flujo de salida estándar de caracteres estrechos.
4. std::endl es una función Cuando la secuencia se inserta en la salida, equivale a insertar un carácter de nueva línea y actualizar el búfer.
5. << es el operador de inserción de flujo y >> es el operador de extracción de flujo. (El lenguaje C también utiliza estos dos operadores para realizar operaciones bit a bit, como desplazamiento a la izquierda/desplazamiento a la derecha)
6. Es más conveniente usar C++ para entrada y salida. No es necesario especificar manualmente el formato como entrada y salida printf/scanf**.
La salida puede identificar automáticamente tipos de variables(Esencialmente, esto se logra mediante la sobrecarga de funciones). De hecho, lo más importante es que las transmisiones de C ++ pueden admitir mejor la personalización.
Escriba objetos de entrada y salida.
#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. pertenecen a la biblioteca estándar de C++. La biblioteca estándar de C++ se coloca en un espacio de nombres llamado std (estándar), por lo que es necesario.
Utilícelos mediante el uso del espacio de nombres.
8、⼼Podemos utilizar el espacio de nombres estándar en los ejercicios diarios generales, pero no se recomienda utilizar el espacio de nombres estándar en el desarrollo de proyectos reales.
Los parámetros predeterminados especifican un valor predeterminado para los parámetros de la función al declarar o definir la función.Al llamar a esta función, si no se especifican parámetros reales
Luego se usa el valor predeterminado del parámetro formal; de lo contrario, se usa el parámetro real especificado. Los parámetros predeterminados se dividen en parámetros predeterminados completos y semipredeterminados. (En algunos lugares,
Los parámetros predeterminados también se denominan parámetros predeterminados).
Valor predeterminado completo significa que a todos los parámetros formales se les asignan valores predeterminados, y semipredeterminado significa que algunos parámetros formales reciben valores predeterminados.C ++ estipula que los parámetros semipredeterminados deben ser de derecha a izquierda
Los valores predeterminados son continuos en secuencia y no pueden saltar al valor predeterminado a intervalos.
Para llamadas a funciones con parámetros predeterminados, C ++ estipula que los parámetros reales deben proporcionarse secuencialmente de izquierda a derecha y no se pueden omitir.
Cuando la declaración y la definición de la función están separadas, los parámetros predeterminados no pueden aparecer tanto en la declaración como en la definición de la función. Se estipula que la función debe declararse como predeterminada.
valor.
#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;
}
El semi-predeterminado no se puede escribir así:
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;
}
Debe cumplir estrictamente con:
Los parámetros semipredeterminados deben establecerse continuamente de derecha a izquierda y no se pueden omitir a los valores predeterminados a intervalos.
Antes de aprender C++, cuando implementamos la inicialización e inserción de la pila, escribimos esto:
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++;
}
Si queremos insertar 100 datos, necesitaremos una expansión continua y una pérdida eficiente, pero después de conocer los parámetros predeterminados, podemos escribir así:
// 栈顶
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;
}
Esto evita efectivamente el problema de abrir espacio repetidamente.
C++ admite funciones con el mismo nombre que aparecen en el mismo ámbito, pero requiere que los parámetros formales de estas funciones con el mismo nombre sean diferentes. Puede ser un número diferente de parámetros.
Diferentes tipos. De esta manera, las llamadas a funciones de C++ exhiben un comportamiento polimórfico y son más flexibles de usar. (Sin embargo, no se pueden utilizar diferentes valores de retorno como condiciones de sobrecarga.
Debido a que no se puede distinguir al llamar, si el valor de retorno y el tipo o número de parámetro cambian al mismo tiempo, también es una condición de sobrecarga).
#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;
}
En particular, si el método anterior utiliza parámetros predeterminados, se informará un error al llamar sin pasar parámetros. El compilador no sabe a quién llamar.
// 下⾯两个函数构成重载
// 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;
}``
resultado: