c语言笔试基础(二)

  1. 关于二维数组取地址的问题
    这里写图片描述
    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.
  2. 以下代码的执行结果是
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。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值