C语言:指针数组、函数、二级指针

news2025/4/3 5:46:07

1.指针数组

指针数组是一个数组,数组中的每个元素都是指针。这些指针可以指向各种类型的数据,如整数、字符、结构体等,甚至可以指向其他数组或函数。

指针数组的声明格式通常为:

数据类型 *数组名[数组大小];

其中,数据类型 表示指针所指向的数据的类型,数组名 是指针数组的名称,数组大小 表示数组中元素的个数。


#include <stdio.h>

int getMax(int data1,int data2)
{
	
	return data1>data2?data1:data2;
}
int getMin(int data1,int data2)
{
	
	return data1<data2?data1:data2;
}
int getSum(int data1,int data2)
{
	return data1+data2;
}


int main()
{
	int a=10;
	int b=20;
	int ret;
	
	int(*pfunc[3])(int ,int )={getMax,getMin,getSum};//函数指针数组
	for(int i=0;i<3;i++){
		ret=(*pfunc[i])(a,b);
		printf("ret=%d\n",ret);
		
	}
	return 0;
}

代码定义了三个函数:getMax 用于获取两个整数中的最大值,getMin 用于获取两个整数中的最小值,getSum 用于计算两个整数的和。在 main 函数中,创建了一个函数指针数组 pfunc,数组中的每个元素分别指向这三个函数。通过 for 循环遍历该函数指针数组,依次调用每个函数对给定的两个整数 a 和 b 进行处理,并输出每次调用的结果。

代码详细分析

1. 函数定义部分
int getMax(int data1, int data2)
{
    return data1 > data2 ? data1 : data2;
}

getMax 函数接收两个整数参数 data1 和 data2,使用三元运算符 ? : 比较它们的大小,若 data1 大于 data2 则返回 data1,否则返回 data2,即返回两个数中的最大值。

int getMin(int data1, int data2)
{
    return data1 < data2 ? data1 : data2;
}

getMin 函数同样接收两个整数参数 data1 和 data2,使用三元运算符比较大小,若 data1 小于 data2 则返回 data1,否则返回 data2,也就是返回两个数中的最小值。

int getSum(int data1, int data2)
{
    return data1 + data2;
}

getSum 函数接收两个整数参数 data1 和 data2,直接返回它们的和。

2. main 函数部分
int main()
{
    int a = 10;
    int b = 20;
    int ret;

    int(*pfunc[3])(int, int) = {getMax, getMin, getSum};

在 main 函数中,首先定义了两个整数变量 a 和 b 并分别初始化为 10 和 20,ret 用于存储函数调用的结果。然后声明并初始化了一个函数指针数组 pfunc,数组包含 3 个元素,每个元素都是一个指向返回值为 int 类型、接收两个 int 类型参数的函数的指针,分别指向 getMaxgetMin 和 getSum 函数。

    for (int i = 0; i < 3; i++) {
        ret = (*pfunc[i])(a, b);
        printf("ret=%d\n", ret);
    }

使用 for 循环遍历函数指针数组 pfunc。在每次循环中,通过 (*pfunc[i])(a, b) 调用当前指针所指向的函数,并将 a 和 b 作为参数传递给该函数,将调用结果存储在 ret 中,最后使用 printf 函数输出结果。

    return 0;
}

main 函数返回 0,表示程序正常结束。

3.核心定义与本质区别

特性指针数组(Pointer Array)数组指针(Array Pointer)
本质是一个 数组,元素是 指针(如 int* arr[5])。是一个 指针,指向一个 数组(如 int (*ptr)[5])。
语法声明类型* 数组名[长度],如 char* strs[3];类型 (*指针名)[长度],如 int (*arr_ptr)[10];
内存布局数组元素是指针,指针指向的内存可能不连续。指针指向一个连续的数组内存块,数组元素在内存中连续。
操作对象操作多个独立的指针(每个指针可指向不同内存)。操作一个整体的数组(将数组视为一个整体对象)。
  • 指针数组它本质是数组,数组中的每个元素都是指针。这些指针能够指向各种类型的数据,像整数、字符、结构体等,甚至可以指向其他数组或者函数。
  • 数组指针它本质是指针,该指针指向一个数组。也就是说,数组指针保存的是数组的起始地址,并且它的类型与所指向的数组类型相匹配。

二、适用场景对比

1. 指针数组(适用场景)
  • 管理多个独立的指针
    当需要存储多个指针(如字符串指针、函数指针、对象指针等)时,使用指针数组。
    示例 1:字符串数组

    char* strs[] = {"hello", "world", "array"}; // 每个元素是char*,指向不同字符串
    

    优势:方便管理长度不同的字符串(无需固定数组总长度),节省内存(仅存储指针,而非复制字符串内容)。

  • 函数指针数组
    当需要通过索引快速调用不同函数时,使用函数指针数组。
    示例 2:计算器功能选择

    int (*funcs[])(int, int) = {getMax, getMin, getSum}; // 指针数组存储函数指针
    result = funcs[0](a, b); // 调用第一个函数(取最大值)
    
     

    优势:通过索引直接调用函数,简化代码逻辑,提高可扩展性。

  • 动态内存管理
    每个指针可独立分配内存,适合处理动态变化的数据(如不同长度的数组、链表头指针等)。

    int* arr1 = malloc(5*sizeof(int));
    int* arr2 = malloc(10*sizeof(int));
    int* ptr_arr[] = {arr1, arr2}; // 指针数组管理多个动态数组
    
2. 数组指针(适用场景)
  • 处理多维数组或固定长度数组
    当需要将数组作为整体处理(尤其是二维数组),或函数参数需要保留数组维度信息时,使用数组指针。
    示例 1:二维数组作为函数参数

    void print_array(int (*arr)[5], int rows) { // arr是指向包含5个int的数组的指针
        for (int i=0; i<rows; i++) {
            for (int j=0; j<5; j++) {
                printf("%d ", arr[i][j]);
            }
        }
    }
    int matrix[3][5] = {{1,2,3,4,5}, ...};
    print_array(matrix, 3); // 传递二维数组,数组指针保留列数5的信息
    
     

    优势:直接通过指针操作二维数组,避免退化为int**(二维指针数组)导致的维度信息丢失。

  • 访问连续内存块
    当需要操作一个连续的数组(如栈上的数组、固定大小的缓冲区),并将其视为整体时,使用数组指针。

    int arr[10] = {1,2,3,...};
    int (*arr_ptr)[10] = &arr; // 数组指针指向整个数组
    printf("%d", (*arr_ptr)[5]); // 访问第6个元素
    
     

    优势:确保指针操作时保持数组的边界,避免越界(编译时可检查数组长度)。

  • 类型安全与语法简洁
    数组指针在声明时明确指定了数组元素的类型和长度,编译器可进行更强的类型检查,避免指针运算错误。

三、关键决策点

  1. 数据结构的形态

    • 如果需要管理 多个独立的指针(如字符串、函数、动态数组),选 指针数组
    • 如果需要操作 一个整体的数组(尤其是多维数组、固定长度数组),选 数组指针
  2. 内存连续性

    • 若数据在内存中 不连续(每个指针指向不同位置),用 指针数组(如字符串数组)。
    • 若数据 连续存储(如栈上的数组、静态分配的二维数组),用 数组指针
  3. 函数参数传递

    • 当函数需要接收 二维数组 时,用数组指针(如 int (*arr)[cols]),保留列数信息,避免退化为int**导致的访问错误。
    • 当函数需要接收 多个独立指针(如多个字符串),用指针数组(如 char* strs[])。
  4. 动态性需求

    • 若需要动态添加 / 删除指针(如指针指向的内容动态变化),用 指针数组(可动态分配数组本身或每个指针)。
    • 若数组长度固定(编译时已知),用 数组指针(更安全,语法更直接)。

四、示例对比

场景:处理字符串集合
  • 指针数组(推荐):

    char* names[] = {"Alice", "Bob", "Charlie"}; // 每个字符串独立存储,指针数组管理地址
    
     

    优势:字符串长度不同,直接存储指针更高效。

  • 数组指针(不适用):

    char (*arr_ptr)[20]; // 指向固定长度20的字符数组,无法处理长度不同的字符串
    
     

    劣势:需固定数组长度,浪费内存或导致越界。

场景:处理二维数组
  • 数组指针(推荐):

    int matrix[3][5];
    int (*ptr)[5] = matrix; // 数组指针指向二维数组的一行(每行5个int)
    
     

    优势:直接通过ptr[i][j]访问元素,保留列数信息。

  • 指针数组(不适用,除非是 “行指针数组”):

    int* rows[3]; // 每行是独立的int*,需手动分配每行内存,适合不规则二维数组(如锯齿数组)
    
     

    适用场景:当二维数组各行长度不同时(锯齿数组),用指针数组。

五、总结

  • 选指针数组:当需要管理 多个独立的指针(如字符串、函数、动态数组),且数据内存不连续或长度可变时。
  • 选数组指针:当需要操作 一个整体的连续数组(尤其是多维数组、固定长度数组),并希望保留数组维度信息或进行类型安全的操作时。

 

 2.指针函数 

指针函数本质上是一个函数,只不过它的返回值是一个指针。这个指针可以指向各种类型的数据,如整数、字符、结构体等。

指针函数的声明格式通常为:

数据类型 *函数名(参数列表);

其中,数据类型 表示指针所指向的数据的类型,函数名 是函数的名称,参数列表 是函数的参数类型和数量。


#include <stdio.h>

// 沿用例8.25的指针函数,用于获取学生成绩指针
int* getPosPerson(int pos, int (*pstu)[4]) {
    int *p;
    p = (int *)(pstu + pos);
    return p;
}

int main() {
    int scores[3][4] = {  // 假设的学生成绩(3学生,4门课)
        {55, 66, 77, 88},  // 学生0:第1门不及格
        {66, 55, 99, 100}, // 学生1:第2门不及格
        {11, 22, 33, 59}   // 学生2:全部不及格
    };
    int student_num = 3;  // 学生数量
    int course_num = 4;   // 课程数量

    // 遍历每个学生
    for (int i = 0; i < student_num; i++) {
        int has_failure = 0;  // 标记是否有不及格课程
        int *student_scores = getPosPerson(i, scores);  // 获取当前学生成绩指针

        // 遍历学生的每门课程成绩
        for (int j = 0; j < course_num; j++) {
            if (*(student_scores + j) < 60) {  // 检查成绩是否不及格
                has_failure = 1;
                break;
            }
        }
        // 输出有不及格课程的学生学号
        if (has_failure) {
            printf("学生号 %d 存在不及格课程\n", i);
        }
    }
    return 0;
}

 区别

概念

  • 指针函数:本质是一个函数,和普通函数一样具有特定的功能和执行逻辑,只不过其返回值是一个指针类型。这个指针可以指向各种类型的数据,如基本数据类型(整数、字符等)、数组或者结构体等。例如,在内存管理场景中,可能需要返回一个指向动态分配内存块的指针。
  • 函数指针:本质是一个指针变量,它存储的是函数的地址。在程序编译时,每个函数都会被分配一段内存空间,函数名就代表该函数的起始地址,函数指针就是用来存放这个地址的。通过函数指针,可以在运行时动态地调用不同的函数。

语法

  • 指针函数:声明格式为 数据类型 *函数名(参数列表);。例如,int *func(int a, int b); 表示 func 是一个指针函数,它接受两个 int 类型的参数,返回一个指向 int 类型数据的指针。这里的 * 结合顺序是从右到左,先确定 func 是一个函数,再确定其返回值是指针。
  • 函数指针:声明格式为 数据类型 (*指针名)(参数列表);。例如,int (*fp)(int, int); 表示 fp 是一个函数指针,它可以指向返回值为 int 类型、接受两个 int 类型参数的函数。这里的 * 被括号括起来,表明 fp 首先是一个指针,然后指向一个函数。

用途

  • 指针函数
    • 动态内存分配:在程序运行过程中,根据需要动态地分配内存,并将分配的内存地址返回给调用者。例如,malloc 函数就是一个典型的指针函数,它返回一个指向分配内存块起始地址的指针。
    • 返回复杂数据结构:当函数需要返回一个数组或者结构体等复杂数据结构时,由于函数不能直接返回数组,通常会返回指向这些数据结构的指针。例如,一个函数可以返回一个指向自定义结构体的指针,方便在调用者中访问和操作结构体的成员。
  • 函数指针
    • 实现回调机制:在很多场景下,需要将一个函数作为参数传递给另一个函数,以便在合适的时机调用,这就是回调函数。例如,在一些排序算法(如 qsort 函数)中,可以传递一个比较函数的指针作为参数,从而实现自定义的比较规则。
    • 动态函数调用:可以在运行时根据不同的条件决定调用哪个函数,增强程序的灵活性。比如在一个游戏程序中,根据玩家选择的不同角色,调用不同的角色技能函数。
    • 构建函数表:在一些状态机或者菜单系统中,使用函数指针数组(函数表)来管理不同的操作函数,通过索引来快速调用相应的函数。

 3.二级(多级)指针

定义

  • 一级指针:普通指针是指向某个变量的内存地址的变量。例如int a = 10; int *p = &a;,这里p是一级指针,存储变量a的地址。
  • 二级指针:二级指针是指向一级指针的指针。它存储的是一级指针的内存地址。比如int **pp = &p;pp就是二级指针,它指向一级指针p
  • 多级指针:以此类推,多级指针就是指向更高一级指针的指针。
声明
  • 二级指针数据类型 **指针名; ,像int **pp;声明了一个指向int类型指针的二级指针。
  • 多级指针:更多级指针可依此类推,如int ***ppp;声明了一个三级指针。

二级指针的声明格式为:

数据类型 **指针名;

其中,数据类型 表示最终指向的数据的类型,指针名 是二级指针变量的名称。例如,int **pp 声明了一个二级指针 pp,它最终可以指向一个 int 类型的数据,不过中间需要经过一个一级指针。

使用场景

#include <stdio.h>

int main()
{
	int data=100;
	int *p=&data;
	printf("data的地址是:%p\n",&data);
	printf("p保存data地址是:%p\n",p);
	
	int **p2=&p;
	printf("p2保存p的地址是:%p\n",p2);
	printf("*p2是:%p\n",*p2);//对 p2 进行一次解引用操作 *p2,得到 p 本身,也就是 data 的地址
	printf("**p2来访问data:%d\n",**p2);
	
	int ***p3=&p2;
	printf("p3保存p2的地址是:%p\n",p3);
	printf("*p3是:%p\n",*p3);//对 p3 进行一次解引用操作 *p3,得到 p2 本身,也就是 p 的地址
	printf("**p3来访问data的值:%d\n",***p3);
	return 0;
}
/*int ***p3 = &p2;:定义一个三级指针 p3,并将二级指针 p2 的地址赋给 p3。也就是说,p3 指向 p2。
printf("p3保存p2的地址是:%p\n", p3);:输出三级指针 p3 所保存的地址,即 p2 的地址。
printf("*p3是:%p\n", *p3);:对 p3 进行一次解引用操作 *p3,得到 p2 本身,也就是 p 的地址。
printf("**p3来访问data的值:%d\n", ***p3);:对 p3 进行三次解引用操作 ***p3,先通过 *p3 得到 p2,再对 p2 进行解引用得到 p,最后对 p 进行解引用得到 data 的值,所以这里输出 100。
*/
  • int ***p3 = &p2;:定义一个三级指针 p3,并将二级指针 p2 的地址赋给 p3。也就是说,p3 指向 p2。
  • printf("p3保存p2的地址是:%p\n", p3);:输出三级指针 p3 所保存的地址,即 p2 的地址。
  • printf("*p3是:%p\n", *p3);:对 p3 进行一次解引用操作 *p3,得到 p2 本身,也就是 p 的地址。
  • printf("**p3来访问data的值:%d\n", ***p3);:对 p3 进行三次解引用操作 ***p3,先通过 *p3 得到 p2,再对 p2 进行解引用得到 p,最后对 p 进行解引用得到 data 的值,所以这里输出 100。

#include <stdio.h>

void getPosperson(int pos,int (*pstu)[4],int **ppos)//函数指针,返回指针的函数 用于接收 main 函数中 ppos 指针的地址。
{
	*ppos=(int *)(pstu+pos);
	
}
int main()
{
	int scores[3][4]={
		{55,66,77,88},
		{66,55,99,100},
		{11,22,33,90},
	};
	int *ppos;
	int pos;
	printf("请输入你需要看的学生号数:0,1,2\n");
	scanf("%d",&pos);
	getPosperson(pos,scores,&ppos);
	for(int  i=0;i<4;i++){
		printf("%d ",*ppos++);
		
	}
	
	return 0;
}

这段 C 语言代码的主要功能是让用户输入一个学生的编号(范围是 0 - 2),然后程序会输出该学生的四门课程成绩。具体实现是通过一个函数 getPosperson 来获取指定学生成绩数组的起始地址,然后在 main 函数中遍历该学生的四门课程成绩并输出。

代码详细分析

1. getPosperson 函数
void getPosperson(int pos, int (*pstu)[4], int **ppos) {
    *ppos = (int *)(pstu + pos);
}
  • 参数
    • pos:表示要查询的学生编号,范围是 0 - 2。
    • pstu:这是一个指向包含 4 个 int 类型元素的数组的指针,用于指向存储学生成绩的二维数组 scores
    • ppos:这是一个二级指针,用于接收 main 函数中 ppos 指针的地址,通过修改 *ppos 的值,可以改变 main 函数中 ppos 指针的指向。
  • 功能
    • pstu + pos 计算出指向指定学生成绩数组的起始地址,由于 pstu 是指向包含 4 个 int 类型元素的数组的指针,所以 pstu + pos 会跳过 pos 行,指向第 pos 个学生的成绩数组。
    • (int *) 是类型转换,将 pstu + pos 的类型转换为 int * 类型,以便赋值给 *ppos
    • *ppos = (int *)(pstu + pos); 将计算得到的地址赋值给 *ppos,也就是修改了 main 函数中 ppos 指针的指向,使其指向第 pos 个学生的成绩数组。
2. main 函数
int main() {
    int scores[3][4] = {
        {55, 66, 77, 88},
        {66, 55, 99, 100},
        {11, 22, 33, 90},
    };
    int *ppos;
    int pos;
    printf("请输入你需要看的学生号数:0,1,2\n");
    scanf("%d", &pos);
    getPosperson(pos, scores, &ppos);
    for (int i = 0; i < 4; i++) {
        printf("%d ", *ppos++);
    }
    return 0;
}
  • 变量定义
    • scores:这是一个 3 行 4 列的二维数组,用于存储 3 个学生的四门课程成绩。
    • ppos:这是一个一级指针,用于指向指定学生的成绩数组。
    • pos:用于存储用户输入的学生编号。
  • 用户输入
    • printf("请输入你需要看的学生号数:0,1,2\n"); 提示用户输入学生编号。
    • scanf("%d", &pos); 读取用户输入的学生编号。
  • 调用函数
    • getPosperson(pos, scores, &ppos); 调用 getPosperson 函数,将用户输入的学生编号 pos、二维数组 scores 的地址以及 ppos 指针的地址传递给该函数,以便获取指定学生成绩数组的起始地址。
  • 输出成绩
    • for (int i = 0; i < 4; i++) { printf("%d ", *ppos++); } 通过 for 循环遍历指定学生的四门课程成绩,并使用 *ppos++ 输出每个成绩,同时 ppos 指针向后移动一位。

当你通过函数调用来修改调用函数指针指向的时候,就像通过函数调用修改某变量的值的时候一样。

3. 总结

 中小公司大概率考题

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

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

相关文章

批量修改记事本文本文件编码,可以解决文本文件乱码问题

对于文本文件来说&#xff0c;通常都可以设置不同的编码格式&#xff0c;每一种不同的编码格式支持的字符都可能是不一样的。因此当编码格式出现错误的时候&#xff0c;文本文件可能会出现乱码的问题。如何将文本文件的编码由一种格式变为另外一种格式呢&#xff1f;如果文件出…

亚马逊云科技提供完全托管的DeepSeek-R1模型

近日&#xff0c;亚马逊云科技宣布在Amazon Bedrock上线完全托管的DeepSeek-R1模型。DeepSeek是首个登陆Amazon Bedrock的国产大模型&#xff0c;自今年1月底推出以来&#xff0c;已有数千客户使用Amazon Bedrock的自定义模型导入功能部署了DeepSeek-R1模型。 DeepSeek在过去几…

利用 Chrome devTools Source Override 实现JS逆向破解案例

之前讲解 Chrome 一大强势技术 override 时&#xff0c;给的案例貌似没有给大家留下多深的印象 浏览器本地替换&#xff08;local overrides&#xff09;快速定位前端样式问题的案例详解&#xff08;也是hook js的手段&#xff09;_浏览器的 overrides 替换功能-CSDN博客 其实…

容器C++ ——STL常用容器

string容器 string构造函数 #include<iostream> using namespace std; #include<string.h> void test01() {string s1;//默认构造const char* str "hello world";string s2(str);//传入char*cout << "s2" << s2 << endl;s…

npu踩坑记录

之前使用qwen系列模型在ascend 910a卡进行了一些生成任务, 贴出踩坑过程也许对遇到类似问题的同学有帮助: ) 目录 千问 qwq32环境配置 代码部署 生成内容清洗 已生成内容清洗 生成过程优化 Failed to initialize the HCCP process问题 assistant 的历史回答丢失 推理执…

Linux信号——信号的产生(1)

注&#xff1a;信号vs信号量&#xff1a;两者没有任何关系&#xff01; 信号是什么&#xff1f; Linux系统提供的&#xff0c;让用户&#xff08;进程&#xff09;给其他进程发送异步信息的一种方式。 进程看待信号的方式&#xff1a; 1.信号在没有发生的时候&#xff0c;进…

【机器学习】——机器学习思考总结

摘要 这篇文章深入探讨了机器学习中的数据相关问题&#xff0c;重点分析了神经网络&#xff08;DNN&#xff09;的学习机制&#xff0c;包括层级特征提取、非线性激活函数、反向传播和梯度下降等关键机制。同时&#xff0c;文章还讨论了数据集大小的标准、机器学习训练数据量的…

JMeter进行分布式压测

从机&#xff1a; 1、确认防火墙是否关闭&#xff1b; 2、打开网络设置&#xff0c;关闭多余端口&#xff1b;&#xff08;避免远程访问不到&#xff09; 3、打开JMeter/bin 目录底下的jmeter.properties&#xff1b; remove_hosts设置当前访问地址&#xff0c;192.XXXXX&…

快速入手-基于Django-rest-framework的第三方认证插件(SimpleJWT)权限认证扩展返回用户等其他信息(十一)

1、修改serializer.py&#xff0c;增加自定义类 # 自定义用户登录token等返回信息 class MyTokenObtainPair(TokenObtainPairView): def post(self, request, *args, **kwargs): serializer self.get_serializer(datarequest.data) try: serializer.is_valid(raise_exceptio…

关于IP免实名的那些事

IP技术已成为个人与企业保护隐私、提升网络效率的重要工具。其核心原理是通过中介服务器转发用户请求&#xff0c;隐藏真实IP地址&#xff0c;从而实现匿名访问、突破地域限制等目标。而“免实名”代理IP的出现&#xff0c;进一步简化了使用流程&#xff0c;用户无需提交身份信…

【SQL性能优化】预编译SQL:从注入防御到性能飞跃

&#x1f525; 开篇&#xff1a;直面SQL的"阿喀琉斯之踵" 假设你正在开发电商系统&#x1f6d2;&#xff0c;当用户搜索商品时&#xff1a; -- 普通SQL拼接&#xff08;危险&#xff01;&#xff09; String sql "SELECT * FROM products WHERE name "…

SQL Server从安装到入门一文掌握应用能力。

本篇文章主要讲解,SQL Server的安装教程及入门使用的基础知识,通过本篇文章你可以快速掌握SQL Server的建库、建表、增加、查询、删除、修改等基本数据库操作能力。 作者:任聪聪 日期:2025年3月31日 一、SQL Server 介绍: SQL Server 是微软旗下的一款主流且优质的数据库…

力扣HOT100之矩阵:54. 螺旋矩阵

这道题之前在代码随想录里刷过类似的&#xff0c;还有印象&#xff0c;我就按照当初代码随想录的思路做了一下&#xff0c;结果怎么都做不对&#xff0c;因为按照代码随想录的边界条件设置&#xff0c;当行数和列数都为奇数时&#xff0c;最后一个元素无法被添加到数组中&#…

5.1 WPF路由事件以及文本样式

一、路由事件 WPF中存在一种路由事件&#xff08;routed event&#xff09;&#xff0c;该事件将发送到包含该控件所在层次的所有控件&#xff0c;如果不希望继续向更高的方向传递&#xff0c;只要设置e.Handled true即可。 这种从本控件-->父控件->父的父控件的事件&am…

Python数据可视化-第1章-数据可视化与matplotlib

环境 开发工具 VSCode库的版本 numpy1.26.4 matplotlib3.10.1 ipympl0.9.7教材 本书为《Python数据可视化》一书的配套内容&#xff0c;本章为第1章 数据可视化与matplotlib 本文主要介绍了什么是数据集可视化&#xff0c;数据可视化的目的&#xff0c;常见的数据可视化方式…

Flutter敏感词过滤实战:基于AC自动机的高效解决方案

Flutter敏感词过滤实战&#xff1a;基于AC自动机的高效解决方案 在社交、直播、论坛等UGC场景中&#xff0c;敏感词过滤是保障平台安全的关键防线。本文将深入解析基于AC自动机的Flutter敏感词过滤实现方案&#xff0c;通过原理剖析实战代码性能对比&#xff0c;带你打造毫秒级…

Odoo/OpenERP 和 psql 命令行的快速参考总结

Odoo/OpenERP 和 psql 命令行的快速参考总结 psql 命令行选项 选项意义-a从脚本中响应所有输入-A取消表数据输出的对齐模式-c <查询>仅运行一个简单的查询&#xff0c;然后退出-d <数据库名>指定连接的数据库名&#xff08;默认为当前登录用户名&#xff09;-e回显…

Vue中使用antd-table组件时,树形表格展开配置不生效-defaultExpandedRowKeys-默认展开配置不生效

defaultExpandedRowKeys属性 defaultExpandAllRows这个属性仅仅是用来设置默认值的,只在第一次渲染的时候起作用,后续再去改变,无法实现响应式 解决方案一 a-table表格添加key属性,当每次获取值时,动态改变key,以达到重新渲染的效果 <a-table:key="tableKey"…

VRRP交换机三层架构综合实验

题目要求&#xff1a; 1&#xff0c;内网Ip地址使用172.16.0.0/16分配 说明可以划分多个子网&#xff0c;图中有2个VLAN&#xff0c;可以根据VLAN划分 2&#xff0c;sw1和SW2之间互为备份 互为备份通常通过VRRP&#xff08;虚拟路由冗余协议&#xff09;来实现。VRRP会在两个…

基于卷积神经网络的眼疾识别系统,resnet50,efficentnet(pytorch框架,python代码)

更多图像分类、图像识别、目标检测、图像分割等项目可从主页查看 功能演示&#xff1a; 眼疾识别系统resnet50&#xff0c;efficentnet&#xff0c;卷积神经网络&#xff08;pytorch框架&#xff0c;python代码&#xff09;_哔哩哔哩_bilibili &#xff08;一&#xff09;简介…