版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第6讲指针授课内容6.1指针与指针变量6.2指针运算6.3指针与数组6.4动态存储分配6.5指针和函数6.6指针的数组6.1
地址和指针地址的概念计算机的内存储器就象一个一维数组,每个存储单元就对应一个数组元素。内存储器的每一个存储单元都有一个唯一的编号,这个编号就是该存储单元的地址。它是一个无符号整数。地址的概念我们可以直接通过地址处理数据,这样可以提高程序的运行效率。C++规定:变量的地址:可以用取地址运算符‘&’来获取数组的地址:可以用数组名表示函数的地址:可以用函数名表示指针和指针变量的概念指针:某个变量、数组、函数或对象的地址称为该变量、数组、函数或对象的指针。0X0012ff710000000000000000000111100X0012ff700X0012ff730X0012ff720X0012ff750X0012ff74inta=30;0000001E00000000a指针和指针变量的概念指针变量:存放指针的变量。0X0012ff710000000000000000000111100X0012ff700X0012ff730X0012ff720X0012ff750X0012ff74inta=30;int*p=&a;00000000a0X0012ff760X0012ff770X0012ff78p11111111000100100111000000000000指针型变量的定义指针变量也是一个变量,必须遵守“先定义后使用”的原则一般格式:类型描述符*指针变量名表;int*ptr;float*array;char*s1,*s2;指针变量是有类型的指针变量有类型是源于指针(地址)有类型指针类型不同类型的指针变量所占据的存储区域都一样大。intmain(){ int*p1;float*p2; double*p3;char*p4; cout<<sizeof(p1)<<endl; cout<<sizeof(p2)<<endl; cout<<sizeof(p3)<<endl; cout<<sizeof(p4)<<endl; return0;}指针类型指针类型规定了用指针间接访问数据时的访问方式。7.5f在机器中如何表示(IEEE754)用二进制来表示(32位)。7.5D=111.1B111.1B=1.111*22B尾码M为1.111阶码E为2+127=129=100000010100000011110000000000000000000040F00000指针类型1089470464在机器中如何表示(IEEE754)1089470464D=40F00000Bintmain(){ floats=7.5f; inta=1089470464; cout<<s<<endl; cout<<a<<endl; return0;}指针类型指针类型规定了用指针间接访问数据时的访问方式。intmain(){inta=1089470464;int*p1=&a;float*p2=(float*)&a;cout<<p1<<endl;cout<<p2<<endl;cout<<*p1<<endl;cout<<*p2<<endl;return0;}a:0X0012ff7cp10X0012ff7c0X0012ff7cp2
0X40F0000040F00000指针型变量的定义指针类型规定了用指针间接访问数据时的访问方式。intmain(){ inta=65; int*p1=&a; char*p2=(char*)&a; cout<<*p1<<endl; cout<<*p2<<endl; return0;}a:0X0012ff7cp10X0012ff7c0X0012ff7cp2
0X0012ff7c0X0012ff7f0X0000004100000041指针类型指针类型规定了指针的运算规则。intmain(){ inta=1; int*pa=&a; doubles=2.4;double*ps=&s; cout<<pa<<endl; cout<<ps<<endl; cout<<pa+1<<endl; cout<<ps+1<<endl; return0;}//1000H//2000H//1004H//2008H指针类型存储任何类型的指针(地址)所需要的存储区域大小相同。指针类型规定了用指针(地址)间接访问数据时的访问方式。指针类型规定了指针(地址)的运算规则。指针变量的使用指针变量在定义后必须初始化才能使用;否则,结果不确定。int*p;*p=3;//编译可能通过,但危险!p随机内容随机内容随机内容1000H指针变量的使用指针初始化的一般格式:指针变量名=数据对象的地址;数据对象可以是变量、数组、函数、对象等。举例:int*ptr,i=10;ptr=&i;//指向单个变量char*sp="string"; //指向字符串inta[5],*ap;ap=a;//指向数组intmax(){…}int(*fp)();fp=max;//指向函数存储指针变量的指针的指针变量定义格式:数据类型**p例:inti=3; int*q=&i; int**p;
intp=&q;
*(*p)*qi
cout<<i<<*q<<**p;
//输出结果:3,3,3
┠────┨2000┃3┃i┠────┨2002┃┃┠────┨2004┃2008┃p┠────┨2006┃┃┠────┨2008┃2000┃q┠────┨指向指针的指针变量利用指针变量访问另一变量称为“间接访问”,
分为:单级间址:一个指针变量存放一个目标变量的地址。
二级间址:存储指针变量的指针的指针变量。多级间址:易发生混乱。6.2指针的运算指针的运算指针是一个地址,地址是一个值,因此指针也可以参加运算。指针的运算方式“*”和“&”运算(专门的指针元算符)指针变量算术运算指针变量比较运算指针变量下标运算“*”和“&”运算符“&”称为取地址运算符,用以返回变量的指针,即变量的地址。单目运算符、结合性:自右向左“*”称为指针运算符,用以返回指针所指向的内存单元的内容。单目运算符、结合性:自右向左两者关系:互为逆运算“*”和“&”运算符“*”和“&”用在不同的地方有不同的含义例如:inta=3;int*ptr=&a; y=*ptr; //将指针变量ptr所指向的内存单元的内容赋给变量yint&ref=a; ptr=&x; //取变量x的地址指针的其他运算指针的算术运算指针可以自增++、自减--,也可以加减整型数据,完成指针改变,实现对不同数据单元的访问操作。指针的其他运算例如:inta[3];int*ptr=a,*qtr;
qtr=ptr+1;
如果数组a的首地址为0x0012ff74,则qtr=?doublea[3];double*ptr=a,*qtr;
qtr=ptr+1;
如果数组a的首地址为0x0012ff74,则qtr=?指针的其他运算inta[10];int*p=a;p++;ints=*(p+1);chara[10];char*p=a;p++;chars=*(p+1);p1000H1004H1000Ha[0]a[1]a[2]a[3]a[9]...指针的其他运算指针的算术运算指向同一数组的不同数组元素的指针之间可以进行减法运算。例如:inta[10];
int*p=&a[0];
int*q=&a[5];
ints=q-p;指针间的相乘或相除,两个指针间的相加、位操作,指针与浮点型数据的加减都是没有意义的。指针的其他运算指针的比较(关系)运算通过==或者!=运算符来表示指针是否指向内存中的同一位置(地址)inta;int*p=&a;int*q=&a;boolb=(p==q);inta[5]={1,2,3,4,5};int*e=&a[4]; for(int*p=a;p!=e;++p) {cout<<*p;
}指针的其他运算指针的比较(关系)运算不允许两个类型不同的指针进行比较。 doubles=3.4;inta=10; double*sP=&s;int*aP=&a; if(sP==aP){…}//错误,没有意义指针变量可以被赋值为零表示指针变量不指向任何地址inta,int*p=&a;p=0;if(p!=0){…}指针的其他运算下标运算[]intx; inta[3]={1,2,3}; int*p=a; x=p[1];intx; inta=10; int*p=&a; x=p[1];//相当于x=*(p+1)//相当于x=*(p+1)6.3指针与数组指针与一维数组数组名本身是指针常量,它表示该数组的首地址计算机中处理数组时,实际上是将a[i]转换成*(a+i)的形式。即
a[i]*(a+i)inta[10];int*ptr=&a;a[i]*(a+i)*(ptr+i)ptr[i]指针与一维数组例inta[]={1,2,3,4,5,6,7,8,9,10},*p=a,i=2;
数组元素地址的正确表示:
(A)&(a+1)(B)a++ (C)&p(D)&p[i]inta[]={1,2,3,4,5,6,7,8,9,10},*p=a; 下面哪个正确。a++,a--p++,p--a+1,*(a+2)指针与一维数组编写函数对一维int 数组用 随机值初始化。#include<cstdlib>voidinit(int*a,intn
){ for(inti=0;i<n;++i) {a[i]=rand();}}intmain(){intaray[3];init(aray,3);return0;}//*(a+i)=rand();arrayinit()…………a1000Hn31000H6.4动态存储分配inta=10;voidf(){staticints=23;intd=14;}intmain(){ intm=10; f(); return0;}…静态存储区域栈存储区域a(10)s(23)m(10)……d(14)动态存储分配内存分配方式有三种:从静态存储区域分配这块内存在程序的整个运行期间都被程序持有。例如static变量。从栈空间分配在执行函数时,函数内局部变量的存储单元都在栈上分配,函数执行结束时这些存储单元自动被释放。动态存储分配从静态存储区域分配和从栈空间分配的特点。程序员在程序编译之前就必须告知编译器所占用的存储空间无法根据运行时的具体情况灵活的调整存储空间的大小动态存储分配内存分配方式有三种:从堆(内存中的空闲存储区)上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的持续期由我们决定,使用非常灵活,但问题也最多。动态存储分配的格式动态存储分配需要使用指针、new运算符和delete运算符运算符new用来申请所需的内存<指针变量>=new<类型>
<指针变量>=new<类型>(<初值>);也可以为数组申请内存: <指针变量>=new<类型>[<元素数>];含义:new运算符从堆中分配一块与<类型>相适应的存储空间,如果分配成功,则将其首地址存入指针变量中,否则指针的值为NULL(0)动态存储分配的存储区域通过指针访问动态存储分配的格式voidf(){ intn; cin>>n; int*p1=newint; int*p2=newint[n]; int*p3=newint(2); p2[3]=4;}intmain(){ f(); return0;}nf()main()运行状态及返回地址p15p3p20X00121d700X00121d700X00121d800X00121d800X00121d740X00121d742动态分配内存的释放运算符delete用于释放先前申请到的存储块delete<指针>;int*p=newint(12);deletep;若要释放连续的空间,必须在delete后面跟上[]intsize=10; int*p=newint[size]; …… delete[]p;野指针intmain(){ int*p; cout<<p;*p=10;return0;}intmain(){ int*p; { intn=10; p=&n; } *p=20; return0;}10n:p0x10000X1000野指针野指针野指针指向一段内存,但该内存不被当前的程序所控制。voidf(){ intn=4;int*p=newint[n];p[2]=7;delete[]p;//p成为野指针p[2]=8;}4np0x10007动态存储分配注意点动态存储分配应注意的问题要确认分配成功后才能使用。
int*ptr=newint;
if(ptr!=NULL) { *ptr=100; }动态存储分配注意点动态存储分配应注意的问题分配成功后不宜变动 指向该内存的指针变量的值intmain(){ inta=10; int*ptr=newint(12); ptr=&a; deleteptr; return0;}10aptr0x100012&a动态存储分配注意点动态存储分配应注意的问题动态分配的存储单元不会自动释放,因此不用的存储单元一定要及时释放,防止内存泄漏。voidf(){int*p=newint[4];}intmain(){f();f() return0;}……f()p0x10000x100F6.5指针与函数指针作为函数的参数指针作为函数的参数函数参数不仅可以是基本数据类型的变量、对象名、数组名或函数名,而且可以是指针。通过使实参与形参指针指向共同的内存空间,达到了被调用函数向调用函数传递信息的目的。指针作为函数的参数viodf(char*p,intn
){ for(inti=0;i<n;++i)
{++p[i];cout<<p[i];}}intmain(){inta[3]={1,3,5}; f(a,3);return0;}a:1000Hf()…………p311000H5n3//viodf(charp[],intn
)返回指针的函数函数返回值类型不仅可以是int、double之类的简单类型,也可以将一个地址作为函数的返回值char*f(char*p,inti){char*ch=&p[i] returnch;}intmain(){chars[]=“abc”; cout<<*f(s,1); return0;}a:1000Hf()……………p‘b’‘a’tmp:1001H‘c’i3‘\0’1000Hch1001H返回指针的函数不要返回局部变量的地址char*f(){chars='a'; return&s;}intmain(){ char*p;
p=f(); *p='b'; return0;}pf()……………s:tmp:1000H'a'1000H1000H指向函数的指针什么是指向函数的指针函数是一段指令,和数据一样要放入内存才能执行,因此函数在内存里面也要占用一段区域,我们一般关心该段区域的首地址,主函数在调用子函数时,就是让程序转移到函数的首地址开始执行。前面我们利用函数名来指示这一首地址,当然也可以利用指针来指向这一首地址,这个指针就是指向函数的指针。指向函数的指针指向函数的指针变量的说明格式为:<函数返回值类型>(*<指针变量名>)(<参数>);int(*fp)(int,int)声明了一个指针变量,它可以存储一个函数的首地址,这个函数必须有两个int型参数,返回值的类型也必须是int。intf1(inta,intb){…} fp=f1;intf2(intn){…} fp=f2; int(*fp2)(int)=f2;//errorintmax(inta,intb){return(a>b)?a:b;}intadd(inta,intb){returna+b;}intf(inta){returna+1;}voidf2(inta,inta){cout<<a*b;}intmain(){int(*p)(inta,intb);p=max;ints=p(3,5);//ints=max(3,5)p=add;intss=p(3,5);p=f;p=f2;return0;}//error//error指向函数的指针区别声明格式中有无()的不同int*func();函数原型,表示函数的返回值是整型指针int(*func)();表示是指向函数的指针指向函数的指针指向函数的指针的作用可以将指向函数的指针用在函数的参数中,这样可以实现对不同函数进行相同的处理。问题: 编写程序计算函数的定积分,积分区间[a,b],把积分区间分成n等分。a、b、n由用户输入。 被积函数为: f(x)=x2+1;
f(x)=x2+2x+1;f(x)ax1x2b(f(a)+f(x1))*h/2;(f(x1)+f(x2))*h/2
;(f(x2)+f(b))*h/2
;(f(a)/2+f(x1)+f(x2)+f(b)/2)*h
;doubleh=(b-a)/3;sum=(f(a)+f(b))/2;sum=sum+f(x1)+f(x2);sum=sum*hsum=sum+f(x1)+f(x2)+…+f(xn-1);doubleh=(b-a)/n;sum=(f(a)+f(b))/2;for(inti=1;i<=n-1;++i){ sum=sum+f(a+i*h);}sum=sum*hdoublef1(doublex){ returnx*x+1;}doublem1(doublea,doubleb,intn){ doubleh=(b-a)/n; double
sum=(f1(a)+f1(b))/2; for(inti=1;i<n;i=i+1) {sum=sum+f1(a+i*h);} sum=sum*h; returnsum;}intmain(){cout<<m1(-1,1,200);return0;}doublef2(doublex){returnx*x+2*x+1;}doublem(doublea,doubleb,intn,
double(*pf)(double)){ doubleh=(b-a)/n; double
sum=(pf(a)+pf(b))/2; for(inti=1;i<n;i=i+1) { sum=sum+pf(a+i*h); } sum=sum*h; returnsum;}doublef1(doublex){returnx*x+1;}doublef2(doublex){returnx*x+2*x+1;}intmain(){ doublea,b,n;
cin>>a>>b>>n; cout<<m(a,b,n,f1);
cout<<m(a,b,n,f2);
return0;}6.6void和const类型的指针void和const类型的指针voidvoid放在函数前面表示该函数没有返回值void放在函数的形参表里表示该函数不需要参数void放在指针前面表示通用型指针,该指针可以指向任何类型的变量;但是在访问指针指向的内存内容或对指针进行运算之前必须进行强制类型转换。void和const类型的指针voidfloatx=7.5f,y; int*p=&x; void*p1; p1=&x; y=*p1; y=*((float*)ptr);
inta=*((int*)ptr);//编译错误//编译错误//a的值为1089470464const修饰符的用法格式1:修饰普通常量const类型常量名=值;constdoublePI=3.1415;格式2:修饰引用const类型&引用名=变量名;说明:不能通过常引用修改所引用的对象。inti=0; constint&refi=i; i++;//
OK refi++;//Error!const修饰符的用法格式3:
修饰指针变量,放在类型前面const类型*指针变量;inta=6,b=7;constint*p=&a //表示不能通过p改变p指向的内存的内容*p=19a=19; p=&b;
//错误//正确//正确const修饰符的用法格式4:
修饰指针变量,放在指针变量前面类型*const指针变量;inta=6,b=7;int*constp=&a //表明指针变量p是一常变量*p=19a=19; p=&b;
//正确//正确//错误const修饰符的用法const修饰函数中的参数 voidfun(constint&x);表示形参x的值在fun函数中不能被修改voidfun(constint*x);表示不能通过形参x改变x指向的内容。const修饰符的用法voidfun(int&x){ ++x;}intmain(){ ints=100; fun(s); cout<<s; return0;}voidfun(constint&x)//错误const修饰符的用法voidfun(int*x){ ++x; *x=4;}intmain(){ inta[3]={1,3,5}; fun(a
); return0;}voidfun(constint*x)//错误const修饰符的用法当引用作为函数的形参时,如果在函数体里面没有修改形参,最好在形参前面加const修饰。当指针作为函数的形参时,如果在函数体里面没有修改指针指向的内容,最好在形参前面加const修饰。voidprint(int*a,intn){ for(inti=0;i<n;++i) {cout<<a[i];}}constintgrade=4;intgrade=3;intmain(){ inta=grade+grade; return0;}命名空间inta=AAA::grade+BBB::grade;namespaceAAA{intgrade=4;}namespaceBBB{intgrade=3;}解决同名标识符冲突的问题,不同名字空间的同名标识符是不会冲突的。例:namespaceMyName { inti=5; intj=10;}命名空间用途:函数库、类库的编写。比如要编写一图形处理的函数库,为了实现该库,肯定要定义一系列标志符。当使用该库的用户定义了和库中同名的标志符时,可能会引起名字冲突。为了避免名字冲突,可以把该库中的标识符定义在一个命名空间中。命名空间命名空间定义命名空间时,语法如下:namespace命名空间名 {
定义成员 }其中成员的类型包括:常量、变量、函数、结构体、类、模板等,还可以是名字空间
命名空间定义命名空间举例:namespacens{constintRATE=0.08;doublemoney;doubletax(){returnmoney*RATE;}namespacens2{intcount;}}ns::RATEns::moneyns::tax()ns::ns2::count
命名空间使用using命名空间的成员名如:usingns::tax;后面访问tax()时就相当于ns::tax()使用usingnamespace名字空间名如:usingnamespacens;这样在usingnamespace声明的作用域中,名字空间ns中的成员就好像在全局域声明一样,可以直接使用而不必加名字空间名限定命名空间标准C++在名字空间std里定义了标准库的标识符。#include<iostream>usingnamespacestd;intcerr;intmain(){cerr=7;cout<<"asdf";return0;}usingstd::cout;::cerr=7;实验编写一个函数,其原型为: voidindex(int*a,intn,int&sub) 功能是,在大小为n的数组a中,查找某个数sub,若找到,将对应数组元素的下标赋给sub,若没找到,将-1赋给sub,在主调函数中通过判断sub的值来判断数组中是否有该数。voidindex(int*a,intn,int&sub){ for(inti=0;i<n;++i) { if(a[i]==sub) { sub=i; retrun; } } sub=-1;}intmain(){intarray[3]={8,7,5};cout<<"inputnumber";intv;cin>>v;
cout<<v;retrun0;}inti;for(i=0;i<n;++i)index(int*array,int3,int&v);index(array[],3,v);index(array,3,v);voidindex(constint*a,intn,int&sub)voidindex(constint*a,intn,intsub){ for(inti=0;i<n;++i) { if(a[i]==sub) { sub=i; retrun; } } sub=-1;}voidindex(constint*a,intn,intsub){for(inti=0;i<n;++i)if(a[i]==sub){sub=i;retrun;}sub=-1;}缩进对齐
{
… {
… }
… }voidindex(constint*a,intn,intsub){ for(inti=0;i<n;++i) { if(a[i]==sub) { sub=i; retrun; } } sub=-1;}//if(a[i]=sub)inta;cin>>a;if(a==1){ //…}if(1==a)#include<iostream>usingnamespacestd;voidGetMemory(char*p){ p=newchar[5];}intmain(void){ char*str=0; GetMemory(str); strcpy(str,"helloworld"); cout<<str; return0;}strgetMemory()…………p000X1000#include<iostream>usingnamespacestd;char*GetMemory(){ charp[5]={'a','b','c','d','\0'}; returnp;}intmain(void){ char*str=0; str=GetMemory(); str[0]='H'; return0;}#include<iostream>usingnamespacestd;intmain(void){ char*str=newchar[100]; strcpy(str,"hello"); delete[]str;
if(str!=0) { strcpy(str,"world"); cout<<str; } return0;}str=0;规则:用new申请内存之后,应该立即检查指针值是否为NULL。避免数组或指针的下标越界。动态内存的申请与释放必须配对,防止内存泄漏。用delete释放了内存之后,立即将指针设置为0,防止产生“野指针”。作业int*ptr;int*func(int*a,intb);int*a[10];int(*a)[10];int**p;int(*func)();void*ptr;constint*ptr=&a;int*constptr=&a;intmain(){ intn; cout<<"Pleaseinputn=?"; cin>>n; if(n<=0){return1;} inta[n]; //…………
return0;}//errorintmain(){ int*p,n; cout<<"Pleaseinputn=?"; cin>>n; if(n<=0){return1;} p=newint[n]; if(p==0)return1;
//…………
delete[]p; return0;}6.6指针的数组指针的数组什么是指针的数组数组元素是指针的数组就称为指针的数组。指针的数组的声明格式类型*数组名[元素数]例:int*ptr[10]; 定义一个数组,该数组有十个元素,每个元素都是一个指针,指针指向整数。区分指针的数组和指向数组的指针int(*ptr)[10];int*ptr[10];指针小结int*ptr;int*func(int*a,intb);int*a[10];int(*func)();void*ptr;constint*ptr=&a;int*constptr=&a;int**p;int(*a)[10];…...…...2000201620242020200420082012“*”和“&”运算符inta;int*ptr=&a;整型变量a10变量ptr2012ptr&a&(*ptr)a*ptr*(&a)指针与一维数组intmain(){ inti,*p,a[7];p=a;for(i=0;i<7;i++) *(p++)=i; //p=a;for(i=0;i<7;i++,p++) cout<<*p; return0;}pp01234560123456apppppp例6.3数组清零编写一函数将float数组清零。算法分析(用指针实现)①令指针指向数组首地址②向当前地址赋0值③指针++④重复②、③直到整个数组处理完毕为止;⑤用循环语句实现,结束条件是循环N次,N是数组的元素个数。例6.3数组清零voidclear_array(float*ptr,intlen){float*qtr=ptr+len;while(ptr<qtr){*ptr=0.0;ptr++;}}指针与二维数组对于二维数组:a是数组名,包含三个元素a[0],a[1],a[2]每个元素a[i]又是一个一维数组,包含4个元素aa+1a+2*(*(a+0)+1)*
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 蒸汽管道运行考试题目与答案
- 高尔夫专员面试常见问题及解答
- 反差情绪心理测试题及答案
- 2026年心理辅导技巧与应用测试
- 2026年国际商法知识体系专项习题
- 2026年天津市可持续发展知识竞赛试卷
- 2026年国防教育理念与实践竞赛题库
- 2026年幼儿音乐记忆力测试卷
- 2026年江苏省九年级化学下册第4单元期末试卷
- 2026年心理素质提升测评题库
- 2026年泌尿外科出科试卷及答案
- AI原生数据平台研究报告(2026年)(2026.6)
- 2026年成都玉林紫荆初一入学数学分班考试真题含答案
- 工程预应力张拉与灌浆质量控制措施
- 一氧化二氮的理化性质与危险特性培训
- 2026年江苏省安全员C2证(土建安全员)考试题库及答案
- DB11-T 1610-2026 民用建筑信息模型深化设计建模细度标准
- 2026年巨量本地推初级题库
- 保安员监控岗工作制度
- (正式版)DB36∕T 1297-2020 《城市消防物联网大数据应用平台物联设施设备接口规范》
- GB/Z 46984.3-2026光伏电池第3部分:双面光伏电池电流-电压特性的测量
评论
0/150
提交评论