15 字符数组与二维数组(定义、初始化、访问、遍历、内存调试分析),数组编程练习

news2025/1/21 22:04:14

目录

1 字符数组(字符串)

1.1 介绍

1.2 字符数组的定义与初始化

1.2.1 使用字符列表进行初始化

1.2.1.1 VS Code 调试内存

1.2.2 使用字符串字面量进行初始化

1.3 字符数组的访问和遍历

2 多维数组

2.1 介绍

2.2 二维数组的定义

2.2.1 先定义后初始化

2.2.2 直接定义并初始化

2.2.2.1 以矩阵的形式初始化

2.2.2.2 通过连续的数值初始化

2.2.2.3 省略第一维的数组长度

2.3 二维数组的访问和遍历

2.3.1 计算行数和列数

2.3.2 案例演示

2.4 二维数组的内存分析

2.5 案例:计算三个班级的成绩平均分及总平均分

3 数组编程练习

3.1 循环输入并输出 5 个成绩

3.2 计算鸡的总体重与平均体重

3.3 创建并打印 26 个字母的数组

3.4 求出数组的最小值及其索引

4 测试题


1 字符数组(字符串)

1.1 介绍

        用来存放字符的数组称为字符数组,也可以称为字符串。字符串的输入输出格式占位符是 %s

        %s 格式说明符专门用于输出 C 风格的字符串(最好是末尾要有结束符),即从指定的字符数组(或指针指向的位置)开始,直到遇到第一个 '\0' 字符为止的字符序列。这个结束符 '\0' 用于在内存中标记字符串的结束,但它不是字符串内容的一部分,因此在输出时不会包括它

        字符串结尾,会自动添加一个 \0 作为字符串结束的标志,所以字符数组最后一个元素必须(最好)是 \0

        \0 是 ASCII 码表中的第 0 个字符,用 NUL 表示,称为空字符,该字符既不能显示,也不是控制字符,输出该字符不会有任何效果,它在 C 语言中仅作为字符串的结束标志

1.2 字符数组的定义与初始化

1.2.1 使用字符列表进行初始化

        在给某个字符数组使用字符列表赋值时,如果没有显示的添加结束符 '\0':当赋值的元素个数小于字符数组的长度,则会自动在后面加 '\0' 表示字符串结束当赋值的元素的个数等于该数组的长度或不指定数组长度,则不会自动添加 '\0'。当赋值的元素的个数大于该数组的长度,编译器会报错,因为多余的初始化值没有对应的位置存储。

        在上一章节中我们曾说过,当整型数组初始化的元素个数少于定义的数组长度时,未被初始化的元素将默认被赋值为 0。那么现在对于字符数组来说,未被初始化的元素将默认被赋值为 '\0'

        如果字符数组没有以 '\0' 结尾,则不应将其视为字符串进行字符串操作。字符串操作函数(如 strlen、strcpy、strcat 等)会一直读取字符直到遇到 '\0' 为止。如果数组没有以 '\0' 结尾,那么这些函数会继续读取数组后面的内存区域,直到偶然遇到某个内存位置恰好存储了 '\0' 为止,这可能导致访问不属于原数组的内存,引发安全问题。

#include <stdio.h>

int main()
{
    // 显式地为字符串数组 str1 的每个字符赋值,包括空字符 '\0' 作为字符串的结束标识
    // 这样定义字符串是安全的,因为明确指定了字符串的结束。
    char str1[12] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '\0'};

    // 为字符串数组 str2 的前三个字符赋值,数组大小是 4,编译器会自动在末尾添加 '\0'
    // 这里编译器确实会自动添加 '\0',因为数组大小足够容纳一个额外的 '\0'。
    char str2[4] = {'t', 'o', 'm'};

    // str3 数组大小是 3,不会自动添加 '\0',这会导致未定义行为。
    // 后续不应该使用 tr3 进行字符串操作,因为它不是以 '\0' 结尾的。
    // 由于 str3 没有以 '\0'结尾,尝试将其作为字符串(如使用 %s 格式说明符)是未定义行为。
    char str3[3] = {'t', 'o', 'm'};
    // char str3[3] = {'t', 'o', 'm', 'm', 'm'}; // 报错

    // 为字符数组 str4 的前四个字符赋值,但没有显式地添加 '\0'
    // 这里数组大小是自动计算的,但不包括 '\0'。
    // 使用 str4 作为字符串(如使用 %s 格式说明符)是不安全的,因为它不是以'\0'结尾的。
    // 由于 str4 没有以'\0'结尾,尝试将其作为字符串将读取未定义的数据,直到遇到'\0'。
    char str4[] = {'j', 'a', 'c', 'k'};

    // 打印字符串
    printf("str1=%s \n", str1); // 正确打印 "Hello World"
    printf("str2=%s \n", str2); // 正确打印 "tom",因为编译器自动添加了 '\0'

    // 下面的两行是未定义行为,因为 str3 和 str4 都不是以 '\0' 结尾的字符串
    printf("str3=%s \n", str3); // 这里的行为是未定义的,因为 str3 没有以 '\0' 结尾
    printf("str4=%s \n", str4); // 这里的行为也是未定义的,因为 str4 没有以 '\0' 结尾

    // 替代方案:显式地打印 str3 和 str4 的前三个和前四个字符(不将它们视为字符串)
    // 注意:这里仅为了演示,实际使用中应避免这种潜在的内存越界
    printf("str3 first 3 chars: %c%c%c \n", str3[0], str3[1], str3[2]);
    printf("str4 first 4 chars: %c%c%c%c \n", str4[0], str4[1], str4[2], str4[3]);

    return 0;
}

        输出结果如下所示:

1.2.1.1 VS Code 调试内存

        对于上面这个程序,为什么输出结果是这样的呢? 

        下面我们通过调试程序来揭秘答案,首先在最后一行代码 return 0; 处添加一个断点,然后开启调试模式,如下图所示:

        在左侧变量区域中,我们可以发现,str3(初始化时赋值的元素的个数等于该数组的长度)和 str4(数组定义时不指定数组长度)这两个字符数组最后没有结束符 '\0',如下图所示:

        然后开始监视这四个数组,这需要添加监视的表达式,在左侧监视区域中,点击 + 号,依次输出 &str1,&str2,&str3,&str4 进行添加监视(也可以不用 & 符号,应为数组名就是首地址),如下图所示:

        通过监视区域,可以看出这四个数组所在的内存地址,下面需要查看对应的二进制数据,操作如下图所示:

        通过查看二进制数据文件,对于原程序的输出结果就一目了然了。

        对于数组 str1 中存储的是: Hello World\0, H: 0x48,e: 0x65,l: 0x6c,l: 0x6c,o: 0x6f,(空格): 0x20,W: 0x57,o: 0x6f,r: 0x72,l: 0x6c,d: 0x64 ,\0:0x00,完整 ASCII 十六进制表示为:48656c6c6f20576f726c6400。对应的内存中的存储地址如下图所示:

        由于 str1 数组最后一个元素存储了结束符 '\0',所以通过 printf 的格式占位符 %s 可以正确输出。  

        对于数组 str2 中存储的是:tom 以及编辑器自动添加的 '\0'。对应的内存中的存储地址如下图所示:

        由于 str2 数组最后一个元素存储了结束符 '\0',所以通过 printf 的格式占位符 %s 也可以正确输出。   

        对于数组 str3 中存储的是:tom ,由于赋值的元素的个数等于该数组的长度,编译器不会自动添加 '\0'。如果通过 printf 的格式占位符 %s 进行输出,会一直读取输出字符直到遇到 '\0' 为止。所以,通过 printf 的格式占位符 %s 输出的内容是:tomtom,对应的内存中的存储地址如下图所示:

        对于数组 str4 中存储的是:jack,由于初始化时未指定数组长度,编译器不会自动添加 '\0'。如果通过 printf 的格式占位符 %s 进行输出,会一直读取输出字符直到遇到 '\0' 为止。所以,通过 printf 的格式占位符 %s 输出的内容是:jacktomtom,对应的内存中的存储地址如下图所示:

1.2.2 使用字符串字面量进行初始化

        如果一直使用之前那种方法进行数组的初始化,当字符较多时,就会显得不够便捷,因此现在介绍一种更简便的方法。

        在 C 语言中,字符串字面量(如 "I am happy")在内存中是以字符数组的形式存储的,且每个字符串字面量都自动以空字符('\0')作为结束符

        直接使用双引号包围的字符串字面量来初始化字符数组时,编译器会自动在字符串的末尾添加 '\0' 作为结束符

#include <stdio.h>

int main()
{
    // 因为字符串字面量本身就是以'\0'结尾的字符序列。
    // 编译器会忽略大括号,并自动在字符串末尾添加'\0'。
    char str1[] = {"I am happy"}; // 后面自动添加 \0,{} 的使用是不必要的

    // 这是更常见的初始化字符串的方式,直接使用双引号包围的字符串字面量。
    // 编译器会自动在字符串末尾添加 '\0'。
    char str2[] = "I am happy"; // 省略 {} 号,后面自动添加 \0

    printf("str1=%s \n", str1); // str1=I am happy
    printf("str2=%s \n", str2); // str2=I am happy

    return 0;
}

        当使用字符串字面量来初始化字符数组时,初始化列表中如果还使用大括号 {} 来包围字符串字面量,虽然语法上允许,但通常不推荐,因为它可能会降低代码的可读性,并且容易让人误解为可以修改字符串的内容(实际上字符串字面量是不可修改的)。建议直接使用双引号包裹进行初始化! 

1.3 字符数组的访问和遍历

        字符数组(字符串)的访问和遍历,按照一般数组的方式访问和遍历即可。

#include <stdio.h>

int main()
{
    // 定义字符串(实际上是一个字符数组,包含字符串 "Hello" 和结尾的空字符 '\0')
    char string[] = "Hello!";

    // 计算包含字符串的字符数组的总长度(包含结尾的空字符'\0')
    int len = sizeof string / sizeof string[0];
    // char 类型的数据占 1 字节,即 sizeof string[0] = 1
    // 所以可以不用除以 sizeof string[0],
    int len1 = sizeof string;

    // 打印字符串
    printf("%s \n", string); // Hello!

    // 打印整个字符数组的长度(包含结尾的空字符'\0')
    printf("数组长度(包括结尾的空字符): %d <-> %d\n", len, len1); // 7 <-> 7

    // 访问字符串的第 5 个字符(索引为 4 )
    printf("第5个字符: %c \n\n", string[4]); // o
    // 修改字符串的第 1 个字符(索引为 0 )
    string[0] = 'h';
    // 修改字符串的第 6 个字符(索引为 5 )
    string[5] = '?';

    // 遍历整个字符数组(包括结尾的空字符'\0',但'\0'在输出时不会显示)
    printf("第一次遍历字符数组:\n");
    for (int i = 0; i < len; i++)
    {
        printf("string中的第%d字母为:%c \n", (i + 1), string[i]);
    }

    // 注意:上述循环中,虽然'\0'也会被计算在内,但由于它是空字符,所以在控制台上不会显示。

    // 如果不想打印 '\0',可以减少一次循环
    printf("第二次遍历字符数组:\n");
    for (int i = 0; i < len - 1; i++)
    {
        printf("string中的第%d字母为:%c \n", (i + 1), string[i]);
    }

    return 0;
}

        注意:上述循环中,虽然 '\0' 也会被计算在内,但由于它是空字符,所以在控制台上不会显示。

        输出结果如下所示:


2 多维数组

2.1 介绍

        如果数组的元素还是数组,这样的数组就称为多维数组。这种多层次的结构允许我们以表格矩阵的方式组织数据,其中每个维度都对应于不同的行、列或更多的维度,使数据更加结构化和有组织。

        多维数组可以分为二维数组、三维数组、四维数组 …… 等,这里我们以二维数组为例进行演示。

        下图是一个四行六列的二维数组示意图:

2.2 二维数组的定义

        二维数组的定义类似于一维数组,但需要指定两个维度的大小:行数列数。语法格式如下:

数据类型 数组名[行数][列数];

2.2.1 先定义后初始化

        在定义完二维数组后,可以通过逐个元素赋值的方式对其进行初始化。

// 定义一个 4 行 6 列的二维数组
int a[4][6]; 

// 进行初始化赋值
a[0][0] = 10;  // 第一行第一列的元素
a[0][1] = 20;  // 第一行第二列的元素
a[0][2] = 30;  // 第一行第三列的元素
a[0][3] = 40;  // 第一行第四列的元素
a[0][4] = 50;  // 第一行第五列的元素
a[0][5] = 60;  // 第一行第六列的元素
a[1][0] = 100; // 第二行第一列的元素
a[1][1] = 200; // 第二行第二列的元素
// ...

2.2.2 直接定义并初始化

        在 C 语言中,我们不仅可以先定义二维数组然后再逐一初始化,还可以在定义的同时直接初始化数组。这种方式更加简洁并且易于阅读。

2.2.2.1 以矩阵的形式初始化

        定义并初始化一个 4 行 6 列的二维数组,以矩阵的形式初始化

int a[4][6] = {
    {10, 20, 30, 30, 40, 60},
    {100, 200, 300, 400, 500, 600},
    {1000, 2000, 3000, 4000, 5000, 6000},
    {10000, 20000, 30000, 40000, 50000, 60000}
};

        在这个例子中,每一行的元素被明确地放置在一个大括号 {} 中,形成一个矩阵式的布局。这样的初始化方式使得数组的结构非常清晰。

2.2.2.2 通过连续的数值初始化

        定义并初始化一个 4 行 6 列的二维数组,通过连续的数值初始化,编译器会自动匹配到各行和各列

int b[4][6] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24};

        这种方式中,虽然没有显式地使用大括号 {} 来分隔行,但是编译器会根据提供的元素数量和数组的维度自动填充到相应的行列中,就是看着不是很直观清晰。

2.2.2.3 省略第一维的数组长度

        如果所提供的值的数量能够与数组元素的数量对应,可以省略第一维的数组长度【行数】

int b[][6] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24};

        这里,第一维的长度可以不指定,编译器会根据初始化列表中的元素数量自动推断出数组的行数。 

        注意:在一维数组中,可以省略数组的长度,编译器会自动计算。这一特性也可以应用于二维数组,不过只能省略行数,列数不能省略,否则编译器无法正确解析数组的结构。

2.3 二维数组的访问和遍历

        访问二维数组的元素,需要使用两个下标(索引),一个用于访问行(第一维),另一个用于访问列(第二维),我们通常称为行下标(行索引)列下标(列索引)。

        遍历二维数组,需要使用双层循环结构。

2.3.1 计算行数和列数

        计算行数: 使用 sizeof(a) 获取整个数组的大小,然后除以 sizeof(a[0]),即单行的大小,得到行数。int rows = sizeof(a) / sizeof(a[0]); 

        计算列数: 使用 sizeof(a[0]) 获取单行的大小,然后除以 sizeof(a[0][0]),即单个元素的大小,得到列数。int cols = sizeof(a[0]) / sizeof(a[0][0]); 或者 int cols = sizeof(a[0]) / sizeof(数组的基本数据类型); 

2.3.2 案例演示

#include <stdio.h>

int main()
{
    // 定义一个 3 行 4 列的二维数组
    int map[3][4] = {
        {1, 2, 3, 4},     // 第一行
        {11, 12, 13, 14}, // 第二行
        {21, 22, 23, 24}  // 第三行
    };

    // 计算第一维度(行数)的长度
    int rows = sizeof(map) / sizeof(map[0]);
    // 计算第二维度(列数)的长度
    int cols = sizeof(map[0]) / sizeof(int);
    int cols2 = sizeof(map[0]) / sizeof(map[0][0]);

    // 遍历并输出二维数组的每个元素
    printf("二维数组的元素:\n");
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            printf("%d \t", map[i][j]); // 使用制表符 \t 使输出更加整齐
        }
        // 打印完一行就换行
        printf("\n");
    }

    // 计算二维数组中所有元素的和
    int sum = 0;
    printf("计算所有元素的和:\n");
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            sum += map[i][j];
        }
    }
    printf("所有元素的和:%d\n", sum); // 150

    return 0;
}

        输出结果如下所示:

2.4 二维数组的内存分析

        用矩阵形式(如 3 行 4 列形式)表示二维数组,是逻辑上的概念,能形象地表示出行列关系。而在内存中,各元素是连续存放的,不是二维的,是线性的

        C 语言中,二维数组中元素排列的顺序是按行存放的。即:先顺序存放第一行的元素,再存放第二行的元素。

        比如,举例,数组 a[3][4] 在内存中的存放:

        通过调试内存,可以更直观的分析出二维数组在内存中的存储情况,以下面这个二维数组为例:

int map[3][4] = {
        {1, 2, 3, 4},     // 第一行
        {11, 12, 13, 14}, // 第二行
        {21, 22, 23, 24}  // 第三行
};

        Clion 中的内存调试情况: 

        VS Code 中的内存调试情况: 

2.5 案例:计算三个班级的成绩平均分及总平均分

        现在有三个班,每个班五名同学,用二维数组保存他们的成绩,并求出每个班级平均分、以及所有班级平均分,数据要求从控制台输入。

#include <stdio.h>

int main()
{
    // 定义一个 3 行 5 列的数组,用于存储不同班级的学生的成绩
    double scores[3][5];

    // 定义变量存储第一个维度长度(班级数)和第二个维度长度(学生数)
    // int rows = 3, cols = 5;
    int rows = sizeof scores / sizeof scores[0];
    int cols = sizeof scores[0] / sizeof scores[0][0];

    /* 暂时先不对用户输入的数据做校验 */

    // 遍历二维数组进行赋值
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            // 提示用户输入成绩
            printf("请输入第%d个班的第%d个学生的成绩:", i + 1, j + 1);
            // 读取用户输入的成绩
            scanf("%lf", &scores[i][j]);
        }
    }

    // 遍历数组,计算每个班级的平均分和总的平均分
    // 定义变量记录所有班级总分数
    double total_sum = 0;
    // 定义变量记录每个班级总分数
    double class_sum = 0;

    // 遍历班级(行)
    for (int i = 0; i < rows; i++)
    {
        // 将当前班级总分数重置为 0,至关重要!!!
        // 或者将这个变量的声明拿进来
        class_sum = 0;

        // 遍历当前班级的每个成绩(该行的每一列)
        for (int j = 0; j < cols; j++)
        {
            // 累加成绩
            class_sum += scores[i][j];
        }

        // 输出当前班级的平均分
        printf("第%d个班级的平均分为:%.2f \n", i + 1, class_sum / cols);

        // 将该班级总分加入到所有总分中
        total_sum += class_sum;
    }

    // 输出所有班级的平均分
    printf("所有班级的平均分为:%.2f \n", total_sum / (rows * cols));

    return 0;
}

        输出结果如下所示:


3 数组编程练习

3.1 循环输入并输出 5 个成绩

        从终端循环输入 5 个成绩,保存到 double 数组,并输出。

#include <stdio.h>

int main()
{
    // 定义一个 double 类型的数组,用于保存成绩
    double grades[5];

    // 计算数组的长度
    int length = sizeof(grades) / sizeof(grades[0]);

    // 遍历数组进行赋值
    for (int i = 0; i < length; i++)
    {
        // 提示用户输入成绩
        printf("请输入第 %d 个成绩:", i + 1);
        // 读取用户输入的成绩
        scanf("%lf", &grades[i]);
    }

    // 输出成绩
    printf("成绩为:");
    for (int i = 0; i < length; i++)
    {
        printf("%.2f ", grades[i]);
    }

    return 0;
}

        输出结果如下所示:

3.2 计算鸡的总体重与平均体重

        一个养鸡场有 6 只鸡,它们的体重分别是 3kg,5kg,1kg,3.4kg,2kg,50kg。请问这六只鸡的总体重是多少?平均体重是多少?

#include <stdio.h>

int main()
{
    // 定义一个 double 类型的数组,用于保存鸡的体重
    double weights[] = {3.0, 5.0, 1.0, 3.4, 2.0, 50.0};

    // 计算数组的长度
    int num_chickens = sizeof(weights) / sizeof(weights[0]);

    // 初始化总体重为 0
    double total_weight = 0.0;

    // 遍历数组累加总体重
    for (int i = 0; i < num_chickens; i++)
    {
        total_weight += weights[i];
    }

    // 计算平均体重
    double average_weight = total_weight / num_chickens;

    // 输出总体重和平均体重
    printf("总体重为:%.2f kg\n", total_weight);     // 64.40 kg
    printf("平均体重为:%.2f kg\n", average_weight); // 10.73 kg

    return 0;
}

3.3 创建并打印 26 个字母的数组

        创建一个 char 类型的 26 个元素的数组,分别放置 'A'-'Z‘。使用 for 循环访问所有元素并打印出来。

#include <stdio.h>

int main()
{
    // 长度 26 ,后面使用循环输出
    char letters1[26];
    // 长度 27 ,比 26 大一,用于保存结束符,后面使用 %s 输出
    char letters2[27];

    // 方法一
    for (int i = 0; i < 26; i++)
    {
        letters1[i] = 'A' + i;
    }
    // 循环打印数组元素 - 可以没有'\0'
    for (int i = 0; i < 26; i++)
    {
        printf("%c ", letters1[i]);
        // A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
    }
    printf("\n");

    // 方法二
    for (char c = 'A'; c <= 'Z'; c++)
    {
        letters2[c - 'A'] = c;
    }
    // 末尾添加结束符,方便后面操作字符串
    letters2[26] = '\0';
    // 使用 %s 输出最好末尾要有结束符 '\0'
    // %s 格式说明符被设计为仅输出字符串的可见部分,即直到第一个 '\0' 字符之前的所有字符。
    printf("%s", letters2); // ABCDEFGHIJKLMNOPQRSTUVWXYZ

    return 0;
}

        提示:使用 %s 输出最好末尾要有结束符 '\0',%s 格式说明符被设计为仅输出字符串的可见部分,即直到第一个 '\0' 字符之前的所有字符。 

3.4 求出数组的最小值及其索引

        请求出一个数组的最小值,并得到对应的索引。

#include <stdio.h>

int main()
{
    // 定义一个 double 类型的数组,用于保存成绩
    double grades[] = {85.5, 92.0, 78.3, 90.1, 82.7};

    // 计算数组的长度
    int length = sizeof(grades) / sizeof(grades[0]);

    // 初始化最小值,假设第一个是最值
    double min_value = grades[0];
    // 初始化索引
    int min_index = 0;

    // 寻找最小值及其索引
    // i 可以从 1 开始
    for (int i = 1; i < length; i++)
    {
        if (grades[i] < min_value)
        {
            min_value = grades[i];
            min_index = i;
        }
    }

    // 输出最小值及其索引
    printf("最小值为:%.2f,索引为:%d\n", min_value, min_index);
    // 最小值为:78.30,索引为:2

    return 0;
}

4 测试题

1. 字符数组(字符串)的最后一个元素是什么?

【答案】\0


2. 请写出下面程序的运行结果:

int arr[3][2] = {{10,20},{30,40},{50,60}};
printf("%d", arr[1][1] + arr[2][0]);

【答案】90

【解析】arr[1][1] 可以获取到 40,arr[2][0] 可以获取到 50, 40+50=90。

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

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

相关文章

探索ACPL-302J光耦合器的多功能性

ACPL-302J是一款高度集成的2.5A栅极驱动光耦合器&#xff0c;经过精心设计&#xff0c;可用于驱动大功率工业应用中的IGBT&#xff08;绝缘栅双极晶体管&#xff09;和功率MOSFET。其精巧的设计和强大的功能使其成为效率、安全性和可靠性至关重要的系统中不可或缺的组件。本文详…

Nature | 应变不敏感的柔性可拉伸射频组件(柔性传感/柔性健康监测/可穿戴电子/界面调控/电子皮肤/柔性电子/集成电路)

韩国首尔汉阳大学Yei Hwan Jung和Hyoungsuk Yoo团队&#xff0c;在《Nature 》上发布了一篇题为“Strain-invariant stretchable radio-frequency electronics”的论文。论文内容如下&#xff1a; 一、 摘要 可实现无线通信和无线能量传输功能的射频&#xff08;radio-frequen…

《黑神话:悟空》专题 收集相关的攻略、壁纸、视频、辅助器等

本专题专注于收集游戏《黑神话&#xff1a;悟空》的相关资料&#xff0c;如游戏攻略、壁纸、音乐、视频等。《黑神话&#xff1a;悟空》是一款以中国神话为背景的动作角色扮演游戏。故事取材于中国古典小说“四大名著”之一的《西游记》。你将扮演一位“天命人”&#xff0c;为…

大佬都在用的抓包工具:Wireshark、BurpSuite分享,零基础入门到精通 (1)

各位师傅们&#xff0c;你们平常用什么抓包工具&#xff1f; 抓包工具多种多样&#xff0c;比如Charles、Microsoft Network Monitor、Tcpdump。今天这些我们都不介绍&#xff0c;而是来介绍两款非常优秀的大牛都在用的抓包工具&#xff1a;Wireshark、BurpSuite。 1 Wiresh…

【SQL】连续出现的数字

目录 题目 分析 代码 题目 表&#xff1a;Logs ---------------------- | Column Name | Type | ---------------------- | id | int | | num | varchar | ---------------------- 在 SQL 中&#xff0c;id 是该表的主键。 id 是一个自增列。找出…

python爬虫——入门

一、概念 万维网之所以叫做网&#xff0c;是因为通过点击超链接或者进入URL&#xff0c;我们可以访问任何网络资源&#xff0c;从一个网页跳转到另一个网页&#xff0c;所有的相关资源连接在一起&#xff0c;就形成了一个网。 而爬虫呢&#xff0c;听名字就让人想起来一个黏糊…

2024最全性能测试学习指南【建议收藏】

浅谈软件测试中的性能测试 很多时候&#xff0c;我们都知道软件有黑白盒测试&#xff0c;但往往还遗漏掉了一个性能测试。 在下面的这篇文章中&#xff0c;就带领大家来了解性能测试。一起来学习吧~ 学习目录 一、 性能测试概念 二、 性能测试指标 三、 性能测试种类 四、 性能…

【科技前沿探索】电路仿真软件SmartEDA:重塑教学新纪元,解锁学习无限可能

在信息爆炸的时代&#xff0c;科技的力量正以前所未有的速度改变着我们的生活方式&#xff0c;而教育领域也不例外。电路学&#xff0c;作为理工科教育中的基石&#xff0c;其复杂性与抽象性常让初学者望而生畏。但幸运的是&#xff0c;随着电路仿真软件SmartEDA的横空出世&…

MEDICAL SAM 2: SEGMENT MEDICAL IMAGES AS VIDEO VIA SEGMENT ANYTHING MODEL 2

Jiayuan ZhuUniversity of Oxfordjiayuan.zhuieee.orgYunli QiUniversity of OxfordJunde WuUniversity of Oxfordjundewuieee.org 原文链接:https://arxiv.org/pdf/2408.00874 代码链接&#xff1a;https://github.com/MedicineToken/Medical-SAM2 文章的主要贡献如下&…

TCRAG:图灵完备 RAG + 高效医学诊断

TCRAG&#xff1a;图灵完备 RAG 高效医学诊断 提出背景图灵完备过程解法拆解分析性关联图 论文&#xff1a;TC–RAG: Turing–Complete RAG’s Case study on Medical LLM Systems 提出背景 RAG技术大致可分为朴素RAG和高级RAG两类&#xff1a; 朴素RAG采用简单的"检索…

固态硬盘数据丢失了如何恢复?

在数字化时代&#xff0c;固态硬盘&#xff08;SSD&#xff09;因其高速读写性能成为许多用户首选的存储设备。然而&#xff0c;数据丢失的风险也随之而来。无论是误删除、系统崩溃还是硬件故障&#xff0c;都可能导致宝贵的数据瞬间消失。本文将为您提供一套全面的固态硬盘数据…

MinIO 企业级人工智能存储的数据和驱动器同等重要

为什么会这样&#xff1f;这是因为硬件故障发生在不同的级别。有一些中断会导致整个站点瘫痪。然后&#xff0c;会出现中断&#xff0c;导致集群中的一部分节点瘫痪。但是&#xff0c;在更精细的硬盘驱动器位级别也存在故障&#xff0c;这些故障需要复制本身无法提供的另一种类…

AI问答对比-谁是世界上最可爱的人?

无聊的时候突然想起皇后问魔镜问题的情节&#xff0c;于是突发奇想&#xff0c;找了几个AI问答助手试试”谁是世界上最可爱的人&#xff1f;”&#xff0c;看看AI们会怎么回答。 问之前还满怀期待的猜测&#xff1a;它们有可能回答自己的所属公司的老板吗&#xff0c;或是直白…

基于Matlab GUI的信号发生器界面程序示例

前些日子&#xff0c;被一朋友拜托了一课设&#xff0c;不是很难&#xff0c;但基于matlab GUI的设计中文论坛资源较少&#xff0c;所以我做完顺便分享一下。 程序主要内容&#xff1a; 效果展示&#xff1a; 主要代码&#xff1a; 代码展示&#xff0c;复制粘贴不能直接执行…

顶顶通呼叫中心中间件-一句话语音识别安装步骤

顶顶通呼叫中心中间件-一句话语音识别安装步骤&#xff0c;对接mod_vad。一句话识别&#xff08;http接口提交录音文件识别&#xff09; 一、安装asrproxy 1、将下载软件压缩包上传到需要安装的服务器中 2、SSH终端依次执行以下命令&#xff1a; mkdir -p /ddt/asrproxysud…

抖音商城随身wifi销量排行榜!排名第一的格行随身wifi怎么样?

对于经常出差办公&#xff0c;或者酷爱旅行的人来说随身wifi简直是必备神器&#xff0c;但是随身wifi行业乱象频发&#xff0c;不小心就会踩坑。这不&#xff0c;刚去青岛旅游回来的同事正在吐槽&#xff0c;旅游前特意买个随身wifi&#xff0c;咨询时商家一顿夸&#xff0c;结…

王丹妮演绎“美女与蛇” 红黑对撞下的超现实美学

今日&#xff0c;香港演员王丹妮&#xff08;Louise Wong&#xff09;释出一组时尚大片。 这组大片以浓郁饱满的红色和深邃奢华的黑色为主调&#xff0c;搭配超现实风装置&#xff0c;尽显神秘诗意之美。黑色背景与红色装置象征锐意与优雅的交锋&#xff1b;神秘面罩下&#xf…

当移动端H5中的display:flex不生效时,给我整破防了

情况&#xff1a; 在项目开发中遇到一个“更多”按钮放置于卡片的右下角时&#xff0c;在安卓9版本的浏览器打开项目&#xff0c;结果测试出来“更多”按钮样式错乱&#xff0c;做了这么久的开发&#xff0c;在移动端给我整破防了。。。 <style> display:flex; justify…

MyBatis-Plus 三、(进阶使用)

一、typeHandler 的使用 1、存储json格式字段 如果字段需要存储为json格式&#xff0c;可以使用JacksonTypeHandler处理器。使用方式非常简单&#xff0c;如下所示&#xff1a; 只需要加上两个注解即可&#xff1a; TableName(autoResultMap true) 表示自动…

使用Instrumentation创建代理程序监测Java对象信息

文章目录 创建代理使用代理监测测试代码运行配置运行效果 总结 Instrumentation 是Java提供的一种能够在程序运行时检查和修改类定义的技术。使用Instrumentation&#xff0c;可以构建一个独立于应用程序的代理程序&#xff0c;检测和协助运行在JVM上的程序&#xff0c;甚至可以…