8.2 数组遍历访问

news2024/7/6 18:07:44

本节必须掌握的知识点:

        示例三十

        代码分析                               

        汇编解析     

在上一节中介绍了数组相关的概念,而在本节中将介绍数组的使用。

8.2.1 示例三十

       ■访问数组

示例代码三十

●第一步:分析需求,设计程序结构框架。

分析需求:

1.定义一个 int 型数组,其中有 5 个元素组成,5 个元素分别为 1、2、3、4、5。 int arr[5]={1,2,3,4,5};获取 arr 数组中第 2 个元素(从0开始计数)并打印出来。

2.将 arr 数组中第 2 个元素的值修改为 6。然后把改变后的数组遍历一遍,查看数组的元素是否有变化。

设计程序结构框架:顺序结构+循环结构。先输出数组第 2 个元素的值,再修改数组第 2 个元素的值,最后通过一个for循环语句遍历并输出数组。

●第二步:数据定义,定义恰当的数据结构;

定义一个int类型的数组变量int arr[5] = { 1,2,3,4,5 };

●第三步:分析算法。

(略)

●第四步:编写伪代码,即用我们自己的语言来编写程序。

int main(void) {

    定义一个int类型数组int arr[5] = { 1,2,3,4,5 };

    调用printf函数输出第二个数组元素("%d\n",arr[2]);

    修改第二个数组元素的值:arr[2] = 6;

    调用printf函数输出修改后的第二个数组元素("%d\n",arr[2]);

        for (int i = 0; i < 5; i++)

        {

            调用printf函数输出每个数组元素的值:("arr[%d] = %d\n", i, arr[i]);

         }

        system("pause");

        return 0;                                                                                                    

}

●第五步:画流程图,使用Visio、Excel或者其他绘图工具绘制算法流程和逻辑关系图;(略)

●第六步:编写源程序,其实就是将我们的伪代码翻译成计算机语言;

/*

   修改并访问数组元素

*/

#include <stdio.h>

#include <stdlib.h>

int main(void) {

    int arr[5] = { 1,2,3,4,5 }; //定义数组

    printf("%d\n", arr[2]); //打印arr数组中第2个元素

    arr[2] = 6; //修改数组元素

    printf("arr[2] = %d\n", arr[2]);    //输出修改后的

    for (int i = 0; i < 5; i++)

    {

        printf("arr[%d] = %d\n", i, arr[i]);    //遍历数组元素

    }

    system("pause");

    return 0;

}

●输出结果:

arr[2] = 3

arr[2] = 6

arr[0] = 1

arr[1] = 2

arr[2] = 6

arr[3] = 4

arr[4] = 5

请按任意键继续. . .

8.2.2 代码分析

我们可以利用数组名加中括号下标的形式访问数组中的每一个元素。如果要访问第2个数组元素,它的下标为2。如果有n个数组元素,访问最后一个数组元素下标为n-1,切记计算机中从0开始计数,数组下标不能溢出。

如果修改数组元素的值,同样需要使用数组名加中括号下标的形式表示数组元素,比如将 arr 数组中第 2个元素 3 变成 6。arr[2]=6;

我们可以把数组元素看作是一个独立的变量,变量名是变量存储的地址标号,数组元素就是使用数组下标方式命名的变量名。由于数组元素具有相同的数据类型,且连续存储在内存中,数组下标就是数组元素相对于数组起始地址的偏移(隐含比例因子),所以可以通过改变数组下标的方式变量数组元素。

一维数组使用一个for循环结构遍历数组。循环变量i作为数组下标arr[i]。循环变量i取值范围0~4,代表第0个到第4个数组元素。

8.2.3 汇编解析

汇编代码

;C标准库头文件和导入库

include vcIO.inc

.data

arr sdword  1,2,3,4,5

i sdword  0

.const    

szMsg1 db "arr[2] = %d",0dh,0ah,0

szMsg2 db "arr[%d] = %d",0dh,0ah,0

.code     

start:

       mov eax,[arr+2*4] ;输出第2个数组元素

       invoke printf,offset szMsg1,eax

       mov sdword ptr [arr+2*4],6 ;修改第2个数组元素的值为6

       mov eax,[arr+2*4]

       invoke printf,offset szMsg1,eax  

       .while i < 5

              ;数组元素的地址arr+4*i            

              mov ebx,i

              shl ebx,2

              mov eax,sdword ptr [arr+ebx];取数组元素值[arr+4*i]           

              invoke printf,offset szMsg2,i,eax 

              inc sdword ptr i

       .endw

       ;     

       invoke _getch

       ret                       

end start

●输出结果:

arr[2] = 3

arr[2] = 6

arr[0] = 1

arr[1] = 2

arr[2] = 6

arr[3] = 4

arr[4] = 5

      

访问数组元素:

语句:mov eax,[arr+2*4]     ;输出第2个数组元素

       第二个数组元素地址的计算方法:数组首地址arr+数组元素的偏移;

       偏移的计算方法为:数组下标*4,第2个数组元素的下标为2,每个数组元素占4个字节空间,所以第3个数组元素相对于数组起始地址的偏移为arr+4+4=arr+2*4。

       循环遍历数组元素:[arr+4*i]

       遍历数组元素就是计算每个数组元素的地址的过程。循环变量i作为数组下标,取值范围0~4。每个数组元素占用4个字节空间,4作为比例因子*i,再加上数组的起始地址就是每个数组元素的地址。

反汇编代码

           int arr[5] = { 1,2,3,4,5 }; //定义数组

008E1046  mov         dword ptr [arr],1 

008E104D  mov         dword ptr [ebp-14h],2 

008E1054  mov         dword ptr [ebp-10h],3 

008E105B  mov         dword ptr [ebp-0Ch],4 

008E1062  mov         dword ptr [ebp-8],5 

上述代码初始化数组arr,汇编代码将数组arr定义在数据段中,为全局变量。而C语言中,将数组arr定义为局部变量,在main函数中,因此数组存储在函数的堆栈中。数组首地址arr为第0个数组元素的地址arr+0=ebp-18h,以此类推,第1个数组元素的地址为ebp-14h,第2个数组元素地址为ebp-10h,第3个数组元素地址为ebp-0Ch,第4个数组元素地址为ebp-8,分别存入1,2,3,4,5。

    printf("arr[2] = %d\n", arr[2]); //打印arr数组中第2个元素

008E1069  mov         eax,4  ;比例因子,每个数组元素占4个字节内存

    printf("arr[2] = %d\n", arr[2]); //打印arr数组中第2个元素

008E106E  shl         eax,1  ;4*2

008E1070  mov         ecx,dword ptr arr[eax]  ;将第2个数组元素的值存入ecx

008E1074  push        ecx 

008E1075  push        8E3000h 

008E107A  call        printf (08E1100h)  ;输出第二个数组元素的值

008E107F  add         esp,8 

    arr[2] = 6;  //修改数组元素

008E1082  mov         edx,4  ;比例因子,edx为编译器随机分配的寄存器

008E1087  shl         edx,1  ;4*2

008E1089  mov         dword ptr arr[edx],6  ;将6存入第二个数组元素中

    printf("arr[2] = %d\n", arr[2]);   //输出修改后的

008E1091  mov         eax,4 

008E1096  shl         eax,1 

008E1098  mov         ecx,dword ptr arr[eax] 

008E109C  push        ecx 

008E109D  push        8E3010h 

008E10A2  call        printf (08E1100h)  ;输出第二个数组元素的值

008E10A7  add         esp,8 

    for (int i = 0; i < 5; i++);遍历数组元素

008E10AA  mov         dword ptr [ebp-4],0  ;表达式1

008E10B1  jmp         main+7Ch (08E10BCh) 

008E10B3  mov         edx,dword ptr [ebp-4]  ;表达式3

008E10B6  add         edx,1 

008E10B9  mov         dword ptr [ebp-4],edx 

008E10BC  cmp         dword ptr [ebp-4],5 

008E10C0  jge         main+9Dh (08E10DDh)  ;表达式2

    {

        printf("arr[%d] = %d\n", i, arr[i]);   //遍历数组元素

008E10C2  mov         eax,dword ptr [ebp-4]  ;将循环变量i存入eax

008E10C5  mov         ecx,dword ptr arr[eax*4]  ;取数组元素arr[i*4]的值

008E10C9  push        ecx 

008E10CA  mov         edx,dword ptr [ebp-4] 

008E10CD  push        edx 

008E10CE  push        8E3020h 

008E10D3  call        printf (08E1100h)  ;输出数组元素的值

008E10D8  add         esp,0Ch 

    }

008E10DB  jmp         main+73h (08E10B3h;跳转到表达式3

    system("pause");

008E10DD  push        8E3030h 

008E10E2  call        dword ptr [__imp__system (08E2078h)] 

008E10E8  add         esp,4 

    return 0;

       请读者留意注释代码中数组元素地址的计算方法。需要注意的是:在C语言中,数组arr定义在main函数内,作为局部变量存储在堆栈空间,使用栈内基址寄存器ebp计算每个数组元素的偏移地址。

如何获取第i个元素,其实就是获取其数组首部地址,加上相对偏移就可以计算出第i个元素的存储位置。我们定义的是int型变量,所以这些元素都有共同的特点,它们都是4个字节大小,所以只要找到数组的首地址,就可以找到存储第i个元素的位置。

通过数组内存结构图的形式展示:

首地址  

1

2

3

4

5

 

数组元素地址 = 首地址+偏移

第0个元素的地址 = 首地址+0*元素大小;

第1个元素的地址 = 首地址+1*元素大小;

第2个元素的地址 = 首地址+2*元素大小;

第3个元素的地址 = 首地址+3*元素大小;

第4个元素的地址 = 首地址+4*元素大小;

如果有i个元素:

第i个元素的地址 = 首地址+(i-1)*元素大小。

实验五十九:数组间赋值

在VS中新建项目8-2-2.c:

两个数组 arr1、arr2,arr1[6]={1,2,3,4,5,6};将数组 arr1 里的元素复制到数组 arr2中。

谨慎

既然是把一个数组的元素全部复制到另一个数组中,可不可以这样写呢?arr2=arr1;因为数组也是变量,给变量赋值不就是这样写的。如果你有这样的想法,那你就错了。数组名表示的是数组的起始地址,而不是数组的值。

我们来看正确的答案:

/*

   数组间赋值

*/

#include <stdio.h>

#include <stdlib.h>

int main(void) {

    int arr1[6] = { 1,2,3,4,5,6 };

    int arr2[6] = { 0 };

    //循环遍历数组元素并赋值

    for (int i = 0; i < 6; i++)

    {

        arr2[i] = arr1[i];

        printf("arr2[%d] = %d\n", i, arr2[i]);

    }

    system("pause");

    return 0;

}

●输出结果:

arr2[0] = 1

arr2[1] = 2

arr2[2] = 3

arr2[3] = 4

arr2[4] = 5

arr2[5] = 6

请按任意键继续. . .

●代码解析:

    int arr1[6]= {1,2,3,4,5,6};//定义arr1数组,并初始化。

int arr2[6]={0};//定义arr2数组,并将所有数组元素初始化为0。

使用for循环进行遍历数组中的元素。

1.当i = 0时,arr1[0] = 1,并把arr1[0]的元素赋给arr2[0],此时arr2[0]的元素为1;

输出 arr2[0] = 1;

2.当i = 1时,arr1[1] = 2,并把arr1[1]的元素赋给arr2[1],此时arr2[1]的元素为2;

输出 arr2[1] = 2;

    3.当i = 2时,arr1[2] = 3,并把arr1[2]的元素赋给arr2[2],此时arr2[2]的元素为3;

输出 arr2[2] = 3;

4.当i = 3时,arr1[3] = 4,并把arr1[3]的元素赋给arr2[3],此时arr2[3]的元素为4;

输出 arr2[3] = 4;

    5.当i = 4时,arr1[4] = 5,并把arr1[4]的元素赋给arr2[4],此时arr2[4]的元素为5;

输出 arr2[4] = 5;

    6.当i = 5时,arr1[5] = 6,并把arr1[5]的元素赋给arr2[5],此时arr2[5]的元素为6;

输出 arr2[5] = 6;

实验六十:数组元素倒序排序

在VS中新建项目8-2-3.c:

定义int型数组,并输入6个元素,按倒序的方式排序。

arr[0]与arr[5]交换

arr[1]与arr[4]交换

Arr[2]与arr[3]交换

/*

   数组元素倒序排序

*/

#include <stdio.h>

#include <stdlib.h>

int main(void) {

    int arr[6] = { 0 };

    int i;

    for (i = 0; i < 6; i++)

    {

        printf("arr[%d]=", i);

        scanf_s("%d", &arr[i]);//输出6个元素

    }

    for (i = 0; i < 3; i++) //交换

    {

        int temp = arr[i];//临时变量

        arr[i] = arr[5 - i];

        arr[5 - i] = temp;

    }

    printf("倒序:\n");

    for (i = 0; i < 6; i++)//交换后的数组进行输出

    {

        printf("arr[%d]=%d\n", i, arr[i]);

    }

    system("pause");

    return 0;

}

●输出结果:

arr[0]=1

arr[1]=2

arr[2]=3

arr[3]=4

arr[4]=5

arr[5]=6

倒序:

arr[0]=6

arr[1]=5

arr[2]=4

arr[3]=3

arr[4]=2

arr[5]=1

请按任意键继续. . .

●代码分析:

for(i=0;i<3;i++) //交换

    {

        int temp = arr[i];

        arr[i] = arr[5-i];

        arr[5-i] = temp;

    }

    主要分析这段代码:

    1.当i=0时,把arr[0]的元素放入变量temp中,然后把arr[5-0]的值放入arr[0]中,再把变量temp的值赋值给arr[5],此时完成arr[0]与arr[5]的交换。

2.当i=1时,把arr[1]的元素放入变量temp中,然后把arr[4]的值放入arr[1]中,再把变量temp的值赋值给arr[4],此时完成arr[1]与arr[4]的交换。

3.当i=2时,把arr[2]的元素放入变量temp中,然后把arr[3]的值放入arr[2]中,再把变量temp的值赋值给arr[3],此时完成arr[2]与arr[3]的交换。

实验六十一:数组元素的删除

在VS中新建项目8-2-4.c:

怎样实现数组元素的删除呢?

(1)、查找要删除数字的下标;

(2)、从下标开始,后面一个覆盖前面一个元素;

(3)、数组的总长度-1。

 注意

数组是一块连续的内存空间,一旦被定义,是不可以被改变大小的,因为在定义数组时,就已经写入内存中了,大小也被确定了。既然不能改变,那怎么删除呢?这属于障眼法,删除的元素会被它后面的元素覆盖掉,在控制台输出时,看似被删除了,但删除掉的那块内存已经被写入了,已分配的内存空间是不可能被抹掉的。

/*

   数组元素的删除

*/

#include <stdio.h>

#include <stdlib.h>

int main(void) {

    int arr[] = { 25,11,22,44,33 };

    int deleteArr = 0; //删除元素

    int deleteIndex = -1;//删除下标 给一个不可能的初始值,容易判断

    int i;

    int count = 5;

    printf("请输入要删除的元素:");

    scanf_s("%d", &deleteArr);

    for (i = 0; i < count; i++)

    {

        if (deleteArr == arr[i])

        {

            //记录下标

            deleteIndex = i;

            break;//找到后直接跳出循环

        }

    }

    //未找到要删除的数组元素

    if (-1 == deleteIndex)

    {

        printf("没有找到要删除的下标值");

    }

    else

    {

//从下标开始,后面一个覆盖前面一个

        for (i = deleteIndex; i < count - 1; i++)

        {

            arr[i] = arr[i + 1];

        }

        count--;//删除一个元素,其数组长度会减1

    }

    printf("删除后的数组:\n");

    //遍历数组

    for (i = 0; i < count; i++)

    {

        printf("%d   ", arr[i]);

    }

    printf("\n删除后的原数组:\n");

    //遍历数组

    for (i = 0; i < count+1; i++)

    {

        printf("%d   ", arr[i]);

    }

    printf("\n");

    system("pause");

    return 0;

}

●输出结果:

请输入要删除的元素:22

删除后的数组:

25   11   44   33

删除后的原数组:

25   11   44   33   33

请按任意键继续. . .

       ●代码分析:

删除前内存中的数组:

图8-5 删除前内存中的数组

图8-6 删除后内存中的数组

上图很好的诠释数组是一块连续的内存空间,一旦被定义,则是不可以被改变大小的。尽管我们在控制台显示输出的结果中已经没有了被删除的元素22,但是它申请的内存是存在的,后面一个数组元素44覆盖了22,同样再下一个数组元素33覆盖了44,最后一个数组元素33仍然保留在内存中。

实验六十二:插入数组元素

在VS中新建项目8-2-5.c:

/*

   插入数组元素

*/

#include <stdio.h>

#include <stdlib.h>

#define NUM 6

int main(void) {

    int arr[NUM] = {25,11,22,44,33};

    int instetArr = 0;

    int count = 5;

    int i = 0;

    printf("插入前的数组元素:\n");

    for (i; i < NUM; i++)

    {

        printf("%d   ", arr[i]);

    }

    printf("\n输入要插入的元素:");

    scanf_s("%d", &instetArr);

    arr[count++] = instetArr;

    for (i = 0; i < count; i++)

    {

        printf("%d   ", arr[i]);

    }

    printf("\n");

    system("pause");

    return 0;

}    

●输出结果:

插入前的数组元素:

25   11   22   44   33   0

输入要插入的元素:66

25   11   22   44   33   66

请按任意键继续. . .

●代码分析:

       如果要插入一个数组元素,必须保证有相应的内存空间。数组是静态内存分配,在编译器编译时,已经从数组名起始地址分配了固定的内存空间,不可以被改变。上述代码中使用#define宏定义了一个常量值NUM为6。表面初始化数组int arr[NUM] = {25,11,22,44,33};实际是int arr[NUM] = {25,11,22,44,33,0};输出的结果也证明了这一点。

    插入的值66覆盖了数组最后一个元素0。

    如果将66插入到数组的中间位置,将如何实现呢?

arr[NUM] = {25,11,66,22,44,33};

请读者参考8-2-4.c的代码独立完成。

练习

1、输入10名同学的成绩,并按从高到低的形式输出。

2、int arr[5] = {1,2,3,4,5}; 交换第二个元素和第三个元素。

3、int arr[4] = { 1, 2, 3, 4}; 求arr数组中元素的和、乘积。

4、使用数组表示下面的数据:

姓名      工资       工号

张三      10000.11    101

李四      9999.999    102

王五      8999.12     103

小李      12000       104

小王      15000       105

小章      14000.5     106

5、输入5名学生的分数并显示出他们的最高分和最低分。

6、把下面的汇编指令,写出对应的C语言代码。

00401010   push        ebp

00401011   mov         ebp,esp

00401013   sub         esp,64h

00401016   push        ebx

00401017   push        esi

00401018   push        edi

00401019   lea         edi,[ebp-64h]

0040101C   mov         ecx,19h

00401021   mov         eax,0CCCCCCCCh

00401026   rep stos    dword ptr [edi]

00401028   mov         dword ptr [ebp-14h],4Dh

0040102F   mov         dword ptr [ebp-10h],42h

00401036   mov         dword ptr [ebp-0Ch],21h

0040103D   mov         dword ptr [ebp-8],63h

00401044   mov         dword ptr [ebp-4],37h

0040104B   mov         dword ptr [ebp-18h],0

00401052   mov         dword ptr [ebp-1Ch],0FFFFFFFFh

00401059   mov         dword ptr [ebp-24h],5

00401060   push              offset string "\xc7\xeb\xca\xe4\xc8\xeb\xd2\xaa\xc9\xbe\xb3\xfd\xb5\xc4\xd4\xaa\xcb\xd8"

00401065   call        printf (00401320)

0040106A   add         esp,4

0040106D   lea         eax,[ebp-18h]

00401070   push        eax

00401071   push        offset string "%d" (0042505c)

00401076   call        scanf (004012c0)

0040107B   add         esp,8

0040107E   mov         dword ptr [ebp-20h],0

00401085   jmp         main+80h (00401090)

00401087   mov         ecx,dword ptr [ebp-20h]

0040108A   add         ecx,1

0040108D   mov         dword ptr [ebp-20h],ecx

00401090   mov         edx,dword ptr [ebp-20h]

00401093   cmp         edx,dword ptr [ebp-24h]

00401096   jge         main+9Eh (004010ae)

00401098   mov         eax,dword ptr [ebp-20h]

0040109B   mov         ecx,dword ptr [ebp-18h]

0040109E   cmp         ecx,dword ptr [ebp+eax*4-14h]

004010A2   jne         main+9Ch (004010ac)

004010A4   mov         edx,dword ptr [ebp-20h]

004010A7   mov         dword ptr [ebp-1Ch],edx

004010AA   jmp         main+9Eh (004010ae)

004010AC   jmp         main+77h (00401087)

004010AE   cmp         dword ptr [ebp-1Ch],0FFh

004010B2   jne         main+0B3h (004010c3)

004010B4   push        offset string "\xc3\xbb\xd3\xd0\xd5\xd2\xb5\xbd\xd2\xaa\xc9\xbe\xb3\xfd\xb5\xc4\xcf\xc2\

004010B9   call        printf (00401320)

004010BE   add         esp,4

004010C1   jmp         main+0E8h (004010f8)

004010C3   mov         eax,dword ptr [ebp-1Ch]

004010C6   mov         dword ptr [ebp-20h],eax

004010C9   jmp         main+0C4h (004010d4)

004010CB   mov         ecx,dword ptr [ebp-20h]

004010CE   add         ecx,1

004010D1   mov         dword ptr [ebp-20h],ecx

004010D4   mov         edx,dword ptr [ebp-24h]

004010D7   sub         edx,1

004010DA   cmp         dword ptr [ebp-20h],edx

004010DD   jge         main+0DFh (004010ef)

004010DF   mov         eax,dword ptr [ebp-20h]

004010E2   mov         ecx,dword ptr [ebp-20h]

004010E5   mov         edx,dword ptr [ebp+ecx*4-10h]

004010E9   mov         dword ptr [ebp+eax*4-14h],edx

004010ED   jmp         main+0BBh (004010cb)

004010EF   mov         eax,dword ptr [ebp-24h]

004010F2   sub         eax,1

004010F5   mov         dword ptr [ebp-24h],eax

004010F8   push        offset string "\xc9\xbe\xb3\xfd\xba\xf3\xb5\xc4\xbd\xe1\xb9\xfb\xa3\xba\n" (0042502c)

004010FD   call        printf (00401320)

00401102   add         esp,4

00401105   mov         dword ptr [ebp-20h],0

0040110C   jmp         main+107h (00401117)

0040110E   mov         ecx,dword ptr [ebp-20h]

00401111   add         ecx,1

00401114   mov         dword ptr [ebp-20h],ecx

00401117   mov         edx,dword ptr [ebp-20h]

0040111A   cmp         edx,dword ptr [ebp-24h]

0040111D   jge         main+126h (00401136)

0040111F   mov         eax,dword ptr [ebp-20h]

00401122   mov         ecx,dword ptr [ebp+eax*4-14h]

00401126   push        ecx

00401127   push        offset string "%d   " (00425024)

0040112C   call        printf (00401320)

00401131   add         esp,8

00401134   jmp         main+0FEh (0040110e)

00401136   push        offset string "pause" (0042501c)

0040113B   call        system (004011b0)

00401140   add         esp,4

00401143   xor         eax,eax

本文摘自编程达人系列教材《汇编的角度——C语言》。

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

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

相关文章

【C语言习题】26.字符逆序

文章目录 1.描述2.解题思路3.具体代码 1.描述 输入描述: 将一个字符串str的内容颠倒过来&#xff0c;并输出。可以有空格 数据范围&#xff1a;1≤&#x1d459;&#x1d452;&#x1d45b;(&#x1d460;&#x1d461;&#x1d45f;)≤10000 1≤len(str)≤10000 输出描述&…

httpJVM

目录 HTTPS如何保证安全 1&#xff09;引入非对称加密 2&#xff09;引入非对称加密 3.中间人攻击 4.解决中间人攻击 JVM 1.JVM内存划分 2.JVM类加载过程 八股内容 3.JVM中的垃圾回收机制 释放垃圾的策略 1.标记-清除 2.复制算法 3.标记-整理 分代回收 HTTPS如何…

基于JCEF实现网页资源性能分析

文章目录 1、需求2、实现代码3、运行效果 1、需求 在使用chrome浏览器访问页面时&#xff0c;浏览器自带的开发者工具可以查看页面每个资源的资源大小和加载时间。 这个功能可以让我们直接知道接口或资源的耗时情况和大小情况&#xff0c;如果存在性能问题&#xff0c;可以进…

AST反混淆|对一段非常复杂的混淆代码深度剖析与还原

关注它&#xff0c;不迷路。 本文章中所有内容仅供学习交流&#xff0c;不可用于任何商业用途和非法用途&#xff0c;否则后果自负&#xff0c;如有侵权&#xff0c;请联系作者立即删除&#xff01; 1.代码片段 ((((ld0 ((ld1 (ld1 Uint8Array) && undefined…

云计算-Lambda事件 (Lambda Events)

检索事件信息 (Retrieving Event Information) 在上一个主题中&#xff0c;我们已经看到了如何创建一个Lambda函数、添加handler、添加触发器和配置执行策略。在本主题中&#xff0c;我们将对其进行扩展。到目前为止&#xff0c;我们看到的handler应用非常简单&#xff0c;但我…

uniapp一些问题解决

1.按钮边框如何去除&#xff1f; 参考博主&#xff1a;微信小程序按钮去不掉边框_微信小程序button去掉边框-CSDN博客文章浏览阅读1k次。最近在学uni-app&#xff0c;顺便自己写个小程序。左上角放了个button&#xff0c;可边框怎么也去不掉…原来微信小程序的按钮要去掉边框要…

基于 Solana 的 Drift Protocol 快速崛起,重新定义去中心化衍生品市场

随着区块链技术的快速发展&#xff0c;加密市场的格局正在悄然改变。投资者对透明度、效率和去中心化的需求愈发强烈&#xff0c;之前完全由中心化交易主导的加密货币交易&#xff0c;开始向链上转移。 根据 Coingecko 的最新数据&#xff0c;CEX 和 DEX 的现货交易量已经达到了…

凤香的“蜜”密

执笔 | 文 清 编辑 | 古利特 “遇水则漏&#xff0c;遇酒生香”。酒海&#xff0c;一种大型盛酒容器&#xff0c;因盛酒量以“吨”计算&#xff0c;故称“海”&#xff0c;传于唐宋&#xff0c;兴盛于明清&#xff0c;距今有1400多年的历史。文人墨客笔下&#xff0c;也多有…

xjar加密springboot的jar包,并编译为执行程序

场景&#xff1a;当前项目需要进行jar包部署在windows环境和linux环境&#xff0c;并要求使用xjar加密。 1. xjar加密 源码程序自行搜索&#xff0c;这里只介绍加密及运行&#xff0c;运行加密程序&#xff0c;指定jar包&#xff0c;输入密码 2. 加密后的目录 3. go程序编译 …

AI图书推荐:基于ChatGPT API和Python开发应用程序的详细指南

ChatGPT已经以其革命性的能力引起了人们的关注&#xff0c;利用其API可能会成为你的游戏规则改变者。这不仅仅是关于编码&#xff1b;它是关于为您的创作添加一层智能&#xff0c;将它们提升到之前无法想象的水平。《基于ChatGPT API和Python开发应用程序的详细指南》&#xff…

Git——pull request详细教程

当我们需要协助其他仓库完成更改时&#xff0c;往往会用到git中的Pull Request操作&#xff0c;从而方便团队的协作管理和代码持续集成。 下面是详细的教程步骤。 一. Fork目标项目 比如说我现在要fork以下Qwen-VL的项目&#xff0c;如图所示&#xff1a; 随后点击Create即可…

操作系统—简要分析FAT文件系统

文章目录 简要分析FAT文件系统1.FAT的起源与发展历史2.FAT的基本结构与目录管理机制(1).基本结构(2).文件分配表(3).根目录区(4).数据区 3.优点与缺点4.改进与替代方案(1).exFAT(2).ext2/3/4(3).NTFS 小结参考文献 简要分析FAT文件系统 1.FAT的起源与发展历史 为了更好地管理磁…

柬埔寨语翻译通App,一款真正实现高棉语翻译、语音识别和中柬双语无障碍交流的应用程序。

柬埔寨语翻译通App&#xff0c;一款真正实现高棉语翻译、语音识别和中柬双语无障碍交流的应用程序。它不仅提供文字、语音、图片的翻译&#xff0c;还融入了柬埔寨文化元素&#xff0c;让你在每一次翻译中都能感受到柬埔寨的文化魅力。 这款App支持中文、高棉语双语互译&#x…

LeetCode //C - 143. Reorder List

143. Reorder List You are given the head of a singly linked-list. The list can be represented as: L0 → L1 → … → Ln - 1 → Ln Reorder the list to be on the following form: L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → … You may not modify the values i…

[图解]企业应用架构模式2024新译本讲解03-事务脚本+表数据入口

1 00:00:00,570 --> 00:00:06,290 这里先创建一个service的对象 2 00:00:07,000 --> 00:00:12,470 然后调用对象的方法、操作 3 00:00:12,480 --> 00:00:13,750 就是事务脚本 4 00:00:14,700 --> 00:00:15,900 然后参数是1 5 00:00:16,660 --> 00:00:19,490…

618有什么宠物空气净化器推荐?希喂FreAir Lite宠物空气净化器真实体验

一、宠物空气净化器的必要性 掉毛季又来了&#xff0c;猫咪的毛发满天飞&#xff0c;怎么办&#xff1f;我家里的猫咪一到换毛季就掉满地的毛发&#xff0c;尤其喜欢在家里奔跑打闹&#xff0c;结果整个房间都是毛。为了减少家里空气中的浮毛&#xff0c;你都做过哪些努力呢&a…

Shell编程用户注册及登录

需求&#xff1a; 用Shell编程完成用户的注册及登录 完成 注册用户 用户名首字母大写 密码需8个字符及以上且含“$”,“&”,“-”中的任意一个手机号需以139开头的11位号码邮箱需以数字开头的qq.com 2.检测重复注册 3.注册信息写入/etc/secfinfe 4.用户登录 5.检测是否存…

SQLI-labs-第二十七关和第二十七a关

目录 第二十七关 1、判断注入点 2、判断数据库 3、判断表名 第二十七a关 第二十七关 知识点&#xff1a;空格、select、union等过滤绕过 思路&#xff1a; 通过分析源码&#xff0c;我们可以知道对用户的输入进行过滤&#xff0c;对空格、select、union等进行了过滤&…

钡铼PLC集成BL121PO协议网关优化电子制造产线的生产效率

PLC转OPC UA协议转换网关BL121PO在电子制造产线中的优化应用&#xff0c;可以显著提高生产效率&#xff0c;促进生产线的智能化和信息化发展。本文将从以下几个方面进行阐述&#xff1a; 提高设备间通信效率&#xff1a;PLC转OPC UA协议转换网关BL121PO通过高效的协议转换&…

Docker-02-02 Docker离线下载安装与配置(linux)

一、Docker下载 官网下载地址:Index of linux/static/stable/x86_64/ (docker.com) 推荐下载最新的社区版: 二、将安装包上传至服务器并解压 将安装包上传至服务器的/usr/local目录并解压 cd /usr/local lstar -zxvf docker-18.06.3-ce.tgz三、将docker目录下的文件复制到…