精华内容
下载资源
问答
  • java变长参数,是怎样变长的?

    千次阅读 2018-07-29 13:20:41
    java方法支持变长参数。这样能够极大地简化我们的编程。我们看这样一段代码: public class Args { public static void main(String[] args) { String two = stringConcat("A", "B"); ...

    java方法支持变长参数。这样能够极大地简化我们的编程。我们看这样一段代码:

    public class Args {
        public static void main(String[] args) {
            String two = stringConcat("A", "B");
            String three = stringConcat("A", "B", "C");
        }
    
        public static String stringConcat(String... objs) {
             String sum = "";
             for (String s : objs) {
                 sum += s;
             }//for
             return sum;
        }
    }

    在JDK1.8.0_151的环境下,我们利用javac编译上面的源代码,得到Args.class字节码文件。

    利用javap反编译了Args.class字节码文件,截取StringConcat方法的反编译结果。如图:

    为什么会出现,arraylength指令,难道,变长参数和数组有什么关系?大胆假设,小心求证。

    我们借助于IDEA, 反编译Args.class字节码文件,以得到更直观的结果:

     请注意,我用红笔画出的部分。因为它证明了我的猜想,的确,变长参数是通过数组来实现的。

    再用jd-gui来看看反编译结果。

    看到标出重点的部分,jd-gui的反编译结果再次验证了我们的猜想。

    我们改写文章开头的代码,改成如下形式:

    public class Args {
        public static void main(String[] args) {
            String two = stringConcat("A", "B");
            String three = stringConcat("A", "B", "C");
            System.out.println(two);
            System.out.println(three);
        }
    
        public static String stringConcat(String... objs) {
             String[] arr = objs;
             int length = arr.length;
             String sum = "";
             for (int i = 0; i < length; i++) {
                 sum += arr[i];
             }//for
             return sum;
        }
    }

    同样,在JDK1.8.0_151环境下,我们尝试编译并运行这段代码,看它是否可以正常工作。

    如图:

    程序正常通过编译,并成功运行。 我们用【javap -c Args.class】反编译看看StringConcat方法:

    arraylength指令出现了。用IDEA反编译结果如下:

    除了那两行输出,其余是不是和前面的IDEA反编译结果一模一样。这也证明了我们的猜想。

    【结论】:java的变长参数,是java的一颗语法糖,其本质上是用数组形式来实现。

    展开全文
  • C语言的变长参数在平时做开发时很少会在自己设计的接口中用到,但我们最常用的接口printf就是使用的变长参数接口,在感受到printf强大的魅力的同时,是否想挖据一下到底printf是如何实现的呢?这里我们一起来挖掘...
  • 本文就来探究一下,变长参数函数的实现机制是怎样的,以及我们自己如何实现一个变长参数函数。在此之前,我们先来了解一下参数入栈顺序是怎样的。函数参数入栈顺序我们可能知道,参数入栈顺序是从右至左,是不是这样...

    前言

    变长参数,指的是函数参数数量可变,或者说函数接受参数的数量可以不固定。实际上,我们最开始学C语言的时候,就用到了这样的函数:printf,它接受任意数量的参数,向终端格式化输出字符串。本文就来探究一下,变长参数函数的实现机制是怎样的,以及我们自己如何实现一个变长参数函数。在此之前,我们先来了解一下参数入栈顺序是怎样的。

    函数参数入栈顺序

    我们可能知道,参数入栈顺序是从右至左,是不是这样的呢?我们可以通过一个小程序验证一下。小程序做的事情很简单,main函数调用了传入8个参数的test函数,test函数打印每个参数的地址。

    #include

    void test(int a,int b,int c,int d,int e,int f,int g,int h)

    {

    printf("%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n",&a,&b,&c,&d,&e,&f,&g,&h);

    }

    int main(int argc,char *argv[])

    {

    int a = 1;

    int b = 2;

    int c = 3;

    int d = 4;

    int e = 5;

    int f = 6;

    int g = 7;

    int h = 8;

    test(a,b,c,d,e,f,g,h);

    return 0;

    }

    编译成32位程序:

    gcc -m32 -o paraTest paraTest.c

    运行(不同的机器运行结果不同,且每次运行结果也不一定相同):

    0xffdadff0

    0xffdadff4

    0xffdadff8

    0xffdadffc

    0xffdae000

    0xffdae004

    0xffdae008

    0xffdae00c

    观察打印出来的地址,可以发现,从a到h地址值依次增加4。我们知道,栈是从高地址向低地址增长的,从地址值可以推测h是最先入栈,a是最后入栈的。也就是说,参数是从右往左入栈的(注:并非所有语言都是如此)。

    但是如果将函数test参数b改为char 型呢?运行结果如下:

    0xffb29500

    0xffb294ec

    0xffb29508

    0xffb2950c

    0xffb29510

    0xffb29514

    0xffb29518

    0xffb2951c

    观察结果可以发现,b的地址并非是a的地址值加4,也不是在a和c的地址值之间,这是为何?这是编译器出于对空间,压栈速度等因素的考虑,对其进行了优化,但这并不影响变长参数的实现。

    对于上面的情况,如果我们编译成64位程序又是什么样的情况呢?

    gcc -o paraTest paraTest.c

    ./paraTest

    运行结果如下:

    0x7fff4b83cbcc

    0x7fff4b83cbc8

    0x7fff4b83cbc4

    0x7fff4b83cbc0

    0x7fff4b83cbbc

    0x7fff4b83cbb8

    0x7fff4b83cbe0

    0x7fff4b83cbe8

    通过观察可以发现,从参数a到f,其地址似乎是递减的,而从g到h地址又变成递增的了,这是为什么呢?事实上,对于x86-64,当参数个数超过6时,前6个参数可以通过寄存器传递,而第7~n个参数则会通过栈传递,并且数据大小都向8的倍数对齐。也就是说,对于7~n个参数,依然满足从右往左入栈,只是对于前6个参数,它们是通过寄存器来传递的。另外,寄存器的访问速度相对于内存来说要快得多,因此为了提高空间和时间效率,实际中其实不建议参数超过6个。

    对于函数参数入栈顺序我们就了解到这里,但是参数入栈顺序和变长参数又有什么关系呢?

    变长参数实现分析

    通过前面的例子,我们了解到函数参数是从右往左依次入栈的,而且第一个参数位于栈顶。那么,我们就可以通过第一个参数进行地址偏移,来得到第二个,第三个参数的地址,是不是可以实现呢?我们来看一个32位程序的例子。例子同样很简单,我们通过a的地址来获取其他参数的地址:

    #include

    void test( int a, char b, int c, int d, int e)

    {

    printf("%d\n%d\n%d\n%d\n%d\n\n",a,*(&a+1),*(&a+2),*(&a+3),*(&a+4));

    }

    int main(int argc,char *argv[])

    {

    int a = 1;

    char b = 2;

    int c = 3;

    int d = 4;

    int e = 5;

    test(a,b,c,d,e);

    return 0;

    }

    编译为32位程序运行:

    gcc -m32 -o paraTest paraTest.c

    ./paraTest

    1

    2

    3

    4

    5

    通过观察运行结果我们可以发现,即使只有a的地址也可以访问到其他参数。也就是说,即便传入的参数是多个,只要我们知道每个参数的类型,只需通过第一个参数就能够通过地址偏移正确访问到其他参数。同时我们也注意到,即便b是char类型,访问c的值也是偏移4的倍数地址,这是字节对齐的缘故,有兴趣的可以阅读理一理字节对齐的那些事。

    变长参数实现

    经过前面的理解分析,我们知道,正是由于参数从右往左入栈(但是要注意的是,对于x86-64,它的参数不是完全从右往左入栈,且参数可能不在一个连续的区域中,它的变长参数实现也更为复杂,我们这里不展开)可以实现变长参数。当然了,这一切,C已经有现成可用的一些东西来帮我们实现变长参数。

    它主要通过一个类型(va_list)和三个宏(va_start、va_arg、va_end)来实现

    va_list :存储参数的类型信息,32位和64位实现不一样。

    void va_start ( va_list ap, paramN );

    参数:

    ap: 可变参数列表地址

    paramN: 确定的参数

    功能:初始化可变参数列表,会把paraN之后的参数放入ap中

    type va_arg ( va_list ap, type );

    功能:返回下一个参数的值。

    void va_end ( va_list ap );

    功能:完成清理工作。

    可变参数函数实现的步骤如下:1.在函数中创建一个va_list类型变量

    2.使用va_start对其进行初始化

    3.使用va_arg访问参数值

    4.使用va_end完成清理工作

    接下来我们来实现一个变长参数函数来对给定的一组整数进行求和。程序清单如下:

    #include

    /*要使用变长参数的宏,需要包含下面的头文件*/

    #include

    /*

    * getSum:用于计算一组整数的和

    * num:整数的数量

    *

    * */

    int getSum(int num,...)

    {

    va_list ap;//定义参数列表变量

    int sum = 0;

    int loop = 0;

    va_start(ap,num);

    /*遍历参数值*/

    for(;loop < num ; loop++)

    {

    /*取出并加上下一个参数值*/

    sum += va_arg(ap,int);

    }

    va_end(ap);

    return sum;

    }

    int main(int argc,char *argv[])

    {

    int sum = 0;

    sum = getSum(5,1,2,3,4,5);

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

    return 0;

    }

    上面的小程序接受变长参数,第一个参数表明将要计算和的整数个数,后面的参数是要计算的值。

    编译运行可得结果:15。

    但是我们要注意的是,这个小程序不像printf那样,对传入的参数做了校验,因此一但传入的参数num和实际参数不匹配,或者传入类型与要计算的int类型不匹配,将会出现不可预知的错误。我们举一个简单的例子,如果第二个参数传入一个浮点数,程序清单如下:

    #include

    /*要使用变长参数的宏,需要包含下面的头文件*/

    #include

    /*

    * getSum:用于计算一组整数的和

    * num:整数的数量

    *

    * */

    int getSum(int num,...)

    {

    va_list ap;//定义参数列表变量

    int sum = 0;

    int loop = 0;

    int value = 0;

    va_start(ap,num);

    for(;loop < num ; loop++)

    {

    value = va_arg(ap,int);

    printf("the %d value is %d\n",loop.value);

    sum += value;

    }

    va_end(ap);

    return sum;

    }

    int main(int argc,char *argv[])

    {

    int sum = 0;

    float a = 8.25f;

    printf("a to int=%d\n",*(int*)&a);

    sum = getSum(5,a,2,3,4,5);

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

    return 0;

    }

    编译运行:

    gcc -m32 -o multiPara multiPara.c

    ./multiPara

    a to int=1090781184

    the 0 loop value is 0

    the 1 loop value is 1075871744

    the 2 loop value is 2

    the 3 loop value is 3

    the 4 loop value is 4

    the sum is1075871753

    观察上面的运行结果,发现结果与我们所预期大相径庭,我们可能会有以下几个疑问:1.把a的地址上的值转换为int,为什么会是1090781184?

    2.getSum函数中,为什么第一个值是0?

    3.getSum函数中,为什么第二个值是1075871744?

    4.getSum函数中,为什么没有获取到5?

    5.为什么最后的结果不是我们预期的值?

    我们逐一解答第一个问题,我们不在本文解释,但可以通过对浮点数的一些理解来找到答案。

    对于第二个、第三个问题以及第四个问题,涉及到类型提升。也就是说在C语言中,调用一个不带原型声明的函数时,调用者会对每个参数执行“默认实际参数提升",提升规则如下:

    ——float将提升到double

    ——char、short和相应的signed、unsigned类型将提升到int

    ——如果int不能存储原值,则提升到unsigned int

    那么也就可以理解了,调用者会将提升之后的参数传给被调用者。也就是说a被提升为了8字节的double类型,自然而然,而我们取值是按int4字节取值,第一次取值取的double的前4字节,第二次取的后4字节,而由于总共取数5次,因此最后的5也就不会被取到。

    了解了前面几个问题的答案,那么最后一个问题的答案也就随之而出了。前面取值已经不对了,最后的结果自然不是我们想要的。

    总结

    通过前面的分析和示例,我们来做一些总结变长参数实现的基本原理

    对于x86来说,函数参数入栈顺序为从右往左,因此,在知道第一个参数地址之后,我们能够通过地址偏移获取其他参数,虽然x86-64在实现上略有不同,但`对于开发者使用来说,实现变长参数函数没有32位和64位的区别。

    变长参数实现注意事项

    1.…前的参数可以有1个或多个,但前一个必须是确定类型。

    2.传入参数会可能会出现类型提升。

    3.va_arg的type类型不能是char,short int,float等类型,否则取值不正确,原因为第2点。

    4.va_arg不能往回取参数,但可以使用va_copy拷贝va_list,以备后用。

    5.变长参数类型注意做好检查,例如可以采用printf的占位符方式等等。

    6.即便printf有类型检查,但也要注意参数匹配,例如,将int类型匹配%s打印,将会出现严重问题。

    7.当传入参数个数少于使用的个数时,可能会出现严重问题,当传入参数大于使用的个数时,多出的参数不会被处理使用。

    8.注意字节对齐问题。

    展开全文
  • 变长参数探究

    2018-09-22 15:06:37
    本文就来探究一下,变长参数函数的实现机制是怎样的,以及我们自己如何实现一个变长参数函数。在此之前,我们先来了解一下参数入栈顺序是怎样的。 函数参数入栈顺序 我们可能知道,参数入栈顺序是从右至左,是不.....

     

    前言

    变长参数,指的是函数参数数量可变,或者说函数接受参数的数量可以不固定。实际上,我们最开始学C语言的时候,就用到了这样的函数:printf,它接受任意数量的参数,向终端格式化输出字符串。本文就来探究一下,变长参数函数的实现机制是怎样的,以及我们自己如何实现一个变长参数函数。在此之前,我们先来了解一下参数入栈顺序是怎样的。

    函数参数入栈顺序

    我们可能知道,参数入栈顺序是从右至左,是不是这样的呢?我们可以通过一个小程序验证一下。小程序做的事情很简单,main函数调用了传入8个参数的test函数,test函数打印每个参数的地址。

    #include<stdio.h>
    void test(int a,int b,int c,int d,int e,int f,int g,int h)
    {
        printf("%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n",&a,&b,&c,&d,&e,&f,&g,&h);
    }
    int main(int argc,char *argv[])
    {
        int a = 1;
        int b = 2;
        int c = 3;
        int d = 4;
        int e = 5;
        int f = 6;
        int g = 7;
        int h = 8;
        test(a,b,c,d,e,f,g,h);
        return 0;
    }
    

    编译成32位程序:

    gcc -m32 -o paraTest paraTest.c 
    

    运行(不同的机器运行结果不同,且每次运行结果也不一定相同):

    0xffdadff0
    0xffdadff4
    0xffdadff8
    0xffdadffc
    0xffdae000
    0xffdae004
    0xffdae008
    0xffdae00c
    

    观察打印出来的地址,可以发现,从a到h地址值依次增加4。我们知道,栈是从高地址向低地址增长的,从地址值可以推测h是最先入栈,a是最后入栈的。也就是说,参数是从右往左入栈的(注:并非所有语言都是如此)。

    但是如果将函数test参数b改为char 型呢?运行结果如下:

    0xffb29500
    0xffb294ec  
    0xffb29508
    0xffb2950c
    0xffb29510
    0xffb29514
    0xffb29518
    0xffb2951c
    

    观察结果可以发现,b的地址并非是a的地址值加4,也不是在a和c的地址值之间,这是为何?这是编译器出于对空间,压栈速度等因素的考虑,对其进行了优化,但这并不影响变长参数的实现。

    对于上面的情况,如果我们编译成64位程序又是什么样的情况呢?

    gcc -o paraTest paraTest.c
    ./paraTest
    

    运行结果如下:

    0x7fff4b83cbcc
    0x7fff4b83cbc8
    0x7fff4b83cbc4
    0x7fff4b83cbc0
    0x7fff4b83cbbc
    0x7fff4b83cbb8
    0x7fff4b83cbe0
    0x7fff4b83cbe8
    

    通过观察可以发现,从参数a到f,其地址似乎是递减的,而从g到h地址又变成递增的了,这是为什么呢?事实上,对于x86-64,当参数个数超过6时,前6个参数可以通过寄存器传递,而第7~n个参数则会通过栈传递,并且数据大小都向8的倍数对齐。也就是说,对于7~n个参数,依然满足从右往左入栈,只是对于前6个参数,它们是通过寄存器来传递的。另外,寄存器的访问速度相对于内存来说要快得多,因此为了提高空间和时间效率,实际中其实不建议参数超过6个。

    对于函数参数入栈顺序我们就了解到这里,但是参数入栈顺序和变长参数又有什么关系呢?

    变长参数实现分析

    通过前面的例子,我们了解到函数参数是从右往左依次入栈的,而且第一个参数位于栈顶。那么,我们就可以通过第一个参数进行地址偏移,来得到第二个,第三个参数的地址,是不是可以实现呢?我们来看一个32位程序的例子。例子同样很简单,我们通过a的地址来获取其他参数的地址:

    #include<stdio.h>
    void test( int a, char b,  int c, int d, int e)
    {
        printf("%d\n%d\n%d\n%d\n%d\n\n",a,*(&a+1),*(&a+2),*(&a+3),*(&a+4));
    }
    int main(int argc,char *argv[])
    {
        int a = 1;
        char b = 2;
        int c = 3;
        int d = 4;
        int e = 5;
        test(a,b,c,d,e);
        return 0;
    }
    

    编译为32位程序运行:

    gcc -m32 -o paraTest paraTest.c 
    ./paraTest
    1
    2
    3
    4
    5
    

    通过观察运行结果我们可以发现,即使只有a的地址也可以访问到其他参数。也就是说,即便传入的参数是多个,只要我们知道每个参数的类型,只需通过第一个参数就能够通过地址偏移正确访问到其他参数。同时我们也注意到,即便b是char类型,访问c的值也是偏移4的倍数地址,这是字节对齐的缘故,有兴趣的可以阅读理一理字节对齐的那些事

    变长参数实现

    经过前面的理解分析,我们知道,正是由于参数从右往左入栈(但是要注意的是,对于x86-64,它的参数不是完全从右往左入栈,且参数可能不在一个连续的区域中,它的变长参数实现也更为复杂,我们这里不展开)可以实现变长参数。当然了,这一切,C已经有现成可用的一些东西来帮我们实现变长参数。
    它主要通过一个类型(va_list)和三个宏(va_start、va_arg、va_end)来实现

    va_list :存储参数的类型信息,32位和64位实现不一样。
    void va_start ( va_list ap, paramN );
    参数:
    ap: 可变参数列表地址 
    paramN: 确定的参数
    功能:初始化可变参数列表,会把paraN之后的参数放入ap中
    
    type va_arg ( va_list ap, type );
    功能:返回下一个参数的值。
    
    void va_end ( va_list ap );
    功能:完成清理工作。
    

    可变参数函数实现的步骤如下:

    • 1.在函数中创建一个va_list类型变量

    • 2.使用va_start对其进行初始化

    • 3.使用va_arg访问参数值

    • 4.使用va_end完成清理工作

    接下来我们来实现一个变长参数函数来对给定的一组整数进行求和。程序清单如下:

    #include <stdio.h>
    /*要使用变长参数的宏,需要包含下面的头文件*/
    #include <stdarg.h>
    /*
     * getSum:用于计算一组整数的和
     * num:整数的数量
     *
     * */
    int getSum(int num,...)
    {
        va_list ap;//定义参数列表变量
        int sum = 0;
        int loop = 0;
        va_start(ap,num);
        /*遍历参数值*/
        for(;loop < num ; loop++)
        {
            /*取出并加上下一个参数值*/
            sum += va_arg(ap,int);
        }
        va_end(ap);
        return sum;
    }
    int main(int argc,char *argv[])
    {
        int sum = 0;
        sum = getSum(5,1,2,3,4,5);
        printf("%d\n",sum);
        return 0;
    }
    

    上面的小程序接受变长参数,第一个参数表明将要计算和的整数个数,后面的参数是要计算的值。
    编译运行可得结果:15。

    但是我们要注意的是,这个小程序不像printf那样,对传入的参数做了校验,因此一但传入的参数num和实际参数不匹配,或者传入类型与要计算的int类型不匹配,将会出现不可预知的错误。我们举一个简单的例子,如果第二个参数传入一个浮点数,程序清单如下:

    #include <stdio.h>
    /*要使用变长参数的宏,需要包含下面的头文件*/
    #include <stdarg.h>
    /*
     * getSum:用于计算一组整数的和
     * num:整数的数量
     *
     * */
    int getSum(int num,...)
    {
        va_list ap;//定义参数列表变量
        int sum = 0;
        int loop = 0;
        int value = 0;
        va_start(ap,num);
        for(;loop < num ; loop++)
        {
            value = va_arg(ap,int);
            printf("the %d value is %d\n",loop.value);
            sum += value;
        }
        va_end(ap);
        return sum;
    }
    int main(int argc,char *argv[])
    {
        int sum = 0;
        float a = 8.25f;
        printf("a to int=%d\n",*(int*)&a);
        sum = getSum(5,a,2,3,4,5);
        printf("%d\n",sum);
        return 0;
    }
    

    编译运行:

    gcc -m32 -o multiPara multiPara.c
    ./multiPara
    a to int=1090781184
    the 0 loop value is 0
    the 1 loop value is 1075871744
    the 2 loop value is 2
    the 3 loop value is 3
    the 4 loop value is 4
    the sum is1075871753
    

    观察上面的运行结果,发现结果与我们所预期大相径庭,我们可能会有以下几个疑问:

    • 1.把a的地址上的值转换为int,为什么会是1090781184?

    • 2.getSum函数中,为什么第一个值是0?

    • 3.getSum函数中,为什么第二个值是1075871744?

    • 4.getSum函数中,为什么没有获取到5?

    • 5.为什么最后的结果不是我们预期的值?

    我们逐一解答

    • 第一个问题,我们不在本文解释,但可以通过对浮点数的一些理解来找到答案。

    • 对于第二个、第三个问题以及第四个问题,涉及到类型提升。也就是说在C语言中,调用一个不带原型声明的函数时,调用者会对每个参数执行“默认实际参数提升",提升规则如下:
      ——float将提升到double
      ——char、short和相应的signed、unsigned类型将提升到int
      ——如果int不能存储原值,则提升到unsigned int
      那么也就可以理解了,调用者会将提升之后的参数传给被调用者。也就是说a被提升为了8字节的double类型,自然而然,而我们取值是按int4字节取值,第一次取值取的double的前4字节,第二次取的后4字节,而由于总共取数5次,因此最后的5也就不会被取到。

    • 了解了前面几个问题的答案,那么最后一个问题的答案也就随之而出了。前面取值已经不对了,最后的结果自然不是我们想要的。

    总结

    通过前面的分析和示例,我们来做一些总结

    • 变长参数实现的基本原理
      对于x86来说,函数参数入栈顺序为从右往左,因此,在知道第一个参数地址之后,我们能够通过地址偏移获取其他参数,虽然x86-64在实现上略有不同,但`对于开发者使用来说,实现变长参数函数没有32位和64位的区别。

    • 变长参数实现注意事项
      1.…前的参数可以有1个或多个,但前一个必须是确定类型。
      2.传入参数会可能会出现类型提升。
      3.va_arg的type类型不能是char,short int,float等类型,否则取值不正确,原因为第2点。
      4.va_arg不能往回取参数,但可以使用va_copy拷贝va_list,以备后用。
      5.变长参数类型注意做好检查,例如可以采用printf的占位符方式等等。
      6.即便printf有类型检查,但也要注意参数匹配,例如,将int类型匹配%s打印,将会出现严重问题。
      7.当传入参数个数少于使用的个数时,可能会出现严重问题,当传入参数大于使用的个数时,多出的参数不会被处理使用。
      8.注意字节对齐问题。

     

     

    微信公众号:编程珠玑

    守望的笔记本

    展开全文
  • 罗斯蒙特644温度送器怎样接线,我们要先了解罗斯蒙特644温度送器是一款带液晶显示的双只温度送器,质量在同类当中算是过硬的,罗斯蒙特644温度送器价格也是很优惠的,下面详细给大家介绍下罗斯蒙特644温度...

    罗斯蒙特644温度变送器怎样接线,我们要先了解罗斯蒙特644温度变送器是一款带液晶显示的双只温度变送器,质量在同类当中算是过硬的,罗斯蒙特644温度变送器价格也是很优惠的,下面详细给大家介绍下罗斯蒙特644温度变送器是怎样接线的。
    罗斯蒙特644温度变送器分为单输入644H和双输入644S两种,

    fe4326b1e80dcfaf1b4a8a2f640a5f2e.png


    问题1:下图①位置这四个端子是干什么的?
    问题2:下图②位置这三个端子是干什么的?
    问题3:下图③位置这三个端子是干什么的?
    问题4:下图④位置这个插针是干什么的?
    问题5:下图⑤位置拨盘L和H位置代表什么?
    问题6:上图⑥位置这两个端子是干什么的?

    a52c6de9ce2007f3d0ae009bf15d54cd.png


    结合上图,不难看出644各个位置的作用:
    问题1答案:图中①位置这四个端子是单输入644H温度变送器的输入信号端子;
    问题2和3答案:图中②和③位置这几个端子是双输入644S温度变送器的两路输入信号端子;
    问题4答案:图中④位置插针是连接显示屏用的,在现场中,有的测点中配置了显示屏,有的测点中没有配置显示屏,大家在现场中了可以打开仪表盖看看。
    问题5答案:图中⑤位置H和L是表示故障模式位置,即将物理硬件报警开关设置到所需的位置。H表示高, L表示低。
    问题6答案:644温度变送器的电源端子
    记好这个644温度变送器接线图,温度变送器644接线接线不用愁:

    0c0f38c28ba2ce8f99c624a8153af2f4.png


    另外rosemount温度变送器644接线需要注意一些问题,比如罗斯蒙特温度变送器在热电阻输入接线时,温度变送器变送器可接受多种热电阻组态,包括2线、3线或4线组态。若变送器安装在远离3线或4线热电阻的位置,如果每条引线的电阻最高为60欧姆,那么变送器能够按规范工作,无需重新校准。在此情况中,热电阻和变送器之间的引线应有屏蔽层。若仅使用两条引线,并且两条热电阻引线与传感器元件串联,则当引线长度超过三英尺[20AWG线,注:AWG美国线规,AWG前面的数值(如20AWG、24AWG)表示导线形成最后直径前所要经过的孔的数量,数值越大,导线经过的孔就越多,导线的直径也就越小]时,可能出现明显误差。对于2线和3线热电阻,当环境温度发生变化时,会产生额外的引线电阻误差。微信:270638425

    展开全文
  • 首先列出: 若要使用动态分配的内存来存储数组元素,并且需要一个指针成员变量 重载分配=运算符 重载括号[]运算符 重载的副本构造函数 实现push_back和length函数 - 2 - 实现步骤 要实现可长度数组类,您基本上...
  • 变长参数 函数初探

    2020-08-13 19:20:20
    本文就来探究一下,变长参数函数的实现机制是怎样的,以及我们自己如何实现一个变长参数函数。在此之前,我们先来了解一下参数入栈顺序是怎样的。 函数参数入栈顺序 我们可能知道,参数入栈顺序是从右至左,是不是...
  • 17日,记者从青岛中青机动车检测站获悉,因柴油检测设备升级导致检测时间变长,建议车主合理安排检测时间,不要扎堆审车。根据山东省生态环境厅要求,环检站应在企业官方网站或办事业务大厅显示屏通过高清视频实时...
  • 我想定义一个接口函数,希望用一个可长度的数组返回一段地址空间中的数据,参考了网上的一些资料,定义如下: (网上的例子) HRESULT GetGrades6([out] long* plCount, [out, size_is(,*plCount)] long** ...
  • C变长参数

    2010-11-09 22:35:00
    C语言的变长参数在平时做开发时很少会在自 己设计的接口中用到,但我们最常用的接口printf就是使用的变长参数接口,在感受到printf强大的魅力的同时,是否想挖据一下到底printf是 如何实现的呢?这里我们一起来挖掘...
  • 表示一些常见的数据类型,怎样把这个结构体复制到一个 char buf[5000]中,我用了很多方法都不行 第一.这个结构体不能设置对齐方式,否则实例化会报内存错误 因此不能用memcpy直接拷贝 第二.我一项一项的拷贝...
  • 关于Pytorch中怎么自定义Dataset数据集类、怎样使用DataLoader迭代加载数据,这篇官方文档已经说得很清楚了,这里就不在赘述。 现在的问题:有的时候,特别对于NLP任务来说,输入的数据可能不是定的,比如多个...
  • 也谈C语言变长参数

    2011-01-18 11:08:00
    C语言的变长参数在平时做开发时很少会在自 己设计的接口中用到,但我们最常用的接口printf就是使用的变长参数接口,在感受到printf强大的魅力的同时,是否想挖据一下到底printf是 如何实现的呢?这里我们一起来挖掘...
  • 怎样让生活简单

    2011-07-31 22:02:15
    Make life simple is not simple.  马云曾说:“今天很残酷,明天依然很残酷,而后天会是美好的。”生活在当下意味着面对着很多的压力,随着年龄的...因为外界的影响使得我们得犹豫,怀疑我们的初衷,一个个困扰或
  • 手部按摩 推荐了护手霜也不是让你随便涂一涂哒~搭配一些按摩手法会更好吸收,时间坚持也能帮助手指得更加细长,最重要的是,手部多运动可以有效预防腱鞘炎~ 1、把护手霜或精油涂满手部,手腕处也不要忘了哦;...
  • 那未来5年生活怎样变?具体有这四大变化! 变化一:人工智能或像水和电一样进入你我生活 纲要草案明确,培育壮大人工智能、大数据、区块链等新兴数字产业,同时提出包括智能交通、智慧教育、智慧医疗等10个数字化...
  • 首发:公众号【编程珠玑】 作者:守望先生 ... 前言 变长参数,指的是函数参数数量可变,或者说函数接受参数的数量可以不固定。...本文就来探究一下,变长参数函数的实现机制是怎样的,以及我们...
  • Pytorch DataLoader 变长数据处理方法

    千次阅读 2019-03-28 16:51:34
    关于Pytorch中怎么自定义Dataset数据集类、怎样使用DataLoader迭代加载数据,这篇官方文档已经说得很清楚了,这里就不在赘述。 现在的问题:有的时候,特别对于NLP任务来说,输入的数据可能不是定的,比如多个句子...
  • GNU C定义变长结构体

    2012-06-22 22:16:09
    在进入主题之前,这里有一个问题:在C中可以定义长度为0的数组吗?  答案是:标准的C中是不可以的,GNU C中可以。  比如定义这样一个数组:int data[0... OK,下面看看怎样在GNU环境下使用长度为0的数组魔法般
  • C/C++变长参数

    千次阅读 2012-04-13 10:45:34
    那么它们是怎样实现的呢?C编译器通常提供了一系列处理这种情况的宏,以屏蔽不同的硬件平台造成的差异,增加程序的可移植性。这些宏包括va_start、va_arg 和va_end等。 ---- 采用ANSI标准形式时,参数个数可...
  • 都知道ArrayList是基于数组的,那它是怎么实现可的呢? 创建ArrayList对象时,ArrayList有个带参数的构造函数,那个参数的意思就代表着ArrayList长度,默认情况是10。当数据多了,ArrayList容不下时,这时...
  • 关于C的变长参数

    2009-12-23 10:57:00
    那么它们是怎样实现的呢?C编译器通常提供了一系列处理这种情况的宏,以屏蔽不同的硬件平台造成的差异,增加程序的可移植性。这些宏包括va_start、 va_arg和va_end等。 采用ANSI标准形式时,参数个数可的函数的...
  • PPT的使用相信大家都不陌生,使用最多的就是制作PPT对工作进行汇报,对新项目进行展开讨论... 上述六个步骤为大家讲述了怎样将照片裸眼3D效果,想要尝试操作的朋友可以根据上述方法进行操作,希望能给大家带来帮助。
  • 来源:公众号【编程珠玑】作者:守望先生ID:shouwangxiansheng前言变长参数,...本文就来探究一下,变长参数函数的实现机制是怎样的,以及我们自己如何实现一个变长参数函数。在此之前,我们先来了解一下参数入栈顺...
  • 那么怎么才能将习惯的容易养成呢?答案就是把大习惯分解成微任务:一个不可能失败的小行动! 总结:坚持的奥秘是习惯;习惯的奥秘是微任务。微任务的奥妙是可以让你不抵触地开始行动。 现实生活中怎么...
  • C语言的变长参数在平时做开发时很少会在自己设计的接口中用到,但我们最常用的接口printf就是使用的变长参数接口,在感受到printf强大的魅力的同时,是否想挖据一下到底printf是如何实现的呢?这里我们一起来挖掘...
  • 用xencenter根据一个模板创建虚拟机,是用差分方式产生的vhd文件,vhd文件为动态增长,结果vhd文件一直大,想知道怎样处理vhd文件碎片,可以让vhd文件小。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 696
精华内容 278
关键字:

怎样变长