C_深入理解指针(五) —— sizeof和strlen的对比、数组和指针笔试题解析、指针运算笔试题解析

news2024/9/21 2:07:56

目录

一、sizeof和strlen的对比

1、sizeof

2、strlen

3、sizeof 和 strlen的对比

二、数组和指针笔试题解析

1、⼀维数组

重点学习代码:sizeof与一维整型数组类型

2、字符数组

代码1:sizeof与字符数组类型

代码2:strlen与字符数组类型

代码3:sizeof与字符串数组类型

代码4:strlen与字符串数组类型

代码5:sizeof与字符指针数组类型

代码6:strlen与字符指针数组类型

3、二维数组

三、指针运算笔试题解析

1、题目一

2、题目二

3、题目三

4、题目四 

5、题目五

6、题目六

7、题目七 


一、sizeof和strlen的对比

1、sizeof

  1. sizeof 可以计算变量所占内存的内存空间大小,单位是字节,它是一个操作符,不是函数
  2. 如果操作数类型的话,则计算的是使用类型创建的变量所占内存空间的大小
  3. sizeof 只关注占用内存空间的大小,不在乎内存中存放什么数据。
#inculde <stdio.h>
int main()
{
    int a = 10;
    printf("%d\n", sizeof(a));//4    
    printf("%d\n", sizeof(int));//4

    int arr[10] = { 100, 200};
    printf("%zd\n",sizeof(arr));//40
 
    return 0;
}

2、strlen

  函数原型如下:
size_t strlen ( const char * str );

重点总结:

  1. strlen 是C语言库函数,使用需要包含头文件 <string.h>;
  2. 其功能是求字符串长度,只能针对字符串(字符数组),统计的是字符串中\0之前的字符个数。
  3. 统计的是从 strlen 函数的参数 str 中这个地址开始向后, \0 之前字符串中字符的个数。strlen 函数会⼀直向后找 \0 字符,直到找到为止,所以可能存在越界查找。
#include <stdio.h>
int main()
{
    char arr1[3] = {'a', 'b', 'c'};
    char arr2[] = "abc";
    printf("%d\n", strlen(arr1));//随机值
    printf("%d\n", strlen(arr2));//3
 
    printf("%d\n", sizeof(arr1));//3
    printf("%d\n", sizeof(arr2));//4
    return 0;
}

3、sizeof 和 strlen的对比

sizeof
strlen
  1. sizeof是操作符
  2. sizeof计算操作数所占内存的大小,单位是字节
  3. 不关注内存中存放什么数据
  1. strlen是库函数,使⽤需要包含头文件 string.h
  2. srtlen是求字符串⻓度的,统计的是 \0 之前字符的个数
  3. 关注内存中是否有 \0 ,如果没有 \0 ,就会持续往后找,可能会越界

二、数组和指针笔试题解析

1、⼀维数组

数组名是数组首元素的地址,但有两个例外

  1. 第一,sizeof(数组名),表示整个数组的大小
  2. 第二,&数组名,表示的是整个数组,取出的是数组的地址

重点学习代码:sizeof与一维整型数组类型

#include <stdio.h>
#include <string.h>

int main()
{
    int a[] = {1,2,3,4};

    printf("%d\n",sizeof(a));//16
    //数组名a单独放在sizeof内部,a表示整个数组,计算的是整个数组的大小,单位是字节

    printf("%d\n",sizeof(a+0));
    //这里的a是数组名表示首元素的地址,a+0还是首元素的地址
    //这里sizeof计算的是首元素地址的大小 4/8

    printf("%d\n",sizeof(*a));//4 
    //这里的a是数组名表示首元素的地址,*a 就是首元素,就是a[0]
    //*a--*(a+0)-- a[0]

    printf("%d\n",sizeof(a+1));
    //这里的a是数组名表示首元素的地址,a+1是第二个元素的地址(&a[1])
    //计算的是地址的大小 4/8

    printf("%d\n",sizeof(a[1]));//4

    printf("%d\n",sizeof(&a));
    //&a -这里的数组名a表示整个数组,&a是整个数组的地址
    //数组的地址也是地址,是地址就是 4/8 个字节的长度

    printf("%d\n",sizeof(*&a));
    //1.*&a,这里的*和&抵消了,所以sizeof(*&a)== sizeof(a) 16
    //2. &a - 这是数组的地址,类型是:int(*)[4],*&a 访问的就是这个数组
    
    printf("%d\n",sizeof(&a+1));
    //&a是数组的地址,&a+1是跳过整个数组后的那个位置的地址
    //&a+1是地址,地址都是4/8个字节

    printf("%d\n",sizeof(&a[0]));//4/8

    printf("%d\n",sizeof(&a[0]+1));//第二个元素的地址 4/8

    return 0;
}

2、字符数组

重点学习代码:

代码1:sizeof与字符数组类型

#include <stdio.h>
#include <string.h>

int main()
{
    char arr[] = {'a','b','c','d','e','f'};

    printf("%d\n", sizeof(arr));
    //计算整个数组的大小    6

    printf("%d\n", sizeof(arr+0));
    //首元素的地址          4/8

    printf("%d\n", sizeof(*arr));
    //通过首元素地址访问首元素  1

    printf("%d\n", sizeof(arr[1]));
    //第二个元素的大小        1

    printf("%d\n", sizeof(&arr));
    //取地址数组名,即取出的是整一个数组,根据计算机的编译环境来确定
    //4/8

    printf("%d\n", sizeof(&arr+1));
    //取地址数组名,即取出的是整一个数组,根据计算机的编译环境来确定    
    //加上1即为跳过整个数组
    //4/8

    printf("%d\n", sizeof(&arr[0]+1));
    //首元素的地址+1,得出来的是第二个元素的地址
    //4/8

    return 0;
}

代码2:strlen与字符数组类型

#include <stdio.h>
#include <string.h>
    
int main()
{
    char arr[] = {'a','b','c','d','e','f'};

    printf("%d\n", strlen(arr));
    //表示首元素的地址,往后数有多少个元素,直到找到\0
    //随机值

    printf("%d\n", strlen(arr+0));
    //表示首元素的地址,往后数有多少个元素,直到找到\0
    //随机值

    printf("%d\n", strlen(*arr));
    //arr是数组名表示首元素的地址
    //*arr 是首元素 ——'a'-97,传递给strlen后,strlen 会认为97就是地址,然后去访问内存
    //error -- 程序奔溃

    printf("%d\n", strlen(arr[1]));//'b'——98  error -- 程序奔溃
    printf("%d\n", strlen(&arr));
    //取整个地址名的地址为表示首元素的地址,往后数有多少个元素,直到找到\0
    //随机值

    printf("%d\n", strlen(&arr+1));
    //取整个地址名的地址为表示首元素的地址,加上1即为跳过一个数组,其跳过的长度为6个字符,再往 
      后数有多少个元素,直到找到\0
    //随机值

    printf("%d\n", strlen(&arr[0]+1));
    //表示首元素的地址,加上1即为跳过一个数组,其跳过的长度为1个字符,也就是到了字符b的位置,再            
      往后数有多少个元素,直到找到\0
    //随机值

    return 0;
}

代码3:sizeof与字符串数组类型

#include <stdio.h>
#include <string.h>

//数组名是数组首元素的地址,但有两个例外:
//第一,sizeof(数组名),表示整个数组的大小;第二,&数组名,表示整个数组,取出的是数组的地址。

int main()
{
    char arr[] = "abcdef";

    printf("%d\n", sizeof(arr));//7
    //数组名单独放在sizeof内部,计算的是数组的大小

    printf("%d\n", sizeof(arr+0));
    //arr+0是数组首元素的地址,大小就是4/8个字节

    printf("%d\n", sizeof(*arr));//1
    //*arr是首元素,sizeof(*arr)  

    printf("%d\n", sizeof(arr[1]));
    //数组第二个元素的大小     1

    printf("%d\n", sizeof(&arr));
    //&arr是数组的地址,大小为4/8个字节

    printf("%d\n", sizeof(&arr+1));
    //&arr是数组的地址,&arr+1跳过了整个数组,指向了数组后面的那个位置
    //&arr+1为地址,大小为4/8个字节

    printf("%d\n", sizeof(&arr[0]+1));
    //&arr[0]是首元素的地址,&arr[0]+1是第二个元素的地址,大小为4/8个字节

    return 0;
}

代码4:strlen与字符串数组类型

#include <stdio.h>
#include <string.h>

int main()
{
    char arr[] = "abcdef";

    printf("%d\n", strlen(arr));//6
    //arr 是首元素的地址,strlen是从第一个元素开始统计\0之前的字符的个数 
    
    printf("%d\n", strlen(arr+0));//6
    //arr 是首元素的地址,arr+0还是首元素的地址
    
    printf("%d\n", strlen(*arr));
    //arr 是首元素的地址,*arr是首元素-'a'-97,97作为地址传给给了strlen
    //但是97这个地址不能被访问-程序会崩溃

    printf("%d\n", strlen(arr[1]));
    //同上,字符数组第二个的元素传过去会被当成地址
    //error -程序崩溃

    printf("%d\n", strlen(&arr));//6
    //-=&arr是数组的地址,数组的地址和数组首元素的地址是指向同一个位置的
    //那么strlen也是从第一个元素的位置开始向后访问的

    printf("%d\n", strlen(&arr+1));
    //&arr是数组的地址,&arr+1跳过了整个数组,指向了数组后面的那个位置
    //随机值

    printf("%d\n", strlen(&arr[0]+1));//5
    //&arr[0]是数组首元素的地址,&arr[0]+1跳过了一个元素,指向了数组中的第二个元素

    return 0;
}

代码5:sizeof与字符指针数组类型

#include <stdio.h>
#include <string.h>

int main()
{
    char *p = "abcdef";
    //这段代码的意思是将这个字符串的首地址存到指针变量p中去

    printf("%d\n", sizeof(p));
    //p是指针变量,计算的是指针变量p的大小,存的是地址,地址大小为4/8个字节

    printf("%d\n", sizeof(p+1));
    //p为char*类型的指针变量,因此p+1是第二个元素的地址,地址的大小为4/8个字节

    printf("%d\n", sizeof(*p));//1
    //p的类型是char*,所以*p只能访问1个字节

    printf("%d\n", sizeof(p[0]));
    //p[0] -->*(0+0)-- * -- 1个字节

    printf("%d\n", sizeof(&p));
    //&p是指针变量p的地址,也是地址,是地址就是4/8个字节
    //&p -- char**二级指针

    printf("%d\n", sizeof(&p+1));
    //&p是p的地址,&p+1是跳过p变量,指向了p的后边
    //&p+1是地址,就是4/8个字节

    printf("%d\n", sizeof(&p[0]+1));
    //&p[0]+ 1 就是b的地址
    //p[0]-- *(p+0)-- *p

    return 0;
}

代码6:strlen与字符指针数组类型

#include <stdio.h>
#include <string.h>

int main()
{
    char *p = "abcdef";
    //这段代码的意思是将这个字符串的首地址存到指针变量p中去

    printf("%d\n", strlen(p));//6
    //从字符串的首元素的地址开始数元素个数

    printf("%d\n", strlen(p+1));//5
    //从字符串的首元素的下一个位置的地址开始数元素个数
    
    printf("%d\n", strlen(*p));
    //*p —— 'a' —— 97
    //97作为地址传给给了strlen
    //但是97这个地址不能被访问-程序会崩溃

    printf("%d\n", strlen(p[0]));
    //p[0] —— *(p+0)
    //97作为地址传给给了strlen
    //但是97这个地址不能被访问-程序会崩溃
    
    printf("%d\n", strlen(&p));//随机值
    //p本来就是一个指针变量,然后又取p的地址,即为二级指针

    printf("%d\n", strlen(&p+1));//随机值
    //p本来就是一个指针变量,然后又取p的地址,即为二级指针,+1之后也是一个指向下一位置的二级指针

    printf("%d\n", strlen(&p[0]+1));//5
    //&p[0]为第一个元素的地址,+1之后为第二个元素的地址,往后数直到遇到\0

    return 0;
}

3、二维数组

二维数组的直观表示图形:

#include <stdio.h>
int main()
{
    int a[3][4] = {0};

    printf("%d\n",sizeof(a));//48
    //a作为数组名,单独放在sizeof内部了,a表示的是整个数组,计算的是整个数组的大小,单位是字节

    printf("%d\n",sizeof(a[0][0]));//4
    //a[0][0]是第一行第一个元素,大小是4个字节    

    printf("%d\n",sizeof(a[0]));//16
    //a[0]是第一行的数组名,单独放在sizeof内部,计算的是数组的大小 4*4 = 16个字节

    printf("%d\n",sizeof(a[0]+1));
    //a[0]是第一行的数组名,但是没有单独放在sizeof内部,
    //那么只能是数组首元素的地址,那就是第一行第一个元素的地址 - &a[0][0]
    //a[0]+1 == &a[0][0]+1 == &a[0][1]
    //地址的大小为4/8个字节

    printf("%d\n",sizeof(*(a[0]+1)));
    //*(a[0]+ 1)是第一行第二个元素,大小是4个字节

    printf("%d\n",sizeof(a+1));
    //a是二维数组的数组名,并没有单独放在sizeof内部,a表示首元素的地址-也就是第一行的地址
    //a+1 是第二行的地址,是地址大小就是4/8个字节

    printf("%d\n",sizeof(*(a+1)));//16
    //1.*(a+1)--a[1]--是第二行的数组名,单独放在sizeof内部,计算的是第二行的大小
    //2.a+1是第二行的地址,类型是int(*)[4],数组指针,解引用访问的是这个数组,大小是16个字节

    printf("%d\n",sizeof(&a[0]+1));//4/8
    //a[0]是第1行的数组名,&数组名其实就是第一行的地址,&a[0]+1就是第二行的地址,是地址就是4/8个字节

    printf("%d\n",sizeof(*(&a[0]+1)));//16    

    printf("%d\n",sizeof(*a));//16
    //1.a- 首元素的地址(第一行的地址),*a是第一行了
    //2:*a--*(a+0)-- a[0]

    printf("%d\n",sizeof(a[3]));//16
    //sizeof内部的表达式是不会真实计算的
    //a[3]- 第四行的数组名 int [4]

    return 0;
}

重点:sizeof内部的表达式是不会真实计算的,体现在:

#include <stdio.h>

int main()
{
    short s=8;//2
    int n= 12;//4

    printf("%zd\n",sizeof(s =n + 5));

    printf("%d\n",s);

    return 0;
}

数组名的意义:
  1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
  2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
  3. 除此之外所有的数组名都表示首元素的地址。

三、指针运算笔试题解析

1、题目一

#include <stdio.h>

int main()
{
    int a[5] = { 1, 2, 3, 4, 5 };

    int *ptr = (int *)(&a + 1);
    //&数组名即为取整个数组的地址,类型为int(*)[5],
    //当&a+1时,即为跳过整个数组,即指针现在指向末尾的位置,类型还是为int(*)[5];
    //(int*)为强制类型转化,将&a+1强制类型转化为int*的指针变量,再放入ptr的指针变量中

    printf( "%d,%d", *(a + 1), *(ptr - 1));
    //*(ptr-1)为往前倒退一个元素位置再解引用,*(a+1)为往后前进一个元素位置再解引用

    return 0;
}

解题分析思路: 

        &数组名即为取整个数组的地址,类型为int(*)[5],当&a+1时,即为跳过整个数组,即指针现在指向末尾的位置,类型还是为int(*)[5];(int*)为强制类型转化,将&a+1强制类型转化为int*的指针变量,再放入ptr的指针变量中,*(ptr-1)为往前倒退一个元素位置再解引用,*(a+1)为往后前进一个元素位置再解引用。

以下为思路结构图:

 

2、题目二

//在X86环境下
//假设结构体的⼤⼩是20个字节

#include <stdio.h>
#include <string.h>

struct Test
{
    int Num;
    char *pcName;
    short sDate;
    char cha[2];
    short sBa[4];
}*p = (struct Test*)0x100000;
//强制类型转化为struct Test*结构体指针类型
//p为结构体指针变量

int main()
{
    printf("%p\n", p + 0x1);
    //p是结构体指针,+1就是跳过一个结构体,一个结构体是20个字节
    //0x00100014    

    printf("%p\n", (unsigned long)p + 0x1);
    //unsigned long是无符号长整型
    //整数+1   0x00100001    

    printf("%p\n", (unsigned int*)p + 0x1);
    //unsigned int*是无符号整型指针类型
    //+1跳过一个unsigned int类型的变量,为4个字节
    //0x00100004

    return 0;
}

注意:

        整数+n和指针变量+n是两种不同的概念,整数+n是直接加上所要加上的数字,而指针变量+n是跳过多少个字节,取决于编译器的环境是32位还是64位的。

3、题目三

#include <stdio.h>

int main()
{
    int a[3][2] = { (0, 1), (2, 3), (4, 5) };
    //()里面为逗号表达式,是一种运算符号
    //逗号表达式运算顺序为从左往右计算,取最大的那个元素作为结果
    //()并不是二维数组的表达形式,正确的二维数组表达形式是用{}来表示的
    //即为int a[3][2] = { {0, 1}, {2, 3}, {4, 5} };

    int *p;
    p = a[0];
    printf( "%d", p[0]);//1

    return 0;
}

解题思路分析:

  1. ()里面为逗号表达式,是一种运算符号
  2. 逗号表达式运算顺序为从左往右计算,取最大的那个元素作为结果
  3. ()并不是二维数组的表达形式,正确的二维数组表达形式是用{}来表示的即为int a[3][2] = { {0, 1}, {2, 3}, {4, 5} };
  4. 使用逗号表达式后,数组排序为前三个为逗号表达式的运算结果,而后三个元素用0补齐

该二维数组的直观思维图:

4、题目四 

//假设环境是x86环境,程序输出的结果是啥?
#include <stdio.h>
int main()
{
    int a[5][5];
    int(*p)[4];//数组指针

    p = a;//将数组的第一行的首元素地址赋给指针变量p
    //等号左边p的类型为int(*)[4],等号右边a的类型为int(*)[5]
    //两者类型不相同,强制赋值会报错警告  

    printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
    //p[4][2]=*(*(p+4)+2)
    //两个地址相减得到的是元素与元素之间的个数,相差了几个元素
    //%p打印的是地址,即为相差几个元素作为中间值,再将其转化为补码的形式,这个补码就是地址,每四个连在一起的二进制数换成16进制的,环境为32位;
    //%d打印的是有符号整型,有符号整型是需要求出其原码再读
    //%u打印的无符号整型,无符号整型是需要求出其补码再读    

    return 0;
}

运行结果:

解题思路分析:

  1. 将数组的第一行的首元素地址赋给指针变量p;
  2. 等号左边p的类型为int(*)[4],等号右边a的类型为int(*)[5];
  3. 两者类型不相同,强制赋值会报错警告 

数组的直观表示图:

  1. 其中的等价关系:p[4][2]=*(*(p+4)+2)
  2. 两个地址相减得到的是元素与元素之间的个数,相差了几个元素
  3. %p打印的是地址,即为相差几个元素作为中间值,再将其转化为补码的形式,这个补码就是地址,每四个连在一起的二进制数换成16进制的,环境为32位
  4. %d打印的是有符号整型,有符号整型是需要求出其原码再读
  5. %u打印的无符号整型,无符号整型是需要求出其补码再读(有关原反补码的知识详细请关注往后更新的博客)

5、题目五

#include <stdio.h>
int main()
{
    int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };//二维数组
    
    int *ptr1 = (int *)(&aa + 1);
    //取数组名+1:&aa+1为跳过整个数组,指向数组末尾,再强制类型转化为int*类型赋给指针变量ptr1    

    int *ptr2 = (int *)(*(aa + 1));
    //数组名代表的是数组首元素的地址,即为aa[0]为第一行数组的地址;加上1则变成aa[1]为第二行数组的地址;解引用后再强制类型转化为int*类型赋给指针变量ptr2

    printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));//10   5
    //*(ptr1-1)为退后一个元素,指向前一个元素再解引用    
    //*(ptr2-1)为前进一个元素,指向后一个元素再解引用    

    return 0;
}

解题思路分析:

        取数组名+1:&aa+1为跳过整个数组,指向数组末尾,再强制类型转化为int*类型赋给指针变量ptr1;数组名代表的是数组首元素的地址,即为aa[0]为第一行数组的地址;加上1则变成aa[1]为第二行数组的地址;解引用后再强制类型转化为int*类型赋给指针变量ptr2。

数组排序的逻辑直观图:

 6、题目六

#include <stdio.h>
int main()
{
    char *a[] = {"work","at","alibaba"};
    //一级指针数组a[]存的是字符串首元素的地址
    
    char**pa = a;//二级指针变量pa存的是a[]首元素的地址
    pa++;//指向a[1]的地址

    printf("%s\n", *pa);//打印at
    return 0;
}

主要内容:

        最重要的是学会分别一级指针和二级指针的具体指向的内容,和指针的运算变化。

指向思维直观图:

7、题目七 

#include <stdio.h>
int main()
{
    char *c[] = {"ENTER","NEW","POINT","FIRST"};
    char**cp[] = {c+3,c+2,c+1,c};
    char***cpp = cp;

    //先看运算的优先级,再下手去运算

    printf("%s\n", **++cpp);//打印POINT
    //先运算++,再运算*解引用操作符

    printf("%s\n", *--*++cpp+3);//打印ER
    //先算++,再算*解引用,然后算--,再算*解引用,最后再算+3

    printf("%s\n", *cpp[-2]+3);//打印ST
    //等价关系*cpp[-2]+3 -> **(cpp-2) + 3
    //先算*解引用,再算+3

    printf("%s\n", cpp[-1][-1]+1);//打印EW
    //等价关系cpp[-1][-1]+1 -> *(*(cpp-1)-1) + 1    
    //先算(cpp-1),再算*(cpp-1)-1,然后算*(*(cpp-1)-1),最后再+1

    return 0;
}

指向直观思维图:

重要前提:

        前面运算的++或--运算操作符,会影响后面的运算结果;而数组的等价转化的加减,是不会影响后面的运算结果的。

解题思路分析:

1.第一个打印:printf("%s\n", **++cpp);//打印POINT
        先运算++,cpp从原来的指向指针数组cpp的起始地址指向到cpp[1],即下一个地址中去;再运算*解引用,得到c+2(c[2]的地址),再*解引用打印得到POINT。

 2.第二个打印:printf("%s\n", *--*++cpp+3);//打印ER
         先算++,因为第一次打印cpp已经++过一次了,这次再++,会使cpp从原来的指向指针数组cpp的起始地址指向到cpp[2],即下一个地址中去;再算*解引用,得到c+1,然后--得到c,再*解引用得到ENTER字符串的首元素,最后+3,地址向后移动3位,再通过打印函数得到ER。

3.第三次打印: printf("%s\n", *cpp[-2]+3);//ST
        等价关系*cpp[-2]+3 -> **(cpp-2) + 3等价后先算cpp-2得到cpp当前指向的位置,再算解引用的到c+3(c[3]的地址),然后再解引用得到FIRST字符串的首元素,最后进行+3打印出ST。

 4.第四次打印:printf("%s\n", cpp[-1][-1]+1);//打印EW
        等价关系cpp[-1][-1]+1 -> *(*(cpp-1)-1) + 1等价后先算(cpp-1)得到cpp当前指向的位置,再算*(cpp-1)得到c+2,然后再-1得到c+1(指向c[1]),经过*解引用之后得到NEW字符串的首元素,最后再+1跳过第一个字母打印。

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

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

相关文章

log4j 和 java.lang.OutOfMemoryError PermGen space

还是OneCoder在项目中沙箱的问题&#xff0c;用classloader隔离做的沙箱&#xff0c;反复运行用户的任务&#xff0c;出现永生区内存溢出&#xff1a; java.lang.OutOfMemoryError: PermGen space 这个问题在tomcat重复热部署的时候其实比较常见。其道理也和我们沙箱的道理基本…

【重学 MySQL】十二、SQL 语言的规则与规范

【重学 MySQL】十二、SQL 语言的规则与规范 基本规则注释语法规则命名规则基本命名规则具体命名规范其他注意事项 数据导入指令 SQL&#xff08;Structured Query Language&#xff0c;结构化查询语言&#xff09;的规则与规范是确保SQL语句能够正确执行、提高代码可读性和可维…

HarmonyOS开发实战( Beta5.0)Native Drawing自绘制能力替代Canvas提升性能

简介 Canvas 画布组件是用来显示自绘内容的组件&#xff0c;它具有保留历史绘制内容、增量绘制的特点。Canvas 有 CanvasRenderingContext2D/OffscreenCanvasRenderingContext2D 和 DrawingRenderingContext 两套API&#xff0c;应用使用两套API绘制的内容都可以在绑定的 Canv…

语音测试(一)ffmpeg视频转音频

视频转音频 下载ffmpeg工具进入bin目录cmd进入控制台输入命令 ffmpeg.exe -i ./视频.mp4 ./音频.wav命令说明 ffmpeg -i input.mp4 output.mkv FFmpeg 可能会尝试自动选择合适的编码器对视频和音频进行重新编码&#xff0c;以便适应 MKV 格式的要求ffmpeg -i input.mp4 -c c…

Java项目:140 springboot203医疗挂号管理系统

作者主页&#xff1a;舒克日记 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 一共有管理员、挂号人员、划价人员、医生 四个角色 管理员登录进入本系统操作的功能包括对挂号人员&#xff0c;划价人员&#xff0c;患者&#xff0…

初始QT!

作业&#xff1a;了解QT文件夹初始代码的意义 QT core gui #QT工程所需得类库 core是核心库 gui图形化界面相关库类 greaterThan(QT_MAJOR_VERSION, 4): QT widgets #版本超过4.0会加上widgetsCONFIG c11 #该编辑器支持c11后的版本 # The following define makes you…

ngrok forward本地argocd并设置为github repo webhook

为什么需要ngrok 我们刚学了argocd的安装和部署应用&#xff0c;但是argocd什么时候部署部署我们的应用&#xff0c;就取决于repo的sync机制。我们采用以下cmd设置为autosync。 argocd app list # to get our app argocd app set argocd/tekton-learning-nginx --sync-polic…

小试牛刀-SOL链创建Token

目录 1.编写目的 2.账户结构 3.环境及使用依赖 4.步骤分解 4.1.导入相关依赖 4.2. 初始化变量 4.3. 创建并初始化Mint Account 4.4. 创建并初始化Metadata Account 4.5. 发送创建和初始化mint Account 4.6 铸造Token 5.源码分享 Welcome to Code Blocks blog 本篇文…

震惊,从仿真走向现实,3D Map最大提升超12,Cube R-CNN使用合成数据集迁移到真实数据集

震惊&#xff0c;从仿真走向现实&#xff0c;3D Map最大提升超12&#xff0c;Cube R-CNN使用合成数据集迁移到真实数据集 Abstract 由于摄像机视角多变和场景条件不可预测&#xff0c;在动态路边场景中从单目图像中准确检测三维物体仍然是一个具有挑战性的问题。本文介绍了一…

基于飞桨paddle2.6.1+cuda11.7+paddleRS开发版的目标提取-道路数据集训练和预测代码

基于飞桨paddle2.6.1cuda11.7paddleRS开发版的目标提取-道路数据集训练和预测代码 预测结果&#xff1a; 预测影像&#xff1a; &#xff08;一&#xff09;准备道路数据集 下载数据集地址&#xff1a; https://aistudio.baidu.com/datasetdetail/56961 mass_road.zip …

国际标准图像分辨率测试ISO12233 - 2017中文翻译

参考&#xff1a;https://blog.csdn.net/jgw2008/article/details/116519404?spm1035.2023.3001.6557&utm_mediumdistribute.pc_relevant_bbs_down_v2.none-task-blog-2~default~OPENSEARCH~Rate-2-116519404-bbs-392397517.264^v3^pc_relevant_bbs_down_v2_default&d…

SpringBoot与Minio的极速之旅:解锁文件切片上传新境界

目录 一、前言 二、对象存储&#xff08;Object Storage&#xff09;介绍 &#xff08;1&#xff09;对象存储的特点 &#xff08;2&#xff09;Minio 与对象存储 &#xff08;3&#xff09;对象存储其他存储方式的区别 &#xff08;4&#xff09;对象存储的应用场景 三、…

万龙觉醒辅助:VMOS云手机助力资源采集!挂机升级!

《万龙觉醒》是一款策略型游戏&#xff0c;玩家需要合理规划资源采集、建筑升级、科技研发等来提升实力。在本文中&#xff0c;我们将为您提供一篇详细的游戏辅助攻略&#xff0c;并介绍如何使用VMOS云手机来提升您的游戏体验&#xff0c;实现24小时的自动化管理。 使用VMOS云…

R3M: A Universal Visual Representation for Robot Manipulation

R3M [25] explores how visual representations obtained by training on diverse human video data using time-contrastive learning and video-language can enable data-efficient learning&#xff08;实际上就是小样本学习&#xff09; of downstream robotic manipulati…

【FreeRTOS】事件组实验-改进姿态控制

目录 0 前言1 事件组实验_改进姿态控制2 改进思路2.1 创建事件2.2 等待事件2.3 设置事件2.4 Debug2.5 设置MPU6050寄存器 3 总结 0 前言 学习视频&#xff1a; 【FreeRTOS 入门与工程实践 --由浅入深带你学习 FreeRTOS&#xff08;FreeRTOS 教程 基于 STM32&#xff0c;以实际项…

pdf文件怎么编辑?6个pdf编辑方法学起来(图文教程)

pdf文件怎么编辑&#xff1f;现今的互联网时代&#xff0c;我们的办公也趋向于数字化办公。PDF文件已经成为我们日常工作和学习中不可或缺的格式文件。然而&#xff0c;编辑PDF文档不是一件容易的事。很多人会因为编辑pdf文档感到非常苦恼&#xff0c;尤其是当需要对PDF进行内容…

Linux内核编程(十五)网络设备驱动

本文目录 一、常见的网络协议二、传输介质三、RJ-45接口 对于网络知识不太熟悉的同学可以查看这篇文章&#xff1a;计算机网络知识点详情总结。 一、常见的网络协议 TCP、UDP协议&#xff1a;详情查看-TCP、UDP系统编程。DNS协议&#xff1a;是互联网中用于将域名&#xff08…

【刷题笔记】删除并获取最大点数粉刷房子

欢迎来到 破晓的历程的 博客 ⛺️不负时光&#xff0c;不负己✈️ 题目一 题目链接&#xff1a;删除并获取最大点数 思路&#xff1a; 预处理状态表示 状态转移方程 代码如下&#xff1a; class Solution { public:int deleteAndEarn(vector<int>& nums) {int N1…

八股(7)——Redis

八股&#xff08;7&#xff09;——Redis 4.3 RedisRedis 基础简单介绍一下 Redis!分布式缓存常见的技术选型方案有哪些&#xff1f;说一下 Redis 和 Memcached 的区别和共同点缓存数据的处理流程是怎样的&#xff1f;为什么要用 Redis/为什么要用缓存&#xff1f;Redis 除了做…

2024 年全国大学生数学建模竞赛(国赛)浅析

需要完整资料&#xff0c;请关注WX&#xff1a;“小何数模”&#xff01; &#xff08;需要完整B、C和E题资料请关注WX&#xff1a;“小何数模”&#xff0c;获取资料链接&#xff01;&#xff09; 本次万众瞩目的全国大学生数学建模赛题已正式出炉&#xff0c;无论是赛题难度…