2014-12-18 15 views
6

Đây có phải là đệ quy không?Đang khởi tạo thành viên của lớp Kiểm tra trong lớp Kiểm tra đệ quy?

public class Test { 
    Test test = new Test(); 

    public static void main(String[] args) { 
     new Test(); 
    } 
} 

Phiên bản nào với instance initalizer?

public class Test { 
    { Test test = new Test(); } 

    public static void main(String[] args) { 
     new Test(); 
    } 
} 

Tôi hỏi, vì tôi cập nhật my old answer, được thể hiện như thế nào để làm cho StackOverflowError mà không đệ quy, nhưng bây giờ tôi không chắc chắn 100% nếu mã trên là đệ quy hay không.

+0

Hãy thử và xem bạn có làm nổ tung ngăn xếp không. Cả hai dường như khá rõ ràng với tôi. –

+1

Bạn đã chạy mã chưa? – brso05

+0

Mã của bạn sẽ có kết quả tương tự. Không có sự khác biệt. Tôi không thể nói nếu nó đệ quy hay không, thật đáng buồn = \ –

Trả lời

3

Ý kiến ​​của tôi là nó là đệ quy. Tôi không thể tìm được nguồn tốt hay chống lại nó. Vì vậy, tôi đã cố gắng để so sánh mã lắp ráp của một chức năng đệ quy được biết đến với mã lắp ráp được tạo ra của mã java trong OP. Hai mã assembly tương tự nhau, trong câu hỏi nó xảy ra cho phương thức (Constructor) gọi chính nó.

mã kiểm tra của tôi:

public class Test3 { 

    void printMe() { 
    printMe(); 
    } 

    public static void main(String[] args) { 
    Test3 test = new Test3(); 
    test.printMe(); 
    } 

} 

lắp ráp In bằng: java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -server -cp . Test3

liên quan chuỗi mã lắp ráp, cho thấy rằng các chức năng tự gọi mình:

Decoding compiled method 0x00007f2e2910ac90: 
Code: 
[Entry Point] 
[Constants] 
    # {method} {0x00007f2e27121230} 'printMe' '()V' in 'com/vs/soutils/Test3' 
    #   [sp+0x40] (sp of caller) 
    0x00007f2e2910ae00: mov 0x8(%rsi),%r10d 
    0x00007f2e2910ae04: shl $0x3,%r10 
    0x00007f2e2910ae08: cmp %rax,%r10 
    0x00007f2e2910ae0b: jne 0x00007f2e29045b60 ; {runtime_call} 
    0x00007f2e2910ae11: nopw 0x0(%rax,%rax,1) 
    0x00007f2e2910ae1c: xchg %ax,%ax 
[Verified Entry Point] 
    0x00007f2e2910ae20: mov %eax,-0x14000(%rsp) 
    0x00007f2e2910ae27: push %rbp 
    0x00007f2e2910ae28: sub $0x30,%rsp 
    0x00007f2e2910ae2c: mov $0x7f2e271213f8,%rdi ; {metadata(method data for {method} {0x00007f2e27121230} 'printMe' '()V' in 'com/vs/soutils/Test3')} 
    0x00007f2e2910ae36: mov 0x64(%rdi),%ebx 
    0x00007f2e2910ae39: add $0x8,%ebx 
    0x00007f2e2910ae3c: mov %ebx,0x64(%rdi) 
    0x00007f2e2910ae3f: mov $0x7f2e27121230,%rdi ; {metadata({method} {0x00007f2e27121230} 'printMe' '()V' in 'com/vs/soutils/Test3')} 
    0x00007f2e2910ae49: and $0x1ff8,%ebx 
    0x00007f2e2910ae4f: cmp $0x0,%ebx 
    0x00007f2e2910ae52: je  0x00007f2e2910aec0 ;*aload_0 
               ; - com.vs.soutils.Test3::[email protected] (line 6) 

    0x00007f2e2910ae58: mov %rsi,%rdi 
    0x00007f2e2910ae5b: mov $0x7f2e271213f8,%rbx ; {metadata(method data for {method} {0x00007f2e27121230} 'printMe' '()V' in 'com/vs/soutils/Test3')} 
    0x00007f2e2910ae65: addq $0x1,0xa0(%rbx) 
    0x00007f2e2910ae6d: mov $0x7f2e271213f8,%rdi ; {metadata(method data for {method} {0x00007f2e27121230} 'printMe' '()V' in 'com/vs/soutils/Test3')} 
    0x00007f2e2910ae77: mov 0x64(%rdi),%ebx 
    0x00007f2e2910ae7a: add $0x8,%ebx 
    0x00007f2e2910ae7d: mov %ebx,0x64(%rdi) 
    0x00007f2e2910ae80: mov $0x7f2e27121230,%rdi ; {metadata({method} {0x00007f2e27121230} 'printMe' '()V' in 'com/vs/soutils/Test3')} 
    0x00007f2e2910ae8a: and $0x7ffff8,%ebx 
    0x00007f2e2910ae90: cmp $0x0,%ebx 
    0x00007f2e2910ae93: je  0x00007f2e2910aed4 
    0x00007f2e2910ae99: mov %rsi,%rdi 
    0x00007f2e2910ae9c: mov $0x7f2e271213f8,%rbx ; {metadata(method data for {method} {0x00007f2e27121230} 'printMe' '()V' in 'com/vs/soutils/Test3')} 
    0x00007f2e2910aea6: addq $0x1,0xa0(%rbx) 
    0x00007f2e2910aeae: nop  
    0x00007f2e2910aeaf: callq 0x00007f2e29045d60 ; OopMap{off=180} 
               ;*invokevirtual printMe 
               ; - com.vs.soutils.Test3::[email protected] (line 6) 
               ; - com.vs.soutils.Test3::[email protected] (line 6) 
               ; {optimized virtual_call} 
    0x00007f2e2910aeb4: add $0x30,%rsp 
    0x00007f2e2910aeb8: pop %rbp 
    0x00007f2e2910aeb9: test %eax,0x16461241(%rip)  # 0x00007f2e3f56c100 
               ; {poll_return} 
    0x00007f2e2910aebf: retq 
    0x00007f2e2910aec0: mov %rdi,0x8(%rsp) 
    0x00007f2e2910aec5: movq $0xffffffffffffffff,(%rsp) 
    0x00007f2e2910aecd: callq 0x00007f2e290fdde0 ; OopMap{rsi=Oop off=210} 
               ;*synchronization entry 
               ; - com.vs.soutils.Test3::[email protected] (line 6) 
               ; {runtime_call} 
    0x00007f2e2910aed2: jmp 0x00007f2e2910ae58 
    0x00007f2e2910aed4: mov %rdi,0x8(%rsp) 
    0x00007f2e2910aed9: movq $0xffffffffffffffff,(%rsp) 
    0x00007f2e2910aee1: callq 0x00007f2e290fdde0 ; OopMap{rsi=Oop off=230} 
               ;*synchronization entry 
               ; - com.vs.soutils.Test3::[email protected] (line 6) 
               ; - com.vs.soutils.Test3::[email protected] (line 6) 
               ; {runtime_call} 
    0x00007f2e2910aee6: jmp 0x00007f2e2910ae99 
    0x00007f2e2910aee8: nop  
    0x00007f2e2910aee9: nop  
    0x00007f2e2910aeea: mov 0x288(%r15),%rax 
    0x00007f2e2910aef1: mov $0x0,%r10 
    0x00007f2e2910aefb: mov %r10,0x288(%r15) 
    0x00007f2e2910af02: mov $0x0,%r10 
    0x00007f2e2910af0c: mov %r10,0x290(%r15) 
    0x00007f2e2910af13: add $0x30,%rsp 
    0x00007f2e2910af17: pop %rbp 
    0x00007f2e2910af18: jmpq 0x00007f2e2906be20 ; {runtime_call} 

Bây giờ so sánh nó với việc lắp ráp mã cho mã ban đầu:

Decoding compiled method 0x00007fea24ef0dd0: 
Code: 
[Entry Point] 
[Constants] 
    # {method} {0x00007fea229431b0} '<init>' '()V' in 'com/vs/soutils/Test' 
    #   [sp+0x80] (sp of caller) 
    0x00007fea24ef0f60: mov 0x8(%rsi),%r10d 
    0x00007fea24ef0f64: shl $0x3,%r10 
    0x00007fea24ef0f68: cmp %rax,%r10 
    0x00007fea24ef0f6b: jne 0x00007fea24e29b60 ; {runtime_call} 
    0x00007fea24ef0f71: nopw 0x0(%rax,%rax,1) 
    0x00007fea24ef0f7c: xchg %ax,%ax 
[Verified Entry Point] 
    0x00007fea24ef0f80: mov %eax,-0x14000(%rsp) 
    0x00007fea24ef0f87: push %rbp 
    0x00007fea24ef0f88: sub $0x70,%rsp 
    0x00007fea24ef0f8c: mov $0x7fea22943350,%rdx ; {metadata(method data for {method} {0x00007fea229431b0} '<init>' '()V' in 'com/vs/soutils/Test')} 
    0x00007fea24ef0f96: mov 0x64(%rdx),%edi 
    0x00007fea24ef0f99: add $0x8,%edi 
    0x00007fea24ef0f9c: mov %edi,0x64(%rdx) 
    0x00007fea24ef0f9f: mov $0x7fea229431b0,%rdx ; {metadata({method} {0x00007fea229431b0} '<init>' '()V' in 'com/vs/soutils/Test')} 
    0x00007fea24ef0fa9: and $0x1ff8,%edi 
    0x00007fea24ef0faf: cmp $0x0,%edi 
    0x00007fea24ef0fb2: je  0x00007fea24ef1172 ;*aload_0 
               ; - com.vs.soutils.Test::<init>@0 (line 3) 

    0x00007fea24ef0fb8: mov %rsi,%rdx 
    0x00007fea24ef0fbb: mov $0x7fea22943350,%rdi ; {metadata(method data for {method} {0x00007fea229431b0} '<init>' '()V' in 'com/vs/soutils/Test')} 
    0x00007fea24ef0fc5: addq $0x1,0x90(%rdi) 
    0x00007fea24ef0fcd: mov $0x7fea226a1f10,%rdx ; {metadata(method data for {method} {0x00007fea22543488} '<init>' '()V' in 'java/lang/Object')} 
    0x00007fea24ef0fd7: mov 0x64(%rdx),%edi 
    0x00007fea24ef0fda: add $0x8,%edi 
    0x00007fea24ef0fdd: mov %edi,0x64(%rdx) 
    0x00007fea24ef0fe0: mov $0x7fea22543488,%rdx ; {metadata({method} {0x00007fea22543488} '<init>' '()V' in 'java/lang/Object')} 
    0x00007fea24ef0fea: and $0x7ffff8,%edi 
    0x00007fea24ef0ff0: cmp $0x0,%edi 
    0x00007fea24ef0ff3: je  0x00007fea24ef1189 
    0x00007fea24ef0ff9: mov $0x7c0060028,%rdx ; {metadata('com/vs/soutils/Test')} 
    0x00007fea24ef1003: mov %rsi,0x58(%rsp) 
    0x00007fea24ef1008: mov 0x60(%r15),%rax 
    0x00007fea24ef100c: lea 0x10(%rax),%rdi 
    0x00007fea24ef1010: cmp 0x70(%r15),%rdi 
    0x00007fea24ef1014: ja  0x00007fea24ef11a0 
    0x00007fea24ef101a: mov %rdi,0x60(%r15) 
    0x00007fea24ef101e: mov 0xa8(%rdx),%rcx 
    0x00007fea24ef1025: mov %rcx,(%rax) 
    0x00007fea24ef1028: mov %rdx,%rcx 
    0x00007fea24ef102b: shr $0x3,%rcx 
    0x00007fea24ef102f: mov %ecx,0x8(%rax) 
    0x00007fea24ef1032: xor %rcx,%rcx 
    0x00007fea24ef1035: mov %ecx,0xc(%rax) 
    0x00007fea24ef1038: xor %rcx,%rcx   ;*new ; - com.vs.soutils.Test::<init>@5 (line 5) 

    0x00007fea24ef103b: mov %rax,%rdx 
    0x00007fea24ef103e: mov $0x7fea22943350,%rsi ; {metadata(method data for {method} {0x00007fea229431b0} '<init>' '()V' in 'com/vs/soutils/Test')} 
    0x00007fea24ef1048: addq $0x1,0xa0(%rsi) 
    0x00007fea24ef1050: mov $0x7fea22943350,%rdx ; {metadata(method data for {method} {0x00007fea229431b0} '<init>' '()V' in 'com/vs/soutils/Test')} 
    0x00007fea24ef105a: mov 0x64(%rdx),%esi 
    0x00007fea24ef105d: add $0x8,%esi 
    0x00007fea24ef1060: mov %esi,0x64(%rdx) 
    0x00007fea24ef1063: mov $0x7fea229431b0,%rdx ; {metadata({method} {0x00007fea229431b0} '<init>' '()V' in 'com/vs/soutils/Test')} 
    0x00007fea24ef106d: and $0x7ffff8,%esi 
    0x00007fea24ef1073: cmp $0x0,%esi 
    0x00007fea24ef1076: je  0x00007fea24ef11ad 
    0x00007fea24ef107c: mov %rax,%rdx 
    0x00007fea24ef107f: mov $0x7fea22943350,%rsi ; {metadata(method data for {method} {0x00007fea229431b0} '<init>' '()V' in 'com/vs/soutils/Test')} 
    0x00007fea24ef1089: addq $0x1,0x90(%rsi) 
    0x00007fea24ef1091: mov $0x7fea226a1f10,%rdx ; {metadata(method data for {method} {0x00007fea22543488} '<init>' '()V' in 'java/lang/Object')} 
    0x00007fea24ef109b: mov 0x64(%rdx),%esi 
    0x00007fea24ef109e: add $0x8,%esi 
    0x00007fea24ef10a1: mov %esi,0x64(%rdx) 
    0x00007fea24ef10a4: mov $0x7fea22543488,%rdx ; {metadata({method} {0x00007fea22543488} '<init>' '()V' in 'java/lang/Object')} 
    0x00007fea24ef10ae: and $0x7ffff8,%esi 
    0x00007fea24ef10b4: cmp $0x0,%esi 
    0x00007fea24ef10b7: je  0x00007fea24ef11c4 
    0x00007fea24ef10bd: mov $0x7c0060028,%rdx ; {metadata('com/vs/soutils/Test')} 
    0x00007fea24ef10c7: mov %rax,0x50(%rsp) 
    0x00007fea24ef10cc: mov 0x60(%r15),%rax 
    0x00007fea24ef10d0: lea 0x10(%rax),%rdi 
    0x00007fea24ef10d4: cmp 0x70(%r15),%rdi 
    0x00007fea24ef10d8: ja  0x00007fea24ef11db 
    0x00007fea24ef10de: mov %rdi,0x60(%r15) 
    0x00007fea24ef10e2: mov 0xa8(%rdx),%rcx 
    0x00007fea24ef10e9: mov %rcx,(%rax) 
    0x00007fea24ef10ec: mov %rdx,%rcx 
    0x00007fea24ef10ef: shr $0x3,%rcx 
    0x00007fea24ef10f3: mov %ecx,0x8(%rax) 
    0x00007fea24ef10f6: xor %rcx,%rcx 
    0x00007fea24ef10f9: mov %ecx,0xc(%rax) 
    0x00007fea24ef10fc: xor %rcx,%rcx   ;*new ; - com.vs.soutils.Test::<init>@5 (line 5) 
               ; - com.vs.soutils.Test::<init>@9 (line 5) 

    0x00007fea24ef10ff: mov %rax,%rsi 
    0x00007fea24ef1102: mov $0x7fea22943350,%rdi ; {metadata(method data for {method} {0x00007fea229431b0} '<init>' '()V' in 'com/vs/soutils/Test')} 
    0x00007fea24ef110c: addq $0x1,0xa0(%rdi) 
    0x00007fea24ef1114: mov %rax,%rsi   ;*invokespecial <init> 
               ; - com.vs.soutils.Test::<init>@9 (line 5) 
               ; - com.vs.soutils.Test::<init>@9 (line 5) 

    0x00007fea24ef1117: mov %rax,0x48(%rsp) 
    0x00007fea24ef111c: nop  
    0x00007fea24ef111d: nop  
    0x00007fea24ef111e: nop  
    0x00007fea24ef111f: callq 0x00007fea24e29d60 ; OopMap{[72]=Oop [80]=Oop [88]=Oop off=452} 
               ;*invokespecial <init> 
               ; - com.vs.soutils.Test::<init>@9 (line 5) 
               ; - com.vs.soutils.Test::<init>@9 (line 5) 
               ; {optimized virtual_call} 
    0x00007fea24ef1124: mov 0x48(%rsp),%rsi 
    0x00007fea24ef1129: mov 0x50(%rsp),%rax 
    0x00007fea24ef112e: mov %rsi,%r10 
    0x00007fea24ef1131: shr $0x3,%r10 
    0x00007fea24ef1135: mov %r10d,0xc(%rax) 
    0x00007fea24ef1139: mov %rax,%rsi 
    0x00007fea24ef113c: shr $0x9,%rsi 
    0x00007fea24ef1140: mov $0x7fea20c23000,%rdi 
    0x00007fea24ef114a: movb $0x0,(%rsi,%rdi,1) ;*putfield test 
               ; - com.vs.soutils.Test::<init>@12 (line 5) 
               ; - com.vs.soutils.Test::<init>@9 (line 5) 

    0x00007fea24ef114e: mov 0x58(%rsp),%rsi 
    0x00007fea24ef1153: mov %rax,%r10 
    0x00007fea24ef1156: shr $0x3,%r10 
    0x00007fea24ef115a: mov %r10d,0xc(%rsi) 
    0x00007fea24ef115e: shr $0x9,%rsi 
    0x00007fea24ef1162: movb $0x0,(%rsi,%rdi,1) ;*putfield test 
               ; - com.vs.soutils.Test::<init>@12 (line 5) 

    0x00007fea24ef1166: add $0x70,%rsp 
    0x00007fea24ef116a: pop %rbp 
    0x00007fea24ef116b: test %eax,0x15e21f8f(%rip)  # 0x00007fea3ad13100 
               ; {poll_return} 
    0x00007fea24ef1171: retq 
    0x00007fea24ef1172: mov %rdx,0x8(%rsp) 
    0x00007fea24ef1177: movq $0xffffffffffffffff,(%rsp) 
    0x00007fea24ef117f: callq 0x00007fea24ee1d20 ; OopMap{rsi=Oop off=548} 
               ;*synchronization entry 
               ; - com.vs.soutils.Test::<init>@-1 (line 3) 
               ; {runtime_call} 
    0x00007fea24ef1184: jmpq 0x00007fea24ef0fb8 
    0x00007fea24ef1189: mov %rdx,0x8(%rsp) 
    0x00007fea24ef118e: movq $0xffffffffffffffff,(%rsp) 
    0x00007fea24ef1196: callq 0x00007fea24ee1d20 ; OopMap{rsi=Oop off=571} 
               ;*synchronization entry 
               ; - java.lang.Object::<init>@-1 (line 37) 
               ; - com.vs.soutils.Test::<init>@1 (line 3) 
               ; {runtime_call} 
    0x00007fea24ef119b: jmpq 0x00007fea24ef0ff9 
    0x00007fea24ef11a0: mov %rdx,%rdx 
    0x00007fea24ef11a3: callq 0x00007fea24edda60 ; OopMap{[88]=Oop off=584} 
               ;*new ; - com.vs.soutils.Test::<init>@5 (line 5) 
               ; {runtime_call} 
    0x00007fea24ef11a8: jmpq 0x00007fea24ef103b 
    0x00007fea24ef11ad: mov %rdx,0x8(%rsp) 
    0x00007fea24ef11b2: movq $0xffffffffffffffff,(%rsp) 
    0x00007fea24ef11ba: callq 0x00007fea24ee1d20 ; OopMap{[88]=Oop rax=Oop off=607} 
               ;*synchronization entry 
               ; - com.vs.soutils.Test::<init>@-1 (line 3) 
               ; - com.vs.soutils.Test::<init>@9 (line 5) 
               ; {runtime_call} 
    0x00007fea24ef11bf: jmpq 0x00007fea24ef107c 
    0x00007fea24ef11c4: mov %rdx,0x8(%rsp) 
    0x00007fea24ef11c9: movq $0xffffffffffffffff,(%rsp) 
    0x00007fea24ef11d1: callq 0x00007fea24ee1d20 ; OopMap{[88]=Oop rax=Oop off=630} 
               ;*synchronization entry 
               ; - java.lang.Object::<init>@-1 (line 37) 
               ; - com.vs.soutils.Test::<init>@1 (line 3) 
               ; - com.vs.soutils.Test::<init>@9 (line 5) 
               ; {runtime_call} 
    0x00007fea24ef11d6: jmpq 0x00007fea24ef10bd 
    0x00007fea24ef11db: mov %rdx,%rdx 
    0x00007fea24ef11de: callq 0x00007fea24edda60 ; OopMap{[88]=Oop [80]=Oop off=643} 
               ;*new ; - com.vs.soutils.Test::<init>@5 (line 5) 
               ; - com.vs.soutils.Test::<init>@9 (line 5) 
               ; {runtime_call} 
    0x00007fea24ef11e3: jmpq 0x00007fea24ef10ff 
    0x00007fea24ef11e8: nop  
    0x00007fea24ef11e9: nop  
    0x00007fea24ef11ea: mov 0x288(%r15),%rax 
    0x00007fea24ef11f1: mov $0x0,%r10 
    0x00007fea24ef11fb: mov %r10,0x288(%r15) 
    0x00007fea24ef1202: mov $0x0,%r10 
    0x00007fea24ef120c: mov %r10,0x290(%r15) 
    0x00007fea24ef1213: add $0x70,%rsp 
    0x00007fea24ef1217: pop %rbp 
    0x00007fea24ef1218: jmpq 0x00007fea24edcce0 ; {runtime_call} 
    0x00007fea24ef121d: hlt 

Chúng tôi thấy hàm khởi tạo được gọi lặp đi lặp lại. Điều đó giải thích tràn ngăn xếp, và dường như đệ quy.

+0

Tôi thực sự thích ý tưởng này khi so sánh với phương pháp đệ quy đã biết. Tôi đã so sánh tương tự của bytecode được tạo với 'javap -c'. Việc đệ quy phương thức không tĩnh liên quan đến 'invokevirtual' trong thân phương thức, đệ quy phương thức tĩnh liên quan đến' invokestatic' và hai trường hợp tôi trình bày trong một câu hỏi liên quan đến 'invokespecial'. Tất cả chúng đều giống nhau, khác biệt duy nhất là lệnh 'invoke *', vì vậy tôi đồng ý nó là đệ quy. –

0

Chỉ đệ quy của nó.

Khi một cuộc gọi Constructor từ chính.

nó gọi trình khởi tạo biến thể hiện.

Nó một lần nữa gọi Constructor

0

Có đúng vậy. Bạn tạo đối tượng trong vòng lặp vô hạn và kết thúc bằng StackOverflow

+0

Looping có nghĩa là lặp lại, không đệ quy. Mặc dù vậy, không có vòng lặp nào trong mã. – xehpuk

0

"Đệ quy là một kỹ thuật lập trình cơ bản bạn có thể sử dụng trong Java, trong đó một phương thức tự gọi nó là để giải quyết một số vấn đề. các vấn đề lập trình có thể được giải quyết chỉ bằng đệ quy, và một số vấn đề có thể được giải quyết bằng các kỹ thuật khác được giải quyết tốt hơn bằng đệ quy. " - link

dictionary.reference.com - "quy trình xác định hàm hoặc tính số bằng ứng dụng lặp lại của thuật toán". - link

Theo định nghĩa của đệ quy, đây không phải là đệ quy. Lý do là bạn không có một phương thức gọi chính nó trong trường hợp này, đối tượng toàn cầu được tự động hóa ngay lập tức vì nó nằm trong phạm vi toàn cầu và đối tượng đó có một đối tượng trong phạm vi toàn cầu của nó được khởi tạo ...

Nếu bạn lưu ý định nghĩa cũng đề cập đến "để giải quyết một số vấn đề" trong trường hợp này bạn không giải quyết được vấn đề.

Định nghĩa dictionary.reference.com cho biết "ứng dụng lặp lại một thuật toán" (nghĩa là phương pháp) để nó cũng ngụ ý rằng đây không phải là đệ quy.

Trường hợp của bạn, một phương thức không tự gọi là một cá thể mới được tạo mỗi lần, ví dụ: một hàm tạo mặc định mới là một phương thức khác không phải là cùng một phương thức nó thuộc về một đối tượng/cá thể riêng biệt.

+0

Từ định nghĩa trong wikipedia: * Sức mạnh của đệ quy rõ ràng nằm trong khả năng xác định một tập vô hạn các đối tượng bằng một tuyên bố hữu hạn. Theo cách tương tự, một số lượng tính toán vô hạn có thể được mô tả bằng một chương trình đệ quy hữu hạn, ngay cả khi chương trình này không chứa lặp lại rõ ràng * làm cho việc triển khai này trở thành đệ quy hợp lệ. Nhưng một lần nữa, nó phụ thuộc vào một định nghĩa chính thức về đệ quy. –

+0

@LuiggiMendoza wikipedia không phải là nguồn thông tin đáng tin cậy. Nó không nên được sử dụng cho các nguồn hợp lệ. – brso05

+0

@LuiggiMendoza từ dictionary.reference.com định nghĩa đệ quy "quá trình xác định hàm hoặc tính số bằng ứng dụng lặp lại của thuật toán". Điều này ngụ ý một phương thức gọi chính nó ... tức là không đệ quy. – brso05

Các vấn đề liên quan