2018腾讯内部调岗面试试题1——使用C/C++但不能用sizeof判断操作系统是32位还是64位

2018上半年折腾了一回,想换个后台开发岗尝试锻炼一下自己,面了三个部门,将有关有意思的题目汇总记录下来,供大家参考。

题目:使用C/C++但不能用sizeof判断操作系统是32位还是64位。

解法一: 我们知道,C/C++中,32位系统下编译生成的程序,书写代码时,整形数值默认取值范围是-2^31至2^31-1,加上数值后缀L,表示长整型,取值范围也是-2^31至2^31-1,加上LL表示长长整型数值,取值范围是-2^63至2^63-1。64位系统下编译生成的64位程序(为什么指明说64位的程序,因为64系统下也可以编译生成32的位的程序),整型数值默认取值范围是-2^31至2^31-1,加上数值后缀L,表示长整型,取值范围也是-2^63至2^63-1,加上LL表示长长整型数值,取值范围是-2^63至2^63-1。所以根据数值后缀L可以判断系统是32位还是64位,实际上我们是利用最大值是否溢出情况来做判断,示例代码如下:

#include <iostream>
using namespace std;

int main()
{
        long  ldTmp=1L<<32;
        cout<<"sizeof(long):"<<sizeof(long)<<endl;
        cout<<"ldTmp:"<<ldTmp<<endl;
        if(ldTmp)
                cout<<"64 bits"<<endl;
        else
                cout<<"32 bits"<<endl;
}

使用g++ -m64 testSysDigits.cpp -o a64.out生成64位程序输出结果为:

sizeof(long):8
ldTmp:4294967296
64 bits

使用g++ -m32 testSysDigits.cpp -o a32.out生成32位程序输出结果为:

sizeof(long):4
ldTmp:0
32 bits

解法二: Linux环境下,可以根据GNU C库的头文件wordsize.h中定义的宏__WORDSIZE来判断。wordsize.h路径一般为/usr/include/bits/wordsize.h,其内容如下:

/* Determine the wordsize from the preprocessor defines.  */

#if defined __x86_64__
# define __WORDSIZE     64
# define __WORDSIZE_COMPAT32    1
#else
# define __WORDSIZE     32
#endif

判断代码如下:

#include <bits/wordsize.h>

#if __WORDSIZE == 64
char *size = "64bits";
#else
char *size = "32bits";
#endif

同样的方法,在limits.h头文件中,包含了头文件wordsize.h后,根据__WORDSIZE做了如下相关宏定义:

/* Maximum value an `unsigned long int' can hold.  (Minimum is 0.)  */
#  if __WORDSIZE == 64
#   define ULONG_MAX    18446744073709551615UL
#  else
#   define ULONG_MAX    4294967295UL
#  endif

所以,根据如下代码也可以判断程序是32位还是64位。

#include <limits.h>

#if ULONG_MAX==0xFFFFFFFFFFFFFFFFUL 
    #define LONG_IS64BIT
#else
    #define LONG_IS32BIT
#endif

解法三: 根据栈指针变量宽度来判断,感谢blitzhong同学的提示。对指针变量地址相减时,须将其转换为char*或无符号长整型(unsigned long),否则相减的结果为1,表示地址间隔内存放元素的个数。代码如下:

#include <iostream>
using namespace std;

int main()
{
        void* a;
        void* b;
        int scope=(char*)&a-(char*)&b;
        cout<<"&a:"<<&a<<endl;
        cout<<"&b:"<<&b<<endl;
        cout<<"scope:"<<scope<<endl;
        if(scope==8)
                cout<<"64bits"<<endl;
        else
                cout<<"32bits"<<endl;
}

使用g++ -m64 testSysDigits.cpp -o a64.out编译执行输出:

&a:0x7fffcc84b650
&b:0x7fffcc84b648
scope:8
64bits

使用g++ -m32 testSysDigits.cpp -o a32.out编译执行输出:

&a:0xffbb42e8
&b:0xffbb42e4
scope:4
32bits

如果网友有其他方法,也请留言告知,万分感谢!


参考文献

[1]Determining 32 vs 64 bit in C++

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏九彩拼盘的叨叨叨

JavaScript 数组练习题之实现

** 题 3:改变传入的数组,将数组中第 n(从 0 开始算 ) 个元素放到数组的开头 **

921
来自专栏数据小魔方

NoSQL学习笔记之——Redis基础

之前练习过一篇NoSQL之Mongodb基础的笔记,这一篇开始练习NoSQL系列的又一重要利器——Redis。 Redis是一个开源的,基于内存并可持久化的日志...

2826
来自专栏黑泽君的专栏

Java设计模式之单例设计模式

932
来自专栏与神兽党一起成长

根据xml配置校验bean

例子参考自官方文档,http://oval.sourceforge.net/u... 官方文档的xml配置有点过期了,一两个属性不合法。

1334
来自专栏LinkedBear的个人空间

唠唠SE的面向对象-06——单例模式 原

我们让之前写的Arrays工具类变成非静态的,但又只能保证有且只有一个Arrays的对象

763
来自专栏Java学习网

10个常见的 Java 错误及避免方法之第一集(后续持续发布)

当Java软件代码通过编译器运行时,会创建编译器错误消息。谨记编译器可能会针对一个错误抛出许多错误消息。所以得修复第一个错误并重新编译。这样做可以解决很多问题。

1083
来自专栏聊聊技术

原 初学ACM - 半数集(Half Se

3908
来自专栏沈唁志

深入解析PHP中array_merge函数的用法

1062
来自专栏文渊之博

小议隐式转换引起的问题

隐式转换(Implicit conversion) ,这个情况每个程序员都或多或少的遇到过,这里我结合实际情况简单描述下常见的问题以及如何解决并阐述下原理。 所...

1979
来自专栏mukekeheart的iOS之旅

Java程序员面试宝典——重要习题整理

1、下面程序的输出结果是() public class Test { public static void main(String[] arg...

2379

扫码关注云+社区