2014-08-29 69 views
2

我正在學習從編程2D遊戲編程C++遊戲,我有一個基本的WinMain程序如下所示,但本書說使用兩個默認標籤。不過,我的IDE(VS2013)告訴我,交換機中已經出現了默認標籤。C++中的開關中只能有一個默認值?

有沒有解決這個問題的方法,或者我在交換機內犯了一個錯誤?我已經與該書交叉引用,但我無法找到任何有關此信息。

#define WIN32_LEAN_AND_MEAN 
#include <windows.h> 
// Function prototypes 
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int); 
bool CreateMainWindow(HINSTANCE, int); 
LRESULT WINAPI WinProc(HWND, UINT, WPARAM, LPARAM); 
// global variable 
HINSTANCE hinst; 
HDC hdc;    // Handle to device context 
TCHAR ch = ' ';   // Character entered 
RECT rect;    // Rectangle structure 
PAINTSTRUCT ps;   // Used in WM_PAINT 
// Constants 
const char CLASS_NAME[] = "Keyboard"; 
const char APP_TITLE[] = "Character Input"; 
const int WINDOW_WIDTH = 400; 
const int WINDOW_HEIGHT = 400; 
//================================== 
// Starting point for the windows application 
// Parameters are 
// hInstance. Handle to the current instance of the application 
// hPrevInstance. Always NULL, obsolete parameter 
// lpCmdLine. Pointer to null-terminated string of command arguements 
// nCmdShow. Specifies how the window is to be shown 
//================================= 

int WINAPI WinMain(HINSTANCE hInstance, 
    HINSTANCE hPrevInstance, 
    LPSTR  lpCmdLine, 
    int   nCmdShow) 

{ 
    MSG msg; 
    // Create thw window 
    if (!CreateMainWindow(hInstance, nCmdShow)) 
     return false; 
    // Main message loop 
    int done = 0; 
    while (!done) 
    { 
     // PeekMessage is a non blocking message for Windows messages 
     if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
     { 
      // Look for quit message 
      if (msg.message == WM_QUIT) 
       done = 1; 
      // Decode and pass messages on to WinProc 
      TranslateMessage(&msg); 
      DispatchMessage(&msg);  

     } 

    } 
    return msg.wParam; 

} 

//============== 
// Window event callback function 
// =============================== 
LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 
     { 
    switch (msg) 
    { 
    case WM_DESTROY: 
      //Tell windows to kill this program 
      PostQuitMessage(0); 
      return 0; 
    case WM_CHAR:  // A character was entered by the keyboard 
     switch (wParam); // The character is in wParam 
     { 
     case 0x08: //Backspace 
     case 0x09: // Tab 
     case 0x0A: // Linefeed 
     case 0x0D: // Carriage return 
     case 0x1B: // Escape 
      MessageBeep((UINT) -1);   // Beep but do not display 
      return 0; 
     default:   // Displayable character 
      ch = (TCHAR) wParam;  // Get the character 
      InvalidateRect(hWnd, NULL, TRUE); // Force WM_PAINT 
      return 0; 
     } 
     case WM_PAINT:     // The window needs to be redrawn 
      hdc = BeginPaint(hWnd, &ps); // Get handle to device context 
      GetClientRect(hWnd, &rect);  // Get the window rectangle 
      // Display the character 
      TextOut(hdc, rect.right/2, rect.bottom/2, &ch, 1); 
      EndPaint(hWnd, &ps); 
      return 0; 
     default: 
      return DefWindowProc(hWnd, msg, wParam, lParam); 
     } 


} 
//=========================================== 
// Create the window 
// Returns: False on error 
//=========================================== 
bool CreateMainWindow(HINSTANCE hInstance, int nCmdShow) 
{ 
    WNDCLASSEX wcx; 
    HWND hwnd; 

    // Fill in the window class structure with parameters 
    // That describe the main window 
    wcx.cbSize = sizeof(wcx);    // Size of the structure 
    wcx.style = CS_HREDRAW | CS_VREDRAW; // Redraw if the size changes 
    wcx.lpfnWndProc = WinProc;    // Points to windows procedure 
    wcx.cbClsExtra = 0;      // No extra class memory 
    wcx.cbWndExtra = 0;      // No extra window memory 
    wcx.hInstance = hInstance; 
    wcx.hIcon = NULL; 
    wcx.hCursor = LoadCursor(NULL, IDC_ARROW);  // Predifined arrow 
    // Background brush 
    wcx.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); 
    wcx.lpszMenuName = NULL; // Name of menu resource 
    wcx.lpszClassName = CLASS_NAME; // Name of window class 
    wcx.hIconSm = NULL; 

    // Register the window class 
    // RegisterClassEx return 0 on error 
    if (RegisterClassEx(&wcx) == 0) // if error 
     return false; 
    // Create Window 
    hwnd = CreateWindow(
     CLASS_NAME,      // Name of window class 
     APP_TITLE,      // Title bar text 
     WS_OVERLAPPEDWINDOW,   // Window style 
     CW_USEDEFAULT,     // Default horizontal postion of window 
     CW_USEDEFAULT,     // Default vertical postion of window 
     WINDOW_WIDTH,     // Width of window 
     WINDOW_HEIGHT,     // Height of window 
     (HWND) NULL,     // No parent window 
     (HMENU) NULL,     // No menu 
     hInstance,      // Handle to application window 
     (LPVOID) NULL);     // No window parameters 
    // If there was an error the window 
    if (!hwnd) 
     return false; 
    // Show the window 
    ShowWindow(hwnd, nCmdShow); 
    // Send a WM_PAINT message to the window procedure 
    UpdateWindow(hwnd); 
    return true; 
} 
+0

首先,不能在switch語句2默認情況。第二,你給出的代碼顯示了嵌套開關,所以每個開關都有它自己的默認情況,這是沒問題的。 – Arpit 2014-08-29 16:21:21

+1

有些人剛剛幫助我瞭解到,現在它非常有意義,但在此之前我沒有問過它。 – PapaSmurf 2014-08-29 16:36:29

+0

沒有支架的開關會咬你。看起來你在正確的軌道上。很高興聽到有人拿起'C++',我很好奇你是如何選擇的?鑑於高級語言的普及,很高興看到人們仍然接近金屬。 – Ternary 2014-08-29 16:43:10

回答

9

根據switch聲明,您只能有一個default:。但是,您可以將switch聲明放入另一個switch聲明中,然後每個聲明都可以有default:大小寫。

switch (var1) 
{ 
    case 1: 
    break; 
    case 2: 
    { 
     switch (var2) 
     { 
      case 1: 
      break; 
      case 3: 
      break; 
      default: // var1 is 2, and var2 is not 1 or 3 
      break; 
     } 
    } 
    break; 
    default: // var1 is not 1 or 2 
    break; 
} 

你的代碼幾乎是嵌套switch陳述這樣,但你犯了一個錯誤:

​​

不應該有分號;。 A switch適用於緊接在)之後的一個語句,並且您幾乎總是希望該語句成爲「複合語句」,即由{}包圍的塊。相反,這switch適用於執行無效聲明;

+0

謝謝,這很清楚,我現在明白我的錯誤。 – PapaSmurf 2014-08-29 16:32:05

7

您在這裏有一個錯字:

switch (wParam); // semicolon shouldn't be there 
{ 
    //... 
} 

分號形成內部開關的機構,其意圖身體變得外部交換機的一部分。這會導致錯誤,因爲兩者都包含default分支。

0

交換機中不能有多個默認語句。從語義上講,它無論如何都是沒有意義的。

交換機將通過案例來查找匹配的案例,然後從那裏開始執行。如果達到默認情況,任何仍然存在的執行路徑(未與案例匹配)將從此處開始執行。任何將在交換機中稍後匹配的情況都將在執行中。

考慮以下幾點:

char my_case = /*(some value)*/ ; 
switch (my_case) { 
    case 'a': 
     cout << "a case\n"; 
    case 'b': 
     cout << "b case\n"; 
     break; 
    default: 
     cout << "DEFAULT\n"; 
    case 'c': 
     cout << "c case"; 

    default: 
     cout << "DEFAULT 2\n"; 
} 

my_case下列值以下輸出會導致:

// my_case = a 
a case 
b case 

// my_case = b 
b case 

// my_case = c 
DEFAULT 
c case 
DEFAULT 2 

// my_case = d 
DEFAULT 
c case 
DEFAULT 2