学习c++的第十四天

news2024/11/24 17:15:48

目录

动态内存

new 和 delete 运算符

命名空间

定义命名空间

using 指令

不连续的命名空间

嵌套的命名空间

模板

函数模板

类模板

C++ 中 typename 和 class 的区别

函数模板的重载


动态内存

了解动态内存在 C++ 中是如何工作的是成为一名合格的 C++ 程序员必不可少的。C++ 程序中的内存分为两个部分:

  • 栈:在函数内部声明的所有变量都将占用栈内存。
  • 堆:这是程序中未使用的内存,在程序运行时可用于动态分配内存。

很多时候,您无法提前预知需要多少内存来存储某个定义变量中的特定信息,所需内存的大小需要在运行时才能确定。

在 C++ 中,您可以使用特殊的运算符为给定类型的变量在运行时分配堆内的内存,这会返回所分配的空间地址。这种运算符即 new 运算符。

如果您不再需要动态分配的内存空间,可以使用 delete 运算符,删除之前由 new 运算符分配的内存。

new 和 delete 运算符

在 C++ 中,使用 new 运算符来动态分配内存,以便在运行时创建对象或数组。new 运算符首先会在堆上分配所需大小的内存,并返回指向这块内存的指针。然后,您可以使用该指针来操作这块内存。

以下是使用 new 运算符动态分配内存的一些示例:

1、动态分配单个对象的内存:

T* pointer = new T;

其中,T 是要分配的对象的类型,pointer 是指向新分配的对象的指针。

示例:

int* p = new int;  // 动态分配一个整数类型的内存
*p = 10;          // 在分配的内存中存储值

2、动态分配数组的内存:

T* arrayPointer = new T[size];

其中,T 是数组元素的类型,size 是数组的大小,arrayPointer 是指向新分配数组的指针。

示例:

int* arr = new int[5];  // 动态分配一个包含 5 个整数的数组的内存
arr[0] = 1;            // 在分配的数组中存储值

当您不再需要动态分配的内存时,应使用 delete 运算符将其释放。释放内存后,内存将返回给操作系统以供其他程序使用。

以下是使用 delete 运算符释放动态分配的内存的示例:

1、释放通过 new 运算符分配的单个对象的内存:

delete pointer;

其中,pointer 是通过 new 运算符分配的指针。

示例:

int* p = new int;
*p = 10;
delete p;  // 释放通过 new 分配的内存

2、释放通过 new[ ] 运算符分配的数组的内存:

delete[] arrayPointer;

其中,arrayPointer 是通过 new[  ] 运算符分配的指针。

示例:

int* arr = new int[5];
arr[0] = 1;
delete[] arr;  // 释放通过 new[] 分配的内存

请注意以下几点:

  1. 使用完动态分配的内存后,务必记得释放内存,以免造成内存泄漏。
  2. 如果使用 new 分配了内存,必须使用 delete 释放;如果使用 new[ ] 分配了数组,必须使用 delete[ ] 释放。
  3. 避免重复释放内存或释放非动态分配的内存,这可能导致未定义行为。
  4. 在动态内存分配失败的情况下,需要进行适当的错误处理,例如捕获 std::bad_alloc 异常或检查指针是否为 nullptr。

使用动态内存分配可以在程序运行时根据需要动态地分配内存。这使得您能够灵活地管理内存资源,但也需要小心使用以避免内存泄漏和其他相关问题。

命名空间

命名空间是 C++ 中的一种机制,用于避免全局作用域中的命名冲突。命名空间定义了一个范围,称为命名空间作用域,在该范围内定义的名称不会与其他命名空间或全局作用域中的名称冲突。

我们举一个计算机系统中的例子,一个文件夹(目录)中可以包含多个文件夹,每个文件夹中不能有相同的文件名,但不同文件夹中的文件可以重名。

定义命名空间

C++ 中可以使用关键字 namespace 来定义命名空间。下面是一个简单的例子:

namespace myNamespace {
    int x;
    void func();
}

void myNamespace::func() {
    // function body
}

在上面的例子中,我们定义了一个名为 myNamespace 的命名空间,并在其中定义了一个整数变量 x 和一个函数 func。请注意,我们需要在定义函数时指定它所属的命名空间。

在使用命名空间中的名称时,可以使用限定符 :: 来指定其所属的命名空间。例如,在另一个命名空间或全局作用域中,您可以通过 myNamespace::x 和 myNamespace::func() 来访问这些名称。

如果您希望使用命名空间中的所有名称,可以使用 using namespace 语句导入该命名空间,例如:

using namespace myNamespace;

int main() {
    x = 10;
    func();
    return 0;
}

请注意,虽然使用命名空间可以避免名称冲突,但在使用 using namespace 语句时,可能会导致意外的命名冲突。为了避免这种情况,最好只在局部作用域中使用 using namespace。

除此之外,C++ 还支持嵌套的命名空间和匿名命名空间等高级特性。嵌套的命名空间可以将多个命名空间嵌套在一起,以创建更具层次结构的命名空间。匿名命名空间是一个没有名称的命名空间,其中定义的名称只能在当前文件中访问。

using 指令

using 指令是 C++ 中的一个关键字,用于引入命名空间中的特定名称或整个命名空间到当前作用域,以便在代码中可以直接使用这些名称而无需使用限定符。

C++ 中有两种形式的 using 指令:using namespace 和 using 声明。

1、using namespace 指令:

using namespace 指令用于引入整个命名空间到当前作用域,使得该命名空间中的所有名称都可以直接使用,而无需使用限定符。该指令通常放在代码文件的开头或函数的开头,示例:

using namespace std;  // 引入 std 命名空间

int main() {
    string name = "John"; // 可以直接使用 std 命名空间中的名称 string
    cout << "Hello, " << name << endl;
    return 0;
}

注意:在使用 using namespace 指令时,应该注意命名空间冲突的问题。如果不同的命名空间中有相同名称的实体,可能会导致命名冲突。为了避免这种情况,最好只在局部作用域中使用 using namespace。

2、using 声明:

using 声明用于引入命名空间中的特定名称到当前作用域,使得这些名称可以直接使用,而无需使用限定符。该指令通常放在函数或作用域的内部,示例:

#include <iostream>

int main() {
    using std::cout; // 引入 std 命名空间中的名称 cout
    using std::endl; // 引入 std 命名空间中的名称 endl

    cout << "Hello, world!" << endl; // 可以直接使用引入的名称
    return 0;
}

使用 using 声明时,只有被声明的名称可以直接使用,其他名称仍需使用限定符。

使用 using 指令可以简化代码书写,并提高代码的可读性。但需要注意的是,在较大的项目中,过多地使用 using 指令可能导致命名冲突的问题或不明确的名称来源,所以在使用时需要谨慎选择使用范围,并遵循良好的编码规范。

不连续的命名空间

在 C++ 中,我们可以通过多个不连续的命名空间定义来创建一个命名空间的内容。这意味着我们可以在同一个命名空间中的不同位置多次定义命名空间的内容,以便将其分隔为多个部分。

下面是一个示例:

namespace myNamespace {
    void func1();  // 第一部分声明

    // 其他代码...

    namespace subNamespace {
        void func2();  // 第二部分声明
    }
}

// 可选的其他代码...

namespace myNamespace {
    void func1() {
        // 第一部分的实现
    }
}

namespace myNamespace::subNamespace {
    void func2() {
        // 第二部分的实现
    }
}

在上面的示例中,我们首先声明了一个命名空间 myNamespace,并在其中分隔了两个部分。第一部分的声明包含了函数 func1 的声明,而第二部分的声明位于命名空间 subNamespace 中,包含了函数 func2 的声明。

然后,在后续的代码中,我们通过不连续的命名空间定义来实现这些函数。在第一个命名空间定义中,我们实现了函数 func1,在第二个命名空间定义中,我们实现了函数 func2。

使用不连续的命名空间定义可以使代码更加模块化和可读性更强。它允许我们将命名空间的内容分散到不同的位置,以便更好地组织和管理代码。但是,需要注意的是,多个命名空间定义之间必须位于同一个命名空间中,否则会导致编译错误。

此外,还可以将不同的命名空间定义放在不同的源文件中,并在需要使用命名空间内容的源文件中进行引用,以进一步分隔代码。

嵌套的命名空间

在 C++ 中,我们可以创建嵌套的命名空间,也就是将一个命名空间定义在另一个命名空间内部。嵌套的命名空间可以帮助我们更好地组织和管理代码,并提供更好的命名空间层次结构。

下面是一个示例:

#include <iostream>

namespace outer {
    void func1();  // 外部命名空间中的函数声明

    namespace inner {
        void func2();  // 内部命名空间中的函数声明
    }
}

// 外部命名空间中的函数实现
void outer::func1() {
    std::cout << "这是外部命名空间。" << std::endl;
}

// 内部命名空间中的函数实现
void outer::inner::func2() {
    std::cout << "这是内部命名空间." << std::endl;
}

int main() {
    // 调用外部命名空间函数
    outer::func1();

    // 调用嵌套命名空间函数
    outer::inner::func2();

    return 0;
}

这段代码定义了一个外部命名空间 outer,并在其中定义了一个嵌套命名空间 inner。在 outer 中,我们声明了一个名为 func1 的函数,在 inner 中,我们声明了一个名为 func2 的函数。然后我们通过限定符分别实现了这两个函数:

  • 在外部命名空间中的函数 func1 的实现中,我们使用命名空间限定符 outer:: 来指明该函数所在的命名空间。
  • 在内部命名空间中的函数 func2 的实现中,我们使用命名空间限定符 outer::inner:: 来指明该函数所在的命名空间。

在 main() 函数中,我们通过命名空间限定符来调用外部命名空间函数 func1() 和嵌套命名空间函数 func2()。

需要注意的是,这两个函数实现位于同一个源文件中。

使用命名空间可以更好地组织和管理代码,并提高代码的可读性和可维护性。嵌套命名空间可以进一步将功能相关的内容进行归类,使得代码的模块化程度更高。

模板

模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。

模板是创建泛型类或函数的蓝图或公式。库容器,比如迭代器和算法,都是泛型编程的例子,它们都使用了模板的概念。

每个容器都有一个单一的定义,比如 向量,我们可以定义许多不同类型的向量,比如 vector <int> 或 vector <string>

您可以使用模板来定义函数和类,接下来让我们一起来看看如何使用。

函数模板

函数模板是一种通用的函数定义,它可以使用不同的数据类型进行实例化。函数模板允许编写一个函数定义,该定义可以接受任何数据类型作为函数的参数或返回值,从而提供了一种通用的算法实现方法。模板函数定义的一般形式如下所示:

template <typename type> ret-type func-name(parameter list)
{
   // 函数的主体
}

在这里,type 是函数所使用的数据类型的占位符名称。这个名称可以在函数定义中使用。 

下面是一个简单的函数模板示例,演示如何在C++中定义和使用函数模板:

#include <iostream>

template <typename T>
T max(T a, T b) {
    return a > b ? a : b;
}

int main() {
    int x = 1, y = 2;
    std::cout << "max(" << x << ", " << y << ") = " << max(x, y) << std::endl;

    double m = 2.0, n = 1.5;
    std::cout << "max(" << m << ", " << n << ") = " << max(m, n) << std::endl;

    return 0;
}

在这个示例中,我们定义了一个函数模板 max,它具有一个类型参数 T。这个函数模板比较两个类型为 T 的参数,并返回它们之间的最大值。

在 main 函数中,我们分别使用了 int 和 double 类型的数据类型来调用 max 函数。通过使用不同的数据类型,我们可以实例化函数模板 max,并生成相应的函数定义。

运行以上代码将输出如下结果:

max(1, 2) = 2
max(2, 1.5) = 2

类模板

类模板是一种通用的类定义,它可以使用不同的数据类型进行实例化。类模板允许编写一个类定义,该定义可以处理不同的数据类型,并提供通用的数据结构和算法。

泛型类声明的一般形式如下所示:

template <class type> class class-name {
.
.
.
}

在这里,type 是占位符类型名称,可以在类被实例化的时候进行指定。您可以使用一个逗号分隔的列表来定义多个泛型数据类型。

以下是一个示例代码,展示了如何定义和使用类模板来实现一个栈(Stack)数据结构:

#include <iostream>

template <class T>
class Stack {
private:
    T* stackArray;
    int top;
    int capacity;

public:
    Stack(int size) : capacity(size), top(-1) {
        stackArray = new T[capacity];
    }

    ~Stack() {
        delete[] stackArray;
    }

    void push(T element) {
        if (top == capacity - 1) {
            std::cout << "堆栈已满。无法推送元素。" << std::endl;
            return;
        }
        stackArray[++top] = element;
    }

    T pop() {
        if (top == -1) {
            std::cout << "堆栈为空。无法弹出元素。" << std::endl;
            return T();
        }
        return stackArray[top--];
    }

    bool isEmpty() const {
        return top == -1;
    }
};

int main() {
    Stack<int> intStack(5);
    intStack.push(1);
    intStack.push(2);
    intStack.push(3);

    std::cout << "Popped: " << intStack.pop() << std::endl;
    std::cout << "Popped: " << intStack.pop() << std::endl;

    Stack<double> doubleStack(3);
    doubleStack.push(1.23);
    doubleStack.push(4.56);

    std::cout << "Popped: " << doubleStack.pop() << std::endl;

    return 0;
}

在这个示例中,我们定义了一个类模板 Stack,它表示一个栈数据结构。通过使用类型参数 T,我们可以在栈中存储任意类型的元素。

在 main 函数中,我们分别实例化了 Stack<int> 和 Stack<double>。通过调用类模板中的方法,我们可以对不同的数据类型进行入栈和出栈操作。

运行以上代码将输出如下结果:

Popped: 3
Popped: 2
Popped: 4.56

这个示例展示了类模板的基本用法。通过使用类模板,我们可以定义通用的数据结构,以处理不同的数据类型。类模板提供了一种灵活和可扩展的方式来操作各种数据类型,并提高代码的复用性和可读性。

C++ 中 typename 和 class 的区别

在 C++ 中,typename 和 class 关键字都可以用来定义类模板中的类型参数,但它们在某些情况下有一些区别。

typename 关键字用于指示后面的名称是一个类型,可以用在类型推导、嵌套依赖类型和模板别名等场景中。例如,以下是一个使用 typename 的示例:

template <typename T>
void printSize(const T& container) {
    typename T::size_type size = container.size();
    std::cout << "Size of container: " << size << std::endl;
}

在这个示例中,我们使用 typename 关键字来指示 T::size_type 是一个类型。T::size_type 是容器类型的一个嵌套类型,表示容器中元素的数量。

class 关键字也可以用来指示一个类型参数,但有时候使用 class 可能会导致歧义或编译错误。例如,以下是一个由于使用了 class 关键字而导致编译错误的示例:

template <typename T>
void foo(typename T::iterator iter) {}

template <class T>
void bar(T t) {
    foo(t.begin());
}

在这个示例中,foo 函数接受一个迭代器类型作为参数。然而,当我们在 bar 函数中调用 foo 时,使用 T::iterator 语法会导致编译器无法确定 iterator 是否为一个类型,因为它也可能是一个静态成员变量。

在这种情况下,我们需要使用 typename 关键字来明确告诉编译器 T::iterator 是一个类型:

template <typename T>
void bar(T t) {
    foo(typename T::iterator(t.begin()));
}

在这个示例中,我们使用了 typename 关键字来说明 T::iterator 是一个类型。这样编译器就不会将其解析为静态成员变量了。

因此,虽然在定义类模板时可以使用 class 或 typename 关键字来指示类型参数,但在某些情况下,使用 typename 更加明确和安全。

函数模板的重载

函数模板的重载是指在同一个作用域内,定义多个具有相同名称但参数类型不同的函数模板。通过函数模板的重载,可以根据不同的参数类型来选择相应的函数模板进行调用。

函数模板的重载遵循以下规则:

  1. 与普通函数一样,函数模板的重载必须在参数数量或参数类型上有所区别。
  2. 当存在多个匹配的函数模板时,编译器使用一套优先级规则来选择最佳匹配的函数模板。
  3. 编译器会尽量选择能够实现精确匹配的函数模板,如果有多个精确匹配的函数模板,则选择最特化的版本。
  4. 如果没有找到完全匹配的函数模板,编译器将尝试进行隐式类型转换来匹配其他函数模板。
  5. 如果存在多个可行的匹配,但没有一个明显的最佳匹配时,编译器将报错。

以下是一个示例,展示了如何在函数模板中进行重载:

#include <iostream>

template <typename T>
void print(const T& value) {
    std::cout << "Generic print: " << value << std::endl;
}

template <typename T>
void print(T* value) {
    std::cout << "Pointer print: " << *value << std::endl;
}

int main() {
    int num = 10;
    print(num);         // 调用第一个重载的 print 函数模板
    print(&num);        // 调用第二个重载的 print 函数模板

    double pi = 3.14159;
    print(pi);          // 调用第一个重载的 print 函数模板

    return 0;
}

在这个示例中,我们定义了两个函数模板 print 的重载版本。第一个重载版本接受一个值类型的参数,而第二个重载版本接受一个指针类型的参数。

在 main 函数中,我们分别调用了相应的函数模板。根据参数的类型,编译器将选择最匹配的函数模板进行调用。

运行以上代码将输出如下结果:

Generic print: 10
Pointer print: 10
Generic print: 3.14159

通过函数模板的重载,我们可以根据不同的参数类型来实现相应的函数逻辑,提高代码的复用性和灵活性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1176415.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

二.ACW154. 滑动窗口详解

窗口滑动: 几行代表for里的语句 1行看队列,例子.空的不执行 2行q[0]1 3行看队列.1>-1不执行 4行看例子例子.窗口不完整 ht1,只看最后一行的总队列q就行1行.2<6不执行,只存越来越大 2行q[1]2,所以q存的下标 3行.i在增加,1>0不执行,新循环了,对头元素滑出窗口 4行窗口不…

使用Python自动修改电脑的静态IP地址

目录 一、引言 二、实现思路 三、详细步骤 四、Python代码 五、注意事项 六、适用性和局限性 七、总结 一、引言 在网络应用中&#xff0c;有时我们需要频繁更改电脑的静态IP地址。例如&#xff0c;当我们在不同网络环境&#xff08;家庭、办公室&#xff09;中使用电脑…

AMEYA360荣获“国际潜力之星分销商”奖!

由全球电子技术领域知名媒体集团ASPENCORE主办的“全球电子元器件分销商卓越表现奖"颁奖典礼于2023年11月3日晚在深圳大中华喜来登酒店圆满结束! 全球电子元器件分销商卓越表现奖创办于2001 年&#xff0c;迄今已成功举办20年&#xff0c;此奖项旨在表彰支持电子产业发展的…

电脑监控软件丨2023全网最详细解析

电脑监控软件是一个比较敏感的话题&#xff0c;因为很多员工会觉得电脑监控侵犯了自己的隐私&#xff0c;电脑上企业会觉得安装软件只不过是为了保护自己的核心利益。 对于此&#xff0c;我们要辩证的看待。 今天我们从企业的角度出发&#xff0c;谈谈电脑监控软件的话题。 必…

【数据结构】 二叉树理论概念!一文了解二叉树!

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; 数据结构解析 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言&#x1f324;️树的概念☁️树的结构☁️树的小知识☁️树的表示与运用 &#x1f324…

Android View 触摸反馈原理浅析

重写OnTouchEvent() 然后在方法内部写触摸算法 返回true,表示消费事件,所有触摸反馈不再生效,返回事件所有权 if (event.actionMasked MotionEvent.ACTION_UP){performClick()//抬起事件 执行performClick 触发点击 }override fun onTouchEvent(event: MotionEvent): Boolea…

办公套件全家桶 Office2019 mac中文版新功能

office 2019 mac是 Microsoft office 应用程序套件的最新版本。它包括流行的软件&#xff0c;例如 Microsoft Word、Excel、PowerPoint 和 Outlook&#xff0c;office 2019 比其前身有许多新功能和改进&#xff0c;包括增强的协作工具、与 OneDrive 和 SharePoint 等云服务的更…

Figma 怎么切图?新手入门教程详解

Figma 是一个基于浏览器的协作的UI设计工具&#xff0c;其以轻量、便捷、跨平台使用、协同便捷的特点&#xff0c;迅速吸引了广大UI/UX 设计师们的喜欢。但是设计师经常遇到反复切图、交付开发等问题&#xff0c;所以借此机会分享一篇关于 Figma 切图的必要知识点和交付经验。 …

基于 VTable 的多维数据展示的原理与实践

多维表格介绍 多维表格又名透视表、交叉表、Pivot Table&#xff0c;指的是可以在行维度和列维度放入一个或多个维度&#xff0c;显示维度之间相互关系的一种表格。用户可以一目了然地分析出各种场景指标以及对比&#xff0c;旨在帮助业务分析推动决策。 假设需要分析如下表格…

微信支付更换证书最详细方法

6、在【商户平台】&#xff0c;输入操作密码&#xff0c;安全验证后生成证书串 7、在【商户平台】&#xff0c;复制证书串 8、在【证书工具】&#xff0c;粘贴证书串&#xff0c;点击下一步&#xff0c;申请证书成功 &#xff08;若提示"证书与本地公私钥不匹配&qu…

window10 定时任务

window10 定时任务 1、背景2、目标3、思路4、实操4.1、设置定时任务4.2、配置策略4.3、验证 1、背景 项目上由于业务调试需要&#xff0c;开具了一台window10系统&#xff0c;此台window10为项目组公共使用&#xff0c;为防止误操作分配了不通的账号&#xff0c;日常使用各自账…

互联网校园洗衣洗鞋小程序;

互联网校园洗衣洗鞋小程序打造哪足不出户&#xff0c;线上下单上门取货&#xff0c;通过它不仅可以让用户快速便捷的找到小程序下单&#xff0c;在手机上准确的下发洗衣命令&#xff0c;还能洗好后提供取衣服务等&#xff0c;因此受到了广泛用户的喜爱。截止目前&#xff0c;软…

山西电力市场日前价格预测【2023-11-06】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-11-06&#xff09;山西电力市场全天平均日前电价为126.17元/MWh。其中&#xff0c;最高日前电价为405.20元/MWh&#xff0c;预计出现在18: 15。最低日前电价为0.00元/MWh&#xff0c;预计出…

深入了解Jedis:Java操作Redis的常见类型数据存储

目录 前言 一、Jedis介绍 1.Jedis在各方面的功能 2.特点 二、Java连接Redis 1.导入pom依赖 2.建立连接 三、Java操作Redis的常见类型数据存储 1.字符串 2.哈希表 3.列表 4.集合 5.有序集合 四、Redis的实际应用场景实例 1.会议信息实体 2.自定义注解 3.创建切面…

应用场景 | 中小河流治理监测系统,提升流域智能感知能力

当前&#xff0c;受全球气候变化和人类活动影响&#xff0c;我国中小河流洪涝灾害呈多发、频发趋势&#xff0c;中小河流洪水已成为严重威胁人民群众生命财产安全的重大风险隐患。中小河流治理作为一项重要的民生水利任务&#xff0c;近十年来国家不断加大以防洪为主的治理投入…

初始JVM虚拟机

JVM组成 图解 程序计数器 在JVM线程私有的内存区域中。每个线程都有自己独立的程序计数器。 程序计数器用于存储当前线程正在执行的字节码指令的地址。指示着当前线程执行到了哪一条字节码指令。 堆 是线程共享的区域&#xff0c;用于存储对象的实例和数组对象&#xff1b; …

使用OkHttp库爬取百度云视频详细步骤

目录 摘要 一、OkHttp库简介 二、爬虫基本概念 三、使用OkHttp库爬取百度云视频 1、发送HTTP请求 2、处理响应 3、下载文件 四、可能遇到的问题及解决方案 五、注意事项 总结与建议 摘要 本文将详细介绍如何使用OkHttp库爬取百度云视频。文章首先简要介绍OkHttp库和…

三国志14信息查询小程序(历史武将信息一览)制作更新过程03-主要页面的设计

1&#xff0c;小程序的默认显示 分为三部分&#xff0c;头部的标题、中间的内容区和底部的标签栏。点击标签可以切换不同页面&#xff0c;这是在app.json文件中配置的。代码如下&#xff1a; //所有用到的页面都需要在 pages 数组中列出&#xff0c;否则小程序可能会出现错误或…

YOLO v2(2016.12)

文章目录 AbstractIntroduction当前存在的困境基于此&#xff0c;我们给出了方法 BetterBatch NormalizationHigh Resolution ClassifierConvolutional With Anchor BoxesDimension ClustersDirect location predictionFine-Grained FeaturesMulti-Scale TrainingFurther Exper…

Python教程:随机函数,开始猜英文单词的游戏

开始猜英文单词的游戏… 总计生命次数&#xff1a;3次 -----------游戏开始中…----------- &#xff1f;&#xff1f;&#xff1f;&#xff1f;请猜一个&#xff0c;4位数的单词:mafr 猜错了&#xff0c;再努力一下 -----------你还有2次生命------------ ma&#xff1f;&…