首页 > 其他分享 >2024-02-17-物联网C语言(5-指针)

2024-02-17-物联网C语言(5-指针)

时间:2024-02-18 15:56:38浏览次数:21  
标签:02 变量 17 int C语言 地址 数组 printf 指针

5.指针

5.1 关于内存那点事

存储器:外存和内存

	外存:长期存放数据,掉电不会丢失数据,如硬盘、光盘、ROM等

	内存:暂时存放数据,掉电数据丢失,如RAM,DDR等
  1. 内存:物理内存和虚拟内存

    物理内存:实实在在的存储设备

    虚拟内存:操作系统虚拟出来的内存

    操作系统会在物理内存和虚拟内存之间做映射,在32位系统下,每个进程的寻址范围是4G,0x00000000 ~ 0xffffffff

    在写应用程序的时候,能够看到的都是虚拟内存。

    在32位系统中,虚拟内存被分为两个部分:3G的用户空间 + 1G的内核空间。

    其中,用户空间是当前进程私有的,而内核空间是所有进程共有的。

  2. 在运行程序的时候,操作系统会将虚拟内存进行分区

    :在动态申请内存的时候,在堆里开辟空间

    :主要存放局部变量

    静态全局区

    1. 未初始化的静态全局区:

      静态变量(定义变量的时候,加上static修饰)

      全局变量,没有初始化的,存储在该区

    2. 初始化的静态全局区

      全局变量、静态变量,赋初始值的存放在该区

    代码区:存放代码

    文字常量区:存放常量

内存以字节为单位来存储数据可以将程序中的虚拟寻址空间看成很大的一维字符数组

5.2 指针的概念

	操作系统给每个存储单元分配编号,从`0x00000000~0xffffffff`

指针变量:用来存放地址编号,在32的平台下,地址总线是32位的,所以地址编号为32位,即4个字节

注意:

  1. 无论什么类型的地址,都是存储单元的编号,在32位平台下即为4个字节
  2. 对应类型的指针变量只能存放对应类型的变量地址,如整形指针变量只能存放整形变量的地址

扩展:

字符变量`char ch;`ch占用1个字节,它有一个地址编号,这个地址编号就是ch的地址

整型变量`int a;`,`a`占用4个字节,它占用4个字节的存储单元,有4个地址编号

5.3 指针的定义

  1. 简单的指针

    数据类型 *,指针变量名

    int *p;
    

    在定义指针的时候,*用来修饰变量,说明p这个变量是指针变量

  2. 指针运算符

    &取地址符,获取变量的地址

    *取值

    #include <stdio.h>
    
    int main()
    {
        int a = 100;
        // 定义指针变量
        int *p;
        p = &a;
        printf("a的地址为%p\n", p);
        printf("a = %d", *p);
        return 0;
    }
    

    输出结果:

    a的地址为00000052a75ff794
    a = 100
    

    扩展:

    如果一行中定义多个指针变量,每个指针变量前面都需要加上*x修饰

    int *p,*q;
    
    #include <stdio.h>
    
    int main(){
        char *a;
        short *b;
        int *c;
        long *d;
        float *e;
        double *f;
        printf("sizeof(a) = %d\n",sizeof(a));
        printf("sizeof(b) = %d\n",sizeof(b));
        printf("sizeof(c) = %d\n",sizeof(c));
        printf("sizeof(d) = %d\n",sizeof(d));
        printf("sizeof(e) = %d\n",sizeof(e));
        printf("sizeof(f) = %d\n",sizeof(f));
    
    }
    

    输出结果

    sizeof(a) = 8
    sizeof(b) = 8
    sizeof(c) = 8
    sizeof(d) = 8
    sizeof(e) = 8
    

5.4 指针的分类

按指针的指向的数据类型分类:

  1. 字符指针

    char *p; // 定义一个字符型指针,用来存放字符型变量的地址
    char ch;
    p = &ch;
    
  2. 短整型指针

    short int *p; // 定义一个短整型指针,用来存放短整型变量的地址
    short int a;
    p = &a
    
  3. 整型指针

    int *p; // 定义一个整型指针,用来存放整型变量的地址
    int a;
    p =&a;
    
  4. 长整型指针

    long int *p; // 定义一个长整型指针,用来存放长整型变量的地址
    long int a;
    p =&a;
    
  5. float指针

    float *p; // 定义一个浮点型指针,用来存放浮点型变量的地址
    float a;
    p =&a;
    
  6. double指针

    double *p; // 定义一个浮点型指针,用来存放浮点型变量的地址
    double a;
    p =&a;
    
  7. 函数指针

  8. 结构体指针

  9. 指针的指针

5.5 指针和变量的关系

	**指针可以存放变量的地址编号**

在程序中,引用变量的方法:

  1. 直接通过变量的名称

    int a;
    a = 100;
    
  2. 通过指针变量来引用

    int *p;
    int a = 100;
    p = &a; //*p 这个时候就是100
    
    #include <stdio.h>
    
    int main()
    {
        int a = 100, b = 200;
        int *p, *q;
        p = &a;
        q = &b;
        printf("*p = %d,*q = %d\n", *p, *q);
    }
    

    输出结果:

    *p = 100,*q = 200
    

    注意:

    1. 指针变量在定义的时候可以初始化

      int a;
      int *p = &a; // 指针变量就是来存放地址的,*指针变量 就相当于是指向变量,如*p就是指向a;
      
    2. 指针只能保存开辟好的地址空间不能随意保存地址

    3. *指针取值,取几个字节由指针类型决定:字符取一个字节,整型取4个字节,double取8个字节

    4. 指针++指向下一个字符数据,指针存放地址的编号 +1;如果是整形数据,指针++,指针存放的地址编号+4;

    #include <stdio.h>
    
    int main()
    {
        int a = 0x1234,b = 0x5678;
        char *p1,*p2;
        printf("a = %#x b = %#x\n",a,b);
        p1 = (char *) &a;
        p2 = (char *) &b;
        printf("*p1 = %#x *p2 = %#x\n",*p1,*p2);
        p1++;
        p2++;
        printf("*p1 = %#x *p2 = %#x\n",*p1,*p2);
        return 0;
    }
    

    输出结果

    a = 0x1234 b = 0x5678
    *p1 = 0x34 *p2 = 0x78
    *p1 = 0x12 *p2 = 0x56
    

    image-20240217164029397

5.6 指针与数组元素的关系

  1. 指针变量存放数组元素地址

    int a[10];
    int *p;
    p = &a[0]; // 指针变量p保存了数组a中第0个元素的地址,即a[0]的地址
    
  2. 数组元素的引用方法

    // 数组名[下标]
    int a[0];
    a[2] =100;
    
    // 指针[下标]
    int a[10];
    int *p;
    p = a;  //p此时和a等价,数组的名字就是数组的首地址,是一个常量;
    // 注意:p是变量,a是常量,可以用常量给变量赋值
    
    // 通过指针运算加取值的方法来引用数组元素
    int a[10];
    int *p;
    p=a;
    *(p + 2 ) = 100; // 相当于a[2] = 100
    
    #include <stdio.h>
    
    int main()
    {
        int a[5] = {1, 2, 3, 4, 5};
        int *p;
        p = a;
        printf("a[2] = %d\n", a[2]);
        printf("p[2] = %d\n", p[2]);
    
        printf("*(p+2) = %d\n", *(p + 2));
        printf("*(a+2) = %d\n", *(a + 2));
    
        printf("&(p+2) = %p\n", p);
        printf("&(p+2) = %p\n", p + 2);
    
        printf("&a[0] = %p\n", &a[0]);
        printf("&a[2] = %p\n", &a[2]);
    }
    

    输出结果

    a[2] = 3
    p[2] = 3
    *(p+2) = 3
    *(a+2) = 3
    &(p+2) = 0000000fdc7ff680
    &(p+2) = 0000000fdc7ff688
    &a[0] = 0000000fdc7ff680
    &a[2] = 0000000fdc7ff688
    

5.7 指针的运算

  1. 指针可以加上一个整数,相当于地址的偏移(指针指向数组时才有意义)

    int a[10];
    int *p;
    p =a;
    p+2 // p保存a[0]的地址, p+2即为&a[2]
    
  2. 两个相同类型的指针可以比较大小(指针指向数组时才有意义)

    // 指向前面元素的指针小于指向后面元素的指针
    
  3. 相同类型的指针可以做减法,可以用于计算元素个数

    int a[10];
    int *p,*q;
    p = &a[0];
    q = &a[3];
    printf("%d\n",q-p); // 输出为3
    
  4. 相同类型的指针可以进行赋值

    int a = 100;
    int *p,*q;
    p = &a;
    q = p;
    printf("%d\n",*q); // 输出为100
    

5.8 指针数组

  1. 指针和数组的关系

    • 指针可以保存数组元素的地址
    • 可以定义数组,用来保存指针变量

    指针数组概念:指针数组本身是一个数组,由若干个相同类型的指针变量构成的集合

  2. 指针数组定义方法

    类型说明符 * 数组名 [元素个数]
        
    int *p[10]; // 定义一个整型的指针数组p,有10个元素p[0]~p[9],每个元素都是int *类型的变量
    int a;
    p[1] = &a;
    int b[10];
    p[2] = &b[3];
    // p[2]、*(p+2)是等价的,都是指针数组的第二个元素
    
    
  3. 指针数组的分类

    #include <stdio.h>
    
    int main()
    {
        // 大多数情况下指针数组用来保存多个字符串
        char *name[5] = {"Follow me", "Basic", "Greatwall", "Fortran","Python"};
        int i;
        for (i = 0; i < 5; i++)
        {
            printf("%s\n", name[i]);
        }
    }
    

    输出结果:

    Follow me
    Basic
    Greatwall
    Fortran
    Python
    

5.9 指针的指针

	指针的指针也叫二级指针,即为指针的地址

定义一个指针变量,占用4个指针,指针变量也有地址编号。

#include <stdio.h>

int main()
{
    int a = 100;
    // 定义一个一级指针,用来保存普通变量的地址
    int *p = &a;

    // 定义一个二级指针,用来保存一级指针的地址
    int **q = &p;

    printf("a = %d %d %d\n",a,*p,**q);
    
    printf("a = %p %p %p\n",a,*p,**q);

}

输出结果

a = 100 100 100
a = 0000000000000064 0000000000000064 0000000000000064

5.10 字符串和指针

字符串概念:字符串是以\0结尾的若干字符的集合

字符串的存储形式:数组、字符串指针、堆

// 定义一个字符数组string,用来存放多个字符,并且用 "I love C" 给string数组初始化,字符串"I LOVE C"存放在string中
1. char string[100] = "I love C"; 

 //定义了一个指针变量str,只能存放字符地址编号,所以"I love C"这个字符串不能存放在str指针变量中。
// str只能存放字符I的地址编号,而"I love C"存放在文字常量区
2. char *str = "I love C"
    
// 动态申请了10个字节的存储空间,首地址给str赋值
3. char str = (char*)malloc(10*sizeof(char))
    

注意: str指针指向的内存不能被修改,要看str指向哪里

  1. str指向文字常量区的时候,内存的内容不能被修改,如第二种方式
  2. str指向栈、堆、静态全局区的时候,内存的内容是可以被修改的

初始化

  1. 字符数组、指针指向的字符串,定义时可以直接初始化

    char buf_aver[] = "hello world"
    char *buf_pointer = "hello world"
    
  2. 堆中存放的字符串,不能被直接初始化,只能使用strcpy、scanf赋值

    char *buf_heap;
    strcpy(buf_heap,"hello world");
    scanf("%s",buf_heap);
    

使用时赋值

// 字符数组:使用scanf或者strcpy
buf_aver = "hello kitty"; // 错误,因为字符串数组的名字是一个常量,不能不赋值修改
strcpy(buf_aver,"hello kitty"); // 正确
scanf("%s",buf_aver); // 正确

// 指向字符串的指针
buf_point = "hello kitty";
strcpy(buf_point,"hello kitty"); // 错误,只读,不能复制字符串到buf_point指向的内存中

5.11 数组指针

  1. 二维数组

    // 二维数组,有行有列,是多个一维数组的集合
    int a[3][5]; // 可以看成是由3个一维数组组成
    
  2. 数组指针的概念

    数组指针的作用就是可以保存二维数组的首地址

  3. 数组指针的定义方法

    // 指向的数组的类型(*指针变量名)[指向的数组元素个数]
    int(*p)[5];
    
    #include <stdio.h>
    
    int main(){
        int a[3][5];// 定义一个3行5列的二维数组
        int (*p)[5];// 定义一个数组指针变量p,p+1跳一个有5位元素的整型数据
    
        printf("a = %p\n",a); // 第0行的行地址
        printf("a+1=%p\n",a + 1); // 第一行的行地址,a 和 a+1 相差 5*4 = 20 个地址
        p = a;
    
        printf("p = %p\n",p);
        printf("p+1=%p\n",p + 1); // p+1 跳一个有5个整型元素的一维数组
        return 0;
    }
    

    输出结果

    a = 000000ca57fff840
    a+1=000000ca57fff854
    p = 000000ca57fff840
    p+1=000000ca57fff854
    
  4. 注意:
    容易混淆的内容:

    1. 指针数组:是个数组,有若干个相同类型的指针构成的集合

      // 数组 p有 10 个 int *类型的指针变量构成,分别是 p[0]~p[9]
      int *p[10];
      
    2. 数组指针:本身是个指针,指向一个数组,加1跳一个数组

      int (*p)[10]; // p是个数组指针,p加1指向下个数组,跳 10个整形。
      
    3. 指针的牾针:

      int **p;//p 是指针的指针
      int *q;
      p=&q;
      
  5. 数组名字取地址,变成数组指针

    int a[10]; // 一维数组的名字取地址,变成一维数组指针,即加1跳一个一维数组
    
    // a+1 跳一个整型元素,是a[1]的地址
    // a 和 a+1相差一个元素,4个字节
    
    // &a就变成了一个一维数组的指针,是int(*p)[10]类型
    // (&a) + 1 和&a 相差一个数组,即10个元素,40个字节
    
  6. 多维数组的指针转换

    二维数组的数组名降级问题

    // 二维数组的数组名降级问题
    // 二维数组的数组名默认是一个行指针,加1保存下一行的首地址
    // 二维数组的数据名取*,表示地址的降级,意味着行指针降级为列指针
    
    //一维数组的数组名默认是一个列指针,加1保存下一个元素的地址
    //一维数组的数组名取&,则是地址的升级,将列指针升级为行指针,加1保存下一个行元素的首地址
    void main()
    {
        int a[3][5];
        printf("a=%p\n", a);
        printf("a +1=%p\n", a + 1); // *a变成了第0行第0列元素的地址
        printf("*a =%p\n", *a);
        printf("(*a)+1 =%p\n", (*a) + 1); // 结果为第0行第1列元素的地址
    }
    

    输出结果

    a=000000EAE5DFFD40
    a +1=000000EAE5DFFD54
    *a =000000EAE5DFFD40
    (*a)+1 =000000EAE5DFFD44
    

5.12 指针与函数的关系

1. 传数值

可以给一个函数传一个整型、字符型、浮点型数据,也可以传入一个指针

#include <stdio.h>

void myfun1(int a,int b){
    int temp;
    temp = a;
    a = b;
    b = temp;
    printf("in fun: a =%d,b = %d\n ",a,b);
    printf("&a =%p,&b = %p\n ",&a,&b);
}

void test1(){
    int a = 100, b = 20;
    printf("before fun: a =%d,b = %d\n ",a,b);
    printf("&a =%p,&b = %p\n ",&a,&b);
    myfun1(a,b);
    printf("after fun: a =%d,b = %d\n ",a,b);

}

int main(int argc, char const *argv[])
{
    /* code */
    test1();
    return 0;
}

输出结果

before fun: a =100,b = 20
 &a = 000000ae377ff77c,&b = 000000ae377ff778
 in fun: a =20, b = 100
 &a =000000ae377ff750, &b = 000000ae377ff758
 after fun: a =100,b = 20

可以发现形参和实参内存地址是相互独立的,互不影响。

函数传参方式是复制传参:将实参的值传递给形参,不管形参怎么改变,跟实参都没有关系

2. 传地址

#include <stdio.h>

// 函数的传参方式是地址传参
// 形参对保存的地址内容做操作,实参的值也会发生改变
void myfun2(int *p, int *q)
{
    int temp;
    temp = *p;
    *p = *q;
    *q = temp;
    printf("in fun: *p =%p, *q = %p\n ", p, q);
}

void test1()
{
    int a = 100, b = 20;
    printf("before fun: a =%d,b = %d\n ", a, b);
    printf("&a = %p,&b = %p\n ", &a, &b);
    myfun2(&a,&b);
    printf("after fun: a =%d,b = %d\n ", a, b);
}

int main(int argc, char const *argv[])
{
    /* code */
    test1();
    return 0;
}

输出结果

before fun: a =100,b = 20
 &a = 000000b7fbdff8cc,&b = 000000b7fbdff8c8
 in fun: *p =000000b7fbdff8cc, *q = 000000b7fbdff8c8
 after fun: a =20,b = 100

总结: 要想修改主调函数中变量的值,必须传变量地址,还得通过*地址去赋值

注意:

  1. 如果实参是一个普通变量,地址传参的话就需要形参是一级指针
  2. 如果实参是一个一级指针,地址传参的话就需要形参是一个二级指针以此类推

3. 传数组

将数组作为参数传递给函数,不存在复制传参和地址传参。

本质都是地址传参,所以函数内部对数组进行改变,则函数执行完毕后,原本的数据也发生改变

#include <stdio.h>

void fun1(int *p)
{
    printf("%d\n", p[2]);
    printf("%d\n", *(p + 3));
}

void fun2(int (*p)[4])
{
    // p[x][y] 等价于 *((*p+x) + y)
    printf("%d\n", p[0][2]);
    printf("%d\n", *(*(p + 1) + 3));
}

void fun3(char **q)
{
    int i;
    for (i = 0; i < 3; i++)
    {
        printf("%s\n", q[i]);
    }
}

// 传一维数组
void test1()
{
    int a[10] = {1, 2, 3, 4, 5, 6, 7, 8};
    fun1(a);
}

// 传二维数组
void test2()
{
    int a[2][4] = {1, 2, 3, 4,
                   5, 6, 7, 8};
    fun2(a);
}

// 传指针数组
void test3()
{
    char *p[3] = {"hello world", "world", "kitty"};
    fun3(p);
}

int main()
{
    test1();
    test2();
    test3();
    return 0;
}

输出结果

3
4
3
8
hello world
world
kitty

4.指针函数

指针函数本质是一个函数,只不过函数的返回值是一个指针

#include <stdio.h>
// 指针函数:指针作为函数的返回值
char *func(){
    // 栈区开辟的空间会随着当前代码段的结束而释放空间
    // char str[100]="hello world";
    // 静态区的空间不会随着代码段的结束而释放空间
    static char str[100] = "hello world";
    return str;
}

int main()
{
    char *p;
    p = func();
    printf("p = %s\n",p);
    return 0;
}

输出结果

p = hello world

5.函数指针

本质是一个指针,指针指向了函数。

在运行程序的时候,系统会将函数加载到内存中,所以函数也有起始地址。

c语言规定,函数的名字就是函数的首地址,即函数的入口地址。

可以定义指针变量,来存放函数的地址,这就是函数指针

  1. 函数指针的定义方法

    // 返回值类型(*函数指针变量名)(形参列表)
    int (*p)(int,int) // 定义一个函数指针变量p,p指向函数;其中返回值为整型,两个整型的参数
        
    int max(int x,int y){ }
    
    int min(int x,int y){  }
    
  2. 调用函数的方法

    int max(int x ,int y){}
    // 如下面的例子
    int main(){
        int num;
        num = max(3,5);
    }
    
    // 可以通过函数指针变量区调用,但是这种方法几乎不怎么用,没有直接使用函数调用方便
    int max(int x,int y){ }
    int main(){
        int num;
        int (*p)(int ,int );
        p = max;
        num = p(3.,5);
    }
    
  3. 函数指针数组

    函数指针数组,本质是一个数组,数组里的每一个元素都是函数指针,这个数组就是函数指针数组。

    int (*p[10])(int,int); // 了解即可
    
    
  4. 函数指针最常用的地方

    函数指针最常用的地方在于将一个函数作为参数传递到另一个函数时候

    #include <stdio.h>
    
    int add(int x, int y)
    {
        /* code */
    
        return x + y;
    }
    
    int sub(int x, int y)
    {
        /* code */
    
        return x - y;
    }
    
    int mul(int x, int y)
    {
        /* code */
    
        return x * y;
    }
    
    int div(int x, int y)
    {
        /* code */
    
        return x / y;
    }
    
    int process(int (*p)(int, int), int a, int b)
    {
        /* code */
        int ret;
        ret = (*p)(a, b);
        return ret;
    }
    
    int main(int argc, char const *argv[])
    {
        int num;
        num = process(add, 2, 3);
        printf("num = %d\n", num);
    
        num = process(sub, 2, 3);
        printf("num = %d\n", num);
    
        num = process(mul, 2, 3);
        printf("num = %d\n", num);
    
        num = process(div, 2, 3);
        printf("num = %d\n", num);
        return 0;
    }
    

    输出结果

    num = 5
    num = -1
    num = 6
    num = 0
    

5.13 经常容易混淆的指针

  1. int *a[10] : 指针数组,数组中包含10个整型的指针变量,一般可以用来保存字符串

  2. int(*a)[10]: 数组指针,是一个指针变量,占用4个字节,用来存放地址编号。 +1 ,指向下个数组。可以用来保存二维数组的首地址。

  3. int **p:指针的指针,二级指针用来保存一级指针的地址;

    int **p;
    int *q;
    **p = &*q;
    
  4. int *f(void):指针函数,声明一个函数,这个函数的返回值int*

  5. int(*f)(void):用来存放函数的地址,它指向一个函数

5.14 特殊指针

  1. (void *)指针

    通用指针,任何类型的指针都可以给void *指针变量赋值,主要用在函数的参数和返回值的位置。

    int *p;
    void *q;
    q = p; // 这样操作是可以的,不用强制转换 
    
    // memset可以设置字符数组、整型数组、浮点型数组的内容,所以第一个参数就必须使用通过指针
    // 它的返回值是s指向的内存的首地址,可能是不同类型的地址。所以返回值也得是通用指针
    
    void *memset(void *s,int c, size_t n):
    

    注意:void*类型的指针变量,也是个指针变量,在32为系统下,占4个字节

  2. NULL

    空指针,一般用来给指针变量初始化

    // 可以认为p哪里都不指向,也可以认为p指向内存为编号为0的存储单元
    // 在p的四个字节中存放的是0x00000000
    char *p = NULL;
    

5.15 main传参

// argc : int 类型的变量,命令终端传入的参数
// argv :是一个指针数组,保存每一个命令终端传入的参数
int main(int argc, char const *argv[])
{
    /* code */
    return 0;
}

标签:02,变量,17,int,C语言,地址,数组,printf,指针
From: https://www.cnblogs.com/hasaki-yasuo/p/18019413

相关文章

  • ARC171 B~E 四个数数
    A比较简单就不放了,这样刚好是全是数数题F先咕咕咕一会。Blink其实就是对于所有\(P_i>i\)的\(i\)到\(P_i\)连边,然后\(A_i\)就是\(i\)号点在的链上的最后一个点。考虑集合\(S_i=\{j\midA_j=i\}\),显然如果需要有解那么\(S_i\)中最大值必定为\(i\),而且这些点一......
  • [刷题笔记] P9751 [CSP-J 2023] 旅游巴士
    Problem_LinkDescription给定一个\(n\)个点,\(m\)条边的有向图。起点为\(1\),终点为\(n\)。起始时间和终止时间必须是\(k\)的倍数。通过每条边的时间为\(1\)。每条边有限制\(a_i\)即若通过当前边必须满足当前时间\(t\geqa_i\)。求满足上述限制的前提下,到达终点的最小......
  • ts基础类型02
    类型声明letnum:number=11num=10functiona(aaa:string){  console.log(aaa)}a('111')//类型声明,指定ts变量(参数,形参)的类型ts编译器,自动检测//类型声明给变量设置了类型后,该变量只能储存对应类型的值,如下letflag:boolean=trueflag=false......
  • 海亮02/18杂题
    海亮02/18杂题个人题单T1link题意给你一个长度为\(n\)的数列,然后给你\(q\)个交换或不交换操作,你可以选择操作或者不操作,问所有情况下逆序对的总和。答案需要对\(10^9+7\)取模。\(n\leq3000\),\(q\leq3000\)。题解发现一个问题,对于操作执不执行很难描述,怎么办?......
  • ABAP:MM01/MM02/MM03物料主数据增强
    1.屏幕增强-在主表中附加结构(判断数据的主表,如MARA,MARC)增强字段数据元素勾选更改文档以后,会记录字段变更历史 -SPRO-->物流-常规-->物料主数据-->配置物料主记录-->创建定制子屏幕的程序 会生成对应的函数组--里面会包含两个屏幕(0001,0002)这里的0001屏幕作为......
  • SMU Winter 2024 div2 ptlks的周报Week 3(2.12-2.18)
    这周主要加强了对知识点的掌握。P10161[DTCPC2024]小方的疑惑10从题目可以得知a个连续括号贡献为a(a+1)/2,代价为2a。要求总贡献恰为k,且代价不高于n。一开始我想到了模拟,先取一个贡献低于k最大的a,剩下的再直接在外面套括号,结果wa。又想到可以分出多个a来组成k,就用递归,每次......
  • 2024年首发!高级界面控件Kendo UI全新发布2024 Q1
    KendoUI是带有jQuery、Angular、React和Vue库的JavaScriptUI组件的最终集合,无论选择哪种JavaScript框架,都可以快速构建高性能响应式Web应用程序。通过可自定义的UI组件,KendoUI可以创建数据丰富的桌面、平板和移动Web应用程序。通过响应式的布局、强大的数据绑定、跨浏览器兼容......
  • VNCTF2024-WEB-gxngxngxn
    VNCTF2024-WEB-gxngxngxnCheckin签到题,直接看js文件CutePath按照上述穿越下可以看到一串base64加密的,解密后是账号密码:登录看到有新功能,可以重命名文件.我们找到flag.txt文件,但是不能查看,我们可以利用重命名将flag.txt文件传送到share_main目录下,这样我们就可以查看......
  • P10171题解
    P10171[DTCPC2024]取模题目传送门题解不会多项式导致的,赛后秒过。一个显然的结论:如果原序列有相等的数答案为\(0\),其次大于\(4\times10^5\)的\(k\)均符合要求。问题在于小于\(4\times10^5\)的答案。赛时想了很多奇妙的算法,诸如根号分治、线段树维护余数等等。其......
  • 从嘉手札<2024-2-17(2)>
    也不知是岁月过得qianjuan还是花落得匆忙父亲的白发一天天的多下去时至今日竟也满头华发了小时候的父亲总是高大恣意潇洒夏天的蝉鸣悠悠记忆里父亲总是躺在沙发上鼾声大作我蹲在门口用放大镜找那些不知死活的蚂蚁晚风悄悄的吹起天边的月牙我抬起头湛蓝色的天空宛若宝......