---
# System prepended metadata

title: Hello World 旋轉

---

# Hello World 旋轉

![2025-09-08 230013](https://hackmd.io/_uploads/BJQbWuhqex.gif)

## 前置
### 1.打開vscode
![螢幕擷取畫面 2025-09-08 231612](https://hackmd.io/_uploads/SJYU7_n5gg.png)

### 2.開啟任意資料夾
![螢幕擷取畫面 2025-09-08 231731](https://hackmd.io/_uploads/Hyes7uhcgg.png)

### 3.點擊信任
![螢幕擷取畫面 2025-09-08 231902](https://hackmd.io/_uploads/BJLM4On9lg.png)

### 4.創建檔案test.c(檔名隨意)
![螢幕擷取畫面 2025-09-08 232011](https://hackmd.io/_uploads/SkF4Eu3cle.png)

## 詳細步驟
### 1.先寫出基礎的Hello, World!

```c
int main() {
    printf("Hello, World!");
    return 0;
}
```
記得按CTRL+S儲存檔案之後再點擊右上方的執行
![螢幕擷取畫面 2025-09-08 232331](https://hackmd.io/_uploads/HJBWBu39le.png)
![螢幕擷取畫面 2025-09-08 232710](https://hackmd.io/_uploads/HJEJ8d35ee.png)
然後你會發現報錯了，因為系統不知道`printf`是什麼
所以我們要加上一個函式庫`<stdio.h>`(標準輸入輸出)
```c
#include <stdio.h>

int main() {
    printf("Hello, World!");
    return 0;
}
```
:::warning
:warning: `return 0` 表示程式結束，有時候不加不會報錯，但加了一定不會錯
:::

### 2.開始寫各種函式
為了程式碼的簡潔，如果是會多次使用到的「同一段程式邏輯」，就會寫成函式。(`printf`也是一個函式)

* 隱藏游標的函式
為了讓輸出畫面沒有多餘的游標
```c
#include <windows.h>

void hideCursor() {
    CONSOLE_CURSOR_INFO cursorInfo;
    GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
    cursorInfo.bVisible = FALSE;
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
}
```
* 清除畫面的函式
每一次的閃爍其實都是清除畫面再輸出內容，避免和上一次重疊或干擾
```c
#include <stdlib.h>

void clearScreen() {
    system("cls");
}
```
* 繪製旋轉的文字
這裡就是統一用來計算旋轉弧度以及輸出文字的函式
```c
void drawRotatedText(char* text, int centerX, int centerY, int angle) {
    int len = strlen(text);  // 計算文字長度
    double radian = angle * 3.14159 / 180.0;  // 將角度轉換為弧度
    
    // 逐個字元計算旋轉後的位置並顯示
    for (int i = 0; i < len; i++) {
        // 計算每個字元相對於中心點的偏移量
        // 讓字串的幾何中心作為旋轉中心
        double charOffset = (double)i - (double)(len - 1) / 2.0;
        
        // 增加字元間距，讓每個字元都有足夠的空間顯示
        double spacing = 1.5;  // 字元間距係數
        
        // 使用三角函數計算旋轉後的座標
        int x = centerX + (int)(charOffset * spacing * cos(radian));
        int y = centerY + (int)(charOffset * spacing * sin(radian));
        
        // 確保座標在螢幕範圍內（80x25 控制台）
        if (x >= 0 && x < 80 && y >= 0 && y < 25) {
            gotoxy(x, y);  // 移動游標到計算後的位置
            printf("%c", text[i]);  // 顯示原始字元
        }
    }
}
```
### 3.最後主程式的樣子
```c
int main() {
    char message[] = "Hello World";  // 要顯示的訊息
    int angle = 0;                   // 初始旋轉角度
    int centerX = 40;                // 螢幕中心 X 座標（80/2）
    int centerY = 12;                // 螢幕中心 Y 座標（25/2）
    
    hideCursor();  // 隱藏游標
    
    // 無限迴圈，持續顯示旋轉動畫
    while (1) {
        clearScreen();  // 清除螢幕
        drawRotatedText(message, centerX, centerY, angle);  // 繪製旋轉文字
        angle = (angle + 5) % 360;  // 每次增加 5 度
        Sleep(50);  // 暫停 50 毫秒
    }
    
    return 0;  // 程式結束
}
```

::: spoiler 完整code
```c=
// 標準輸入輸出函式庫
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#ifdef _WIN32
  #include <windows.h>
  #define CLEAR_SCREEN() system("cls")
  #define SLEEP_MS(ms) Sleep(ms)
  static void gotoxy(int x, int y) {
      COORD c; c.X = (SHORT)x; c.Y = (SHORT)y;
      SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
  }
  static void hideCursor(void) {
      CONSOLE_CURSOR_INFO ci;
      GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &ci);
      ci.bVisible = FALSE;
      SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &ci);
  }
  static void showCursor(void) {
      CONSOLE_CURSOR_INFO ci;
      GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &ci);
      ci.bVisible = TRUE;
      SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &ci);
  }
#else
  #include <unistd.h>
  #define CLEAR_SCREEN()  printf("\x1b[2J\x1b[H")   /* 清屏 + 游標回到左上 */
  #define SLEEP_MS(ms)    usleep((ms) * 1000)
  static void gotoxy(int x, int y) {
      /* ANSI 座標從 1 開始，且先列(行/y)後行(列/x) */
      printf("\x1b[%d;%dH", y + 1, x + 1);
      fflush(stdout);
  }
  static void hideCursor(void) { printf("\x1b[?25l"); fflush(stdout); }
  static void showCursor(void) { printf("\x1b[?25h"); fflush(stdout); }
#endif

/* 清除螢幕（包一層方便呼叫） */
static void clearScreen(void) { CLEAR_SCREEN(); }

/* 繪製旋轉的文字 */
static void drawRotatedText(const char* text, int centerX, int centerY, int angle) {
    int len = (int)strlen(text);
    double rad = angle * 3.14159265358979323846 / 180.0;

    for (int i = 0; i < len; i++) {
        double charOffset = (double)i - (double)(len - 1) / 2.0;
        double spacing = 1.5;
        int x = centerX + (int)(charOffset * spacing * cos(rad));
        int y = centerY + (int)(charOffset * spacing * sin(rad));

        /* 簡單限制在 80x25，若要自動讀取終端大小可再加強 */
        if (x >= 0 && x < 80 && y >= 0 && y < 25) {
            gotoxy(x, y);
            putchar(text[i]);
        }
    }
    fflush(stdout);
}

int main(void) {
    const char* message = "Hello World";
    int angle = 0;
    int centerX = 40; /* 80/2 */
    int centerY = 12; /* 25/2 */

    hideCursor();

    while (1) {
        clearScreen();
        drawRotatedText(message, centerX, centerY, angle);
        angle = (angle + 5) % 360;
        SLEEP_MS(50);
    }

    showCursor(); 
    return 0;
}

```
:::