指针(基础)

news2024/11/18 11:30:53

目录

一、内存和地址 

二、指针是什么?

三、指针变量的内容

四、指针类型 

五、间接访问操作符 

(一)易混淆

六、野指针

(一)野指针成因  

1. 指针未初始化

2. 指针越界访问 

3. 指针指向的空间释放 

(二)如何规避野指针  

(三)处理未初始化指针 

1. 总是用NULL来初始化指针

2. 用assert函数 

补充:指针为什么要初始化

七、常量和指针 

(一)指向常量的指针   

1. 具体形式

2. 把pci声明为指向整数常量的指针意味着:

(二)指向非常量的常量指针  

1. 举例

2. 注意

(三)指向常量的常量指针 

八、指针的指针

(一)对于二级指针的运算有:

(二)注意:

(三)总结  

 九、字符指针

(一)易错 :cout特性

(二) 把字符串 hello,world! 首字符的地址放到p中

(三)举例  

1. 常量字符串之间

2. 字符数组之间

3. 总结 

十、指针数组

(一)整形数组和字符数组  

(二)整形指针数组  

十一、数组指针

(一)判断数组指针 

举例1: 定义一个数组指针,该指针指向char* arr[5]数组

举例2: 定义一个数组指针,该指针指向int arr2[10]数组 

(二)&数组名VS数组名 

十二、 数组参数、指针参数

(一)一维数组传参  

1. 举例

(二)二维数组传参 

1. 传参方式  

2. 举例 

(三)一级指针传参  

1. 当一个函数的参数部分为一级指针的时候,函数能接收什么参数?

2. 举例 

(四)二级指针传参  

1. 当函数的参数为二级指针的时候,可以接收什么参数? 

2. 举例


一、内存和地址 

  • 此处有五个整数,每个数都对应一个存储地址 

  • 但是要记住地址太笨拙,所以高级语言所提供的特性之一是通过名字而非地址来访问内存的位置。下面这张图与上图相同,但这次使用名字来代替地址 

  • 这些名字就是我们所称的变量,注意名字和内存位置之间的关联不是硬件所提供,它是由编译器为我们实现的。所有这些变量给了我们一种更方便的方法记住地址------硬件仍然通过地址访问内存位置 

二、指针是什么?

  • 在计算机科学中,指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(point to)存在电脑存储器中另一个地方的值,由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化的称为“指针”。意思是通过它能找到以它为地址的内存单元。
  • 简而言之,指针就是变量,用来存放地址的变量(存放在指针中的值都被当成地址处理)
  • 指针的大小在32位平台是4个字节,在64位平台是8个字节 

三、指针变量的内容

int a = 112, b = -1;在内存中开辟空间 
float c = 3.14;
int* d = &a;//这里对变量a,取出它的地址
	//将a的地址存放在d变量中,d就是一个指针变量
float* e = &c;
  •  a的值是112,b的值是-1,c的值是3.14,d的值是100,e的值是108
  • 注意:d的值不是112,e不是3.14,因为变量的值就是分配给该变量的内存位置所存储的数值,即使是指针变量也不以外!
  • 指针变量的赋值只能赋予地址

四、指针类型 

  • 变量有不同的类型,整形,浮点型等,指针也有相应的类型

例如:

char  *pc = NULL;
int  *pi = NULL;
short *ps = NULL;
long  *pl = NULL;
float *pf = NULL;
double *pd = NULL;
  • char* 类型的指针是为了存放 char 类型变量的地址
  • short* 类型的指针是为了存放 short 类型变量的地址
  • int* 类型的指针是为了存放 int 类型变量的地址

五、间接访问操作符 

  • 通过一个指针访问它所指向的地址的过程称为间接访问或解引用指针,这个用于执行间接访问的操作符是单目操作符* 
表达式右值类型
a112int
b-1int
c3.14float
d100int*
e108float*
*d112int
*e3.14float
  • d的值是100,*d表示访问内存位置100 并查看那里的值,即*d=112

(一)易混淆

  • *&a=25表达什么意思?
  • 先取a的地址,然后利用*访问地址,向位置(&a)的空间赋值25,也就是a=25

六、野指针

  • 概念: 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的) 

(一)野指针成因  

1. 指针未初始化

错误写法:

 

正确:

#include <iostream>
#include<cstdlib>
using namespace std;
int main()
{
	int* p = (int*)malloc(sizeof(int));
	if (p == NULL)
		exit(-1);
	*p = 20;
	cout << *p;//20
	free(p);
	return 0;
}

2. 指针越界访问 

//错误写法
#include <iostream>
using namespace std;
int main()
{
	int arr[10] = { 0 };
	int* p = arr;
	int i = 0;
	for (i = 0; i <= 11; i++)
	{
		//当指针指向的范围超出数组arr的范围时,p就是野指针
		*(p++) = i;
	}
	return 0;
}

3. 指针指向的空间释放 

(二)如何规避野指针  

  1. 指针初始化
  2. 小心指针越界
  3. 指针指向空间释放即使置NULL
  4. 避免返回局部变量的地址
  5. 指针使用之前检查有效性 

(三)处理未初始化指针 

1. 总是用NULL来初始化指针

  • 把指针初始化为NULL更熔炉检查是否使用正确,即便这样,检查空值也比较麻烦 
int* p = NULL;
......
if (p == NULL)//不应该解引p
{

}
else//可以使用p
{

}

2. 用assert函数 

  • 下面代码测试了p变量是否为空值,如果表达式为真,那么什么都不会发生;如果表达式为假,程序会终止
assert(p != NULL);

补充:指针为什么要初始化

  • 如果变量没有被初始化,包含的都是垃圾数据,所谓垃圾是指,分配的内存中可能包含任何数据。当内存刚分配时不会被处理,之前的内容可能是任何东西。如果之前的内容是一个浮点数,但是现在需要存放的是整数,将一个浮点数当成一个整数没有什么用,就算确实包含了整数,也不大可能是正确的整数,所有说内容是垃圾
  • 只有初始化后,指针才会正常工作 

七、常量和指针 

(一)指向常量的指针   

  • 将指针定义为指向常量,这意味着不能通过指针修改它所引用的值 (指针认为自己指向的是常量,所有不允许用指针来修改这个常量)

1. 具体形式

const int *pci;//指向整数常量
//等价形式int const* pci;

2. 把pci声明为指向整数常量的指针意味着:

  1. pci可以被修改为指向不同的整数常量
  2. pci可以被修改为指向不同的非整数常量
  3. 可以解引用pci以读取数据
  4. 不能解引用pci从而修改它所指向的数据
#include <iostream>
#include<cstdlib>
using namespace std;
int main()
{
	int num = 5;
	const int limit = 500;
	int* pi = (int*)malloc(sizeof(int));//指向整数
	const int* pci = (int*)malloc(sizeof(int));//指向整数常量
	cout << &pci << " " << pci << endl;//000000ACB338FC98 00000269CB403140
	pci = &limit;//对应第一点
	cout << &pci << " " << pci << endl;//000000ACB338FC98 000000ACB338FC54
	pci = &num;//对应第二点
	cout << &pci << " " << pci << endl;//000000ACB338FC98 000000ACB338FC34
	//*pci=123;是错误的
	free(pi);
	return 0;
}

(二)指向非常量的常量指针  

  •  指针不可变化,但是指向的数据可变

1. 举例

int num = 5;
int *const cpi=&num;

2. 注意

  1. cpi必须被初始化为指向非常量变量
  2. cpi不能被修改
  3. cpi指向的数据可以被修改
#include <iostream>
using namespace std;
int main()
{
	int num = 5;
	const int limit = 25;
	int *const cpi=&num;
	cout << cpi << " " << *cpi<<endl;//000000B56B6FFA04 5
	*cpi = limit;
	cout << cpi << " " << *cpi << endl;//000000B56B6FFA04 25
	//cpi = &limit;错误写法,常量指针不能修改
	return 0;
}

(三)指向常量的常量指针 

  • 指针不能修改,指针指向的数据也不能修改
  • 可以将常量的地址赋值给cpci
#include <iostream>
using namespace std;
int main()
{
	int num = 5;
	const int limit = 25;
	//const int *const cpci;错误写法必须初始化
	const int* const cpci = &limit;
	cout << cpci << " " << *cpci << endl;//000000CF749EF9D4 25
	const int* const cpci2 = &num;
	cout << cpci2 << " " << *cpci2 << endl;//000000CF749EF9B4 5
	return 0;
}

八、指针的指针

  • 指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里?
  • 这就是 二级指针 
int a=12;
int* pa=&a;
int** ppa=&pa;
  • 变量pa是一个指向整型的指针,所以ppa的类型是一个指向“整型的指针”的指针,也就是指针的指针
  • a的地址存放在pa中,pa的地址存放在ppa中 

(一)对于二级指针的运算有:

  • *ppa 通过对ppa中的地址进行解引用,这样找到的是 pa , *ppa 其实访问的就是 pa  
  •  **ppa 先通过 *ppa 找到 pa ,然后对 pa 进行解引用操作: *pa ,那找到的是 a
#include <iostream>
using namespace std;
int main()
{
	int a = 12;
	int* pa = &a;
	int** ppa = &pa;
	cout << &ppa << " " << ppa << endl;//000000C434FEF9F8 000000C434FEF9D8
	cout <<&pa << " " << pa << endl;//000000C434FEF9D8 000000C434FEF9B4
	cout <<&a<<" "<< a;//000000C434FEF9B4 12
	return 0;
}

(二)注意:

  • *具有从右至左的结合性 

(三)总结  

表达式相当的表达式
a12
pa&a
*paa,12
ppa&pa
*ppapa,&a
**ppa*pa,a,12

 九、字符指针

(一)易错 :cout特性

  • cout输出的结尾条件是找到‘\0’,但是字符并没有‘\0’,所有cout会以该字符为第一个字符开始持续打印,并强行将随后的地址当作后续字符,打印出乱码 

(二) 把字符串 hello,world! 首字符的地址放到p中

#include<iostream>
using namespace std;
int main()
{
	const char* p = "hello,world!";
	cout << &p << " " << p;//000000CC043AFAE8 hello,world!
	return 0;
}

 

(三)举例  

1. 常量字符串之间

#include<iostream>
using namespace std;
int main()
{
	const char* p = "hello,world!";
	const char* p2 = "hello,world!";
	if (p == p2)
		cout << "p和p2相同" << endl;
	else
		cout << "p和p2不同" << endl;
	return 0;
}

 

原因:

2. 字符数组之间

#include<iostream>
using namespace std;
int main()
{
	char str[]= "hello,world!";
	char str2[] = "hello,world!";
	if (str == str2)
		cout << "str和str2相同" << endl;
	else
		cout << "str和str2不同" << endl;
	return 0;
}

 

原因:

 

3. 总结 

C/C++会把常量字符串存储到单独的一个内存区域,当几个指针指向同一个字符串的时候,他们实际会指向同一块内存。但是用相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块 

十、指针数组

  • 指针数组是存放指针的数组

(一)整形数组和字符数组  

(二)整形指针数组  

int*arr3[5]

 

十一、数组指针

  • 数组指针是指针?还是数组?答案是:指针 
  • 数组指针:能够指向数组的指针 
int* p;//p是整形指针----指向整形的指针----可以存放整形的地址
char* pc;//pc是字符指针----指向字符的指针----可以存放字符的地址
  •  同理,数组指针----指向数组的指针----存放数组的地址

(一)判断数组指针 

  • 下面代码哪个是数组指针? 
int *p1[10];
int (*p2)[10];
  • 第一个:p1先和[ ]结合 ,有10个元素,每个元素的类型是int*
  • 第二个是数组指针,p2先和*结合,说明p2是一个指针变量,然后指向的是一个大小为10个整型的数组。所以p2是一个指针,指向一个数组,叫数组指针
  • 注意:[]的优先级要高于*号的,所以必须加上()来保证p先和*结合 

举例1: 定义一个数组指针,该指针指向char* arr[5]数组

char* arr[5];
char* (*pa)[5] = &arr;

 

举例2: 定义一个数组指针,该指针指向int arr2[10]数组 

int arr2[10];
int (*p)[10] = &arr2;

(二)&数组名VS数组名 

#include<iostream>
using namespace std;
int main()
{
	int arr[10];
	cout << arr << " " << arr+1 << endl;//000000F84C1AF798 000000F84C1AF79C
	cout << &arr << " " << &arr+1 << endl;//000000F84C1AF798 000000F84C1AF7C0
	return 0;
}
  • arr是数组名,数组名表示数组首元素的地址
  • &arr 表示的是数组的地址,而不是数组首元素的地址。本例中 &arr 的类型是: int(*)[10] ,是一种数组指针类型数组的地址+1,跳过整个数组的大小,所以 &arr+1 相对于 &arr 的差值是40 

十二、 数组参数、指针参数

(一)一维数组传参  

  • 数组名的值就是一个指向数组第一个元素的指针,此时传递给函数的是一份该指针的拷贝,函数如果执行了下标引用(例如arr[0],arr[1]....),实际上是对这个指针执行间接访问操作,并且通过这种间接访问,函数可以访问和修改调用程序的数组元素 

1. 举例

#include<iostream>
using namespace std;
void test1(int a[])
{
	swap(a[0],a[1]);
}
void test2(int b[10])
{
	swap(b[2], b[3]);
}
void test3(int* c)
{
	swap(c[4], c[5]);
}
void test4(int* d[])
{
	swap(d[0], d[1]);
}
void test5(int* e[20])
{
	swap(e[2], e[3]);
}
void test6(int** f)
{
	swap(f[4], f[5]);
}
void print(int arr[])
{
	for (int i = 0; i < 6; i++)
	{
		cout << arr[i] << " ";
	}
	cout << endl<<endl;
}
void print2(int* arr2[])
{
	for (int i = 0; i < 6; i++)
	{
		cout << arr2[i] << " ";
	}
	cout << endl << endl;
}
int main()
{
	int arr[] = { 11,15,13,67,89,45 };
	int* arr2[] = {&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]};

	print(arr);//11 15 13 67 89 45
	test1(arr);
	print(arr);

	test2(arr);
	print(arr);

	test3(arr);
	print(arr);

	print2(arr2);
	test4(arr2);
	print2(arr2);

	test5(arr2);
	print2(arr2);

	test6(arr2);
	print2(arr2);
	return 0;
}

(二)二维数组传参 

  •  二维数组:使用行和列标识数组元素,这类数组需要映射为内存中的一维地址空间
  • 数组名表示首元素地址,二维数组的首元素是第一行,首元素的地址是第一行的地址,而二维数组的第一行是一个一维数组,故首元素的地址是一个一维数组的地址 

1. 传参方式  

void test1(int a[row][col])//第一种
void test2(int b[][col])//第一种
void test3(int (*c)[col])//第二种

错误形式:

void test(int* arr);//参数定义一个整形指针,是存放整形数据
void test(int** arr);//参数是二级指针,二级指针是存放一级指针的地址
  • 注意:二维数组传参,函数形参的设计只能省略第一个[]的数字。因为对一个二维数组,可以不知道有多少行,但是必须知道一行多少元素

2. 举例 

#include<iostream>
using namespace std;
void test1(int a[3][5])
{
	a[0][0] = 1, a[0][1] = 2;
}
void test2(int b[][5])
{
	b[1][0] = 3, b[1][1] = 4;
}
void test3(int(*c)[5])
{
	c[1][0] = 5, c[1][1] = 6;
}
void print(int d[3][5])
{
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 5; j++)
		{
			cout << d[i][j] << " ";
		}
		cout << endl;
	}
}
int main()
{
	int arr[3][5] = { 0 };
	print(arr);
	test1(arr);
	cout << endl;

	print(arr);
	test2(arr);
	cout << endl;

	print(arr);
	test3(arr);
	cout << endl;

	print(arr);

    return 0;

}

 

(三)一级指针传参  

1. 当一个函数的参数部分为一级指针的时候,函数能接收什么参数?

例如:

void test1(int *p);//p是一级指针
  •  可以接收地址或者一级指针

2. 举例 

#include<iostream>
using namespace std;
void test(int* p)
{
	;
}
int main()
{
	int a = 12;
	int* p1 = &a;
	test(&a);//传地址
	test(p1);//传一级指针
	return 0;
}

(四)二级指针传参  

1. 当函数的参数为二级指针的时候,可以接收什么参数? 

  • 可以接收一级指针的地址和二级指针 

2. 举例

#include<iostream>
using namespace std;
void test(int** p)
{
	;
}
int main()
{
	int a = 12;
	int* p = &a;
	int** pp = &p;
	test(&p);//传一级指针的地址
	test(pp);//传二级指针

	int* arr[10];//arr是指针数组,里面存放的指针,传arr过去实际是传首元素的地址过去(首元素是一个指针),也就是传入了一个指针的地址
	test(arr);
	return 0;
}

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

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

相关文章

php xss攻击

文章目录一、什么是xss攻击二、攻击类型三、php相关处理函数1、htmlspecialchars 函数2、htmlentities 函数3、strip_tags 函数一、什么是xss攻击 xss攻击通常指的是通过利用网页开发时留下的漏洞&#xff0c;通过巧妙的方法注入恶意指令代码到网页&#xff0c;使用户加载并执…

make menuconfig分析

在uboot源码顶层目录下&#xff0c;进入scripts/kconfig目录&#xff0c;打开Makefile文件 mconf作为可执行参数,uboot源码顶层目录下的配置文件传递给conf

39_tp6的rce漏洞

tp6的rce漏洞 一、环境搭建 使用docker本地搭建tp6环境 1. 下载镜像 docker pull vulfocus/thinkphp:6.0.122. 端口映射 启动镜像,并将80端口映射到8081端口,防止80端口冲突,运行容器 docker run -it -d -p 8081:80 1fc5d159922e3. 打开网站 默认的网页目录是在public目…

怎么在线识别图片文字?说一个思路

图片中的文字怎么在线识别&#xff1f;很多小伙伴在接收到图片类型的文件时&#xff0c;不知道怎么处理其中记录的信息。打字整理嫌麻烦怕出错的话&#xff0c;可以借助识别软件来处理&#xff0c;下面给大家介绍三种比较好用的工具&#xff0c;希望能解决你的问题。方法一、在…

SAP ADM100-Unit3 系统配置介绍:如何设置配置文件参数

本节将介绍如何改变配置文件参数的值。 1、管理并维护配置文件 如果想去调整配置文件参数,可以使用操作系统特定的编辑器去调整参数。但是,这个过程是有确定风险的,因此用户必须确保这个调整被正确的执行和记录。设置的参数不正确可能导致实例无法启动。因此,SAP系统提供…

JVM学习疑问之——逃逸分析

前言 根据之前安排的jvm学习计划在进行jvm学习&#xff0c;找到了尚硅谷宋红康老师的jvm视频&#xff0c;跟着视频学习、做笔记&#xff0c;学习到了很多&#xff0c;为尚硅谷及宋红康老师点赞。说到这里&#xff0c;虽然我有一键三连&#xff0c;但这么好的视频&#xff0c;我…

(六)redis持久化操作(RDBAOF)

目录 一、RDB&#xff08;Redis DataBase&#xff09; 1、简介 2、持久化流程 3、dump.rdb文件 4、配置文件 5、rdb的备份 6、rdb的恢复 7、优势 8、劣势 二、AOF&#xff08;Append Only File&#xff09; 1、简介 2、持久化流程 3、AOF和RDB同时开启 4、AOF启动…

HTML中引入CSS样式的第三种方式:链入外部样式表文件

<!-- 第三种方式&#xff1a;链入外部样式表文件&#xff0c;这种方式最常用。 就是将样式写到一个独立的xxx.css文件当中&#xff0c;在需要的网页上直接引入这个xxx.css文件就可以了。 语法格式&#xff1a; <head> …

【自学Docker 】Docker port命令

Docker port命令 概述 docker port命令教程 docker port 命令可以用于列出指定的 Docker容器 的端口映射&#xff0c;或者将容器里的端口映射到宿主机。该命令后面的 CONTAINER 可以是容器Id&#xff0c;或者是容器名。 docker port语法 haicoder(www.haicoder.net)# docke…

jsp 校园相册管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 jsp 校园相册管理系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统采用web模式开发&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境 为TOMCAT7.0,Myeclipse8.5开发&#xf…

计算机组成原理 | 第五章:输入输出系统 | 程序中断方式

文章目录&#x1f4da;概述&#x1f407;I/O系统的概述&#x1f407;输入输出系统的组成&#x1f407;I/O设备与主机的联系&#x1f407;I/O设备与主机信息传送的控制方式&#x1f4da;I/O接口&#x1f407;为什么要设置接口❓&#x1f407;接口的功能和组成&#x1f407;接口和…

Pygame的SurfaceImageTime

Surface用来生成一个矩形&#xff0c;Image用来导入外部图片&#xff0c;Time用来暂停时间。 Surface 生成矩形 facepy.Surface((200,200))填充颜色 face.fill(blue) 放入界面 screen.blit(face,(50,50)) Image 导入图片 imgpy.image.load(d:\\图片\\1.jpg) 缩放…

make prerequisite: 根据文件状态自动确定是否重新执行

Basic 先看一个简单的例子&#xff08;引自Makefile Tutorial By Example&#xff09;&#xff1a;当我们对同一个makefile执行两次make命令时&#xff0c;由于第一次运行已经生成了目标文件blah&#xff0c;第二次make会直接输出blah is up to date&#xff0c;而不会重新com…

(四)Redis配置文件redis.conf详解

目录 一、Units单位 二、INCLUDES&#xff08;包含配置&#xff09; 三、NETWORK&#xff08;网络配置&#xff09; 四、GENERAL&#xff08;总则&#xff09; 五、SNAPSHOTTING&#xff08;拍摄快照&#xff09; 六、REPLICATION&#xff08;复制&#xff09; 七、SECU…

【苹果相册日历推位置推送iMessage】需要将真机的udid复制出来在此添加

推荐内容IMESSGAE相关 作者✈️IMEAX推荐内容iMessage苹果推软件 *** 点击即可查看作者要求内容信息作者✈️IMEAX推荐内容1.家庭推内容 *** 点击即可查看作者要求内容信息作者✈️IMEAX推荐内容2.相册推 *** 点击即可查看作者要求内容信息作者✈️IMEAX推荐内容3.日历推 *** …

通过伪代码结合理论模拟pc端接入单点登录(Oauth2浙里办)

前言 还记得那是一个惺忪的早晨&#xff0c;带着困意的我正准备去公司上班&#xff0c;坐车坐到一半&#xff0c;钉钉突然袭来一条红色预警信息&#xff0c;公司查出来有个人阳了&#xff0c;好消息&#xff1a;万幸我还在去公司的路上&#xff0c;没有和他有过多的接触&#x…

机器学习中的数学原理——对数似然函数

这个专栏主要是用来分享一下我在 机器学习中的 学习笔记及一些感悟&#xff0c;也希望对你的学习有帮助哦&#xff01;感兴趣的小伙伴欢迎 私信或者评论区留言&#xff01;这一篇就更新一下《 白话机器学习中的数学——对数似然函数》&#xff01; 目录 一、什么是对数似然函数…

SD卡打不开怎么办?sd卡损坏修复,盘点一些实用的教程

SD卡的应用十分广泛&#xff0c;比如&#xff0c;手机、数码相机、摄像机、MP4、航拍器、车载导航等。但是随着SD卡的使用时间的长短&#xff0c;有时会出现常见问题—SD卡打不开。SD卡里面保持着我们很多重要数据&#xff0c;如果它打不开&#xff0c;很可能导致我们里面重要数…

CSS倒影炫酷属性 -webkit-box-reflect 的使用

文章目录效果预览一、相关知识点介绍属性相关二、实现步骤总结效果预览 一、相关知识点 介绍 文档 MDN关于倒影属性介绍&#xff1a;https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-box-reflect 官方说明&#xff1a; 非标准:该特性是非标准的&#xff0c;不在标…

CCF BDCI|算能赛题决赛选手说明论文-05

基于TPU平台实现人群密度估计 队伍&#xff1a;SO-FAST 宋礼 算法工程师 京东科技 中国-北京 song200626163.com柯嵩宇计算机科学与技术专业 博士 上海交通大学 中国-上海 songyukesjtu.edu.cn包锴楠计算机科学与技术 硕士 西南交通大学 中国-成都 baokainan123gmail…