返回顶部
首页 > 资讯 > 前端开发 > html >C指针的使用技巧有哪些
  • 621
分享到

C指针的使用技巧有哪些

2024-04-02 19:04:59 621人浏览 薄情痞子
摘要

这篇文章主要讲解了“C指针的使用技巧有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C指针的使用技巧有哪些”吧!1. 开胃菜:修改主调函数中的数据//&

这篇文章主要讲解了“C指针的使用技巧有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C指针的使用技巧有哪些”吧!

1. 开胃菜:修改主调函数中的数据

// 交换 2 个 int 型数据 void demo1_swap_data(int *a, int *b) {     int tmp = *a;     *a = *b;     *b = tmp; }  void demo1() {     int i = 1;     int j = 2;     printf("before: i = %d, j = %d \n", i, j);     demo1_swap_data(&i, &j);     printf("after:  i = %d, j = %d \n", i, j); }

这个代码不用解释了,大家一看就明白。如果再过多解释的话,好像在侮辱智商。

2. 在被调用函数中,分配系统资源

代码的目的是:在被调用函数中,从堆区分配 size 个字节的空间,返回给主调函数中的 pData 指针。

void demo2_malloc_heap_error(char *buf, int size) {     buf = (char *)malloc(size);     printf("buf = 0x%x \n", buf); }  void demo2_malloc_heap_ok(char **buf, int size) {     *buf = (char *)malloc(size);     printf("*buf = 0x%x \n", *buf); }  void demo2() {     int size = 1024;     char *pData = NULL;      // 错误用法     demo2_malloc_heap_error(pData, size);     printf("&pData = 0x%x, pData = 0x%x \n", &pData, pData);      // 正确用法     demo2_malloc_heap_ok(&pData, size);     printf("&pData = 0x%x, pData = 0x%x \n", &pData, pData);     free(pData); }

2.1 错误用法

刚进入被调用函数 demo2_malloc_heap_error 的时候,形参 buff 是一个 char* 型指针,它的值等于 pData  变量的值,也就是说 buff 与 pData 的值相同(都为 NULL),内存模型如图:

C指针的使用技巧有哪些

在被调用函数中执行 malloc 语句之后,从堆区申请得到的地址空间赋值给 buf,就是说它就指向了这个新的地址空间,而 pData  里仍然是NULL,内存模型如下:

C指针的使用技巧有哪些

从图中可以看到,pData 的内存中一直是 NULL,没有指向任何堆空间。另外,由于形参 buf  是放在函数的栈区的,从被调函数中返回的时候,堆区这块申请的空间就被泄漏了。

2.2 正确用法

刚进入被调用函数 demo2_malloc_heap_error 的时候,形参 buf 是一个 char* 型的二级指针,就是说 buf  里的值是另一个指针变量的地址,在这个示例中 buf 里的值就是 pData 这个指针变量的地址,内存模型如下:

C指针的使用技巧有哪些

在被调用函数中执行 malloc 语句之后,从堆区申请得到的地址空间赋值给 *buf,因为 buf = &pData,所以 *buf 就相当于是  pData,那么从堆区申请得到的地址空间就赋值 pData 变量,内存模型如下:

C指针的使用技巧有哪些

从被调函数中返回之后,pData 就正确的得到了一块堆空间,别忘了使用之后要主动释放。

3. 传递函数指针

从上篇文章中我们知道,函数名本身就代表一个地址,在这个地址中存储着函数体中定义的一连串指令码,只要给这个地址后面加上一个调用符(小括号),就进入这个函数中执行。在实际程序中,函数名常常作为函数参数来进行传递。

熟悉c++的小伙伴都知道,在标准库中对容器类型的数据进行各种算法操作时,可以传入用户自己的提供的算法函数(如果不传入函数,标准库就使用默认的)。

下面是一个示例代码,对一个 int 行的数组进行排序,排序函数 demo3_handle_data  的最后一个参数是一个函数指针,因此需要传入一个具体的排序算法函数。示例中有 2 个候选函数可以使用:

  • 降序排列: demo3_alGorithm_decend;

  • 升序排列: demo3_algorithm_ascend;

typedef int BOOL; #define FALSE 0 #define TRUE  1  BOOL demo3_algorithm_decend(int a, int b) {     return a > b; }  BOOL demo3_algorithm_ascend(int a, int b) {     return a < b; }  typedef BOOL (*Func)(int, int); void demo3_handle_data(int *data, int size, Func pf) {     for (int i = 0; i < size - 1; ++i)     {         for (int j = 0; j < size - 1 - i; ++j)         {             // 调用传入的排序函数             if (pf(data[j], data[j+1]))             {                 int tmp = data[j];                 data[j] = data[j + 1];                 data[j + 1] = tmp;             }         }     } }  void demo3() {     int a[5] = {5, 1, 9, 2, 6};     int size = sizeof(a)/sizeof(int);     // 调用排序函数,需要传递排序算法函数     //demo3_handle_data(a, size, demo3_algorithm_decend); // 降序排列     demo3_handle_data(a, size, demo3_algorithm_ascend);   // 升序排列     for (int i = 0; i < size; ++i)         printf("%d ", a[i]);     printf("\n"); }

这个就不用画图了,函数指针 pf 就指向了传入的那个函数地址,在排序的时候
直接调用就可以了。

4. 指向结构体的指针

在嵌入式开发中,指向结构体的指针使用特别广泛,这里以智能家居中的一条控制指令来举例。在一个智能家居系统中,存在各种各样的设备(插座、电灯、电动窗帘等),每个设备的控制指令都是不一样的,因此可以在每个设备的控制指令结构体中的最前面,放置所有指令都需要的、通用的成员变量,这些变量可以称为指令头(指令头中包含一个代表命令类型的枚举变量)。

当处理一条控制指令时,先用一个通用命令(指令头)的指针来接收指令,然后根据命令类型枚举变量来区分,把控制指令强制转换成具体的那个设备的数据结构,这样就可以获取到控制指令中特定的控制数据了。

本质上,与 Java/C++ 中的接口、基类的概念类似。

// 指令类型枚举 typedef enum _CMD_TYPE_ {     CMD_TYPE_CONTROL_SWITCH = 1,     CMD_TYPE_CONTROL_LAMP, } CMD_TYPE;  // 通用的指令数据结构(指令头) typedef struct _CmdBase_ {     CMD_TYPE cmdType; // 指令类型     int deviceId;     // 设备 Id } CmdBase;  typedef struct _CmdControlSwitch_ {     // 前 2 个参数是指令头     CMD_TYPE cmdType;        int deviceId;          // 下面都有这个指令私有的数据     int slot;  // 排插上的哪个插口     int state; // 0:断开, 1:接通 } CmdControlSwitch;  typedef struct _CmdControlLamp_ {     // 前 2 个参数是指令头     CMD_TYPE cmdType;     int deviceId;          // 下面都有这个指令私有的数据     int color;      // 颜色     int brightness; // 亮度 } CmdControlLamp;  // 参数是指令头指针 void demo4_control_device(CmdBase *pcmd) {     // 根据指令头中的命令类型,把指令强制转换成具体设备的指令     if (CMD_TYPE_CONTROL_SWITCH == pcmd->cmdType)     {         // 类型强制转换         CmdControlSwitch *cmd = pcmd;         printf("control switch. slot = %d, state = %d \n", cmd->slot, cmd->state);     }     else if (CMD_TYPE_CONTROL_LAMP == pcmd->cmdType)     {         // 类型强制转换         CmdControlLamp * cmd = pcmd;         printf("control lamp.   color = 0x%x, brightness = %d \n", cmd->color, cmd->brightness);     } }  void demo4() {     // 指令1:控制一个开关     CmdControlSwitch cmd1 = {CMD_TYPE_CONTROL_SWITCH, 1, 3, 0};     demo4_control_device(&cmd1);      // 指令2:控制一个灯泡     CmdControlLamp cmd2 = {CMD_TYPE_CONTROL_LAMP, 2, 0x112233, 90};     demo4_control_device(&cmd2); }

5. 函数指针数组

这个示例在上篇文章中演示过,为了完整性,这里再贴一下。

int add(int a, int b) { return a + b; } int sub(int a, int b) { return a - b; } int mul(int a, int b) { return a * b; } int divide(int a, int b) { return a / b; }  void demo5() {     int a = 4, b = 2;     int (*p[4])(int, int);     p[0] = add;     p[1] = sub;     p[2] = mul;     p[3] = divide;     printf("%d + %d = %d \n", a, b, p[0](a, b));     printf("%d - %d = %d \n", a, b, p[1](a, b));     printf("%d * %d = %d \n", a, b, p[2](a, b));     printf("%d / %d = %d \n", a, b, p[3](a, b)); }

6. 在结构体中使用柔性数组

先不解释概念,我们先来看一个代码示例:

// 一个结构体,成员变量 data 是指针 typedef struct _ArraryMemberStruct_NotGood_ {     int num;     char *data; } ArraryMemberStruct_NotGood;  void demo6_not_good() {     // 打印结构体的内存大小     int size = sizeof(ArraryMemberStruct_NotGood);     printf("size = %d \n", size);      // 分配一个结构体指针     ArraryMemberStruct_NotGood *ams = (ArraryMemberStruct_NotGood *)malloc(size);     ams->num = 1;      // 为结构体中的 data 指针分配空间     ams->data = (char *)malloc(1024);     strcpy(ams->data, "hello");     printf("ams->data = %s \n", ams->data);      // 打印结构体指针、成员变量的地址     printf("ams = 0x%x \n", ams);     printf("ams->num  = 0x%x \n", &ams->num);     printf("ams->data = 0x%x \n", ams->data);      // 释放空间     free(ams->data);     free(ams); }

在我的电脑上,打印结果如下:

C指针的使用技巧有哪些

可以看到:该结构体一共有 8 个字节(int 型占 4 个字节,指针型占 4 个字节)。

结构体中的 data 成员是一个指针变量,需要单独为它申请一块空间才可以使用。而且在结构体使用之后,需要先释放 data,然后释放结构体指针  ams,顺序不能错。这样使用起来,是不是有点麻烦?

于是,C99 标准就定义了一个语法:flexible array  member(柔性数组),直接上代码(下面的代码如果编译时遇到警告,请检查下编译器对这个语法的支持):

// 一个结构体,成员变量是未指明大小的数组 typedef struct _ArraryMemberStruct_Good_ {     int num;     char data[]; } ArraryMemberStruct_Good;  void demo6_good() {     // 打印结构体的大小     int size = sizeof(ArraryMemberStruct_Good);     printf("size = %d \n", size);      // 为结构体指针分配空间     ArraryMemberStruct_Good *ams = (ArraryMemberStruct_Good *)malloc(size + 1024);      strcpy(ams->data, "hello");     printf("ams->data = %s \n", ams->data);      // 打印结构体指针、成员变量的地址     printf("ams = 0x%x \n", ams);     printf("ams->num  = 0x%x \n", &ams->num);     printf("ams->data = 0x%x \n", ams->data);      // 释放空间     free(ams); }

打印结果如下:

C指针的使用技巧有哪些

与第一个例子中有下面几个不同点:

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区

  2. 结构体的大小变成了 4;

  3. 为结构体指针分配空间时,除了结构体本身的大小外,还申请了 data 需要的空间大小;

  4. 不需要为 data 单独分配空间了;

  5. 释放空间时,直接释放结构体指针即可;

是不是用起来简单多了?!这就是柔性数组的好处。

  • 从语法上来说,柔性数组就是指结构体中最后一个元素个数未知的数组,也可以理解为长度为 0,那么就可以让这个结构体称为可变长的。

  • 前面说过,数组名就代表一个地址,是一个不变的地址常量。在结构体中,数组名仅仅是一个符号而已,只代表一个偏移量,不会占用具体的空间。

另外,柔性数组可以是任意类型。这里示例大家多多体会,在很多通讯类的处理场景中,常常见到这种用法。

7. 通过指针来获取结构体中成员变量的偏移量

这个标题读起来似乎有点拗口,拆分一下:在一个结构体变量中,可以利用指针操作的技巧,获取某个成员变量的地址、距离结构体变量的开始地址、之间的偏移量。

linux 内核代码中你可以看到很多地方都利用了这个技巧,代码如下:

#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE*)0)->MEMBER))  typedef struct _OffsetStruct_ {     int a;     int b;     int c; } OffsetStruct;  void demo7() {     OffsetStruct os;     // 打印结构体变量、成员变量的地址     printf("&os = 0x%x \n", &os);     printf("&os->a = 0x%x \n", &os.a);     printf("&os->b = 0x%x \n", &os.b);     printf("&os->c = 0x%x \n", &os.c);     printf("===== \n");     // 打印成员变量地址,与结构体变量开始地址,之间的偏移量     printf("offset: a = %d \n", (char *)&os.a - (char *)&os);     printf("offset: b = %d \n", (char *)&os.b - (char *)&os);     printf("offset: c = %d \n", (char *)&os.c - (char *)&os);     printf("===== \n");     // 通过指针的强制类型转换来获取偏移量     printf("offset: a = %d \n", (size_t) &((OffsetStruct*)0)->a);     printf("offset: b = %d \n", (size_t) &((OffsetStruct*)0)->b);     printf("offset: c = %d \n", (size_t) &((OffsetStruct*)0)->c);     printf("===== \n");     // 利用宏定义来得到成员变量的偏移量     printf("offset: a = %d \n", offsetof(OffsetStruct, a));     printf("offset: b = %d \n", offsetof(OffsetStruct, b));     printf("offset: c = %d \n", offsetof(OffsetStruct, c)); }

先来看打印结果:

 C指针的使用技巧有哪些

前面 4 行的打印信息不需要解释了,直接看下面这个内存模型即可理解。

C指针的使用技巧有哪些

下面这个语句也不需要多解释,就是把两个地址的值进行相减,得到距离结构体变量开始地址的偏移量,注意:需要把地址强转成 char*  型之后,才可以相减。

printf("offset: a = %d \n", (char *)&os.a - (char *)&os);

下面这条语句需要好好理解:

printf("offset: a = %d \n", (size_t) &((OffsetStruct*)0)->a);

数字 0  看成是一个地址,也就是一个指针。上篇文章解释过,指针就代表内存中的一块空间,至于你把这块空间里的数据看作是什么,这个随便你,你只要告诉编译器,编译器就按照你的意思去操作这些数据。

现在我们把 0 这个地址里的数据看成是一个 OffsetStruct 结构体变量(通过强制转换来告诉编译器),这样就得到了一个 OffsetStruct  结构体指针(下图中绿色横线),然后得到该指针变量中的成员变量 a(蓝色横线),再然后通过取地址符 & 得到 a 的地址(橙色横线),最后把这个地址强转成  size_t 类型(红色横线)。

因为这个结构体指针变量是从 0 地址开始的,因此,成员变量 a 的地址就是 a 距离结构体变量开始地址的偏移量。

上面的描述过程,如果感觉拗口,请结合下面这张图再读几遍:

C指针的使用技巧有哪些

上面这张图如果能看懂的话,那么最后一种通过宏定义获取偏移量的打印语句也就明白了,无非就是把代码抽象成宏定义了,方便调用:

#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE*)0)->MEMBER))  printf("offset: a = %d \n", offsetof(OffsetStruct, a));

可能有小伙伴提出:获取这个偏移量有什么用啊?那就请接着看下面的示例 8。

8. 通过结构体中成员变量的指针,来获取该结构体的指针

标题同样比较拗口,直接结合代码来看:

typedef struct _OffsetStruct_ {     int a;     int b;     int c; } OffsetStruct;

假设有一个 OffsetStruct 结构体变量 os,我们只知道 os 中成员变量 c 的地址(指针),那么我们想得到变量 os  的地址(指针),应该怎么做?这就是标题所描述的目的。

下面代码中的宏定义 container_of 同样是来自于 Linux 内核中的(大家平常没事时多挖掘,可以发现很多好东西)。

#define container_of(ptr, type, member) ({ \      const typeof( ((type *)0)->member ) *__mptr = (ptr); \      (type *)( (char *)__mptr - offsetof(type,member) );})  void demo8() {     // 下面 3 行仅仅是演示 typeof 关键字的用法     int n = 1;     typeof(n) m = 2;  // 定义相同类型的变量m     printf("n = %d, m = %d \n", n, m);       // 定义结构体变量,并初始化     OffsetStruct os = {1, 2, 3};          // 打印结构体变量的地址、成员变量的值(方便后面验证)     printf("&os = 0x%x \n", &os);     printf("os.a = %d, os.b = %d, os.c = %d \n", os.a, os.b, os.c);      printf("===== \n");          // 假设只知道某个成员变量的地址     int *pc = &os.c;     OffsetStruct *p = NULL;          // 根据成员变量的地址,得到结构体变量的地址     p = container_of(pc, OffsetStruct, c);          // 打印指针的地址、成员变量的值     printf("p = 0x%x \n", p);     printf("p->a = %d, p->b = %d, p->c = %d \n", p->a, p->b, p->c); }

先看打印结果:

C指针的使用技巧有哪些

首先要清楚宏定义中参数的类型:

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区

  2. ptr: 成员变量的指针;

  3. type: 结构体类型;

  4. member:成员变量的名称;

这里的重点就是理解宏定义 container_of,结合下面这张图,把宏定义拆开来进行描述:

C指针的使用技巧有哪些

宏定义中的第 1 条语句分析:

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区

  2. 绿色横线:把数字 0 看成是一个指针,强转成结构体 type 类型;

  3. 蓝色横线:获取该结构体指针中的成员变量 member;

  4. 橙色横线:利用 typeof 关键字,获取该 member 的类型,然后定义这个类型的一个指针变量 __mptr;

  5. 红色横线:把宏参数 ptr 赋值给 __mptr 变量;

宏定义中的第 2 条语句分析:

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区

  2. 绿色横线:利用 demo7 中的 offset 宏定义,得到成员变量 member 距离结构体变量开始地址的偏移量,而这个成员变量指针刚才已经知道了,就是  __mptr;

  3. 蓝色横线:把 __mptr 这个地址,减去它自己距离结构体变量开始地址的偏移量,就得到了该结构体变量的开始地址;

  4. 橙色横线:最后把这个指针(此时是 char* 型),强转成结构体 type 类型的指针;

感谢各位的阅读,以上就是“C指针的使用技巧有哪些”的内容了,经过本文的学习后,相信大家对C指针的使用技巧有哪些这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

--结束END--

本文标题: C指针的使用技巧有哪些

本文链接: https://lsjlt.com/news/83923.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C指针的使用技巧有哪些
    这篇文章主要讲解了“C指针的使用技巧有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C指针的使用技巧有哪些”吧!1. 开胃菜:修改主调函数中的数据//&...
    99+
    2024-04-02
  • c++中ostringstream使用技巧有哪些
    在C++中,ostringstream是一个非常有用的类,它允许将各种数据类型转换为字符串。以下是一些使用ostringstream...
    99+
    2023-09-14
    c++
  • C++函数指针的用法有哪些
    这篇“C++函数指针的用法有哪些”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C++函数指针的用法有哪些”文章吧。C++函数...
    99+
    2023-06-26
  • C语言指针的使用技巧与注意事项
    C语言指针的应用技巧与注意事项 一、引言 作为一种面向过程的编程语言,C语言具有高效、灵活的特点。而指针则是C语言中一个非常重要的概念,对于理解和掌握C语言来说至关重要。本文将介绍C语...
    99+
    2024-02-26
    传递 动态内存 野指针 注意事项:空指针
  • c语言中使用指针有哪些好处
    在C语言中使用指针有以下几个好处:1. 节省内存:通过使用指针,可以有效地管理内存,避免内存的浪费。指针可以动态地分配和释放内存,只...
    99+
    2023-08-18
    c语言
  • C/C++指针知识点有哪些
    本篇内容介绍了“C/C++指针知识点有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!基础部分关于内存内存含义:存储器:计算机的组成中,用...
    99+
    2023-06-03
  • C++的引用和指针有哪些区别
    本篇内容主要讲解“C++的引用和指针有哪些区别”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++的引用和指针有哪些区别”吧!引用和指针有如下三种区别:1 引用必须在声明时初始化,而指针不用;2...
    99+
    2023-06-17
  • 常用的C++小技巧有哪些
    小编给大家分享一下常用的C++小技巧有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1、头文件是引用<iostream.h>还是<iostr...
    99+
    2023-06-22
  • C++ 函数的指针参数的使用场景有哪些?
    c++++ 函数指针参数的使用场景是:回调函数:将函数传递给其他函数作为回调,以便在某些事件发生时调用。事件处理:使用事件分发系统处理来自不同源的事件。算法排序:使用函数指针作为比较函数...
    99+
    2024-04-20
    函数指针 参数传递 c++
  • HTML的使用技巧有哪些
    本篇内容主要讲解“HTML的使用技巧有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“HTML的使用技巧有哪些”吧!1、html---position/rel...
    99+
    2024-04-02
  • 使用Vue.js的技巧有哪些
    小编给大家分享一下使用Vue.js的技巧有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!第一招:化繁为简的Watchers场...
    99+
    2024-04-02
  • iFrame的使用技巧有哪些
    这篇文章主要介绍“iFrame的使用技巧有哪些”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“iFrame的使用技巧有哪些”文章能帮助大家解决问题。   1.作为弹...
    99+
    2024-04-02
  • PS的使用技巧有哪些
    这篇文章主要介绍了PS的使用技巧有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇PS的使用技巧有哪些文章都会有所收获,下面我们一起来看看吧。   1.Ctrl+滚轮缩放。...
    99+
    2024-04-02
  • Git的使用技巧有哪些
    本篇内容主要讲解“Git的使用技巧有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Git的使用技巧有哪些”吧!1、你的 ~/.gitconfig 文件在**...
    99+
    2024-04-02
  • 使用CSS的技巧有哪些
    本篇内容介绍了“使用CSS的技巧有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.box-sizin...
    99+
    2024-04-02
  • MySQL的使用技巧有哪些
    这篇文章主要介绍“MySQL的使用技巧有哪些”,在日常操作中,相信很多人在MySQL的使用技巧有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”MySQL的使用技巧有哪些”...
    99+
    2024-04-02
  • JS的使用技巧有哪些
    今天小编给大家分享一下JS的使用技巧有哪些的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一、数组乱序在使用需要某种程度的随机...
    99+
    2023-06-29
  • VSCode的使用技巧有哪些
    本篇内容主要讲解“VSCode的使用技巧有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“VSCode的使用技巧有哪些”吧!1. 查看日志步骤1. 执行Ctrl+Shift+P步骤2. 搜 s...
    99+
    2023-06-25
  • Vue的使用技巧有哪些
    本篇内容介绍了“Vue的使用技巧有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1. 将一个 prop 限制在一个类型的列表中使用 pr...
    99+
    2023-06-29
  • KeePassXC的使用技巧有哪些
    这篇“KeePassXC的使用技巧有哪些”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“KeePassXC的使用技巧有哪些”文...
    99+
    2023-06-27
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作