C++基础入门:掌握核心概念(超全!)

C++作为一门广泛使用的编程语言,以其高性能和灵活性在软件开发领域占据重要地位。无论是游戏开发、系统编程还是实时应用,C++都是一个不可或缺的工具。本博客旨在为初学者提供C++编程语言的核心概念,帮助你建立坚实的基础。

C++关键字

C++关键字是编程语言中预定义的保留词,用于执行特定的编程功能。了解这些关键字是理解C++编程的第一步。例如,intreturnvoidif等,都是执行基础操作的关键字。一个好的起点是熟悉这些关键字及其用法,这有助于你编写更有效的C++代码。

函数重载

为什么 C++ 支持函数重载,而 C 语言不支持函数重载呢?
C/C++ 中,一个程序要运行起来,需要经历以下几个阶段: 预处理、编译、汇编、链接

 

1. 实际项目通常是由多个头文件和多个源文件构成,而通过 C 语言阶段学习的编译链接,我们
可以知道,【当前 a.cpp 中调用了 b.cpp 中定义的 Add 函数时】,编译后链接前, a.o 的目标
文件中没有 Add 的函数地址,因为 Add 是在 b.cpp 中定义的,所以 Add 的地址在 b.o 中。那么
怎么办呢?
2. 所以链接阶段就是专门处理这种问题, 链接器看到 a.o 调用 Add ,但是没有 Add 的地址,就
会到 b.o 的符号表中找 Add 的地址,然后链接到一起 ( 老师要带同学们回顾一下 )
3. 那么链接时,面对 Add 函数,链接接器会使用哪个名字去找呢?这里每个编译器都有自己的
函数名修饰规则。
4. 由于 Windows vs 的修饰规则过于复杂,而 Linux g++ 的修饰规则简单易懂,下面我们使
用了 g++ 演示了这个修饰后的名字。
5. 通过下面我们可以看出 gcc 的函数修饰后名字不变。而 g++ 的函数修饰后变成【 _Z+ 函数长度
+ 函数名 + 类型首字母

 

结论:linux下,采用gcc编译完成后,函数名字的修饰没有发生改变。 

函数重载允许你使用相同的函数名进行不同的操作,前提是它们的参数列表不同。这是一种提高程序可读性和功能性的有效方式。通过函数重载,你可以根据不同的参数类型或数量来执行不同的任务。

函数重载是C++中一种允许多个同名函数共存的特性,只要这些函数的参数列表不同。这意味着重载的函数可以有不同的参数类型、数量或者两者都不同。函数重载使得函数命名更加直观,避免了为每个不同操作版本的函数起不同名字的麻烦。

函数重载的规则

为了成功实现函数重载,需要遵循以下几个规则:

  1. 不同的参数列表:重载的函数必须在参数类型、数量或者两者都不同。仅仅返回类型的不同是不足以重载函数的。
  2. 作用域:只有在相同的作用域内,函数才能被重载。
  3. 调用的明确性:任何函数调用时,编译器都必须能够明确地确定应该使用哪个函数版本,否则将报错。
示例代码

以下是函数重载的一个简单示例,展示了如何根据不同的参数类型和数量来重载函数:

#include <iostream>
using namespace std;

// 打印整数
void print(int i) {
    cout << "Printing int: " << i << endl;
}

// 打印浮点数
void print(double f) {
    cout << "Printing float: " << f << endl;
}

// 打印字符数组
void print(const char* c) {
    cout << "Printing character: " << c << endl;
}

int main() {
    print(5);    // 调用打印整数的函数
    print(500.263); // 调用打印浮点数的函数
    print("Hello C++"); // 调用打印字符数组的函数
    return 0;
}

在这个例子中,print函数被重载三次,每个函数接受不同类型的参数。当print函数被调用时,编译器通过传递给它的参数类型和数量来决定使用哪个版本的函数。

函数重载的好处

  • 提高代码可读性:通过函数重载,可以为执行相似功能的函数使用统一的名称,使得代码更加直观。
  • 增加程序的灵活性:能够根据不同的数据类型或参数数量执行不同的操作,从而使程序更加灵活。
  • 类型安全:与使用泛型编程相比,函数重载提供了一种类型安全的方式来处理不同类型的数据。

注意事项

  • 避免歧义:确保重载的函数之间在调用时能够被编译器明确区分,否则会导致编译错误。
  • 不要仅依赖于返回类型:由于函数调用时不考虑返回类型,因此不能仅通过返回类型来重载函数。
  • 使用默认参数时的额外注意:函数重载与默认参数同时使用时要特别小心,以避免调用时的歧义。

 

 

命名空间

命名空间是C++中用于解决名称冲突的一种机制。最常见的命名空间是std,它包含了标准库的所有功能。通过使用using namespace std;声明,你可以避免在调用标准库函数时重复使用std::前缀。理解并正确使用命名空间,对于编写组织良好的代码非常重要。

命名空间的声明和使用

命名空间通过namespace关键字声明,其基本语法如下:

namespace NamespaceName {
    // code declarations
}

 例如,可以创建一个名为myNamespace的命名空间,其中包含一个函数和一个变量:

namespace myNamespace {
    void myFunction() {
        std::cout << "Inside myNamespace" << std::endl;
    }
    int myVariable = 42;
}

为了使用命名空间中的成员,你需要使用作用域解析运算符::来指定成员所属的命名空间,如下所示: 

myNamespace::myFunction();
std::cout << myNamespace::myVariable << std::endl;

 

using namespace myNamespace;
myFunction(); // 直接调用,不需要前缀

使用using声明

如果你不希望每次调用命名空间中的成员时都输入完整的命名空间,可以使用using声明。这可以让你在特定范围内不必使用命名空间前缀,直接访问其中的成员。例如:

 

using namespace myNamespace;
myFunction(); // 直接调用,不需要前缀

 需要注意的是,滥用using声明可能会导致命名冲突,特别是当两个命名空间包含同名的成员时。因此,推荐仅在确信不会引发冲突的情况下使用using声明,或者只针对特定的命名空间成员使用using指令,如:

using myNamespace::myFunction;
myFunction(); // 直接调用myFunction,但其它myNamespace成员仍需前缀

命名空间的嵌套

C++允许命名空间的嵌套使用,即在一个命名空间内部定义另一个命名空间。这种结构有助于进一步组织和封装代码,例如:

 

namespace outer {
    int x = 10;
    namespace inner {
        void display() {
            std::cout << "Value: " << x << std::endl; // 访问外部命名空间的x
        }
    }
}

 在这个例子中,inner命名空间嵌套在outer命名空间内部。要访问inner命名空间中的display函数,可以使用:

outer::inner::display();

无名(匿名)命名空间

无名(或匿名)命名空间是一个特殊的命名空间,它不具有名称。在同一翻译单元(通常是一个源文件)中,无名命名空间的成员可以直接访问,就好像它们被声明在全局作用域一样,但在其他翻译单元中不可见。这提供了一种限制访问范围的方法,用于替代静态全局变量:

namespace {
    void privateFunction() {
        std::cout << "This is a private function." << std::endl;
    }
}
// 在同一源文件中可以直接调用
privateFunction();

 

C++输入&输出

C++使用cincout来处理标准输入输出,它们分别用于从键盘读取输入和向屏幕输出文本。掌握这些基本的I/O操作对于与用户交互的程序来说至关重要。例如,使用cout << "Hello, World!" << endl;可以在屏幕上打印一条消息。

C++标准库中的输入和输出操作主要通过iostream库实现,它包括用于输入的cin、用于输出的cout、用于处理错误输出的cerr,以及用于日志输出的clog对象。

基础的输入输出

  • 输出cout用于向标准输出设备(通常是终端或屏幕)输出数据。使用插入操作符<<cout传递数据。
  • 输入cin用于从标准输入设备(通常是键盘)读取数据。使用提取操作符>>cin接收数据。
  • 示例代码
    #include <iostream>
    
    int main() {
        int number;
        std::cout << "Enter an integer: ";
        std::cin >> number;
        std::cout << "You entered " << number << std::endl;
        return 0;
    }
    

    这段代码演示了如何从用户那里获取一个整数并打印出来

格式化输出

C++提供了多种方式来格式化输出,例如设置宽度、填充字符和精度等。

设置宽度和填充 

使用setw来设置下一个输出项的最小宽度,setfill来设置用于填充额外空间的字符。

 

#include <iostream>
#include <iomanip> // For setw and setfill

int main() {
    std::cout << std::setw(10) << std::setfill('*') << 123 << std::endl;
    return 0;
}

输出:*******123

设置精度

使用setprecision来设置浮点数的输出精度。

 

#include <iostream>
#include <iomanip> // For setprecision

int main() {
    double pi = 3.14159;
    std::cout << std::setprecision(4) << pi << std::endl;
    return 0;
}

 输出:3.142

处理文件输入输出

C++使用fstream库中的ifstream(输入文件流)和ofstream(输出文件流)来处理文件输入输出。

文件写入示例
#include <fstream>
#include <iostream>

int main() {
    std::ofstream file("example.txt");
    if (file.is_open()) {
        file << "Hello, file IO!" << std::endl;
        file.close();
    } else {
        std::cout << "Unable to open file";
    }
    return 0;
}

 文件读取示例

#include <fstream>
#include <iostream>
#include <string>

int main() {
    std::ifstream file("example.txt");
    std::string line;
    if (file.is_open()) {
        while (getline(file, line)) {
            std::cout << line << '\n';
        }
        file.close();
    } else {
        std::cout << "Unable to open file";
    }
    return 0;
}

这些例子展示了如何写入和读取文件。在处理文件时,总是检查文件是否成功打开,以及在操作完成后关闭文件是一个好习惯。 

缺省参数

缺省参数允许你在函数声明时指定默认值。这意味着在调用函数时,如果没有提供足够的参数,C++会自动使用这些默认值。这使得函数调用更加灵活,同时减少了代码的冗余。

缺省参数(也称为默认参数)是C++函数定义中的一项特性,它允许函数调用时省略某些参数。如果调用函数时没有提供足够的实参,C++编译器会自动使用定义函数时指定的默认值来填充缺失的参数。这一特性可以使函数调用更加灵活,减少重载函数的需要,同时也让代码更简洁。

使用缺省参数的规则和示例

缺省参数的设置非常简单,只需在函数声明或定义时,为参数指定一个默认值即可。但是,有几个规则需要遵守:

  1. 缺省参数从右向左:如果函数的某个参数有默认值,那么它右边的所有参数也必须有默认值。
  2. 声明与定义:如果函数在头文件中声明,在源文件中定义,那么缺省参数应该在声明时给出,而在定义时则不应重复。
  3. 调用时省略参数:调用函数时,可以省略具有默认值的参数,但是必须从最右边的参数开始省略。
示例代码

考虑以下函数,它用于显示一条消息,并可以指定消息前的空格数和是否换行。

#include <iostream>
using namespace std;

void displayMessage(string message, int indent = 0, bool newline = true) {
    for (int i = 0; i < indent; ++i) {
        cout << " ";
    }
    cout << message;
    if (newline) cout << endl;
}

int main() {
    displayMessage("Hello, World!"); // 使用默认参数
    displayMessage("Hello, C++!", 5); // 指定缩进,使用默认的换行参数
    displayMessage("Welcome to programming!", 0, false); // 指定所有参数
    return 0;
}

在这个例子中,displayMessage函数有两个缺省参数:indentnewline。这使得函数调用非常灵活,你可以只提供必要的参数。

缺省参数的好处与限制

好处

  • 减少函数重载数量:通过为参数提供默认值,可以减少需要编写的函数重载数量,使代码更加简洁。
  • 提高函数调用的灵活性:函数调用者可以根据需要提供不同数量的参数。

限制

  • 可能影响代码清晰度:使用缺省参数时,函数的调用可能不那么直观,尤其是当函数有多个参数时,理解每个参数的默认值可能需要查看函数定义。
  • 与函数重载的潜在冲突:如果函数重载与缺省参数结合使用不当,可能会导致调用模糊不清,编译器可能无法确定调用哪个函数版本。

最佳实践

  • 当函数的某些参数大多数情况下都是相同的值时,考虑使用缺省参数。
  • 在设计接口时,仔细考虑哪些参数是真正需要由调用者指定的,哪些可以有合理的默认值。
  • 保持缺省参数的简单性,避免使用复杂的表达式作为默认值。
  • 明确文档化每个参数的默认值,确保函数的使用者能够清楚地理解每个参数的作用和默认行为。

缺省参数是C++提供的一个强大工具,它在简化函数调用和减少代码重复方面非常有用。合理使用缺省参数可以使你的C++代码更加简洁和灵活,但同时也需要注意避免上述提到的潜在陷阱。

 

引用

在C++中,引用是一种复合类型,它允许你创建一个别名,即对另一个变量的引用。引用在传递大型数据结构给函数或返回函数结果时特别有用,因为它们可以避免数据的复制,从而提高效率。

引用在C++中是一个非常强大的特性,它为变量创建了一个别名。通过使用引用,可以创建一个新的名字来代表某个已存在的变量。引用主要用于函数参数传递和返回值,它们使得函数能够直接操作实参,而不是操作其副本。这不仅提高了效率,因为避免了不必要的对象复制,还允许函数修改传递给它的参数。

引用的基本概念

  • 声明引用:声明引用时,需要在类型后面加上&符号和引用的名称。例如,int& ref = x;声明了一个对整数x的引用。
  • 初始化引用:引用必须在声明时被初始化,并且一旦被初始化后,就不能改变引用的目标。这意味着引用一旦绑定到一个变量上,就会一直代表那个变量,不能被重新赋值为其他变量的引用。
  • 引用与指针:引用在某种意义上类似于指针,但是它们更安全、更易于使用。引用总是指向一个有效的内存地址,而且不需要使用解引用操作符*来访问目标变量。

使用引用的场景

  1. 函数参数传递:通过将函数参数声明为引用类型,可以允许函数内部的操作影响到实参。这对于数据结构如字符串和大型对象尤其有用,因为它避免了复制的开销。
  2. 函数返回值:函数可以返回一个引用,这样可以允许函数调用作为左值使用。但是要小心不要返回局部变量的引用,因为局部变量在函数返回后会被销毁。
  3. 范围for循环:在基于范围的for循环中使用引用,可以直接修改容器中的元素。
示例代码
引用作为函数参数
#include <iostream>
using namespace std;

void swap(int& a, int& b) {
    int temp = a;
    a = b;
    b = temp;
}

int main() {
    int x = 10, y = 20;
    swap(x, y);
    cout << "x: " << x << " y: " << y << endl; // 输出:x: 20 y: 10
    return 0;
}

 返回引用

#include <vector>
#include <iostream>
using namespace std;

int& getElement(vector<int>& v, int index) {
    return v[index];
}

int main() {
    vector<int> vec = {1, 2, 3};
    getElement(vec, 1) = 4; // 修改vec中索引为1的元素
    cout << vec[1] << endl; // 输出:4
    return 0;
}

注意事项

  • 避免返回局部变量的引用。
  • 使用引用时,确保引用的对象在引用的生命周期内是有效的。
  • 引用一旦被初始化后,就不能再绑定到另一个对象上。

 

【面试题】

宏的优缺点?
优点:
1. 增强代码的复用性。
2. 提高性能。
缺点:
1. 不方便调试宏。(因为预编译阶段进行了替换)
2. 导致代码可读性差,可维护性差,容易误用。
3. 没有类型安全的检查 。
C++ 有哪些技术替代宏
1. 常量定义 换用 const enum
2. 短小函数定义 换用内联函数

内联函数

内联函数是一种优化技术,它通过在编译时将函数体插入到每个调用点,来减少函数调用的开销。对于小而频繁调用的函数,使用内联函数可以提高程序的执行速度。

内联函数是C++提供的一种特性,旨在减少函数调用时的开销。当函数被声明为内联时,编译器会尝试将函数调用处替换为函数本身的代码。这意味着在每个调用点,编译器会将整个函数体插入,从而避免了函数调用的成本,如参数传递、控制权转移和返回值处理等。内联函数特别适用于代码体积小、调用频繁的函数。

使用内联函数的优势

  1. 性能提升:避免了函数调用的开销,对于小型函数,尤其是在循环中频繁调用的情况下,可以显著提高程序的执行速度。
  2. 代码优化:编译器可以对内联函数进行更多优化,因为函数体直接嵌入到调用处,编译器有更大的自由度来优化这些代码,比如消除临时变量、合并计算等。

如何声明内联函数

内联函数通过在函数声明前加上inline关键字来指定。例如:

inline int max(int a, int b) {
    return a > b ? a : b;
}

注意事项和限制

  • 编译器的自由度:声明一个函数为内联并不意味着编译器一定会内联该函数。编译器会根据函数的复杂性、调用的上下文以及特定的编译器优化设置来决定是否内联。
  • 代码膨胀:过度使用内联函数可能导致二进制文件体积的增加,因为每个调用点都会插入完整的函数体。这可能导致缓存命中率降低,反而降低程序的整体性能。
  • 适用场景:一般而言,只有当函数体较小(如只有几行代码)、调用频繁且执行时间短于函数调用开销时,将函数声明为内联才是有意义的。
  • 递归函数:递归函数通常不适合声明为内联,因为递归调用自身会导致大量的代码膨胀。
  • 虚函数:虚函数也可以被声明为内联,但内联是在编译时决定的,而虚函数的动态绑定则是在运行时进行的。如果虚函数在编译时可以确定调用哪个函数,则它可以被内联;否则,即使声明为内联,也只能按照普通虚函数调用来处理。

示例:内联函数与普通函数的比较

假设有一个计算平方的简单函数:

// 普通函数
int square(int x) {
    return x * x;
}

// 内联函数
inline int squareInline(int x) {
    return x * x;
}

 在编译时,对squareInline的每个调用都有可能被替换为x * x,而对square的调用则保留为函数调用。这种差异在循环或频繁调用的情况下可能会导致显著的性能差异。

auto关键字

C++11引入的auto关键字允许自动类型推导,使得编码更加简洁。使用auto可以避免复杂类型的显式声明,让编译器自动为变量推断出最合适的类型。

auto关键字在C++11及其后续版本中引入,标志着类型推导的一个重要步骤。它允许编译器自动推导变量的类型,基于变量初始化时赋予的表达式。这不仅可以简化代码,减少编写的类型声明,还能增强代码的可读性和可维护性,特别是在处理复杂类型(如STL容器的迭代器)时。

auto关键字的优点

  1. 简化类型声明:当变量类型显而易见时,使用auto可以避免冗长的类型名称,使代码更加简洁。
  2. 提高可维护性:如果表达式类型更改,auto可以自动更新变量类型,减少必须手动更改的地方。
  3. 增强代码的通用性:使用auto可以编写与类型无关的代码,特别是在模板编程和使用lambda表达式时更加明显。

使用auto的场景

  • 局部变量初始化:最常用于局部变量的初始化,特别是当右侧表达式的类型复杂或难以直接表达时。

    auto x = 5; // x 被推导为 int
    auto pi = 3.14159; // pi 被推导为 double
    

    迭代器和Lambda表达式:在使用STL容器时,迭代器类型经常使用auto来简化

    std::vector<int> vec = {1, 2, 3, 4};
    auto it = vec.begin(); // 自动推导为 std::vector<int>::iterator
    

    范围基于的循环:在C++11中引入的范围基于的循环中使用auto,可以使代码更加清晰

    for (auto& value : vec) {
        std::cout << value << std::endl;
    }
    

    函数返回类型推导:C++14扩展了auto的使用,允许用于函数返回类型的推导。

    auto sum(int x, int y) -> int {
        return x + y;
    }
    

    注意事项

  • 初始化必须:使用auto声明的变量必须在声明时初始化,因为编译器需要初始化表达式来推导类型。

  • 顶层const和引用auto会忽略掉初始化表达式的顶层const,但底层const会被保留。如果需要顶层const或引用,需要显式指定。

    const auto x = 5; // x 是一个 const int
    auto& y = x; // y 是对 const int 的引用
    

    不可用于函数参数auto不能用作函数参数类型,这种情况下仍需明确指定参数类型或使用模板。

基于范围的for循环

基于范围的for循环是C++11标准引入的一项特性,它提供了一种更简洁、更安全的方式来遍历容器(如数组、向量等)或任何序列范围。这种循环方式自动迭代容器或范围的所有元素,无需手动管理迭代器或索引,从而减少了编码错误的可能性并提高了代码的可读性。

基本语法

基于范围的for循环的基本语法如下:

for (declaration : range) {
    // loop body
}

 

其中,declaration声明了一个变量,该变量将被用来访问序列中的每个元素。range是要迭代的序列或容器。

示例

假设有一个整数数组,要遍历数组中的每个元素:

int arr[] = {1, 2, 3, 4, 5};
for (int elem : arr) {
    std::cout << elem << std::endl;
}

使用auto

在基于范围的for循环中,可以使用auto关键字来自动推导元素的类型,这样做可以简化代码并提高其适应性

for (auto elem : vec) {
    std::cout << elem << std::endl;
}

 

修改容器元素

如果想要在循环中修改容器中的元素,需要在循环变量声明中使用引用(&):

for (auto& elem : vec) {
    elem *= 2; // Doubles the value of each element in the vector
}

 

避免不必要的复制

对于包含大型对象的容器,为了避免在每次迭代时复制对象,应该使用引用来遍历元素,特别是当不需要修改元素时,应使用常量引用:

for (const auto& elem : vec) {
    std::cout << elem << std::endl;
}

优点和局限

  • 优点

    • 简化了遍历容器和序列的语法。
    • 减少了与迭代器和索引管理相关的错误。
    • 自动推导元素类型,使代码更简洁。
  • 局限

    • 不适用于需要访问当前迭代元素索引的场景。
    • 当需要在循环中删除或插入元素时,可能不是最佳选择,因为这可能需要直接访问容器的迭代器。

 

结语

C++是一门功能强大的编程语言,拥有广泛的应用领域。通过掌握上述核心概念,你已经迈出了成为C++程序员的第一步。记住,学习编程是一个逐步探索和不断实践的过程。不断练习,寻找资源,并尝试自己编写代码,你将会发现C++的强大之处。祝你旅途愉快!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

扫拖一体洗地机哪个好用?热门扫拖一体机品牌

扫拖一体洗地机是一种现代化的清洁设备&#xff0c;它可以帮助我们更快、更有效地清洁地面。这几年市面上的主流品牌纷纷更新迭代产品&#xff0c;那么&#xff0c;选择什么品牌的洗地机才是算是一个不错的选择呢&#xff1f;我们先了解下洗地机吧。 洗地机的功能与原理 市面…

编码、理解和实现LLM中的自注意力、多头注意力、交叉注意力和因果注意力

原文链接&#xff1a;understanding-and-coding-self-attention 2024年1月14日 自注意力是 LLM 的一大核心组件。对大模型及相关应用开发者来说&#xff0c;理解自注意力非常重要。近日&#xff0c;Ahead of AI 杂志运营者、机器学习和 AI 研究者 Sebastian Raschka 发布了一篇…

三天翻倍!ARM 被炒成“英伟达第二”?

周一&#xff0c;Arm股价再度大涨29%&#xff0c;盘中涨幅一度超过40%&#xff0c;单日交易量是过去三个月日均交易量的十倍以上&#xff0c;创下历史新高。自2月7日市场收盘后Arm公布财报以来&#xff0c;短短三个交易日内&#xff0c;Arm股价累计上涨超过90%。 上周&#xf…

前端JavaScript篇之await 在等待什么呢?async/await 如何捕获异常

目录 await 在等待什么呢&#xff1f;async/await 如何捕获异常 await 在等待什么呢&#xff1f; await 关键字实际上是等待一个表达式的结果&#xff0c;这个表达式的计算结果可以是 Promise 对象或者其他值。如果 await 后面的表达式不是 Promise 对象&#xff0c;那么 awai…

论文阅读-Pegasus:通过网络内一致性目录容忍分布式存储中的偏斜工作负载

论文名称&#xff1a;Pegasus: Tolerating Skewed Workloads in Distributed Storage with In-Network Coherence Directories 摘要 高性能分布式存储系统面临着由于偏斜和动态工作负载引起的负载不平衡的挑战。本文介绍了Pegasus&#xff0c;这是一个利用新一代可编程交换机…

CTFshow web(php命令执行 68-71)

web68 还是那句话&#xff0c;没看到flag在哪&#xff0c;那就优先找到flag位置 这里cvar_dump(scandir("/")); 直接输出根目录的位置&#xff0c;然后查看源代码&#xff0c;发现flag位置为flag.txt 知道flag在根目录下面的flag.txt直接访问就好了 cinclude(/flag…

【开源】JAVA+Vue.js实现农村物流配送系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统登录、注册界面2.2 系统功能2.2.1 快递信息管理&#xff1a;2.2.2 位置信息管理&#xff1a;2.2.3 配送人员分配&#xff1a;2.2.4 路线规划&#xff1a;2.2.5 个人中心&#xff1a;2.2.6 退换快递处理&#xff1a;…

Zig、C、Rust的Pk1

Zig、C、Rust的Pk1 github.com上看到“A basic comparitive analysis of C, C, Rust, and Zig.”&#xff1a;https://github.com/CoalNova/BasicCompare/tree/main 里边的代码是9个月之前的&#xff0c;用现在的zig 0.11.0 及0.12-dev都无法通过编译(具体为&#xff1a;zig-w…

快速搭建PyTorch环境:Miniconda一步到位

快速搭建PyTorch环境&#xff1a;Miniconda一步到位 &#x1f335;文章目录&#x1f335; &#x1f333;一、为何选择Miniconda搭建PyTorch环境&#xff1f;&#x1f333;&#x1f333;二、Miniconda安装指南&#xff1a;轻松上手&#x1f333;&#x1f333;三、PyTorch与Minic…

langchain==win11搭建使用GPU

annaconda安装Python 3.11.7 下载代码&#xff1a; GitHub - chatchat-space/Langchain-Chatchat: Langchain-Chatchat&#xff08;原Langchain-ChatGLM&#xff09;基于 Langchain 与 ChatGLM 等语言模型的本地知识库问答 | Langchain-Chatchat (formerly langchain-ChatGLM)…

适用于Android 的 7 大短信恢复应用程序

对于 Android 用户来说&#xff0c;丢失重要的短信可能是一种令人沮丧的体验。幸运的是&#xff0c;有许多短信恢复应用程序可以帮助恢复丢失或删除的短信。在本文中&#xff0c;将与您分享 7 个最佳短信恢复应用程序&#xff0c;并帮助您找到可用于恢复已删除消息的最佳应用程…

医院排队叫号系统的设计与实践

随着医疗服务需求的增加&#xff0c;医院排队叫号系统成为了现代医院管理的必备工具。它不仅可以提高医院服务效率&#xff0c;减少患者等待时间&#xff0c;还可以优化医院资源利用&#xff0c;提升患者就诊体验。本文将介绍医院排队叫号系统的设计与实践&#xff0c;包括系统…

2.13学习总结

1.出差&#xff08;Bleeman—ford&#xff09;&#xff08;spfa&#xff09; &#xff08;dijkstra&#xff09; 2.最小生成树&#xff08;prim&#xff09;&#xff08;Kruskal&#xff09; 最短路问题&#xff1a; 出差https://www.luogu.com.cn/problem/P8802 题目描述 AA …

MySQL:常用指令

MySQL官网 一、在Windows 系统 cmd窗口里执行的命令 启动:net start MySQL停止:net stop MySQL卸载:sc delete MySQL 二、在macOS系统终端里执行的命令 启动&#xff1a;mysql.server start停止&#xff1a;mysql.server stop重启&#xff1a;mysql.server restart 三、执行帮…

多尺度神经网络新一代创新!精度与速度完美平衡,实现多领域应用落地

多尺度神经网络的设计通常基于对频率原则的理解&#xff0c;目的是为了解决高频成分学习慢的问题。这些网络通过特殊设计&#xff0c;比如给高频成分加更多的权重或者将高频成分平移到低频&#xff0c;来提高学习效率。 为了满足在不同层次上理解和处理数据的需求&#xff0c;…

JS游戏项目合集【附源码】

文章目录 一&#xff1a;迷宫小游戏二&#xff1a;俄罗斯方块三&#xff1a;压扁小鸟 一&#xff1a;迷宫小游戏 【迷宫游戏】是一款基于HTML5技术开发的游戏&#xff0c;玩法简单。玩家需要在一个迷宫中找到出口并成功逃脱&#xff0c;本项目还有自动寻路&#xff08;Track&a…

【开源】JAVA+Vue.js实现城市桥梁道路管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询城市桥梁4.2 新增城市桥梁4.3 编辑城市桥梁4.4 删除城市桥梁4.5 查询单个城市桥梁 五、免责说明 一、摘要 1.1 项目介绍 基于VueSpringBootMySQL的城市桥梁道路管理系统&#xff0c;支持…

Netty应用(九) 之 编解码器概念 Netty常见的编解码器

目录 22.编解码器 22.1 编解码的概念 22.2 netty中的编解码 22.3 序列化 23.编解码器在使用过程中的两部分核心内容 23.1 序列化协议&#xff08;编码格式&#xff09;&#xff08;传输数据的格式&#xff09; 23.1.1 Java默认的序列化与反序列化 23.1.2 XML的序列化与反…

比特币突破5万美元,2年来首次

作者&#xff1a;秦晋 2月13日凌晨&#xff0c;时隔两年&#xff0c;比特币首次突破50000美元关口。最高触及50363美元、24小时涨幅3.53%。创下2021年12月以来的新高。 据《财富》报道&#xff0c;本次上涨得益于三方面&#xff0c;首先是比特币ETF资金流入&#xff0c;比特币E…

docker 2:安装

docker 2&#xff1a;安装 ‍ ubuntu 安装 docker sudo apt install docker.io‍ 把当前用户放进 docker 用户组&#xff0c;避免每次运行 docker 命都要使用 sudo​ 或者 root​ 权限。 sudo usermod -aG docker $USER​id $USER ​看到用户已加入 docker 组 ​​ ‍ …