尾部附 手动实现++i i++ , java和C版本的
对于以下代码,会输出什么呢?
public static void main(String[] args) {
int num = 0;
for (int i = 0; i < 100; i++) {
num = num++;
}
System.out.println(num);
}
分析一下,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。
但是如果换成下面这样,就不一样了。
public static void main(String[] args) {
int num = 0;
for (int i = 0; i < 100; i++) {
num++;
}
System.out.println(num);
}
这种情况下,输出结果就是100。
因为num++虽然把num未自加前的值返回了,但是并没有变量去接收他,所以num自加就是自加,就会随着循环每次加1。循环100次就是100。
代码:java实现 i++ 和 ++i
package com.example.demo.Algorithm;
import lombok.Data;
/**
* @author: HanXu
* on 2021/8/27
* Class description: java实现 前置加加 和 后置加加
*/
@Data
class CustomInt{
private int num;
public CustomInt(int num) {
this.num = num;
}
@Override
protected CustomInt clone() throws CloneNotSupportedException {
return new CustomInt(this.num);
}
}
public class Demo2 {
public static Integer preAdd(Integer i) {
i = i + 1;
return i;
}
public static int afterAdd(int i) {
int temp = i;
i = i + 1;
return temp;
}
public static CustomInt preAdd(CustomInt i) {
i.setNum(i.getNum() + 1);
return i;
}
public static CustomInt afterAdd(CustomInt i) throws CloneNotSupportedException {
CustomInt temp = i.clone();
i.setNum(i.getNum() + 1);
return temp;
}
public static void main(String[] args) throws CloneNotSupportedException {
//---------------------错误的实现方法---------------------
// 使用 int Integer并不能实现效果,因为java中的数字是基本类型,函数传参时传的是值,对于基本类型来说,就是把值传过去了。只有传入引用才能改变函数外变量的值
Integer j = 2;
//前置加加 ++i 加完后并没有让变量本身的值发生改变
System.out.println(preAdd(j)); // 3
System.out.println(j); // 2
//后置加加 i++ 加完后并没有让变量本身的值改变
//System.out.println(afterAdd(j)); // 2
//System.out.println(j); // 2
//---------------------正确的实现方法---------------------
// 函数传参传入的是引用类型时,传进去的值是该引用类型指向的堆空间的地址,所以在函数内作出改变,就会影响到所有指向该堆空间地址的变量的值,包括函数外部的变量。
CustomInt i = new CustomInt(2);
// 前置加加 ++1
//System.out.println(preAdd(i)); // CustomInt(num=3)
//System.out.println(i.getNum()); // 3
// 后置加加 i++
//System.out.println(afterAdd(i)); // CustomInt(num=2)
//System.out.println(i.getNum()); // 3
}
}
C实现 i++ 和 ++i
附上曾经写的代码和文章:https://blog.csdn.net/hanhanhanxu/article/details/103422706 (内涵C++语言实现的前置++和后置++)
评论