又一本市圖借書,限時歸還,讀完不佔空間的課外讀物~

thumbnail

上回寫 Arduino 打卡鐘程式光研究 byte[] 轉成 16 進位字串就花了我一個小時,非常汗顏,C 語言的陣列跟指標一直是我的阿基里斯腱,每次只要看到 char*[] p、char[]* p、&p、**p 腦袋就打結。無意在圖書館看到這本快快樂樂系列,應是老天爺的安排,決定給自己機會雪恥。

學電腦語言怎能不實機練習?用 Visual Studio 寫 C++ 體驗絕對是頭等艙等級,但過於笨重擁腫,來用 Visual Studio Code 好了。VSCode 寫 C 需要另外安裝編譯器軟體及套件,步驟稍多,但其輕巧敏捷還是值回票價。在網路找到這篇:使用 VSCode 編譯並執行 C/C++ 語言,照方煎藥即可完成環境設定。

安裝、設定與使用重點摘要如下:

  1. 安裝MinGW (Minimalist GNU fro Windows,將 GCC 與 GNU Binutils 移植到 Windows 平台,比 Cygwin 輕巧效能好)
  2. 安裝LLVM (編譯器基礎環境)
    包含 Clang (發音為/ˈklæŋ/),為 C/C++/Objective-C 的編譯器前端,使用 LLVM 作為編譯器後端,目標在成為 GCC 替代品。
  3. 安裝編輯、編譯與執行所需的擴充套件:
    • C/C++ (Intellisense 語法提示、偵錯)
    • C/C++ Clang Command Adapter (提供 Clang語法自動完成)
    • Code Runner (程式執行工具,直譯式語言甚至可選取特定程式碼按右鍵選單執行)
  4. 建立專案資料夾,在其下建立 .vscode 資料夾(以 . 起始的資料夾不能用檔案總管建立,需改用 DOS/Cmder 視窗 mkdir .vscode)
  5. 在 .vscode 放入 c_cpp_properties.json、launch.json、settings.json、tasks.json 等內容
  6. 專案資料夾右鍵選單執行「Open with code」或在命令列視窗執行 code . 啟動 VSCode,開始在專案資料夾編輯 .c 或 .cpp 程式檔
  7. 按視窗右上的箭頭圖示執行:(按 Ctrl-Alt-N 亦可,但在我的電腦與 Evernote 快速鍵衝突)
  8. 可設中斷點、Line By Line 偵錯、滑鼠滑過時會顯示變數內容,偵錯功能強大,VSCode 不負 Visual Studio 的威名。

順利搞定開發環境,隨手附上我的指標與陣列程式練習範例,希望以後遇到 C 語言的指標不再手腳發軟:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void test1() {
    //兩種陣列宣告方式
    int a1[4] = {1, 2, 3, 4};
    int a2[] = {1, 2, 3, 4};
    //字串
    char s1[] = "ABC";
    //記得尾端要放\0
    char s2[4] = {'A', 'B', 'C', '\0'};
}

void test2() {
    char s1[] = "ABC";
    //字串函式,需#include <string.h>
    
    //取得字串長度
    int l = strlen(s1); 
    
    //複製字串
    char s2[6]; //需預先算好長度
    strcpy(s2, "Hello"); 
    
    //字串相接
    char s3[6] = "ABC"; //需預留串接後長度
    char s4[] = "DE";
    strcat(s3, s4);

    //字串比較
    char s5[] = "ABC";
    char s6[] = "ABCD";
    int c = strcmp(s5, s6); 
    //s5==s6時c為0, s5<s6時c<0,s5>s6時c>0

    //數值轉字串
    char s7[40];
    sprintf(s7, "%f", 3.1416);

    //字串轉數值
    char s8[] = "32767";
    int n = atoi(s8);
}

void test3() {
    //指標的兩種宣告寫法
    char* p1;
    char *p2;
    char a = 'A';
    p1 = &a; //指派位址
    printf("%c", *p1); //指向變數內容時寫*p
    //明確表示不指向任何地方時,用NULL
    char *p3 = NULL;
    //檢查是否為空 if (p != NULL), if (!p)

}

void test4() {
    //指標與陣列
    int a[4] = {1, 2, 3, 4};
    int *i = a + 1;
    printf("*i=%d\n", *i); //得到2
    //加1並不是移動一個Byte,而是一個int的長度(sizeof(int))
    printf("*(i+1)=%d\n", *(i+1)); //得到3
    //i++亦可向後移一個元素
    i++;
    printf("*i=%d after i++\n", *i);
}

void test5() {
    //動態配置記憶體
    short *buf;
    //相當於宣告1000個short陣列
    buf = (short *)malloc(sizeof(short) * 1000);
    buf[20] = 40;
    printf("%d\n", buf[20]);
    //使用完要記得釋放(沒有GC幫忙,一切自己來)
    free(buf);

    //calloc初始化並設為0
    buf = (short *)calloc(100, sizeof(short));
    printf("%d\n", buf[5]);

    //realloc重新配置大小
    buf = (short *)realloc(buf, sizeof(short) * 10);
}

void test6() {
    char *b;
    char a[4] = {1, 2, 3, 4};
    b = (char *)malloc(sizeof(char) * 200);
    if (!b)
        return; //無法配置記憶體時不繼續,以後Crash
    memcpy(b, a, sizeof(char) * 4);
    printf("%d\n", b[2]); //得到3
    free(b);
    //另外有memset(buff, value, count)從buff位址填入count個value
}

int main() {
    test6();
    return 0;
}

Notes of installing WinGW, LLVM and VSCode packages on Windows to write C program.


Comments

# by jk

Windows下用gcc開發的話,也可以考慮Windows Subsystem for Linux,只是目前想跟vscode一起用的話會有點難搞,要搭配X Window

Post a comment


19 + 8 =