C++指针(二)

个人主页:PingdiGuo_guo

收录专栏:C++干货专栏

文章目录

1.数组指针

1.1数组指针的概念

1.2数组指针的用处

1.3数组指针的操作

1.4二维数组如何访问

1.5数组指针访问流程

1.6数组指针的练习题

2.指针数组

2.1指针数组的概念

2.2指针数组的用处

2.3指针数组的操作

2.4指针二维数组

2.4指针数组的练习题

3.对比

总结


1.数组指针

在C++指针(一)中,我们知道指针是用来存放地址的,普通的指针只是用来存放一个变量的地址的,可想要存储一个数组的地址呢?接下来就要请出我们的新朋友:数组指针。

1.1数组指针的概念

数组指针是指向数组的指针。它指向数组的第一个元素的地址,通过递增指针的值可以访问数组中的其他元素。数组指针可以帮助程序员更灵活地操作数组,尤其是在需要传递数组作为参数或返回数组的函数中。

1.2数组指针的用处

数组指针有很多用途,以下是其中一些常见的用途:

1.遍历数组:通过指针运算,可以使用数组指针遍历整个数组,访问数组中的每个元素。

2.传递数组给函数:可以使用数组指针作为函数参数,将整个数组传递给函数。这样可以避免在函数中复制整个数组,提高程序的效率。

3.动态分配内存:可以使用数组指针来动态分配内存,创建动态数组。通过指针操作可以方便地访问和修改动态数组中的元素。

4.二维数组访问:对于二维数组,可以使用数组指针来访问和操作多维数组中的元素。

5.字符串操作:字符串在C语言中本质上是一个字符数组,可以使用数组指针来操作和处理字符串。

6.数组的排序和搜索:使用数组指针可以方便地对数组进行排序和搜索操作,以实现快速的查找和排序算法。

1.3数组指针的操作

数组指针存储一个数组的地址的步骤如下:

1. 首先,定义一个数组类型的指针变量。

int *ptr

2. 然后,将数组的首地址赋值给指针变量。有两种方法可以实现这一点:

a. 使用数组名来给指针变量赋值,因为数组名本身就是数组的首地址。具体代码如下所示:

int arr[6]={0,1,2,3,4,5};
ptr = arr;

b. 使用取地址运算符&来获取数组的首地址,并将其赋值给指针变量。具体代码如下所示:

int arr[6]={0,1,2,3,4,5};
ptr = &arr[0];

4.现在,指针变量ptr就存储了数组arr的首地址。我们可以通过该指针变量来访问数组中的元素。例如,可以使用*ptr来访问第一个元素,*(ptr + 1)来访问第二个元素,依此类推。当然,我们也可以用ptr[i]的形式来访问数组元素,这里,我们先学习比较常见的*(ptr+i)的方法。具体代码如下所示:

for (int i = 0; i < 6; i++) {
        cout << *(ptr + i) << " "; // 通过指针变量访问数组元素
    }

运行结果:

数组名为地址:

用取地址符:

5.数组数组的累加操作:首先定义一个整型数组arr,然后将数组的首地址赋值给指针ptr。接下来,使用一个循环和一个累加变量sum以及*(ptr + i)来累加数组中的元素。最后,输出结果。下面是一个示例代码:


 

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int* ptr = arr;  // 将数组的首地址赋值给指针

    int sum = 0;
    for (int i = 0; i < 5; i++) {
        sum += *(ptr + i);  // 使用指针加法操作来访问数组中的元素
    }

    cout << "Sum: " << sum << endl;

    return 0;
}

请注意,使用指针加法操作访问数组元素时,需要确保指针的有效性和数组的边界。不要越界访问数组元素,否则会导致未定义的行为。

6.数组指针插入操作:

1. 创建一个新的数组,长度比原数组大1;
2. 将要插入位置之前的元素复制到新数组中;
3. 插入新元素到指定位置;
4. 将原数组指定位置之后的元素复制到新数组中;
5. 释放原数组的内存;
6. 将新数组的地址赋值给原数组指针。

代码示例:
 



#include <iostream>

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    int size = 5;
    int r = 2, p = 10;

    // 创建新的数组,长度比原数组大1
    int *newArr = new int[size + 1];

    // 将要插入位置之前的元素复制到新数组中
    for (int i = 0; i < r; i++) {
        newArr[i] = arr[i];
    }

    // 插入新元素到指定位置
    newArr[r] = p;

    // 将原数组指定位置之后的元素复制到新数组中
    for (int i = r; i < size; i++) {
        newArr[i + 1] = arr[i];
    }

    // 输出新数组
    std::cout << "新数组:";
    for (int i = 0; i < size + 1; i++) {
        std::cout << newArr[i] << " ";
    }
    std::cout << std::endl;

    // 释放原数组的内存
    delete[] arr;

    // 将新数组的地址赋值给原数组指针
     newArr = arr;

    std::cout<<"地址:"<<newArr<<std::endl;
    return 0;
}

在上述代码中,我们通过动态内存分配创建了一个新的数组,然后将原数组的元素复制到新数组中,并在指定位置插入新的元素。最后释放原数组的内存,将新数组的地址赋值给原数组指针。这样就实现了数组中元素的插入操作。

1.4二维数组如何访问

以下是使用数组指针访问二维数组的步骤和示例代码:

步骤:

1. 声明一个二维数组,并初始化。
2. 声明一个指向二维数组的指针变量。
3. 将指针变量指向二维数组的首地址。
4. 使用指针变量访问二维数组的元素。

示例代码:

 

#include <iostream>

int main() {
    // 声明并初始化二维数组
    int matrix[3][3] = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };

    // 声明指向二维数组的指针变量,并将其指向二维数组的首地址
    int (*ptr)[3] = matrix;

    // 使用指针变量访问二维数组的元素
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            std::cout << ptr[i][j] << " ";
        }
        std::cout << std::endl;
    }

    return 0;
}

运行结果:

1.5数组指针访问流程

数组指针访问的流程就是先指向指针头部,再遍历访问数组元素。如下:

其中,下标也可替换为数组元素。

1.6数组指针的练习题

题目:

给定一个整型数组arr和数组的长度size,编写一个函数将数组中的元素按照升序排列。

步骤:
1. 创建一个函数,命名为sortArray。函数参数包括一个整型数组指针arr和一个整型变量size。
2. 使用冒泡排序算法对数组进行排序。冒泡排序的原理是通过比较相邻的元素并交换位置来进行排序。
3. 在排序过程中,需要两层循环。外层循环控制排序的轮数,内层循环用来比较和交换元素。
4. 内层循环的条件是从0到size-1进行遍历,每次比较arr[j]和arr[j+1]的大小,如果arr[j]大于arr[j+1],则交换两个元素的位置。
5. 在外层循环结束后,数组的元素将按照升序排列。
6. 在main函数中创建一个整型数组并初始化,调用sortArray函数进行排序,然后输出排序后的数组。

知识点:
1. 数组指针
2. 冒泡排序算法
3. 循环控制结构

流程图式:

代码示例:
 

#include <iostream>

void sortArray(int* arr, int size) {
    for (int i = 0; i < size - 1; i++) {
        for (int j = 0; j < size - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

int main() {
    int arr[] = {5, 3, 8, 2, 1};
    int size = sizeof(arr) / sizeof(arr[0]);

    std::cout << "排序前的数组:";
    for (int i = 0; i < size; i++) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;

    sortArray(arr, size);

    std::cout << "排序后的数组:";
    for (int i = 0; i < size; i++) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;

    return 0;
}

运行结果:

题目:
请编写一个程序,实现以下功能:

1. 创建一个包含10个整数的数组,并将其初始化为{1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
2. 使用指针操作数组元素,找到数组中最大的元素,并输出其值和索引。

步骤:

1.创建一个包含10个整数的数组,并将其初始化为{1, 3, 5, 7, 9, 2, 4, 6, 8, 10}。

2.声明一个指针变量ptr,并将其指向数组的首地址,即第一个元素。

3.声明一个变量max,并将其初始化为数组的第一个元素。

4.声明一个变量index,并将其初始化为0。

5.使用for循环从数组的第二个元素开始遍历数组。

6.在循环中,使用指针算术运算访问数组元素,并将其与max进行比较。

7.如果当前元素大于max,则将max更新为当前元素,并将index更新为当前元素的索引。

8.循环结束后,max将存储数组中最大的元素,index将存储最大元素的索引。

9.输出max和index的值。

10.程序结束。

知识点:

数组指针,指针算术运算。

流程图式:
 

代码示例:

 

#include <iostream>

int main() {
    int arr[10] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
    int *ptr = arr; // 数组指针指向数组的第一个元素

    int max = *ptr; // 假设第一个元素为最大值
    int index = 0; // 最大值的索引

    // 使用指针遍历数组,找到最大值及其索引
    for (int i = 1; i < 10; i++) {
        if (*(ptr + i) > max) {
            max = *(ptr + i);
            index = i;
        }
    }

    // 输出最大值及其索引
    std::cout << "数组中最大的元素为:" << max << std::endl;
    std::cout << "其索引为:" << index << std::endl;

    return 0;
}

运行结果图:

2.指针数组

那有没有每一个元素都是指针的数组呢?当然也有啦,接下来要讲的指针数组就是。

2.1指针数组的概念

指针数组是指一个数组中的每个元素都是指针的数组。每个元素都指向不同的内存地址,可以在内存中找到实际的数据。

2.2指针数组的用处

指针数组有很多使用场景,以下是一些常见的用途:

1. 字符串数组:指针数组可以用来存储多个字符串,每个字符串都是一个指针,指向不同的字符串常量或字符数组。

2. 存储多个对象的引用:指针数组可以用来存储多个对象的指针,通过遍历指针数组可以操作这些对象,比如进行排序、搜索等操作。

3. 多级指针:指针数组还可以用来存储多个指针的指针,即多级指针。多级指针可以用于动态存储和访问多维数组、链表等数据结构。

4. 动态内存分配:指针数组可以用于动态分配内存,比如创建一个动态大小的数组。通过使用指针数组,可以根据需要动态调整数组的大小。

5. 函数参数传递:指针数组可以作为函数参数,传递给函数需要操作数组的指针。通过指针数组,可以在函数内部对数组进行修改,从而达到改变数组的目的。

总的来说,指针数组提供了一种便捷的方式来管理和操作多个相关的数据或对象,具有灵活性、高效性和方便性。

2.3指针数组的操作


1. 声明一个指针数组,代码如下:

// 创建指针数组并确定大小
    const int SIZE = 5;
    int* arr[SIZE];

SIZE是一个常量,用于记录指针数组arr的大小。


2. 初始化指针数组的元素:可以使用已存在的变量或者动态分配内存来创建新的变量。代码如下:

 // 初始化指针数组的元素
    int num1 = 10;
    int num2 = 20;
    int num3 = 30;
    int* ptr1 = new int(40); // 使用动态内存分配创建新变量
    int* ptr2 = new int(50);

    arr[0] = &num1;
    arr[1] = &num2;
    arr[2] = &num3;
    arr[3] = ptr1;
    arr[4] = ptr2;

看到了么,指针数组是可以记录很多相同类型的变量的,也可以记录一个指针


3. 访问指针数组的元素:即通过指针+循环的形式访问对应的变量或数据,这里就不需要向数组指针那样啦,直接用*arr[i]的形式即可。代码如下:

 // 访问并输出指针数组的元素
    for (int i = 0; i < SIZE; i++) {
        std::cout << *arr[i] << " ";
    }
    std::cout << std::endl;

4.插入:声明一个新的指针来存储要插入的元素的地址。将要插入的元素赋值给新的指针。将所有后续元素往后移动一个位置,为要插入的元素腾出空间。在要插入的位置上将新的指针赋值给指针数组。

下面是一个示例代码,演示了如何在指针数组中插入元素:


 

#include <iostream>
using namespace std;

int main() {
    int* arr[5] = { nullptr, nullptr, nullptr, nullptr, nullptr }; // 声明一个指针数组

    int value = 10; // 要插入的元素
    int* newValue = new int(value); // 在堆上分配内存空间,并将元素的地址赋值给新的指针

    int insertIndex = 2; // 要插入的位置

    // 将后续元素往后移动一个位置
    for (int i = 4; i > insertIndex; i--) {
        arr[i] = arr[i - 1];
    }

    // 将新的指针赋值给指针数组的插入位置
    arr[insertIndex] = newValue;

    // 输出指针数组的内容
    for (int i = 0; i < 5; i++) {
        if (arr[i] != nullptr) {
            cout << *arr[i] << " ";
        }
        else {
            cout << "null ";
        }
    }

    delete newValue; // 释放堆上分配的内存

    return 0;
}

注意,在使用完指针数组中的指针后,需要手动释放通过 `new` 运算符分配的内存空间,以避免内存泄漏。


5. 查找:查找指针数组中的特定元素,通过比较指针或变量的值来确定是否存在,我们可以用循环一个一个的查找。代码如下:

 // 查找指针数组中的特定元素
    int* searchNum = &num2;
    bool found = false;
    for (int i = 0; i < SIZE; i++) {
        if (arr[i] == searchNum) {
            found = true;
            break;
        }
    }
    if (found) {
        std::cout << "Element found in the pointer array." << std::endl;
    } else {
        std::cout << "Element not found in the pointer array." << std::endl;
    }

注:这里可以把SIZE改为变量。

对了,最后不要忘记释放内存,代码如下:    

// 释放动态内存
    delete ptr1;
    delete ptr2;

2.4指针二维数组

指针二维数组是一个具有指针类型元素的二维数组。可以使用指针二维数组来表示和操作多维的数据结构,如矩阵、图像等。下面是一个使用指针二维数组来表示矩阵,并进行一些操作的示例代码:


 

#include <iostream>
using namespace std;

int main() {
    int rows = 3;
    int cols = 3;

    // 声明一个指针二维数组
    int** matrix = new int*[rows];
    for (int i = 0; i < rows; i++) {
        matrix[i] = new int[cols];
    }

    // 初始化矩阵
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            matrix[i][j] = i * cols + j + 1;
        }
    }

    // 输出矩阵
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            cout << matrix[i][j] << " ";
        }
        cout << endl;
    }

    // 释放内存
    for (int i = 0; i < rows; i++) {
        delete[] matrix[i];
    }
    delete[] matrix;

    return 0;
}

在这个示例中,我们首先声明了一个指针二维数组 matrix,它有3行3列。然后,使用 new 运算符为每一行分配内存空间。接下来,我们通过双重循环初始化矩阵的元素值。最后,通过双重循环输出矩阵的元素值。

在使用完指针二维数组后,记得释放为每一行分配的内存空间,并释放指针二维数组本身的内存空间,以避免内存泄漏。

运行结果:

2.4指针数组的练习题

题目:

假设有一个字符串数组,其中存储了一些人的姓名,请编写一个程序,将这些人的姓名按照字典序排序,并输出排序后的结果。

步骤:
1. 声明一个指针数组,用来存储人名的指针。
2. 声明一个整型变量 `n`,表示人名的数量,并根据实际情况进行赋值。
3. 使用动态内存分配为指针数组分配内存空间,使每个指针指向一个字符串。
4. 使用循环输入各个人名,并将每个人名的指针存储到指针数组中。
5. 使用冒泡排序对指针数组中的指针进行排序。
6. 使用循环输出排序后的人名。
7. 释放指针数组的内存空间。

知识点:
- 指针数组的声明和初始化
- 冒泡排序算法
- 动态内存分配和释放

流程图:


代码:

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

void bubbleSort(string* arr, int n) {
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                swap(arr[j], arr[j + 1]);
            }
        }
    }
}

int main() {
    int n;
    cout << "Enter the number of names: ";
    cin >> n;

    string* names = new string[n];

    for (int i = 0; i < n; i++) {
        cout << "Enter name " << i + 1 << ": ";
        cin >> names[i];
    }

    bubbleSort(names, n);

    cout << "Sorted names are: ";
    for (int i = 0; i < n; i++) {
        cout << names[i] << " ";
    }
    cout << endl;

    delete[] names;

    return 0;
}


 

在代码中,首先声明了指针数组 `names` 和整型变量 `n`,然后使用动态内存分配为指针数组分配内存空间。接下来,通过循环输入人名,并将每个人名的指针存储到指针数组中。然后,使用冒泡排序算法对指针数组进行排序。最后,通过循环输出排序后的人名,并释放指针数组的内存空间。

题目:

设计一个程序,要求从键盘输入10个学生的成绩,并使用指针数组对成绩进行排序并输出排序后的结果。

步骤:
1. 声明一个指针数组,用于存储学生成绩。
2. 通过循环,从键盘输入10个学生的成绩,将成绩存储到指针数组中。
3. 使用冒泡排序算法对指针数组中的成绩进行排序。
4. 输出排序后的学生成绩。

知识点:指针数组、冒泡排序算法、指针的比较和交换。

流程图:

代码:


 

#include <iostream>
using namespace std;

void bubbleSort(int* arr[], int size) {
    for (int i = 0; i < size - 1; i++) {
        for (int j = 0; j < size - i - 1; j++) {
            if (*arr[j] > *arr[j + 1]) {
                int* temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

int main() {
    const int size = 10;
    int* scores[size];

    // 输入学生成绩
    for (int i = 0; i < size; i++) {
        int score;
        cout << "请输入第" << i + 1 << "个学生的成绩:";
        cin >> score;

        scores[i] = new int(score);
    }

    // 对成绩进行排序
    bubbleSort(scores, size);

    // 输出排序后的成绩
    cout << "排序后的成绩为:" << endl;
    for (int i = 0; i < size; i++) {
        cout << *scores[i] << " ";
    }
    cout << endl;

    // 释放内存
    for (int i = 0; i < size; i++) {
        delete scores[i];
    }

    return 0;
}

以上代码中,我们首先声明了一个指针数组 scores,用于存储学生成绩。然后通过循环,从键盘输入10个学生的成绩,并将成绩存储到指针数组中。接下来,使用冒泡排序算法对指针数组中的成绩进行排序。最后,输出排序后的学生成绩。在程序结束前,记得释放为每个学生成绩分配的内存空间,以避免内存泄漏。

3.对比

指针数组和数组指针是两个不同的概念,有以下区别:

1. 定义方式不同:
   - 指针数组:指针数组是指一个数组,其中的每个元素都是一个指针。定义时需要指定数组的大小,例如 `int* arr[size]`,表示一个大小为 `size` 的指针数组。
   - 数组指针:数组指针是指一个指针,它指向一个数组。定义时需要指定指针所指向数组的类型,例如 `int (*ptr)[size]`,表示一个指向大小为 `size` 的整型数组的指针。

2. 访问方式不同:
   - 指针数组:可以通过索引来访问指针数组中的元素,例如 `arr[i]`。
   - 数组指针:可以通过解引用指针来访问数组中的元素,例如 `(*ptr)[i]`。

3. 内存分配不同:
   - 指针数组:指针数组中的每个元素都可以单独分配内存,可以具有不同的大小和类型。
   - 数组指针:数组指针指向的数组是连续存储的,内存是一次性分配的。

4. 数组维度不同:
   - 指针数组:指针数组的每个元素都可以指向不同大小的数组,维度可以是不同的。
   - 数组指针:数组指针指向的数组有固定的大小和维度,指针只能指向该大小和维度的数组。

需要注意的是,指针数组和数组指针可以结合使用,例如可以定义一个数组指针,使其指向一个指针数组。这样既可以通过指针来访问数组的元素,也可以通过数组的索引来访问指针数组的元素。

总结

本篇博客到这里就结束了,感谢大家的支持与观看,如果有好的建议欢迎留言,谢谢大家啦!

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

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

相关文章

使用Python,networkx绘制有向层级结构图

使用Python&#xff0c;networkx绘制有向层级结构图 1. 效果图2. 源码2.1 tree.txt2.2 pyNetworkx.py参考 上一篇介绍了&#xff1a;1. 使用Python&#xff0c;networkx对卡勒德胡赛尼三部曲之《群山回唱》人物关系图谱绘制 当前博客介绍&#xff1a; 2. 使用Python&#xff0c…

【C++】map和set——树形结构的关联式容器

目录 一、序列式容器和关联式容器 二、键值对pair 三、树形结构的关联式容器 3.1 set 3.1.1.set的模板参数 3.1.2. set的构造 3.1.3. set的迭代器 3.1.4. set的容量 3.1.5. set的操作 3.1.6. set的修改 3.1.7 set的使用示范 3.2 map 3.2.1. map的模板参数说明 3.…

解决android studio build Output中文乱码

1.效果如下所示&#xff1a; 代码运行报错的时候&#xff0c;Build Output报的错误日志中中文部分出现乱码&#xff0c;导致看不到到底报的什么错。 2.解决办法如下&#xff1a; 点击Android studio开发工具栏的Help-Edit Custom VM Options....&#xff0c;Android studio会…

【Acwing】差分矩阵

图1&#xff1a;a和b数组映射表 由于a是b的前缀和数组&#xff0c;因此改变b[ x1][ y1]之后&#xff0c;受到影响的a中元素如右半图所示 图2&#xff1a;求b数组的前缀和 #include<bits/stdc.h> using namespace std;int n,m,q; int a[1010][1010]; int b[1010][1010]…

使用Fabric创建的canvas画布背景图片,自适应画布宽高

之前的文章写过vue2使用fabric实现简单画图demo&#xff0c;完成批阅功能&#xff1b;但是功能不完善&#xff0c;对于很大的图片就只能显示一部分出来&#xff0c;不符合我们的需求。这就需要改进&#xff0c;对我们设置的背景图进行自适应。 有问题的canvas画布背景 修改后的…

【字典树】【KMP】【C++算法】3045统计前后缀下标对 II

作者推荐 动态规划的时间复杂度优化 本文涉及知识点 字符串 字典树 KMP 前后缀 LeetCode:3045统计前后缀下标对 II 给你一个下标从 0 开始的字符串数组 words 。 定义一个 布尔 函数 isPrefixAndSuffix &#xff0c;它接受两个字符串参数 str1 和 str2 &#xff1a; 当 st…

k8s-项目测试环境部署

部署规划 概述 项目开发好后&#xff0c;我们需要部署&#xff0c;我们接下来就基于 阿里云云效 阿里云容器镜像服务 k8s 搭建部署环境 阿里云云效 : 放代码&#xff0c;可以做cicd&#xff08;https://www.aliyun.com/product/yunxiao&#xff09; 阿里云容器镜像服务 :…

在 Linux 环境下安装 Kibana

目录 一、Kibana 是什么 二、在 Linux 环境下安装 Kibana 1、下载安装包 2、解压 3、修改 Kibana的配置文件 config/kibana.yml 4、启动 5、浏览器登录 Kibana 6、测试查询 一、Kibana 是什么 Kibana 是通向 Elastic 产品集的窗口。 它可以在 Elasticsearch 中对数据进…

java爬取深圳新房备案价

Java爬取深圳新房备案价 这是我做好效果,一共分3个页面 1、列表;2、统计;3、房源表 列表 价格分析页面 房源页面 一、如何爬取 第一步:获取深圳新房备案价 链接是:http://zjj.sz.gov.cn/ris/bol/szfdc/index.aspx 第二步:通过楼盘名查询获取明细 链接:http://z…

YOLOv9理性解读 | 网络结构损失函数耗时评估

论文&#xff1a;https://arxiv.org/pdf/2402.13616.pdfHuggingFace Demo&#xff1a;https://hf-mirror.com/spaces/kadirnar/Yolov9Github&#xff1a;https://github.com/WongKinYiu/yolov9 由台北中研院和台北科技大学等机构的研究团队推出的新的目标检测算法&#xff0c;…

应用存储与持久化数据卷

1、PV 引入场景&#xff1a; ① Deployment 管理的 pod&#xff0c;在做镜像升级的过程中&#xff0c;会产生新的 pod并且删除旧的 pod &#xff0c;新旧 pod 之间如何复用数据&#xff1f; ② 宿主机宕机的时候&#xff0c;如何实现带卷迁移&#xff1f; ③ 多个 pod 之间&…

基于springboot+vue的相亲网站

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

Stable Video Diffusion(SVD)视频生成模型发布 1.1版

前言 近日&#xff0c;随着人工智能技术的飞速发展&#xff0c;图像到视频生成技术也迎来了新的突破。特别是Stable Video Diffusion&#xff08;SVD&#xff09;模型的最新版本1.1&#xff0c;它为我们带来了从静态图像生成动态视频的全新能力。本文将深入解析SVD 1.1版本的核…

gpt-3.5-turbo与星火认知大模型v3.5回答对比

创建kernel // Create a kernel with OpenAI chat completionKernel kernel Kernel.CreateBuilder().AddOpenAIChatCompletion(modelId:"使用的模型id" ,apiKey: "APIKey").Build();使用讯飞星火认知大模型的话&#xff0c;可以参考我这一篇文章&#xff…

Linux系统——Nginx负载均衡模式

目录 一、Nginx优点 二、Nginx配置项——Conf Upstream 模块 三、Nginx负载均衡 1.负载均衡策略 1.1轮询 1.2IP_hash 1.3URL_hash 1.4Least_conn 1.5Weight 1.6Fair 2.Nginx负载均衡配置状态参数 3.什么是会话保持 3.1会话保持有什么作用呢 3.2Nginx会话保持 3…

JVM工作原理与实战(四十一):ShenandoahGC原理

专栏导航 JVM工作原理与实战 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、ShenandoahGC介绍 二、ShenandoahGC 1.0版本 三、ShenandoahGC 2.0版本 四、ShenandoahGC执行流程 总结 前言 JVM作为Java程序的运行环境&#xff0c;其负责解释和执行字节码&…

ywtool check命令及ywtool clean命令

一.ywtool check命令 1.1 ywtool check -I 1.2 ywtool check all 1.3 ywtool check io 1.4 ywtool check elk 1.5 ywtool check php 1.6 ywtool check mysql 1.7 ywtool check nginx 1.8 ywtool check system 1.9 ywtool check docker_nbip [容器名称] 1.10 ywtool check 1.10…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之FlowItem容器组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之FlowItem容器组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、FlowItem组件 子组件 可以包含子组件。 接口 FlowItem() 使用该接口来…

从0到1使用C++实现一个模拟器-1-【实现最简CPU】

文章目录 uint64_tstdstd::arrayCPU和CU类构造函数size_tstatic_caststd::ifstreamriscv64-unknown-elf-objcopy -O binary add-addi add-addi.binriscv64-unknown-elf-gcc -Wl,-Ttext0x0 -nostdlib -o add-addi add-addi.s-wlstd::hex std::setw() std::setfill()各自的用法he…

DOM 创建节点、添加节点和删除节点

创建元素节点 document.createElement(‘标签名’) 创建文本节点document.createTextNode ( 内容 ) 根据传入的标签名创建出一个空的元素对象创建出来的默认不显示&#xff0c;要成为别人的子元素才能显示&#xff0c;所以要结合appendChild使用 添加节点&#xff08;后面&am…