C语言:第14天笔记

内容提要

  • 指针
    • 变量指针与指针变量
      • 指针变量做函数参数
      • 指针变量指向数组元素
    • 数组指针与指针数组
      • 数组指针

回顾

变量指针与指针变量

变量指针:变量的地址值(首地址),本质是指针、地址

指针变量:存储指针的变量,本质是变量

指针操作的两个运算符

&:取地址运算符,作用是获取指定对象的地址

*:指针操作符,如果这个符号前面有数据类型,就被称作声明指针;如果没有,就被称作解引用

关于指针中指向的问题

int a = 10;
int *p = &a   // 指针变量p指向对象a

指向:指针变量存储了谁的地址,这个指针变量就指向了谁!

使用间接操作,如何交换a和b的值

  1. 交换指向:指向发生改变,指向对象的数据不会改变
  2. 交换数据:指向不发生改变,指向对象的数据会改变

关于指针变量

指针变量本质上还是变量,只不过指针变量只能存储其他内存单元的地址,我们借助于指针变量,可以实现内存空间的共享。

关于共享

  1. 共享他人的空间

    int a = 10;
    int *p = &a;
    int *q = p;  // p和q共享a的空间
    
  2. 共享自己的空间

    int a = 10;
    int *p = &a;  // a和p共享a的空间
    

指针

变量指针与指针变量

指针变量做函数参数

指针变量做函数参数往往传递的是变量的首地址,借助于指针变量间接访问是可以修改实参变量数据的。

指针有一个作用就是,通过形参修改实参,我们将这样的参数称之为输出型参数

案例

需求:有a,b两个变量,要求交换后输出,使用函数处理,用指针变量做函数的参数

  • 方式1:交换指向(指针指向改变,指向对象的数据不变)

    代码:

    #include <stdio.h>

    /**

    • 方式1:交换指向
      */
      void swap(int *p_a, int *p_b)
      {
      int *p_t;

      // 交换
      p_t = p_a;
      p_a = p_b;
      p_b = p_t;

      printf(“交换后:%d,%d\n”,*p_a, *p_b); // 交换后:4,3
      }

    int main(int argc,char *argv[])
    {
    int a = 3, b = 4;
    printf(“交换前:%d,%d\n”, a, b);// 交换前:3,4

    swap(&a, &b);  // 传参的过程可以理解:int *p_a = &a, int *p_b = &b;return 0;
    

    }

    
    
  • 方式2:交换数据(指针指向不变,指向对象的数据改变)

    代码:

    #include <stdio.h>

    /**

    • 方式2:交换数据
      */
      void swap(int *p_a, int *p_b)
      {
      int temp;

      // 交换
      temp = *p_a;
      *p_a = *p_b; // 将p_b指向对象的值赋给p_a指向的对象
      *p_b = temp; // p_b:访问指针变量的空间,*p_b:访问指针指向对象的空间

      printf(“交换后:%d,%d\n”,*p_a, *p_b); // 交换后:4,3
      }

    int main(int argc,char *argv[])
    {
    int a = 3, b = 4;
    printf(“交换前:%d,%d\n”, a, b);// 交换前:3,4

    swap(&a, &b);  // 传参的过程可以理解:int *p_a = &a, int *p_b = &b;return 0;
    

    }

    
    
指针变量指向数组元素【重难点】
数组元素的指针
  • 数组的指针就是数组中第一个元素的地址,也就是数组的首地址。
  • 数组元素的指针是指数组的首地址。因此,同样可以用指针变量来指向数组或者数组元素。
  • 在C语言中,由于数组名代表数组的首地址,因此数组名实际上也是指针。访问数组名就是访问数组首地址。

范例:

#include <stdio.h>int main(int argc,char *argv[])
{// 创建一个数组int arr[] = {11,22,33};int *p1 = &arr[0];  // 指针变量指向数组arr第一个元素,指针的范围就是数组元素int *p2 = arr;      // 等价于上面写法,数组名默认就是一个指向首元素地址的指针,推荐printf("%p,%p,%p\n", p1, p2, arr);  // 0x7ffe33135e2c,0x7ffe33135e2c,0x7ffe33135e2creturn 0;
}

注意:虽然我们定义了一个指针变量接收了数组地址,但不能理解为指针变量指向了数组,而应该理解为指向来了数组的元素(默认为第1个元素)。

指针的运算

指针运算:前提是指针变量必须要指向数组的某个元素。(指针运算只能在同一数组内进行,并且只能是元素之间的偏移

序号指针运算偏移量说明
1自增:p++、++p、p+=1sizeof(type)指向下一个元素的首地址
需边界检测,防止越界
2自减:p--、--p、p-=1sizeof(type)指向上一个元素的首地址
需边界检测,防止越界
3加n个数:p+nn * sizeof(type)指向后面n个元素的首地址
需边界检测,防止越界
4减n个数:p-nn * sizeof(type)指向前面n个元素的首地址
需边界检测,防止越界
5指针相减:p1 - p2`(p1 - p2)
6指针比较:p1 < p2逻辑值:真(1),假(0)前面的指针小于后面的指针

注意:

  • 上面表格中的type,是指针指向数组的元素的类型

  • sizeof不支持运算,举例:

    #include <stdio.h>int main(int argc,char *argv[])
    {int a = 10;printf("sizeof(a)=%lu,sizeof(int)=%lu,sizeof(++a)=%lu\n", sizeof(a), sizeof(int), sizeof(++a)); // sizeof(a)=4,sizeof(int)=4,sizeof(a++)=4return 0;
    }

    说明

    ① 如果指针变量p已指向数组中的一个元素,则p+1指向同一数组中的 下一个元素,p-1指向同一数组中的上一个元素。即p+1或p-1也表示地址。但要注意的是,虽然指针变量p中存放的是地址,但p+1并不表示该地址加1,而表示在原地址的基础上加了该数据类型所占的字节数d(d = sizeof(数据类型)) 。

    ② 如果p原来指向a[0],执行++p后p的值改变了,在p的原值基础上加d,这样p就指向数组的下一个元素a[1]。d是数组元素占的字节数。

    ③ 如果p的初值为&a[0]则p+i 和a+i 就是数组元素a[i]的地址,或者说,它们指向a数组的第 i 个元素 。

    *(p+i)或*(a+i)是p+i或a+i所指向的数组元素,即a[i]。

    ⑤ 如果指针变量p1和p2都指向同一数组,如执行p2-p1,结果是两个地址之差除以数组元素的长度d。

案例
#include <stdio.h>
#include <math.h>int main(int argc,char *argv[])
{// 创建一个用来实现指针运算的数组int arr[] = {11,22,33,44,55};int *p1 = arr + 4;  // 55 等价于 arr[4]int *p2 = arr + 1;  // 22 等价于 arr[1]size_t size = fabs(p2 - p1); // 3 = fabs(22对应的地址 - 55对应的地址) / int的字节数printf("*p1=%d,*p2=%d,size=%lu,&arr[1]+2=%d\n", *p1, *p2, size, *(&arr[1]+2));return 0;
}

运行结果:
在这里插入图片描述
在这里插入图片描述

案例
  • 需求:通过下标法和指针法遍历数组

  • 代码:

    #include <stdio.h>/*** 下标法遍历数组*/ 
    void arr1(int arr[], int len) // 数组作为函数参数,传递的是数组的首地址(数组被降级为指针)
    {for (register int i = 0; i < len; i++) printf("%-4d", arr[i]);printf("\n");
    }/*** 指针法遍历数组*/ 
    void arr2(int arr[], int len)
    {// 创建一个指针变量,接收数组,此时实际上接收到的是数组中第一个元素的地址int *p = arr;for (register int i = 0; i < len; i++) printf("%-4d",/* *(arr+i) 等价于*/ *(p+i));printf("\n");
    }/*** 指针法遍历数组*/ 
    void arr3(int arr[], int len)
    {int *p = arr;for (register int i = 0; i < len; i++){printf("%-4d", *p);p++;}printf("\n");
    }/*** 指针法遍历数组*/ 
    void arr4(int arr[], int len)
    {int *p = arr;for(; p < arr + len; p++) // 判断的时候不能写作 p + len,因为p在变化,而arr没有变化{printf("%-4d", *p);}printf("\n");
    }int main(int argc,char *argv[])
    {int arr[] = {11,22,33,44,55};int len = sizeof(arr) / sizeof(arr[0]);arr1(arr, len);arr2(arr, len);arr3(arr, len);arr4(arr, len);return 0;
    }
案例
  • 需求:推导以下代码的运行结果

  • 代码:

    
    #include <stdio.h>int arr2()
    {// 创建一个普通数组int arr[] = {11,22,33,44,55,66,77,88};int *p = arr;printf("%d\n", *p);  // 11p++;  // 指针偏移 1 * sizeof(int) 指针移动到22这个位置printf("%d\n", *p);  // 22int x = *p++;  // 第1步:解引用p的值赋值给x, x = 22; 第2步:p++,指针移动到33这个位置printf("%d,%d\n", x, *p);// 22,33int y = *(++p);// 第1步:++p,指针偏移到44这个位置;第2步:对44这个地址解引用,得到44printf("%d,%d\n", y, *p);// 44,44(*p)++;        // 第1步:对p解引用得到44;第2步:对44这个值+1,得到45printf("%d\n",*p); // 45
    }
    

※小贴士

*p++:先解引用p,然后p这个指针自增(指针自增)

 int arr[] = {11,22,33}, *p = arr;int x = *p++; // x=11,*p=22   ① *p解引用,其实就是将指向的对象a的值赋值给x ② 指针p++,也就是指针偏移一位

(*p)++:先解引用p,然后使用解引用出来的数据自增(数值自增)

 int arr[] = {11,22,33}, *p = arr;int x = (*p)++; // x=11,*p=12   ① *p解引用,其实就是将指向的对象a的值赋值给x ② 解引用出来的对象数据自增
通过指针引用数组元素

引用一个数组元素,可以用:

① 下标法:如arr[i]

② 指针法:如*(arr + 1) 或者*(p+i)。其中arr是数组名,p是指向数组元素的指针变量,其初始值:p = arr;

案例

需求:

  • 下标法:(通过改变下标输出所有元素)

    #include <stdio.h>int main()
    {int arr[10], i;// 给数组元素赋值for (i = 0; i < 10; i++) scanf("%d", &arr[i]);// 遍历数组元素for (i = 0; i < 10; i++) printf("%-4d", arr[i]);printf("\n");return 0;
    }
    
  • 指针法(地址):(通过数组名计算出数组元素的地址,找出数组元素值)

    #include <stdio.h>int main()
    {int arr[10], i;// 给数组元素赋值for (i = 0; i < 10; i++) scanf("%d", &arr[i]);// 遍历数组元素for (i = 0; i < 10; i++) printf("%-4d", *(arr + i));   printf("\n");return 0;
    }
    
  • 指针法(指针变量):(用指针变量指向数组元素)

    #include <stdio.h>int main()
    {int arr[10], i, *p;// 给数组元素赋值for (i = 0; i < 10; i++) scanf("%d", &arr[i]);// 遍历数组元素for (p = arr; p < (arr + 10); p++) printf("%-4d", *p);printf("\n");return 0;
    }
    

    注意:数组一旦创建,就无法改变其值。

    以上3种写法比较:

    • 第①种写法和第②种写法执行效率相同。系统是将arr[i]转换为*(arr+i)处理的,即先计算出地址,因此比较费时。
    • 第③种方法比第①②种方法快。用指针变量直接指向数组元素,不必每次都重新计算地址。(p++)能大大提高执行效率。
    • 用第①种写法比较直观,而用地址法或者指针变量的方法难以很快判断出当前处理的元素。

    使用指针变量指向数组元素时(上面第③种写法),注意以下前两点:

    *(p--) 相当于arr[i--],先*p,再p--; *(p++) 相当于arr[i++],先*p,再p++;

    *(--p) 相当于arr[--i],先--p,再* *(++p) 相当于arr[++i],先++p,再*;

    *p++ 先*p,再p++

    (*p)++ 先*p,再*p++

    具体关系参照下面表格:

    操作类型指针表达式数组下标等价执行顺序指针移动方向是否改变指针地址
    前置自减+取值*(--p)arr[--i]1. 指针前移
    2. 取新地址的值
    向前(←)
    前置自加+取值*(++p)arr[++i]1. 指针后移
    2. 取新地址的值
    向后(→)
    后置自减+取值*(p--)arr[i--]1. 取原地址的值
    2. 指针前移
    向前(←)
    后置自加+取值*(p++)arr[i++]1. 取原地址的值
    2. 指针后移
    向后(→)
    后置自减(简写)*p--arr[i--]1. 取原地址的值
    2. 指针前移
    向前(←)
    后置自加(简写)*p++arr[i++]1. 取原地址的值
    2. 指针后移
    向后(→)
    取值后值自减(*p)--arr[i]--1. 取原地址的值
    2. 值-1
    不移动×
    取值后值自加(*p)++arr[i]++1. 取原地址的值
    2. 值+1
    不移动×
数组名作函数参数

① 形参和实参都是数组名

// arr 数组 形参
void fun(int arr[], int len){..}void main()
{int arr[] = {11,22,33};int len = sizeof(arr) / sizeof(arr[0]);// arr 数组 实参fun(arr, len);
}

② 实参用数组名,形参用指针变量

// arr 指针 形参
void fun(int *arr, int len){..}void main()
{int arr[] = {11,22,33};int len = sizeof(arr) / sizeof(arr[0]);// arr 数组 实参fun(arr, len);
}

③ 实参和形参都用指针变量

// arr 指针 形参
void fun(int *arr, int len){..}void main()
{int arr[] = {11,22,33};int len = sizeof(arr) / sizeof(arr[0]);// arr 指针 实参int *p = arr;fun(p, len);
}

④ 实参用指针,形参用数组名

// arr 数组 形参
void fun(int arr[], int len){..}void main()
{int arr[] = {11,22,33};int len = sizeof(arr) / sizeof(arr[0]);// arr 指针 实参int *p = arr;fun(p, len);
}
案例:

需求:将数组a中的n个整数按相反顺序存放(数组反转)

分析:

在这里插入图片描述

代码:


#include <stdio.h>/*** 数组的反转:下标法*/ 
void inv1(int arr[], int len)
{// 反转思路:第0个和最后一个交换,第1个和倒数第二个交换...// 定义循环变量和临时变量register int i = 0, temp;// 遍历数组for (; i < len/2; i++){temp = arr[i];arr[i] = arr[len-1-i];arr[len-1-i] = temp;}
}/*** 数组的反转:指针法*/ 
void inv2(int *p, int len)
{// 反转思路:第0个和最后一个交换,第1个和倒数第二个交换...// 定义循环变量和临时变量int *i = p, *j = p + len - 1, temp;// 遍历数组for (; i < j; i++, j--){temp = *i;*i = *j;*j = temp;}
}/*** 遍历数组*/ 
void list(const int *arr, int len)  // const int *arr = arr;
{const int *p = arr; // 添加const之后,指针指向对象的值不变,指针指向可以改变for (; p < arr + len; p++) printf("%-4d", *p); printf("\n");
}int main(int argc,char *argv[])
{int arr[] = {11,12,13,14,15};int len = sizeof(arr) / sizeof(arr[0]);list(arr, len);inv1(arr, len);list(arr, len);inv2(arr, len);list(arr, len);return 0;
}

数组指针与指针数组

数组指针
定义

**概念:**数组指针是指向数组的指针(指针变量),本质上还是指针。

指针变量指向数组元素和数组指针的区别?

在这里插入图片描述

特点:

① 先有数组,再有指针

② 它指向的是一个完整的数组

一维数组指针

语法:

数据类型 (*指针变量名)[容量];

案例:


#include <stdio.h>int main(int argc,char *argv[])
{// 一维数组指针int arr[] = {100,200,300};int len = sizeof(arr) / sizeof(arr[0]);// 定义一个数组指针(一维数组指针)int (*p)[len] = &arr; // arr默认指向数组元素,&arr指向整个数组,需要注意的的是,它们表示的范围不同,地址相同// p++:此时不能p++,否则会越界printf("&arr=%p,arr=%p,&arr[0]=%p\n", &arr, arr, &arr[0]); // arr 等价于 &arr[0]// 如何访问数组指针printf("%d\n", (*p)[2]); // 300// 遍历数组指针for (int i = 0; i < len; i++) printf("%-6d", (*p)[i]); printf("\n");return 0;
}

我们之前所学的是指向数组元素的指针,本质上是指针变量;现在我们学的是指向数组的指针,叫作数组指针。

二维数组指针

语法:

数据类型 (*指针变量名)[行容量][列容量];

案例:

  • 写法1:二维数组指针指向二维数组【不推荐】

    #include <stdio.h>int main(int argc,char *argv[])
    {// 创建一个二维数组int arr[][3] = {10,20,30,100,200,300,1000,2000,3000};// 定义一个二维数组指针指向二维数组int (*p)[][3] = &arr;// 遍历数组for (int i = 0; i < 3; i++){for (int j = 0; j < 3; j++){printf("%-6d", (*p)[i][j]);}}printf("\n");return 0;
    }
  • 写法2:一维数组指针指向二维数组【推荐】

    #include <stdio.h>int main(int argc,char *argv[])
    {// 创建一个二维数组int arr[][3] = {10,20,30,100,200,300,1000,2000,3000};// 定义一个一维数组指针指向二维数组,相当于指针指向的是二维数组的行 [行容量]int (*p)[3] = arr; // 等价于 &arr[0] (*p):指向数组的行   int arr[] = {100, 200, 300}; int *p = arr;  解引用p 得到第一个元素// 遍历数组for (int i = 0; i < 3; i++){for (int j = 0; j < 3; j++){printf("%-6d", p[i][j]);// printf("%-6d", *(*(p+i)+j));// printf("%-6d", (*(p+i))[j]);// printf("%-6d", *(p[i]+j));}}printf("\n");return 0;
    }

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【笔记】活度系数推导

文章目录一、理想溶液的假设与局限性1.1 理想溶液的定义1.2 理想溶液的局限性二、活度与活度系数的引入2.1 活度的定义2.2 修正后的化学势表达式三、活度系数的物理意义四、为什么需要活度系数&#xff1f;4.1 理论需求4.2 扩散理论中的必要性五、活度系数的具体作用5.1 在化学…

基于Docker的GPU版本飞桨PaddleOCR部署深度指南(国内镜像)2025年7月底测试好用:从理论到实践的完整技术方案

还是网上没找到这个基于Docker的GPU版本飞桨PaddleOCR部署教程&#xff0c;于是就有了这一篇。 这个的确坑很多&#xff0c;可能后面变一个版本就不好用了&#xff0c;也是为什么这篇博客不完全粘贴代码的原因。 端口是示例&#xff0c;可以随意改。在人工智能与文档数字化高速…

Python-初学openCV——图像预处理(三)

目录 一、边缘填充 1、边界复制 2、边界反射 3、边界反射101 4、边界常数 5、边界包裹 二、透视变换 三、图像掩膜 1、制作掩膜 2、与运算 3、颜色替换 四、ROI切割 五、图像添加水印 一、边缘填充 我们对图像进行处理后&#xff0c;需要对空出来的区域进行一个填充…

【ESP32设备通信】-W5500与ESP32 /ESP32 S3集成

W5500与ESP32 /ESP32 S3集成 文章目录 W5500与ESP32 /ESP32 S3集成 1、W5500介绍 2、硬件准备与接线 3、代码实现 3.1 以太网设置 3.2 简单HTTP请求 3.3 HTTPS请求 3.4 查询证书 ESP32 凭借其强大的 Wi-Fi 功能,一直是物联网项目的热门选择。ESP32 现在支持带有 SSL 的原生以太…

vue - 使用canvas绘制验证码

封装绘制验证码 verify-code.vue<template><div class"captcha"><canvas ref"canvasRef" :width"width" :height"height" click"refreshCaptcha"></canvas></div> </template><scri…

[10月考试] F

[10月考试] F 题目描述 给定长度为 nnn 的序列 ana_nan​&#xff0c;保证 aia_iai​ 为非负整数。 mmm 次询问&#xff0c;每次给定区间 l,rl,rl,r&#xff0c;求出 al,al1,…,ara_l,a_{l1},\ldots,a_ral​,al1​,…,ar​ 的 mexmexmex。 对于一个序列&#xff0c;定义其 mexm…

收集了全球55个AI写作工具

我们即将推出一整套AI生产力工具矩阵&#xff0c;覆盖内容创作&#xff08;AI写作助手&#xff09;、视觉设计&#xff08;智能图像处理&#xff09;、音视频制作&#xff08;自动转录与编辑&#xff09;及智能编程等多个核心领域。这些解决方案通过先进的机器学习算法&#xf…

Elastic 劳动力的生成式 AI:ElasticGPT 的幕后解析

作者&#xff1a;来自 Elastic Jay Shah, Adhish Thite ElasticGPT — 由 Elastic 提供支持&#xff0c;专为 Elastic 打造 ElasticGPT 是我们基于检索增强生成&#xff08;RAG&#xff09;框架构建的内部生成式 AI &#xff08;GenAI&#xff09;助手。它是使用 Elastic 自有…

CS231n-2017 Assignment1

KNN&#xff1a;这里要求我们完成一个KNN分类器&#xff0c;实现对图片使用KNN算法进行分类标签k_nearest_neighbor.py这里要求我们完成4个接口# X:测试集 # 使用两个循环 def compute_distances_two_loops(self, X):num_test X.shape[0]num_train self.X_train.shape[0]dist…

[python][flask]Flask-Principal 使用详解

Flask-Principal 是一个专为 Flask 应用设计的身份管理和权限控制扩展。它能够帮助开发者轻松实现用户身份验证和权限管理&#xff0c;从而提升应用的安全性和用户体验。该项目最初由 Ali Afshar 开发&#xff0c;现已成为 Pallets 社区生态系统的一部分&#xff0c;由社区共同…

抖音与B站爬虫实战,获取核心数据

本文将深入讲解两大主流短视频平台&#xff08;抖音、B站&#xff09;的爬虫实战技术&#xff0c;提供可直接运行的代码解决方案&#xff0c;并分享突破反爬机制的核心技巧。一、平台特性与爬虫难点对比平台数据价值主要反爬措施推荐抓取方式抖音视频数据、用户画像、热榜签名验…

WSL切换网络模式

WSL切换网络模式问题WSL从NAT改成MIRRORED找到WSL Setting修改配置重启电脑&#xff08;注意不是重启WSL&#xff09;运行pio run验证IP问题 从鱼香ROS买了一个小鱼车&#xff0c;开始学习&#xff0c;然而装环境都要搞死我了。 垃圾VirtualBox我新买的电脑&#xff0c;装个Vi…

[Linux入门] Linux 远程访问及控制全解析:从入门到实战

目录 一、SSH 远程管理&#xff1a;为什么它是远程访问的首选&#xff1f; 1️⃣什么是 SSH&#xff1f; 2️⃣SSH 为什么比传统工具更安全&#xff1f; 3️⃣SSH 的 “三大组成部分” 4️⃣SSH 工作的 “五步流程” 5️⃣常用 SSH 工具 二、实战&#xff1a;构建 SSH 远…

n8n AI资讯聚合与分发自动化教程:从数据获取到微信与Notion集成

引言 n8n简介&#xff1a;自动化工作流利器 n8n是一款功能强大的开源自动化工具&#xff0c;采用独特的“公平代码”&#xff08;Fair-Code&#xff09;许可模式&#xff0c;旨在帮助用户连接各种应用程序和服务&#xff0c;从而实现工作流的自动化。它通过直观的可视化界面&am…

递归查询美国加速-技术演进与行业应用深度解析

在当今数据驱动的时代&#xff0c;递归查询已成为处理层级数据的核心技术&#xff0c;尤其在美国科技领域获得广泛应用。本文将深入解析递归查询在美国加速发展的关键因素&#xff0c;包括技术演进、行业应用场景以及性能优化策略&#xff0c;帮助读者全面理解这一重要技术趋势…

【AIGC专栏】WebUI实现图片的缩放

图片的缩放包含如下的各类不同的缩放模型。 Lanczos Lanczos重采样是一种数学上精确的方法,用于图像放大或缩小。它使用了一种称为 sinc 函数的数学公式,可以在保留图像细节的同时减少锯齿效应。 Nearest 最近邻插值是一种简单的图像放大方法,通过复制最近的像素值来填充新…

Libevent(4)之使用教程(3)配置

Libevent(4)之使用教程(3)配置事件 Author: Once Day Date: 2025年7月27日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 本文档翻译于&#xff1a;Fast portable non-bl…

若依前后端分离版学习笔记(三)——表结构介绍

前言&#xff1a; 这一节将ruoyi框架中数据库中的表结构过一遍&#xff0c;查看都有哪些表及其表结构及关联关系&#xff0c;为后续代码学习做准备。 一 代码生成表记录代码生成的业务表及相关字段1 代码生成业务表 CREATE TABLE gen_table (table_id bigint(20) NOT NULL AUTO…

NFS服务安装与使用

概述 内网需要使用NFS服务挂载到其他服务器&#xff0c;用做数据备份使用。 安装 # Centos yum install -y nfs-utils # Ubuntu apt install nfs-common配置 # 编辑 vim /etc/exports # 输入内容 /public/KOL-ESbackup 172.29.1.0/24 192.168.8.63 192.168.8.64 192.168.8.65(r…

使用adb 发送广播 动态改变app内的值

前言 在开发过程中有时候我们需要做一些调试工作。可以通过adb发送广播实现。 广播注册 注意最后一个参数&#xff0c;Context.RECEIVER_EXPORTED 这是Android 34以后强制要求的&#xff0c;方便外部发送这个广播。否则会报错val filter IntentFilter()filter.addAction("…