尾部附 手动实现++i i++ , java和C版本的

对于以下代码,会输出什么呢?

  1. public static void main(String[] args) {
  2. int num = 0;
  3. for (int i = 0; i < 100; i++) {
  4. num = num++;
  5. }
  6. System.out.println(num);
  7. }

分析一下,num = num++。无非是先把num的值赋给num,然后再执行num++。所以第一次循环,先把0赋值给num,然后自加,num的值变为了1。第二次循环,先把1赋给num,然后自加,num的值变为2了… 如此循环100次,那么num的值就是100!

但是,答案是0

其实这是一道很简单的考验前置加加和后置加加的题目。因为我曾经用C++手动实现过前置++和后置++运算符,所以自诩在这类题目上不会再错了,但是…

经过这道题目后,让我对前置++和后置++有了更深的印象和理解。

首先赋值号是从右向左执行的,所以会先执行num++,然后执行赋值操作,num++其实是一个函数,只不过各个语言中都已经帮我们实现好了他,跟大家知道的一样,他是后置加加,也就是先返回值,再自加。

但其实这种说法是不对的,上面那种错误的思路也正是被这种说法误导了。num++是一个函数,怎么可能先返回值呢?返回之后函数就结束了,怎么可能还有自加的操作呢?

所以正确的理解是,在函数中,先用临时变量把当前值记录下来,然后对this进行自加操作,最后返回临时变量(的值)。这样就呈现给用户了“先返回值,后加加”的感觉。

所以按照上述,num = num ++; 应该是先执行num++函数,num是自加了,可是返回出去了一个自加前的值0,所以赋值号右边执行时,num先等于1,然后又把0赋值给了num,所以num又变为0了。这样无论多少循环,num都是0。


但是如果换成下面这样,就不一样了。

  1. public static void main(String[] args) {
  2. int num = 0;
  3. for (int i = 0; i < 100; i++) {
  4. num++;
  5. }
  6. System.out.println(num);
  7. }

这种情况下,输出结果就是100。

因为num++虽然把num未自加前的值返回了,但是并没有变量去接收他,所以num自加就是自加,就会随着循环每次加1。循环100次就是100。

代码:java实现 i++ 和 ++i

  1. package com.example.demo.Algorithm;
  2. import lombok.Data;
  3. /**
  4. * @author: HanXu
  5. * on 2021/8/27
  6. * Class description: java实现 前置加加 和 后置加加
  7. */
  8. @Data
  9. class CustomInt{
  10. private int num;
  11. public CustomInt(int num) {
  12. this.num = num;
  13. }
  14. @Override
  15. protected CustomInt clone() throws CloneNotSupportedException {
  16. return new CustomInt(this.num);
  17. }
  18. }
  19. public class Demo2 {
  20. public static Integer preAdd(Integer i) {
  21. i = i + 1;
  22. return i;
  23. }
  24. public static int afterAdd(int i) {
  25. int temp = i;
  26. i = i + 1;
  27. return temp;
  28. }
  29. public static CustomInt preAdd(CustomInt i) {
  30. i.setNum(i.getNum() + 1);
  31. return i;
  32. }
  33. public static CustomInt afterAdd(CustomInt i) throws CloneNotSupportedException {
  34. CustomInt temp = i.clone();
  35. i.setNum(i.getNum() + 1);
  36. return temp;
  37. }
  38. public static void main(String[] args) throws CloneNotSupportedException {
  39. //---------------------错误的实现方法---------------------
  40. // 使用 int Integer并不能实现效果,因为java中的数字是基本类型,函数传参时传的是值,对于基本类型来说,就是把值传过去了。只有传入引用才能改变函数外变量的值
  41. Integer j = 2;
  42. //前置加加 ++i 加完后并没有让变量本身的值发生改变
  43. System.out.println(preAdd(j)); // 3
  44. System.out.println(j); // 2
  45. //后置加加 i++ 加完后并没有让变量本身的值改变
  46. //System.out.println(afterAdd(j)); // 2
  47. //System.out.println(j); // 2
  48. //---------------------正确的实现方法---------------------
  49. // 函数传参传入的是引用类型时,传进去的值是该引用类型指向的堆空间的地址,所以在函数内作出改变,就会影响到所有指向该堆空间地址的变量的值,包括函数外部的变量。
  50. CustomInt i = new CustomInt(2);
  51. // 前置加加 ++1
  52. //System.out.println(preAdd(i)); // CustomInt(num=3)
  53. //System.out.println(i.getNum()); // 3
  54. // 后置加加 i++
  55. //System.out.println(afterAdd(i)); // CustomInt(num=2)
  56. //System.out.println(i.getNum()); // 3
  57. }
  58. }

C实现 i++ 和 ++i

附上曾经写的代码和文章:https://blog.csdn.net/hanhanhanxu/article/details/103422706 (内涵C++语言实现的前置++和后置++)