疑问

  前面在函数篇里介绍了Go语言的函数是支持多返回值的。

  只要在函数体内,对返回值赋值,最后加上return就可以返回所有的返回值。

  最近在写代码的时候经常遇到在return后,还要在defer里面做一些收尾工作,比如事务的提交或回滚。所以想弄清楚这个return和defer到底是什么关系,它们谁先谁后,对于最后返回值又有什么影响呢?

动手验证

  了解下来,问题比我想的要复杂,不信你先看看下面这段代码输出结果是啥

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. func main() {
  6. fmt.Println("f1 result: ", f1())
  7. fmt.Println("f2 result: ", f2())
  8. }
  9.  
  10. func f1() int {
  11. var i int
  12. defer func() {
  13. i++
  14. fmt.Println("f11: ", i)
  15. }()
  16.  
  17. defer func() {
  18. i++
  19. fmt.Println("f12: ", i)
  20. }()
  21.  
  22. i = 1000
  23. return i
  24. }
  25.  
  26. func f2() (i int) {
  27. defer func() {
  28. i++
  29. fmt.Println("f21: ", i)
  30. }()
  31.  
  32. defer func() {
  33. i++
  34. fmt.Println("f22: ", i)
  35. }()
  36.  
  37. i = 1000
  38. return i
  39. }

  

  最后的执行结果如下

  1. f12: 1001
  2. f11: 1002
  3. f1 result: 1000
  4. f22: 1001
  5. f21: 1002
  6. f2 result: 1002

  

f1函数:

  进入该函数,因为没有指定返回值变量,需要先声明i变量,因为是int类型,如果没有赋值,该变量初始化值为0,之后执行i=1000的赋值操作,然后执行return语句,返回i的值。

  真正返回之前还要执行defer函数部分,两个defer函数分别针对i进行自增操作,i的值依次为1001和1002

f2函数:

  进入该函数,因为已经定义好了返回值变量即为i,然后直接赋值i=1000,再返回i的值。

  同样的,也要在真正返回i前,执行两个defer函数,同样i依次自增得到1001和1002。

  问题的关键是为什么无名参数返回的值是1000,其并未收到defer函数对于i自增的影响;而有名函数在执行defer后,最后返回的i值为1002。

  网上找了一些原因,提到一个结论

原因就是return会将返回值先保存起来,对于无名返回值来说,
 保存在一个临时对象中,defer是看不到这个临时对象的;
 而对于有名返回值来说,就保存在已命名的变量中。

  看到这个结论,我想试试通过打印i的地址值是否可以看出一些端倪和线索

  为此在两个函数中添加了打印i的地址信息

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. func main() {
  6. fmt.Println("f1 result: ", f1())
  7. fmt.Println("f2 result: ", f2())
  8. }
  9.  
  10. func f1() int {
  11. var i int
  12. fmt.Printf("i: %p \n", &i)
  13. defer func() {
  14. i++
  15. fmt.Printf("i: %p \n", &i)
  16. fmt.Println("f11: ", i)
  17. }()
  18.  
  19. defer func() {
  20. i++
  21. fmt.Printf("i: %p \n", &i)
  22. fmt.Println("f12: ", i)
  23. }()
  24.  
  25. i = 1000
  26. return i
  27. }
  28.  
  29. func f2() (i int) {
  30. fmt.Printf("i: %p \n", &i)
  31. defer func() {
  32. i++
  33. fmt.Printf("i: %p \n", &i)
  34. fmt.Println("f21: ", i)
  35. }()
  36.  
  37. defer func() {
  38. i++
  39. fmt.Printf("i: %p \n", &i)
  40. fmt.Println("f22: ", i)
  41. }()
  42. i = 1000
  43. return i
  44. }

  

  程序输出结果为

  1. i: 0xc000090000
  2. i: 0xc000090000
  3. f12: 1001
  4. i: 0xc000090000
  5. f11: 1002
  6. f1 result: 1000
  7. i: 0xc00009a008
  8. i: 0xc00009a008
  9. f22: 1001
  10. i: 0xc00009a008
  11. f21: 1002
  12. f2 result: 1002

  

  从这个结果可以看出,无论是f1还是f2函数中,变量i的地址全程没有改变过。

  所以对于上面这个结论我似乎懂了,但是还是有些模糊,return保存在一个临时对象中,defer看不到这个临时变量,但是i的值为什么能够在1000的基础上累加呢?

拨开云雾

  如果要从根本解决这个疑问,最好能够看看这段程序执行,背后的内存是如何分配的。

  这时候想到了前几天看书里提到的可以通过命令将go语言转为汇编语言。

  为了简化问题,将源代码修改为

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. func main() {
  6. fmt.Println("f1 result: ", f1())
  7. fmt.Println("f2 result: ", f2())
  8. }
  9.  
  10. func f1() int {
  11. var i int
  12. defer func() {
  13. i++
  14. fmt.Println("f11: ", i)
  15. }()
  16.  
  17. i = 1000
  18. return i
  19. }
  20.  
  21. func f2() (i int) {
  22. defer func() {
  23. i++
  24. fmt.Println("f21: ", i)
  25. }()
  26. i = 1000
  27. return i
  28. }

  

  通过执行命令go tool compile -S test.go得到汇编代码如下

  1. os.(*File).close STEXT dupok nosplit size=26 args=0x18 locals=0x0
  2. ...
  3. 0x0000 00000 (test.go:5) TEXT "".main(SB), ABIInternal, $136-0
  4. 0x0000 00000 (test.go:5) MOVQ (TLS), CX
  5. 0x0009 00009 (test.go:5) LEAQ -8(SP), AX
  6. 0x000e 00014 (test.go:5) CMPQ AX, 16(CX)
  7. 0x0012 00018 (test.go:5) JLS 315
  8. 0x0018 00024 (test.go:5) SUBQ $136, SP
  9. 0x001f 00031 (test.go:5) MOVQ BP, 128(SP)
  10. 0x0027 00039 (test.go:5) LEAQ 128(SP), BP
  11. 0x002f 00047 (test.go:5) FUNCDATA $0, gclocals·7d2d5fca80364273fb07d5820a76fef4(SB)
  12. ...
  13. "".f1 STEXT size=145 args=0x8 locals=0x28
  14. 0x0000 00000 (test.go:10) TEXT "".f1(SB), ABIInternal, $40-8
  15. 0x0000 00000 (test.go:10) MOVQ (TLS), CX
  16. 0x0009 00009 (test.go:10) CMPQ SP, 16(CX)
  17. 0x000d 00013 (test.go:10) JLS 135
  18. 0x000f 00015 (test.go:10) SUBQ $40, SP
  19. 0x0013 00019 (test.go:10) MOVQ BP, 32(SP)
  20. 0x0018 00024 (test.go:10) LEAQ 32(SP), BP
  21. 0x001d 00029 (test.go:10) FUNCDATA $0, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
  22. 0x001d 00029 (test.go:10) FUNCDATA $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
  23. 0x001d 00029 (test.go:10) FUNCDATA $3, gclocals·9fb7f0986f647f17cb53dda1484e0f7a(SB)
  24. 0x001d 00029 (test.go:10) PCDATA $2, $0
  25. 0x001d 00029 (test.go:10) PCDATA $0, $0
  26. 0x001d 00029 (test.go:10) MOVQ $0, "".~r0+48(SP)
  27. 0x0026 00038 (test.go:11) MOVQ $0, "".i+24(SP)
  28. 0x002f 00047 (test.go:12) MOVL $8, (SP)
  29. 0x0036 00054 (test.go:12) PCDATA $2, $1
  30. 0x0036 00054 (test.go:12) LEAQ "".f1.func1·f(SB), AX
  31. 0x003d 00061 (test.go:12) PCDATA $2, $0
  32. 0x003d 00061 (test.go:12) MOVQ AX, 8(SP)
  33. 0x0042 00066 (test.go:12) PCDATA $2, $1
  34. 0x0042 00066 (test.go:12) LEAQ "".i+24(SP), AX
  35. 0x0047 00071 (test.go:12) PCDATA $2, $0
  36. 0x0047 00071 (test.go:12) MOVQ AX, 16(SP)
  37. 0x004c 00076 (test.go:12) CALL runtime.deferproc(SB)
  38. 0x0051 00081 (test.go:12) TESTL AX, AX
  39. 0x0053 00083 (test.go:12) JNE 119
  40. 0x0055 00085 (test.go:17) MOVQ $1000, "".i+24(SP)
  41. 0x005e 00094 (test.go:18) MOVQ $1000, "".~r0+48(SP)
  42. 0x0067 00103 (test.go:18) XCHGL AX, AX
  43. 0x0068 00104 (test.go:18) CALL runtime.deferreturn(SB)
  44. 0x006d 00109 (test.go:18) MOVQ 32(SP), BP
  45. 0x0072 00114 (test.go:18) ADDQ $40, SP
  46. 0x0076 00118 (test.go:18) RET
  47. 0x0077 00119 (test.go:12) XCHGL AX, AX
  48. 0x0078 00120 (test.go:12) CALL runtime.deferreturn(SB)
  49. 0x007d 00125 (test.go:12) MOVQ 32(SP), BP
  50. 0x0082 00130 (test.go:12) ADDQ $40, SP
  51. 0x0086 00134 (test.go:12) RET
  52. 0x0087 00135 (test.go:12) NOP
  53. 0x0087 00135 (test.go:10) PCDATA $0, $-1
  54. 0x0087 00135 (test.go:10) PCDATA $2, $-1
  55. 0x0087 00135 (test.go:10) CALL runtime.morestack_noctxt(SB)
  56. 0x008c 00140 (test.go:10) JMP 0
  57. ...
  58. 0x0000 00000 (test.go:21) TEXT "".f2(SB), ABIInternal, $32-8
  59. 0x0000 00000 (test.go:21) MOVQ (TLS), CX
  60. 0x0009 00009 (test.go:21) CMPQ SP, 16(CX)
  61. 0x000d 00013 (test.go:21) JLS 117
  62. 0x000f 00015 (test.go:21) SUBQ $32, SP
  63. 0x0013 00019 (test.go:21) MOVQ BP, 24(SP)
  64. 0x0018 00024 (test.go:21) LEAQ 24(SP), BP
  65. 0x001d 00029 (test.go:21) FUNCDATA $0, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
  66. 0x001d 00029 (test.go:21) FUNCDATA $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
  67. 0x001d 00029 (test.go:21) FUNCDATA $3, gclocals·9fb7f0986f647f17cb53dda1484e0f7a(SB)
  68. 0x001d 00029 (test.go:21) PCDATA $2, $0
  69. 0x001d 00029 (test.go:21) PCDATA $0, $0
  70. 0x001d 00029 (test.go:21) MOVQ $0, "".i+40(SP)
  71. 0x0026 00038 (test.go:22) MOVL $8, (SP)
  72. 0x002d 00045 (test.go:22) PCDATA $2, $1
  73. 0x002d 00045 (test.go:22) LEAQ "".f2.func1·f(SB), AX
  74. 0x0034 00052 (test.go:22) PCDATA $2, $0
  75. 0x0034 00052 (test.go:22) MOVQ AX, 8(SP)
  76. 0x0039 00057 (test.go:22) PCDATA $2, $1
  77. 0x0039 00057 (test.go:22) LEAQ "".i+40(SP), AX
  78. 0x003e 00062 (test.go:22) PCDATA $2, $0
  79. 0x003e 00062 (test.go:22) MOVQ AX, 16(SP)
  80. 0x0043 00067 (test.go:22) CALL runtime.deferproc(SB)
  81. 0x0048 00072 (test.go:22) TESTL AX, AX
  82. 0x004a 00074 (test.go:22) JNE 101
  83. 0x004c 00076 (test.go:26) MOVQ $1000, "".i+40(SP)
  84. 0x0055 00085 (test.go:27) XCHGL AX, AX
  85. 0x0056 00086 (test.go:27) CALL runtime.deferreturn(SB)
  86. 0x005b 00091 (test.go:27) MOVQ 24(SP), BP
  87. 0x0060 00096 (test.go:27) ADDQ $32, SP
  88. 0x0064 00100 (test.go:27) RET
  89. 0x0065 00101 (test.go:22) XCHGL AX, AX
  90. 0x0066 00102 (test.go:22) CALL runtime.deferreturn(SB)
  91. 0x006b 00107 (test.go:22) MOVQ 24(SP), BP
  92. 0x0070 00112 (test.go:22) ADDQ $32, SP
  93. 0x0074 00116 (test.go:22) RET
  94. 0x0075 00117 (test.go:22) NOP
  95. 0x0075 00117 (test.go:21) PCDATA $0, $-1
  96. 0x0075 00117 (test.go:21) PCDATA $2, $-1
  97. 0x0075 00117 (test.go:21) CALL runtime.morestack_noctxt(SB)
  98. 0x007a 00122 (test.go:21) JMP 0
  99. ... ........
  100. rel 16+8 t=1 type.[2]interface {}+0

  

  感觉离真相只差一步了,就是看完这段汇编代码就能搞明白这个return在无名和有名返回值时分别做了什么,所谓的零时变量是咋分配的,想想就有点小激动呢

  但是,比较棘手的是,我没学过汇编-_-!

  但是again,这有什么关系呢,两个函数既然执行结果不一样,那么在汇编层面肯定也有不一样的地方,于是开始找不同,最终在上面的汇编代码分别找到关键信息如下

  1. "".f2 STEXT size=124 args=0x8 locals=0x20
  2. 0x0000 00000 (test.go:21) TEXT "".f2(SB), ABIInternal, $32-8
  3. 0x0000 00000 (test.go:21) MOVQ (TLS), CX
  4. 0x0009 00009 (test.go:21) CMPQ SP, 16(CX)
  5. 0x000d 00013 (test.go:21) JLS 117
  6. 0x000f 00015 (test.go:21) SUBQ $32, SP
  7. 0x0013 00019 (test.go:21) MOVQ BP, 24(SP)
  8. 0x0018 00024 (test.go:21) LEAQ 24(SP), BP
  9. 0x001d 00029 (test.go:21) FUNCDATA $0, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
  10. 0x001d 00029 (test.go:21) FUNCDATA $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
  11. 0x001d 00029 (test.go:21) FUNCDATA $3, gclocals·9fb7f0986f647f17cb53dda1484e0f7a(SB)
  12. 0x001d 00029 (test.go:21) PCDATA $2, $0
  13. 0x001d 00029 (test.go:21) PCDATA $0, $0
  14. 0x001d 00029 (test.go:21) MOVQ $0, "".i+40(SP)
  15. 0x0026 00038 (test.go:22) MOVL $8, (SP)
  16. 0x002d 00045 (test.go:22) PCDATA $2, $1
  17. 0x002d 00045 (test.go:22) LEAQ "".f2.func1·f(SB), AX
  18. 0x0034 00052 (test.go:22) PCDATA $2, $0
  19. 0x0034 00052 (test.go:22) MOVQ AX, 8(SP)
  20. 0x0039 00057 (test.go:22) PCDATA $2, $1
  21. 0x0039 00057 (test.go:22) LEAQ "".i+40(SP), AX
  22. 0x003e 00062 (test.go:22) PCDATA $2, $0
  23. 0x003e 00062 (test.go:22) MOVQ AX, 16(SP)
  24. 0x0043 00067 (test.go:22) CALL runtime.deferproc(SB)
  25. 0x0048 00072 (test.go:22) TESTL AX, AX
  26. 0x004a 00074 (test.go:22) JNE 101
  27. 0x004c 00076 (test.go:26) MOVQ $1000, "".i+40(SP)
  28. 0x0055 00085 (test.go:27) XCHGL AX, AX
  29. 0x0056 00086 (test.go:27) CALL runtime.deferreturn(SB)
  30. 0x005b 00091 (test.go:27) MOVQ 24(SP), BP
  31. 0x0060 00096 (test.go:27) ADDQ $32, SP
  32. 0x0064 00100 (test.go:27) RET
  33. 0x0065 00101 (test.go:22) XCHGL AX, AX
  34. 0x0066 00102 (test.go:22) CALL runtime.deferreturn(SB)
  35. 0x006b 00107 (test.go:22) MOVQ 24(SP), BP
  36. 0x0070 00112 (test.go:22) ADDQ $32, SP
  37. 0x0074 00116 (test.go:22) RET
  38. 0x0075 00117 (test.go:22) NOP
  39. 0x0075 00117 (test.go:21) PCDATA $0, $-1
  40. 0x0075 00117 (test.go:21) PCDATA $2, $-1
  41. 0x0075 00117 (test.go:21) CALL runtime.morestack_noctxt(SB)
  42. 0x007a 00122 (test.go:21) JMP 0

  

  这是f2有名返回值的关键信息,主要看

  1. 0x004c 00076 (test.go:26) MOVQ $1000, "".i+40(SP)

  这个大概意思就是把1000放到"".i+40(SP)这个内存地址上,然后下面执行的操作就是返回了

  1. "".f1 STEXT size=145 args=0x8 locals=0x28
  2. 0x0000 00000 (test.go:10) TEXT "".f1(SB), ABIInternal, $40-8
  3. 0x0000 00000 (test.go:10) MOVQ (TLS), CX
  4. 0x0009 00009 (test.go:10) CMPQ SP, 16(CX)
  5. 0x000d 00013 (test.go:10) JLS 135
  6. 0x000f 00015 (test.go:10) SUBQ $40, SP
  7. 0x0013 00019 (test.go:10) MOVQ BP, 32(SP)
  8. 0x0018 00024 (test.go:10) LEAQ 32(SP), BP
  9. 0x001d 00029 (test.go:10) FUNCDATA $0, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
  10. 0x001d 00029 (test.go:10) FUNCDATA $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
  11. 0x001d 00029 (test.go:10) FUNCDATA $3, gclocals·9fb7f0986f647f17cb53dda1484e0f7a(SB)
  12. 0x001d 00029 (test.go:10) PCDATA $2, $0
  13. 0x001d 00029 (test.go:10) PCDATA $0, $0
  14. 0x001d 00029 (test.go:10) MOVQ $0, "".~r0+48(SP)
  15. 0x0026 00038 (test.go:11) MOVQ $0, "".i+24(SP)
  16. 0x002f 00047 (test.go:12) MOVL $8, (SP)
  17. 0x0036 00054 (test.go:12) PCDATA $2, $1
  18. 0x0036 00054 (test.go:12) LEAQ "".f1.func1·f(SB), AX
  19. 0x003d 00061 (test.go:12) PCDATA $2, $0
  20. 0x003d 00061 (test.go:12) MOVQ AX, 8(SP)
  21. 0x0042 00066 (test.go:12) PCDATA $2, $1
  22. 0x0042 00066 (test.go:12) LEAQ "".i+24(SP), AX
  23. 0x0047 00071 (test.go:12) PCDATA $2, $0
  24. 0x0047 00071 (test.go:12) MOVQ AX, 16(SP)
  25. 0x004c 00076 (test.go:12) CALL runtime.deferproc(SB)
  26. 0x0051 00081 (test.go:12) TESTL AX, AX
  27. 0x0053 00083 (test.go:12) JNE 119
  28. 0x0055 00085 (test.go:17) MOVQ $1000, "".i+24(SP)
  29. 0x005e 00094 (test.go:18) MOVQ $1000, "".~r0+48(SP)
  30. 0x0067 00103 (test.go:18) XCHGL AX, AX
  31. 0x0068 00104 (test.go:18) CALL runtime.deferreturn(SB)
  32. 0x006d 00109 (test.go:18) MOVQ 32(SP), BP
  33. 0x0072 00114 (test.go:18) ADDQ $40, SP
  34. 0x0076 00118 (test.go:18) RET
  35. 0x0077 00119 (test.go:12) XCHGL AX, AX
  36. 0x0078 00120 (test.go:12) CALL runtime.deferreturn(SB)
  37. 0x007d 00125 (test.go:12) MOVQ 32(SP), BP
  38. 0x0082 00130 (test.go:12) ADDQ $40, SP
  39. 0x0086 00134 (test.go:12) RET
  40. 0x0087 00135 (test.go:12) NOP
  41. 0x0087 00135 (test.go:10) PCDATA $0, $-1
  42. 0x0087 00135 (test.go:10) PCDATA $2, $-1
  43. 0x0087 00135 (test.go:10) CALL runtime.morestack_noctxt(SB)
  44. 0x008c 00140 (test.go:10) JMP 0

  

这是f1无名返回值的关键信息,主要看

  1. 0x0055 00085 (test.go:17) MOVQ $1000, "".i+24(SP)
  2. 0x005e 00094 (test.go:18) MOVQ $1000, "".~r0+48(SP)

  这个大概意思就是把1000放到"".i+24(SP)这个内存地址上,然后又把1000赋给了"".~r0+48(SP),这就是和f1不一样的地方。对应前面结论,我们在这里找到了验证。大致过程就是无名返回值的情况,在return的时候开辟了一个新内存空间,后续的defer读取的还是"".i+24(SP)这样的内存地址而无法读取临时空间的值。return在函数最后返回的也是"".~r0+48(SP)对应的值即1000。(因为没有研究过汇编,有些细节可能有待考证)

结论

到此,我们算是搞明白了Go语言里面return和defer之间的微妙关系,从汇编层面看清了在无名返回值和有名返回值return返回的差异。

如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!如果您想持续关注我的文章,请扫描二维码,关注JackieZheng的微信公众号,我会将我的文章推送给您,并和您一起分享我日常阅读过的优质文章。

Go语言学习——彻底弄懂return和defer的微妙关系的更多相关文章

  1. c语言学习之基础知识点介绍(五):关系运算式和逻辑运算式

    本节主要说关系运算式和逻辑运算式. 一.关系运算式 1.等于(==):判断左边的表达式是否等于右边的表达式 2.大于(>):判断左边的表达式是否大于右边的表达式 3.大于等于(>=):判断 ...

  2. Java学习——JSTL标签与EL表达式之间的微妙关系

    原文总结的太好了,忍不住记录.转发. 原文地址:http://blog.csdn.net/u010168160/article/details/49182867 目录(?)[-] 一EL表达式 EL相 ...

  3. 必须弄懂的495个C语言问题

    1.1 我如何决定使用那种整数类型? 如果需要大数 值(大于32, 767 或小于¡32, 767), 使用long 型.否则, 如果空间很重要(如有大数组或很多结构), 使用short 型.除此之外 ...

  4. 技能收获与C语言学习

    你有什么技能比大多人(超过90%以上)更好? 我会的东西很多,喜欢的东西太多,但是很遗憾广而不专,会而不精.学了很多东西我都是为了娱乐,因为以前我们那里过于强调学习,很多爱好也都被扼杀在摇篮里.我觉得 ...

  5. 技能学习经验与C语言学习调查

    技能学习经验与C语言学习调查 前言 要说的话,这还是我第一次写博客.不论是为了作业也好,为了将来的学习工作也好,写博客都是必不可少的,也算是个自我提升的途径吧.不过第一次写博客,就用从来没听说过的ma ...

  6. 20155229-付钰涵-分析自我技能延展到c语言学习状况

    我的小技能 我记得幼儿园时表演的舞蹈,也记得从水彩到素描的学习,还记得小学和初中获得的钢琴省级奖项. 舞蹈止于一年级,绘画止于三年级,钢琴从学前班到高一那十年的时间里有过断续. 03年-04年的那个冬 ...

  7. 20155306白皎 学习技能+C语言学习

    你有什么技能比大多数人更好 谈起技能,我还有感觉有微微拿得出手的也只有主持这一项才艺了吧.从小学到高中一直参加朗诵比赛,以及从小学到大学一直在所在学校有担任过主持工作. 上大学以来,也参加了院级朗诵比 ...

  8. 12天学好C语言——记录我的C语言学习之路(Day 8)

    12天学好C语言--记录我的C语言学习之路 Day 8: 从今天开始,我们获得了C语言中很有力的一个工具,那就是函数.函数的魅力不仅于此,一个程序到最后都是由众多函数组成的,我们一定要用好函数,用熟练 ...

  9. 12天学好C语言——记录我的C语言学习之路(Day 7)

    12天学好C语言--记录我的C语言学习之路 Day 7: 昨天进行了一天的数组学习,今天大家可以先写几个昨天的程序热热身,回顾回顾,然后今天第一个新程序也是关于数组的,比较难,准备好就开始啦! //输 ...

随机推荐

  1. CUDA流(Stream)

    CUDA流表示一个GPU操作队列,该队列中的操作将以添加到流中的先后顺序而依次执行.可以将一个流看做是GPU上的一个任务,不同任务可以并行执行.使用CUDA流,首先要选择一个支持设备重叠(Device ...

  2. Java 9 特性

    Java 8 发布三年多之后,已经于在2017年9月21日发布了. 你可能已经听说过 Java 9 的模块系统,但是这个新版本还有许多其它的更新. 这里有九个令人兴奋的新功能. 1. Java 平台级 ...

  3. hdu 1087 Super Jumping! Jumping! Jumping!(dp 最长上升子序列和)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1087 ------------------------------------------------ ...

  4. Linux(Centos7)下自动启动程序

    1.文件转移 先将要执行的文件转移或复制到路径较短的地方如:/usr/local 主要是为了方便,同时防止误删.2.编写Service文件 $ vim /usr/lib/systemd/system/ ...

  5. HDU-4432-Sum of divisors ( 2012 Asia Tianjin Regional Contest )

    Sum of divisors Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  6. 分类算法SVM(支持向量机)

    支持向量机(Support Vector Machine ,SVM)的主要思想是:建立一个最优决策超平面,使得该平面两侧距离该平面最近的两类样本之间的距离最大化,从而对分类问题提供良好的泛化能力.对于 ...

  7. VS2005下第一个ATL

    作者:kagula 日期:  2008-9-2 环境: [1]VisualStudio2005简体中文版(必需已经安装C语言开发环境支持) [2]WinXP+SP3 读者要求: 初步使用过Visual ...

  8. if-then和if-then-else声明

    1.使用if-then声明 结构化命令,主要类型为if-then声明.if-then例如,下面的语句格式: if command then commands fi 假设你在使用其它编程语言的if-th ...

  9. 卷积、卷积矩阵(Convolution matrix)与核(Kernel)

    在图像处理领域,Kernel = convolution matrix = mask,它们一般都为一个较小的矩阵: 用于:Sharpen,Blur, Edge enhance,Edge detect, ...

  10. Web前端开发人员实用Chrome插件收集

    越来越多的前端开发人员喜欢在Chrome里开发调试代码,Chrome有许多优秀的插件可以帮助前端开发人员极大的提高工作效率.尤其Chrome本身是可以登录的,登录后你所有的插件都会自动同步到每一个登录 ...