- 关于二维数组取地址的问题
a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址,a+1是数组下一元素的地址,即a[1],&a+1是下一个对象的地址。int ptr = (int )(&a+1),p此时指向的地址应该是a[1][4]后面的地址,由于ptr是int型指针,ptr-3应该是ptr向前移动3个元素,即ptr-3指向a[1][2],所以*(ptr -3) = 9. - 以下代码的执行结果是
int main(){
int i=-2147483648;
return printf("%d,%d,%d,%d",~i,-i,1-i,-1-i);
}
正数原码、反码、补码形式一致。 负数反码,为其原码的符号位不变,其他位取反; 负数补码,是其反码加1。
举例8bit有符号型整数:
+34原码=反码=补码:00100010
-34原码=10100010,反码=11011101,补码=11011110
不管是在32还是在64位编译器处理下,int都是4字节32位,所以整数范围是-2147483648~2147483647,数值以补码形式存储。
【注意】最小负数-2147483648=-(2^31) 并没有原码和反码,只有补码,由 -0的原码 1 0…0(31个0) 表示 。
因此:
1、~i:对每一位 取反运算。为01…1(31个1),是正数,补码即原码,即231-1=2147483647;
2、 -i: 对该数求补运算,即【每位】取反运算,再加1。取反, 10…0(31个0)-> 01…1(31个1),再加1得 10…0(31个0),该 补 码表现为 最小负数- 2147483648,并没有原码和反码;
3、1-i:补码形式相加,再推回原码得十进制结果。-i( 10…0(31个0) )+(0 …1(31个0) )= 10…1(30个0),此为补码形式,补码转 原码为补码减1,再非符号位取反,即原码1…1(32个1)= -(231-1)= - 2147483647 ;
4、 -1-i :补码形式相加,再推回原码得十进制结果。即-i( 10…0(31个0) )+(1 …1(32个1) )= 01…1(31个1),是正数形式,原码即补码,为231-1= 2147483647 。
3.求函数返回值,输入x=9999
int func(int x){
int count=0;
while (x)
{
count++;
x=x&(x-1);//与运算
}
return count;
}
一个数与这个数减1的结果进行’&’按位与运算,结果为:这个数二进制数最右边的1变为0;
举例说明如下:
X=5;
5&(5-1) = 010 1 & (0100) = 010 0
经过上述计算,5的二进制最右边的1变为了0,由此可知,题目中count是用以统计x的二进制中1的个数的9999的二进制表示为:10011100001111 共有8个1,考察输入数据二进制中一的个数。
所以8个1.显然,答案为8。