2014-05-01 44 views
0

一行代碼看起來有誤導性。我的意思是以for (; ;) ;的形式。一行代碼乘法表

在嘗試使用lambda表達式時,爲了好玩,我編寫了下面的程序。我所做的是將for循環的第三個表達式(通常是++i)更改爲lambda函數。輸出也顯示。這就像一個混淆的代碼,但似乎無論如何,它做的工作。我想知道是否有可能以類似的方式與Java做到這一點。

for (int i=1; i<10; [](int i) {for (int j=2; j<10; ++j) printf("%dx%d=%2d ",j,i,i*j);}(i++)) printf("\n"); 

2x1= 2 3x1= 3 4x1= 4 5x1= 5 6x1= 6 7x1= 7 8x1= 8 9x1= 9 
2x2= 4 3x2= 6 4x2= 8 5x2=10 6x2=12 7x2=14 8x2=16 9x2=18 
2x3= 6 3x3= 9 4x3=12 5x3=15 6x3=18 7x3=21 8x3=24 9x3=27 
2x4= 8 3x4=12 4x4=16 5x4=20 6x4=24 7x4=28 8x4=32 9x4=36 
2x5=10 3x5=15 4x5=20 5x5=25 6x5=30 7x5=35 8x5=40 9x5=45 
2x6=12 3x6=18 4x6=24 5x6=30 6x6=36 7x6=42 8x6=48 9x6=54 
2x7=14 3x7=21 4x7=28 5x7=35 6x7=42 7x7=49 8x7=56 9x7=63 
2x8=16 3x8=24 4x8=32 5x8=40 6x8=48 7x8=56 8x8=64 9x8=72 
2x9=18 3x9=27 4x9=36 5x9=45 6x9=54 7x9=63 8x9=72 9x9=81 

對於有些更好的可讀性,我已經分離的for循環元素和lambda函數。

for (int i=1; i<10; 
    [](int i) { 
     for (int j=2; j<10; ++j) 
      printf("%dx%d=%2d ",j,i,i*j); 
    } (i++)) 
{ 
    printf("\n"); 
} 

我試圖插入類似於C++一樣(int i) -> {...}了Java lambda函數,但它似乎不正確的語法爲Java for循環。

我很好奇,當我讀到article。它是韓文的,但列出的代碼是用C++編寫的,所以我想任何人都可以閱讀它們。首先來看一些我不知道的韓劇的截圖。第一張圖片顯示了乘法的Java代碼。看來,其中一位演員正在告訴其他人,可以用一行代碼完成。

本文的作者試圖在C++中使用它。他正在for循環語句中使用逗號分隔的多個printf。我所做的就是讓它成爲一個lambda函數。

那麼,是否有可能以類似的方式與Java做到這一點?

+2

當然。你可以不使用換行符。 – NiematojakTomasz

+0

你在這裏有多個語句,你只是給了一個關於身份(或者換行符)的狗屎(像編譯器一樣)... – Paranaix

+2

你可以在java中的「一行」中做任何事情。這是一種自由形式的語言,如C++ –

回答

0

嗯,我正在回答我自己的問題。

與C++不同,Java似乎對循環控制變量語句嚴格。以任何形式放入lambda函數都會導致錯誤。

因此,我所做的是使用單個for-loop和兩個循環控制變量,像這樣。

// Single for-loop 
for (int i=1, j=2; i<10; i=(++j==10) ? i+1 : i, j=(j==10) ? 2 : j) 
    System.out.format("%dx%d=%2d%c",j,i,i*j,(j==9) ? '\n' : ' '); 

因爲它可以做與C++一樣,我得到了好奇,並比較了C++源代碼和他們的彙編代碼這兩種方法。

這裏是C++代碼(縮進爲更好的可讀性但是...),和

// 1. Using lambda function 
for (int i=1; i<10; 
    [](int i) {for (int j=2; j<10; ++j) 
     printf("%dx%d=%2d ",j,i,i*j);}(i++)) 
    printf("\n"); 

// 2. Using single for-loop 
for (int i=1, j=2; i<10; i=(++j==10) ? i+1 : i, j=(j==10) ? 2 : j) 
    printf("%dx%d=%2d%c",j,i,i*j,(j==9) ? '\n' : ' '); 

這裏是組件(生成的NetBeans-MinGW的GCC)。 帶有lambda函數的函數比具有多個三元運算符的單個for循環生成的代碼更小。

! // 1. Using lambda function 
! for (int i=1; i<10; [](int i) {for (int j=2; j<10; ++j) printf("%dx%d=%2d ",j,i,i*j);}(i++)) printf("\n"); 
main(int, char**)() 
main(int, char**)+22: movl $0x1,-0xc(%ebp) 
main(int, char**)+29: jmp 0x40172a <main(int, char**)+65> 
main(int, char**)+31: movl $0x40a06f,(%esp) 
main(int, char**)+38: call 0x408248 <printf(char const*, ...)> 
main(int, char**)+43: mov -0xc(%ebp),%edx 
main(int, char**)+46: incl -0xc(%ebp) 
main(int, char**)+49: lea -0x15(%ebp),%eax 
main(int, char**)+52: mov %edx,(%esp) 
main(int, char**)+55: mov %eax,%ecx 
main(int, char**)+57: call 0x4016a0 <operator()(int) const> 
main(int, char**)+62: sub $0x4,%esp 
main(int, char**)+65: cmpl $0x9,-0xc(%ebp) 
main(int, char**)+69: setle %al 
main(int, char**)+72: test %al,%al 
main(int, char**)+74: jne 0x401708 <main(int, char**)+31> 
!  
! // 2. Using single for-loop 
! for (int i=1, j=2; i<10; i=(++j==10) ? i+1 : i, j=(j==10) ? 2 : j) printf("%dx%d=%2d%c",j,i,i*j,(j==9) ? '\n' : ' '); 
main(int, char**)+76: movl $0x1,-0x10(%ebp) 
main(int, char**)+83: movl $0x2,-0x14(%ebp) 
main(int, char**)+90: jmp 0x4017a8 <main(int, char**)+191> 
main(int, char**)+92: cmpl $0x9,-0x14(%ebp) 
main(int, char**)+96: jne 0x401752 <main(int, char**)+105> 
main(int, char**)+98: mov $0xa,%eax 
main(int, char**)+103: jmp 0x401757 <main(int, char**)+110> 
main(int, char**)+105: mov $0x20,%eax 
main(int, char**)+110: mov -0x10(%ebp),%edx 
main(int, char**)+113: imul -0x14(%ebp),%edx 
main(int, char**)+117: mov %eax,0x10(%esp) 
main(int, char**)+121: mov %edx,0xc(%esp) 
main(int, char**)+125: mov -0x10(%ebp),%eax 
main(int, char**)+128: mov %eax,0x8(%esp) 
main(int, char**)+132: mov -0x14(%ebp),%eax 
main(int, char**)+135: mov %eax,0x4(%esp) 
main(int, char**)+139: movl $0x40a071,(%esp) 
main(int, char**)+146: call 0x408248 <printf(char const*, ...)> 
main(int, char**)+151: incl -0x14(%ebp) 
main(int, char**)+154: cmpl $0xa,-0x14(%ebp) 
main(int, char**)+158: jne 0x40178f <main(int, char**)+166> 
main(int, char**)+160: mov -0x10(%ebp),%eax 
main(int, char**)+163: inc %eax 
main(int, char**)+164: jmp 0x401792 <main(int, char**)+169> 
main(int, char**)+166: mov -0x10(%ebp),%eax 
main(int, char**)+169: mov %eax,-0x10(%ebp) 
main(int, char**)+172: cmpl $0xa,-0x14(%ebp) 
main(int, char**)+176: je  0x4017a0 <main(int, char**)+183> 
main(int, char**)+178: mov -0x14(%ebp),%eax 
main(int, char**)+181: jmp 0x4017a5 <main(int, char**)+188> 
main(int, char**)+183: mov $0x2,%eax 
main(int, char**)+188: mov %eax,-0x14(%ebp) 
main(int, char**)+191: cmpl $0x9,-0x10(%ebp) 
main(int, char**)+195: setle %al 
main(int, char**)+198: test %al,%al 
main(int, char**)+200: jne 0x401745 <main(int, char**)+92>