精华内容
下载资源
问答
  • 自己写了一个Swap测试类,代码如下: ``` public class Swap5 ... public static void main(String[] args) ...用字面值方式给字符串赋值是生成在String Pool(字符串池)...应该是生成在堆中,为什么交换不了呢?
  • 开始学编程语言,从c语言学起,记得刚学指针的时候,很是头痛,其中印象最深的一点就是指针传递和值传递的区别:最典型的例子就是swap()函数(具体函数就不写了),当时就在想为什么swap(int i,int j)不能交换两个...

    一年以前,开始学编程语言,从c语言学起,记得刚学指针的时候,很是头痛,其中印象最深的一点就是指针传递和值传递的区别:最典型的例子就是swap()函数(具体函数就不写了),当时就在想为什么swap(int i,int j)不能交换两个整数,而要用swap(int * p,int* q),当时觉得难以理解,后来多看了一些书过后就渐渐明白传地址和传值的区别了,就这个例子而言,比如定义了两个变量 m和n,如果是传值的话,那么函数执行过程是当调用swap,说直白点,就是将m和n发送给i和j,在swap函数内部,通过 t=m;m=n;n=t交换了两者的位置,但是其实不然,在调用完swap的时候m,n两者还是没有交换,原因在于以前存放m的那块内存还是存放的m的值,存放n的那块内存还是存放的n,它们的物理位置还是没有改变,如果是用swap(int * p,int* q)的话那么,将m和n的地址传进去,在调用完函数过后,m以前的地址(叫做p吧)就和n原来的地址(就叫q吧)交换了位置(即交换了数值),这时候p的值就是q以前的值,那么根据这个值就能找到n(即n的地址),同理,q的值就是p以前的值,也可以根据这个值找到m(即m的地址)。今天我在写一个单链表的时候遇到了一个问题,初始化一个链表,检测出来初始化的链表老是不为空(正确的话应该为空),贴上错误代码(检测是否为空就不贴出来了):

    typedef struct node

    {
      int pData;
    struct node* pNext;
    }NODE,*PNODE;

    void init(PNODE pHead;

    int main(){

    NODE Node;
    init(&Node);

    }

    void init(PNODE pHead){

    pHead = (PNODE)malloc(sizeof(node));//这里为了方便就没去检测是否动态内存分配成功与否了
    pHead->pNext = NULL;

    }

    这段代码在执行init(&Node)后,pHead->pNext != NULL。当时我怎么都想不通,因为一看是传的指针啊,我可能一直都把传指针想得太简单了,以为扔个“&”进去就是传指针。后来突然想明白了,为了方便表达,我把pHead->pNext称作为pHead的一个属性吧(这样说不专业但是我觉得更好理解),我们在函数里面想改变的是pHead的属性,而传进去的是pHead,这样肯定不行,通过前面叙述,要想改变变量的属性必须传它的地址,类比过来那么该传的是pHead的地址,这样才能改变pHead的属性。想明白了就好解决了,这里要把pHead的地址传进去,贴上正确代码:

    typedef struct  node
    {
    int pData;
    struct node* pNext;
    }NODE,*PNODE;

    void init(PNODE* PHead);

    int main(){
    PNODE p;
    init(&p);
    }

    void init(PNODE* PHead){
    *PHead = (PNODE)malloc(sizeof(node));
    (*PHead)->pNext = NULL;
    }

    这个涉及到二维指针,其实把它简单成pHead的地址就行了,把pHead就只当成一个变量那么它的地址PHead不就可以看成一维了吗。这里通过(*PHead)->pNext 改变了pHead的属性(pNext),所以初始化成功了!

    ps:这是我写的第一篇博客,我也只是一只菜鸟,想用这种方式记录自己的成长历程,如果有朋友看到了有叙述不恰当的地方,还请多多指出,不要见笑。




    展开全文
  • 问题 1、Java到底是按值传递(Call ...2、如下面的代码,为什么不能进行交换? public CallBy swap2(CallBy a,CallBy b) { CallBy t = a; a = b; b = t; return b; } 3、如下面的代码,为什么能够交换成功? pub...

    问题

    1、Java到底是按值传递(Call by Value),还是按引用传递(Call by Reference)?
    2、如下面的代码,为什么不能进行交换?

    public CallBy swap2(CallBy a,CallBy b) {
        CallBy t = a;
        a = b;
        b = t;
        return b;
    }

    3、如下面的代码,为什么能够交换成功?

    public int swap2(CallBy a,CallBy b) {
        int t = a.value;
        a.value = b.value;
        b.value  = t;
        return t;
    }

    简单的C++例子

    为了解决上面的三个问题,我们从简单的例子开始,为什么是C++的例子呢?看完了你就会明白。

    假设我们要交换两个整形变量的值,在C++中怎么做呢?

    我们来看多种方式,哪种能够做到.

    #include <iostream>
    
    using namespace std;
    
    // 可以交换的例子
    void call_by_ref(int &p,int &q) {
        int t = p;
        p = q;
        q = t;
    }
    
    // 不能交换的例子
    void call_by_val_ptr(int * p,int * q) {
        int * t = p;
        p = q;
        q = t;
    }
    
    // 不能交换的例子
    void call_by_val(int p,int q){
        int t = p ;
        p = q;
        q = t;
    }
    
    int main() {
        int a = 3;
        int b = 4;
    
        cout << "---------- input ------------" << endl;
        cout << "a = " << a << ", b = " << b << endl << endl;
        
        call_by_val(a,b);
        cout << "---------- call_by_val ------------" << endl;
        cout << "a = " << a << ", b = " << b << endl << endl;
    
        call_by_val_ptr(&a,&b);
        cout << "---------- call_by_val_ptr ------------" << endl;
        cout << "a = " << a << ", b = " << b << endl << endl;
    
        call_by_ref(a,b);
        cout << "---------- call_by_ref ------------" << endl;
        cout << "a = " << a << ", b = " << b << endl;
    }

    因为例子非常简单,看代码即可知道只有call_by_ref这个方法可以成功交换。这里,你一定还知道一种可以交换的方式,别着急,慢慢来,我们先看看为什么只有call_by_ref可以交换。

    1、call_by_ref

    这里写图片描述

    void call_by_ref(int &p,int &q) {
        push   %rbp
        mov    %rsp,%rbp
        mov    %rdi,-0x18(%rbp)
        mov    %rsi,-0x20(%rbp)
        
        //int t = p;
        mov    -0x18(%rbp),%rax
        //关键点:rax中存放的是变量的实际地址,将地址处存放的值取出放到eax中
        mov    (%rax),%eax
        mov    %eax,-0x4(%rbp)
        
        //p = q;
        mov    -0x20(%rbp),%rax
        //关键点:rax中存放的是变量的实际地址,将地址处存放的值取出放到edx
        mov    (%rax),%edx
        mov    -0x18(%rbp),%rax
        mov    %edx,(%rax)
        
        //q = t;
        mov    -0x20(%rbp),%rax
        mov    -0x4(%rbp),%edx
        //关键点:rax存放的也是实际地址,同上.
        mov    %edx,(%rax)
    }

    上面这段汇编的逻辑非常简单,我们看到里面的关键点都在强调:

    将值存放在实际地址中.

    上面这句话虽然简单,但很重要,可以拆为两点:

    1、要有实际地址.
    2、要有将值存入实际地址的动作.

    从上面的代码中,我们看到已经有“存值”这个动作,那么传入的是否实际地址呢?

    // c代码
    call_by_val_ptr(&a,&b);
    
    // 对应的汇编代码
    
    lea    -0x18(%rbp),%rdx
    lea    -0x14(%rbp),%rax
    mov    %rdx,%rsi
    mov    %rax,%rdi
    callq  4008c0 <_Z11call_by_refRiS_>
    

    注意到,lea操作是取地址,那么就能确定这种“按引用传递“的方式,实际是传入了实参的实际地址。

    那么,满足了上文的两个条件,就能交换成功。

    2、call_by_val

    这里写图片描述

    call_by_val的反汇编代码如下:

    void call_by_val(int p,int q){
        push   %rbp
        mov    %rsp,%rbp
        mov    %edi,-0x14(%rbp)
        mov    %esi,-0x18(%rbp)
        
        //int t = p ;
        mov    -0x14(%rbp),%eax
        mov    %eax,-0x4(%rbp)
        
        //p = q;
        mov    -0x18(%rbp),%eax
        mov    %eax,-0x14(%rbp)
        
        //q = t;
        mov    -0x4(%rbp),%eax
        mov    %eax,-0x18(%rbp)
    }

    可以看到,上面的代码中在赋值时,仅仅是将某种”值“放入了寄存器,再观察下传参的代码:

    // c++代码
    call_by_val(a,b);
    
    // 对应的汇编代码
    mov    -0x18(%rbp),%edx
    mov    -0x14(%rbp),%eax
    mov    %edx,%esi
    mov    %eax,%edi
    callq  400912 <_Z11call_by_valii>

    可以看出,仅仅是将变量a、b的值存入了寄存器,而非”地址“或者能找到其”地址“的东西。

    那么,因为不满足上文的两个条件,所以不能交换。

    这里还有一点有趣的东西,也就是我们常听说的拷贝(Copy)

    当一个值,被放入寄存器或者堆栈中,其拥有了新的地址,那么这个值就和其原来的实际地址没有关系了,这种行为,是不是很像一种拷贝?

    但实际上,在我看来,这是一个很误导的术语,因为上面的按引用传递的call_by_ref实际上也是拷贝一种值,它是个地址,而且是实际地址。

    所以,应该记住的是那两个条件,在你还不能真正理解拷贝的意义之前最好不要用这个术语。

    2、call_by_val_ptr

    这里写图片描述

    这种方式,本来是可以完成交换的,因为我们可以用指针来指向实际地址,这样我们就满足了条件1:

    要有实际地址。

    别着急,我们先看下上文的实现中,为什么没有完成交换:

    void call_by_val_ptr(int * p,int * q) {
        push   %rbp
        mov    %rsp,%rbp
        mov    %rdi,-0x18(%rbp)
        mov    %rsi,-0x20(%rbp)
        //int * t = p;
        mov    -0x18(%rbp),%rax
        mov    %rax,-0x8(%rbp)
        //p = q;
        mov    -0x20(%rbp),%rax
        mov    %rax,-0x18(%rbp)
        //q = t;
        mov    -0x8(%rbp),%rax
        mov    %rax,-0x20(%rbp)
    }

    可以看到,上面的逻辑和call_by_val非常类似,也只是做了将值放到寄存器这件事,那么再看下传给它的参数:

    // c++代码
    call_by_val_ptr(&a,&b);
    
    // 对应的汇编代码
    lea    -0x18(%rbp),%rdx
    lea    -0x14(%rbp),%rax
    mov    %rdx,%rsi
    mov    %rax,%rdi
    callq  4008ec <_Z15call_by_val_ptrPiS_>

    注意到,lea是取地址,所以这里实际也是将地址传进去了,但为什么没有完成交换?

    因为不满足条件2:

    将值存入实际地址。

    call_by_val_ptr中的交换,从汇编代码就能看出,只是交换了指针指向的地址,而没有通过将值存入这个地址而改变地址中的值

    Java

    通过上面的例子,我们掌握了要完成交换的两个条件,也了解了什么是传引用,什么是传值,从实际效果来讲:

    如果传入的值,是实参的实际地址,那么就可以认为是按引用传递。否则,就是按值传递。而实际上,传值和传引用在汇编层面或者机器码层面没有语义,因为都是将某个”值“丢给了寄存器或者堆栈。

    所以,类似Java是按值传递还是按引用传递这种问题,通常没有任何意义,因为要看站在哪个抽象层次上看。

    如果非要定义一下,好吧,也许你会在面试中碰到这种问题,那么最好这样回答:

    Java是按值传递的,但可以达到按引用传递的效果。

    那么,什么是有意义的呢?
    上文的那两个条件。

    但从编译的角度讲,引用和地址有很强的关系,却不是一回事。

    Java按值传递的行为

    我们回顾下开头的三个问题中的第二个问题:

    如下面的代码,为什么不能进行交换?

    public CallBy swap2(CallBy a,CallBy b) {
        CallBy t = a;
        a = b;
        b = t;
        return b;
    }

    我们首先从比较简单的bytecode看起:

    public com.haoran.CallBy swap2(com.haoran.CallBy, com.haoran.CallBy);
        descriptor: (Lcom/haoran/CallBy;Lcom/haoran/CallBy;)Lcom/haoran/CallBy;
        flags: ACC_PUBLIC
        Code:
          stack=1, locals=4, args_size=3
             0: aload_1
             1: astore_3
             2: aload_2
             3: astore_1
             4: aload_3
             5: astore_2
             6: aload_2
             7: areturn
          LineNumberTable:
            line 45: 0
            line 46: 2
            line 47: 4
            line 48: 6
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0       8     0  this   Lcom/haoran/CallBy;
                0       8     1     a   Lcom/haoran/CallBy;
                0       8     2     b   Lcom/haoran/CallBy;
                2       6     3     t   Lcom/haoran/CallBy;

    集中精力看这一块:

    //t = a
    0: aload_1
    1: astore_3
    
    //a = b
    2: aload_2
    3: astore_1
    
    //b = t
    4: aload_3
    5: astore_2
    
    6: aload_2

    代码很简单,注释也表明了在做什么, 那么需要不需要看传递给它什么参数呢?

    不需要,先看下汇编代码,满足不满足”将值放到实际地址“这个条件,我们截取a = b这一句来观察:

    // a = b bytecode
    2: aload_2
    3: astore_1
    /***************************************
    * aload_2对应的汇编(未优化)
    ****************************************/
    mov    -0x10(%r14),%rax\n
    
    //----------------------------------------
    
    movzbl 0x1(%r13),%ebx
    inc    %r13
    movabs $0x7ffff71ad900,%r10
    jmpq   *(%r10,%rbx,8)
    /***************************************
    * astore_1对应的汇编(未优化)
    ****************************************/
    pop    %rax
    mov    %rax,-0x8(%r14)
    
    //----------------------------------------
    
    movzbl 0x1(%r13),%ebx
    inc    %r13
    movabs $0x7ffff71ae100,%r10
    jmpq   *(%r10,%rbx,8)

    如果将上面的代码和c++实例中的call_by_ref和call_by_val对比,就会发现,上面的代码缺失了这样一种语义:

    将值放入实际地址中。

    其仅仅是将值放入寄存器或者堆栈上,并没有将值放入实际地址这个操作。

    为什么不需要观察给这个方法传参的过程?
    这是一个很简单的必要条件问题,所以,不需要观察。

    从上面的过程来看,Java的行为是Call by Value的。

    Java按引用传递的行为

    这里写图片描述

    现在来讨论第三个问题:

    如下面的代码,为什么能够交换成功?

    public int swap2(CallBy a,CallBy b) {
        int t = a.value;
        a.value = b.value;
        b.value  = t;
        return t;
    }

    还是从bytecode先看起:

    public com.haoran.CallBy swap2(com.haoran.CallBy, com.haoran.CallBy);
        descriptor: (Lcom/haoran/CallBy;Lcom/haoran/CallBy;)Lcom/haoran/CallBy;
        flags: ACC_PUBLIC
        Code:
          stack=2, locals=4, args_size=3
             0: aload_1
             1: getfield      #2                  // Field value:I
             4: istore_3
             5: aload_1
             6: aload_2
             7: getfield      #2                  // Field value:I
            10: putfield      #2                  // Field value:I
            13: aload_2
            14: iload_3
            15: putfield      #2                  // Field value:I
            18: aload_1
            19: areturn
          LineNumberTable:
            line 41: 0
            line 42: 5
            line 43: 13
            line 44: 18
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0      20     0  this   Lcom/haoran/CallBy;
                0      20     1     a   Lcom/haoran/CallBy;
                0      20     2     b   Lcom/haoran/CallBy;
                5      15     3     t   I

    聚焦putfield这句字节码,其对应的是在b.value的值放到操作数栈顶后,拿下这个值, 给a.value:

    a.value = b.value;

    因为putfield字节码对应的汇编代码非常长,我们进一步聚焦其宏汇编,因为CallBy类的value字段,是个int型,所以我们关注itos:

    // itos
    {
        __ pop(itos);
        if (!is_static) pop_and_check_object(obj);
        // 关键点:只看这里
        __ movl(field, rax);
        if (!is_static) {
          patch_bytecode(Bytecodes::_fast_iputfield, bc, rbx, true, byte_no);
        }
        __ jmp(Done);
    }

    其中关键的一句:__ movl(field, rax);

    void Assembler::movl(Address dst, Register src) {
      InstructionMark im(this);
      prefix(dst, src);
      emit_int8((unsigned char)0x89);
      emit_operand(src, dst);
    }

    movl对应的汇编代码:

    // 对应的关键汇编代码
    ...
    mov    %eax,(%rcx,%rbx,1)
    ...

    上面的汇编代码的意思是:

    将eax中的值存入rcx + rbx*1所指向的地址处。

    其中,eax的值就是b.value的值,而rcx+rbx*1所指向的地址就是a.value的地址。

    上面的过程满足了这样的语义:

    将值存入实际地址中.

    所以,a.value和b.value可以交换,类似这样,Java的按值传递方式也可以表现出按引用传递的行为

    另一种交换值的方式

    还记得在C++的实例中,我们提到还有一种交换值的方式,是什么呢?

    call_by_WHAT

    void call_by_WHAT(int * p,int * q) {
        int t = *p;
        *p = *q;
        *q = t;
    }

    这样传参:

    int main() {
        int a = 3;
        int b = 4;
    
        cout << "---------- input ------------" << endl;
        cout << "a = " << a << ", b = " << b << endl << endl;
    
        call_by_WHAT(&a,&b);
        cout << "---------- call_by_WHAT ------------" << endl;
        cout << "a = " << a << ", b = " << b << endl;
    }

    会不会交换呢?

    // 输出
    
    ---------- input ------------
    a = 3, b = 4
    
    ---------- call_by_WHAT ------------
    a = 4, b = 3
    

    从这种方式中,我们也看到了所有能够交换值的方式的统一性:

    1、指针p、q或者对象引用objectRef,能够直接指向对象的实际地址。
    2、要有一个将值放入实际地址的操作:

    // C/C++
    *p = *q;
    ...
    
    // Java
    putField -> a.value = b.value
    ...
    
    // 汇编
    mov reg_src , (reg_dst)
    mov reg_src , (addr_dst)
    ...

    结语

    这里写图片描述

    老生常谈,并无LUAN用,终。

    转载于:https://www.cnblogs.com/foreach-break/p/call-by-reference-OR-call-by-value.html

    展开全文
  • 为什么 Uploader.Register方法报错,undifind,不能识别。。。求救,webuploader如何传递文件的MD5。。。。如果有JAVA大文件分片上传的DEMO,感激不尽,可以金钱交换。。有意联系,QQ510080612
  • 参数传递的是一个指向结构体指针的引用,有一个人问过老师,他说要改变必须要用引用,我感觉他这里根本就没跟我们讲清楚,为什么要用指针的引用呢? 后来我问了别人,自己想了一下,在C语言中,可能接触过这样一...

    记得以前我们刚上数据结构,创建二叉树的时候,void CreateBiTree(BiTree &T);参数传递的是一个指向结构体指针的引用,有一个人问过老师,他说要改变值必须要用引用,我感觉他这里根本就没跟我们讲清楚,为什么要用指针的引用呢?

    后来我问了别人,自己想了一下,在C语言中,可能接触过这样一个例子,通过函数交换两个变量的值,然后打印出来,我们知道这个通过指针是可以做到的,当然引用也是可以的。指针能够改变原来两个变量的值,为什么到这里就不行了呢void  CreateBiTree(BiTree T),同样我这里也是传递的是一个指针,而不能改变其值。

    void CreateBiTree(BiTree T);刚开始创建的时候,实参传进来的指针是为空的,然后形参接受到实参传进来的空指针,然后为形参分配内存空间,函数执行完毕,释放为函数分配的内存空间,形参也随之回收,这时候实参仍为空。所以在这里要改变指针的值才行,而要改变指针的值必须要用指针的指针或指针的引用两种方法都可以。

    而void DeleteChild(BiTree T,BiTree p,int LR);这里用指针就够了,BiTree T这里传给形参本来就是有值的,不为空,当实参传给形参时,对形参改变也会影响到本体。仅个人看法,如果有不正确的地方请指出,相互学习,谢谢!

    展开全文
  • 我在阅读《java核心技术 卷1》第四章时对对象的方法参数传递有疑问,为什么可以通过运行下面函数改变harry的属性 但是不能使用swap函数交换两个对象, 。 https://www.jb51.net/article/80188.htm 这篇...

    我在阅读《java核心技术 卷1》第四章时对对象的方法参数传递有疑问,为什么可以通过运行下面函数改变harry的属性值

    但是不能使用swap函数交换两个对象,

    https://www.jb51.net/article/80188.htm

    这篇文章解答了我的疑问。

    harry储存的是这个对象所在的地址,直接输出harry会得到cn.hello.output.Empolyee@65ab7765这样的结果。运行tripleSalary时,函数先将harry的地址复制到x上,然后x.raiseSalary再对x的地址指向的对象进行操作,所以函数运行结束后可以改变对象;但是如果运行swap(a,b),首先将a,b的地址复制给x,y,再对x,y做交换,函数结束回收x,y变量,a,b也不会有变化。C++的引用则不同,不会复制实参的地址而是直接指向它。

    展开全文
  • 先上正确的代码(交换函数里用到了很多的打印语句,主要是要对比错误的代码,以观察地址和的变化),正确代码能实现两个参数的交换,错误的代码则不能实现。现在有2个疑问: 1为什么传递的地址发生了变化?比如...
  • 为什么计算机会出现乱码—二进制 与其用特殊方式来表示字母,计算机可以用数字表示字母,最直接的方法是给字母编号:A是1,B是2,C是3,以此类。著名英国作家 弗朗西斯·培根(Francis Bacon),曾用 5位序列来编码...
  • 15.为什么说数字交换单元(D3)既进行时间交换,又进行空间交换? IS由16个交换端口构成,每个交換端口接一条双向PC链路,端口之间的交换就是 PC链路之间的交换,即空间交换。每个口上PM链路上的时隙交接就是时间交换。...
  • int & 到底是什么

    2019-08-11 16:43:27
    这里引用“落辰衰”大佬的解释: 1、int; ...如果其用于函数参数时,其传递方向为值传递,即只能将实参的值传递给形参,而不能将 形参的值传递给实参。 例如:通过这种方式去进行交换两个数...
  • 如久拔号、久应答、位间拔号的延时,缺省值为10秒,可选择的时间有10秒、30秒、1分钟。按一次该键则显示下一个时间,三个循环显示,当按下“确认”键时,就选定当前显示供系统使用,按“复位”键则...
  • 传值与传引用的 区别

    2015-08-02 14:22:00
    问题 1、Java到底是按值传递(Call by Value),还是...2、如下面的代码,为什么不能进行交换? public CallBy swap2(CallBy a,CallBy b) { CallBy t = a; a = b; b = t; return b; } 3、如下面的代码,为什么能够交
  • 1.19 为什么不能像下面这样在初始式和数组维度中使用const?constintn=5;inta[n];  1.20 constchar*p、charconst*p和char*constp有什么区别?  复杂的声明  1.21 怎样建立和理解非常复杂的声明?例如定义...
  • 1.19 为什么不能像下面这样在初始式和数组维度中使用const?const int n=5; int a[n]; 39 1.20 const char *p、char const *p和char *const p有什么区别? 39 复杂的声明 40 1.21 怎样建立和理解非常复杂的...
  •  1.19 为什么不能像下面这样在初始式和数组维度中使用const?constintn=5;inta[n]; 1.20 constchar*p、charconst*p和char*constp有什么区别? 复杂的声明 1.21 怎样建立和理解非常复杂的声明?例如定义一...
  • 1.19 为什么不能像下面这样在初始式和数组维度中使用const?constintn=5;inta[n]; 1.20 constchar*p、charconst*p和char*constp有什么区别? 复杂的声明 1.21 怎样建立和理解非常复杂的声明?例如定义一个...
  • 1.19 为什么不能像下面这样在初始式和数组维度中使用const?const int n=5; int a[n]; 10 1.20 const char *p、char const *p和char *const p有什么区别? 10 复杂的声明 11 1.21 怎样建立和理解非常复杂...
  • 《你必须知道的495个C语言问题》

    热门讨论 2010-03-20 16:41:18
    1.19 为什么不能像下面这样在初始式和数组维度中使用const?const int n=5; int a[n]; 10 1.20 const char *p、char const *p和char *const p有什么区别? 10 复杂的声明 11 1.21 怎样建立和理解非常复杂...
  • 1.19 为什么不能像下面这样在初始式和数组维度中使用const?const int n=5; int a[n]; 1.20 const char *p、char const *p和char *const p有什么区别? 复杂的声明 1.21 怎样建立和理解非常复杂的声明?例如定义...
  • 1.19 为什么不能像下面这样在初始式和数组维度中使用const?const int n=5; int a[n]; 1.20 const char *p、char const *p和char *const p有什么区别? 复杂的声明 1.21 怎样建立和理解非常复杂的声明?例如定义...
  •  传值还是传引用的问题,到此已经算是解决了,但是我们仍然不能解决这样一个问题:如果我有两个 int 型的变量 a 和 b,我想写一个方法来交换它们的,应该怎么办?  结论很让人失望——没有办法!因此,我们只能...
  • o 7.18 当数组是函数的参数时, 为什么 sizeof 不能正确报告数组的大小 ? * 8. 内存分配 o 8.1 为什么这段代码不行?char *answer; printf("Type something:\n"); gets(answer); printf("You typed \"%s\"\n", ...
  • C++程序员面试宝典

    热门讨论 2013-04-01 13:36:19
    面试题27 为什么想进本公司 33 面试题28 你最喜欢这份工作的哪一点或者哪些方面 33 面试题29 请描述一下你自己的优缺点 34 面试题30 你对本公司的了解有多少 34 面试题31 对这份工作的期望与目标何在 34 面试题32 你...
  • 你必须知道的495个C语言问题(PDF)

    热门讨论 2009-09-15 10:25:47
    2.11 为什么sizeof 返回的大于结构的期望, 是不是尾部有填充? . . 9 2.12 如何确定域在结构中的字节偏移? . . . . . . . . . . . . . . . . . 9 2.13 怎样在运行时用名字访问结构中的域? . . . . . . . . . . ...
  • javascript入门笔记

    2018-05-15 15:01:07
    3、不能使用JS中的关键字 和 保留关键字 4、变量名不能重复 5、可以采用"驼峰命名法",小驼峰命名法使用居多 6、最好见名知意 var a; var uname; 4、变量的使用 1、变量赋值 - SET操作 只要变量出现在 ...
  • 软件测试经典面试题 (超实用)

    热门讨论 2012-02-16 13:48:08
    2、简述什么值传递什么是地址传递,两者区别是什么? 28 3、结构化程序设计和面向对象程序设计各自的特点及优缺点是什么? 28 4、简述什么是存储过程和触发器? 28 5、使用C语言编写一个函数,用于交换两个变量...
  • 问题1-17:为什么协议不能设计成100%可靠的? 问题1-18:什么是因特网的穆尔定律? 问题1-19:局域网、广域网和公用网、专用网有什么关系? 问题1-20:信道的利用率是否越高越好? 问题1-21:怎样理解教材中图1-8所...
  • 语句if(x == 3)首先判断x的是否3,若相等条件表达式的值为ture,否则false。 2-15 什么叫做作用域?什么叫做局部变量?什么叫做全局变量,如何使用全局变量? 解: 作用域是一个标识符在程序正文中有效的...

空空如也

空空如也

1 2 3 4
收藏数 63
精华内容 25
关键字:

值传递为什么不能交换值