程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> 關於C >> 編寫C語言跨平台函數(以清屏和休眠函數為例)

編寫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]=11)
              printf("您的點數是大\n");
          else
              printf("您的點數是小\n");
      
      }
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved