c语言休眠函数 vs,编纂C语言跨平台函数(以清屏和休眠函数为例)

编写C语言跨平台函数(以清屏和休眠函数为例)

支持C语言的平台有许多,常见的编译器如VC、gcc、Clang等。不同的编译器共同点是都支持标准C(ANSI C),但是各自却又有自己独立的、平台相关的功能以及函数接口。这通常为程序的移植性带来很多问题。这里我简单谈一下解决方案。

常见思路

常见的解决跨平台移植的思路就是利用 宏。不同编译器有各自不同的宏,宏有很多,具体可以参考编译器的相关手册。通过判断一个宏是否存在来选择性的包含头文件或调用函数,其本质就是一种条件编译。

比如一些平台相关的函数,在不同平台要包含不同文件。

#if defined __GNUC__

#include

#elif defined _MSC_VER

#include

#endif

#if defined 在本例中也可以用#ifdef 替换,但是如果是复杂的条件编译(比如if后面同时判断多个宏),就只能用#if defined 实现了。

__GNUC__是在gcc编译器中定义的宏,_MSC_VER是Windows中VC编译器中的宏。当然了你还可以选择这两个编译器中的其他宏来实现这一功能,只要能确保是两个编译器中平台相关的宏就行。

_MSC_VER这个宏还能判断VC的版本。比如:

#if defined(_MSC_VER) && (_MSC_VER >= 1200)

...

它的意思是如果VC的版本大于VC 6.0,那么...

该宏的详细参考,很容易百度到:

MS VC++ 12.0 _MSC_VER = 1800 (Visual C++ 2013)

MS VC++ 11.0 _MSC_VER = 1700 (Visual C++ 2012)

MS VC++ 10.0 _MSC_VER = 1600(Visual C++ 2010)

MS VC++ 9.0 _MSC_VER = 1500

MS VC++ 8.0 _MSC_VER = 1400

MS VC++ 7.1 _MSC_VER = 1310

MS VC++ 7.0 _MSC_VER = 1300

MS VC++ 6.0 _MSC_VER = 1200

MS VC++ 5.0 _MSC_VER = 1100

跨平台函数的栗子

清屏函数

同样的思路。我们也可以把条件编译用在函数内部。比如要实现控制台的清屏功能,VC中的通常做法是这条语句system("cls");调用控制台的cls命令来清屏。而Linux环境下,给终端清屏是没有cls这一命令的,取而代之的是clear命令。那么如何实现跨平台的清屏功能呢?很简单,依样画葫芦:

void clear()

{

#ifdef __GNUC__

system("clear");

#elif defined _MSC_VER

system("cls");

#endif

}

这样就有了跨平台的清屏函数clear。但是其实关键都是system函数,两个平台都提供这个函数(system是标准 C里面的函数)。所以可以再改一版。

#if defined __GNUC__

char *clear = "clear";

#elif defined _MSC_VER

char *clear = "cls";

#endif

...

//当需要清屏的时候

system(clear);

休眠函数

无论是gcc还是VC都有休眠函数,不过具体函数接口却不同。

编译器

头文件

函数名

参数类型

描述

VC

windows.h

Sleep

unsigned

参数为要休眠的毫秒数

gcc

unistd.h

sleep

unsigned

参数为要休眠的秒数

gcc

unistd.h

usleep

unsigned

参数为要休眠的微秒数

可见,两种环境下的休眠函数的函数名并不相同。并且gcc的两个sleep函数并没有没有提供毫秒级的分辨率。也就是说,比如要休眠200毫秒:

Windows中:Sleep(200);

Linux中:usleep(200000);

1秒=1000毫秒,1毫秒=1000微秒

那么来实现一下跨平台的休眠功能,我提供一种我的方案:

#if defined __GNUC__

#include

#define Sleep(x) usleep(x##000)

#elif defined _MSC_VER

#include

#endif

这样即使在gcc的编译环境下,我们也有和VC中一样的Sleep函数可以用了。这里我是用宏函数来实现的。#define

Sleep(x) usleep(x##000) ##是宏定义里面的连接符,这样就默认给参数后面多加了三个0,即扩大了1000倍。

gcc 的宏连接符(##)后面不支持连接+ - * /,所以不能写成

#define Sleep(x) usleep(x##*1000)

不过VC支持##后面接+ - * /符号。

掷骰子游戏

现在,来综合一下刚才的两个函数:清屏和休眠。写一个掷骰子小游戏的demo。

#include

#include

#include

#ifdef __GNUC__

#include

char *clear = "clear";

#endif

#ifdef _MSC_VER

#include

char *clear = "cls";

#endif

int a[3];

//判断是否为顺子

int isShunzi()

{

int max=a[0],min=a[0],sum=a[0];

for(int i=1;i<3;i++)

{

if(a[i]>max)

max=a[i];

if(a[i]

min=a[i];

sum+=a[i];

}

int mid=sum-max-min;

if(mid-min==1&&max-mid==1)

return 1;

return 0;

}

int main()

{

srand((unsigned)time(NULL));

int t=40;//随机40次后结束

while(t--)

{

Sleep(200);

system(clear);

a[0] = rand()%6+1;

a[1] = rand()%6+1;

a[2] = rand()%6+1;

printf("骰子1的点数为:%d\n",a[0]);

printf("骰子2的点数为:%d\n",a[1]);

printf("骰子3的点数为:%d\n",a[2]);

}

if(a[0]==a[1]&&a[0]==a[2])

printf("您掷出的是豹子\n");

else if(isShunzi())

printf("您掷出的是顺子\n");

else if(a[0]+a[1]+a[2]>=11)

printf("您的点数是大\n");

else

printf("您的点数是小\n");

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值