几种讨巧的整形长度计算方法

企鹅15年校招笔试题中出了这么一道题:在不使用sizeof()函数的情况下,取出本机的整形所占位数,如32位、64位等。在我之前的一篇博客:企鹅2015校招笔试之(二)整形长度算法思路实现 中提供了一个常见的算法实现,现在在这里尝试几种讨巧的算法对其进行实现。

一、地址作差法

分析

申请一个整形数组,这样可以确保每两个连续数组元素在内存中所占用的地址是连续的,且地址之差一定为一个整形所占的字节数,通过字节数可以方便的求出整形所占用的位数。

源代码

#include<stdio.h>
int calculate();                // 判断整形所占字节数
int main()
{
    // 输出整形所占位数,其中位数=字节数×8
    printf("本台计算机整形所占位数为:%d\n", calculate() * 8);
    return 0;
}
int calculate()
{
    int sums[3];         // 申请一个数组,保证相邻元素地址连续
    int ret = -1;        // 记录相邻元素之间的地址之差
    ret = (int)&sums[1] - (int)&sums[0];   // 计算相邻元素地址差
    /* 因为整形的长度并不确定,因此无法保证所取到的地址进行强制转换后,一定能保证信息不丢失,因此在这里需要对其进行勘误。 */
    if(ret >=(int)&sums[2] - (int)&sum[1])
        ret =(int)&sums[2] - (int)&sum[1];
    return ret;          // 返回所占字节数
}

二、变量溢出法

分析

申请一个整形变量,赋初值为0,对其进行累加,观察它什么时候数据溢出,通过这样也可以计算出一个整形所占用的位数。

源代码

#include<stdio.h>
#include<math.h>
int calculate();                // 判断整形所占字节数
int main()
{
    // 输出整形所占位数,第一位表示正负号
    printf("本台计算机整形所占位数为:%d\n", calculate()+1);
    return 0;
}
int calculate()
{
    int sum = 0;       // 用来累加的整形变量
    double really = 0; // 用来比较判断是否溢出

    // 判断溢出
    whlie ((double)sum == really)
    {
    // 若无溢出,依次累加
        sum++;
        really++;
    }
    sum=log(really)/log(2.0); // 求出所占位数
    return sum;
}

总结

上述两种方案都比较讨巧,其中第一种是非常推荐的,无论对于时间复杂度还是空间复杂度,都有较好的节约。
第二种算法虽然方便理解,但是耗时长,并不推荐。

你可能感兴趣的:(算法,腾讯-校招)