九 x=x+1,x+=1和x++哪个效率高
x=x+1最低,因为它的执行过程如下:
1. 读取右x的地址;
2. x+1;
3. 读取左x的地址;
4. 将右值传给左边的x(编译器并不认为左右x的地址相同).
x+=1其次,它的执行过程如下:
1. 读取右x的地址;
2. x=1;
3. 将得到的值传给x(因为x的地址已经读出).
x++最高,它的执行如下:
1. 读取右x的地址;
2. x自增1.
自己的理解:
x=x+1;和y=x+1;的执行过程本质相同,都是两次寻址 plus 一次加法运算。编译器在做x+1运算时和之后都不知道结果传向哪里,即x=和y=效果是一样的
而+=复合运算符,本身就被编译器支持,即编译器识别了+=之后,就已经知道源操作数和目的操作数均是一个地址。故x+=1;只有一次寻址和一次加法运算
最后x++为什么比x+=1效率高???
关于红字部分,从CPU和汇编层次去考虑,x自增1还是要将数取到加法器中,才能加1,然后再放回去,但是这样的话就和x+=1执行过程一样了?
八 C中的指针常量和常量指针
七 “a=a++;”在Java和C/C++中不同结果
Java中:
int a=1;
a=a++;
System.out.println("a值为:"+a); // 结果为1
a++和++a都相当于a=a+1; 不同的是, a++的返回值(或者说此表达式的值)为计算“a=a+1;”之前a的值,即1;++a的
返回值(此表达式的值)为计算“a=a+1;”之后的值,为2。
所以,a=a++; 确定a++的返回值为1,然后计算 a=a+1; a等于2,再进行赋值,a=表达式返回值=1;
另注:http://blog.sina.com.cn/s/blog_605f5b4f0100khy0.html
C/C++中:
int a=1;
a=a++;
printf("a值为:%d\n",a); // 结果为2,C++中也是2
一般自增自减运算符单独使用,不推荐符合使用。(这其实又和其本身产生的原因相悖。。。)
六. Java中关于int i=VALUE; integer i=VALUE; Integer i=new Integer(VALUE); 的区别,i存放在栈,堆,及常量池中?
五. 为什么Java中byte为8 bit,表示范围却为-128-127,多出来的那个0的补码到底怎么回事。类似地,4B的int取值范围为-(Max+1)-Max
四. Java为什么全局变量无须初始化,局部变量必须初始化
先说结论:修饰变量时的区别(全部和局部)结论:Java中,全局变量(成员变量)如果没有初始化,JVM会自动初始化为
零;局部变量(方法中自己定义的变量)必须初始化。
public class Demo {
int m;
public static void main(String[] args) {
Demo demo = new Demo();
System.out.println(demo.m); //输出0
}
}
public class Demo {
public static void main(String[] args) {
int m;
System.out.println(m); //报未初始化错误
}
}
https://www.zhihu.com/question/30516949
理解:
全局变量(成员变量)数目是确定的(有限的“少”),新建一个对象时,JVM在Heap区申请内存,用以存放内存区域用以存放类的数据。此时若有未初始化的成员变量,可以初始化为0/null。
而局部变量数目不确定,但是作用域可能又很小(如循环体),在块末尾可能就销毁回收了,若盲目将所有局部变量初始化(必然要为每个局部变量分配空间,并进行赋初值操作),浪费了空间和时间,还不如强制要求程序员自己必须初始化局部变量,不然报错。
类比C/C++:“如果定义全局变量而没有初始化,系统会自动初始化为0,局部变量为随机值。”“全局变量在整个程序运行期间一直占用着存储空间,局部变量只在函数被调用分配内存,调用结束回收。”
三 编译器优化?
#include<stdio.h> #include<time.h> void Interval(int number); void main() { register int i; Interval(i); //register int i 作为实参计时 auto int j; //auto int i 作为实参计时 Interval(j); } void Interval(int number) { clock_t start,finish; double duration; start=clock(); for(number=0;number<100000000;number++); finish=clock(); duration=(double)(finish-start)/CLOCKS_PER_SEC; printf("用时: %f seconds\n", duration); }
结果:
用时: 0.209000 seconds //和上个单独register运行结果基本相同
用时: 0.211000 seconds
void Interval(int number)的参数传递的确是值传递,但是不仅传递参数的数据类型,值大小,也传递其
存储类别,因为定义变量的完整形式为:
存储类别 数据类型 变量名;
参数传递的应该是完整的参数,三要素都包含,故编译时会考虑register和auto的区别,而不是统一处理。故
编译时,因为int number是形参,先不确定其存储位置(当然,知道其肯定不在静态存储区),不分配内存空
间,当实参到来时,会根据实参的存储类别来决定其存储位置,若为register则放在register中,若为auto则放在
动态存储区。
至于为什么最后二者时间会一样,而且都是register的运行时间,可能的原因应该是编译器优化。
为了充分利用计算资源,如果有空闲的寄存器,不管int的存储类别(除static,如auto),默认将int储存位置
预定在register,这样做到了既参数传递传递了完整的三要素,实际的运行中又优化全部作为register处理,结果
相同。
但是,个人猜测,由于编译时编译器并不知道实际运行时CPU的寄存器使用情况,故应该不会强行指定所有int
存储在register中,而是在运行时视寄存器的使用情况来来决定是否优化。
二 static,extern和const区别,逻辑及内存上
一 二维数组的指针运算,到按行和按列?
whu 电信院教材