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;
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;
cout<<"32bits"<<endl;
}
使用
g++ -m64 testSysDigits.cpp -o a64.out
编译执行输出:
&a:0x7fffcc84b650