Ngôn ngữ lập trình C

Môi trường lập trình C

Môi trường phát triển ứng dụng bằng ngôn ngữ C rất đa dạng và phong phú, bạn nên dựa trên nhu cầu thực tế của bản thân để cài đặt và cấu hình môi trường phát triển sao cho phù hợp.

  1. Trình biên dịch - Compiler

    Trình biên dịch chịu trách nhiệm dịch mã nguồn (các tập tin *.c, *.h) thành mã máy để CPU có thể hiểu được, đây là thành phần bắt buộc phải có trong môi trường phát triển. Để phát triển ứng dụng bằng ngôn ngữ C, bạn có thể sử dụng các trình biên dịch sau đây.

    1. Hệ điều hành Linux/macOS

      • gcc - GNU Compiler Collection: Trình biên dịch tiêu chuẩn và rất phổ biến.
      • clang - LLVM: Trình biên dịch hiện đại có tốc độ biên dịch nhanh, hỗ trợ đa nền tảng.
    2. Hệ điều hành Windows

      • MSVC - Microsoft Visual C++: Trình biên dịch mặc định của Visual Studio, tối ưu cho Windows.
      • MinGW-w64: Trình biên dịch được tạo ra bằng cách chuyển đổi gcc từ Linux sang Windows.
      • clang - LLVM: Trình biên dịch hiện đại có tốc độ biên dịch nhanh, hỗ trợ đa nền tảng.

    Trong thực tế, phần lớn các IDE thường tích hợp sẵn trình biên dịch khi cài đặt, ví dụ như : Turbo C / Turbo C++, Dev-C++, Code::Blocks, Visual Studio, v.v. Do đó nếu bạn sử dụng các IDE này không cần cài đặt thêm trình biên dịch nữa.

    Trường hợp bạn sử dụng IDE hoặc công cụ không tích hợp sẵn trình biên dịch (ví dụ như Visual Studio Code), bạn cần tích hợp thêm trình biên dịch.

  2. Linker và Build system

    1. Trình liên kết - Linker

      Kết quả của quá trình biên dịch là các tập tin dạng *.o hoặc *.obj, trình liên kết có nhiệm vụ ghép các tập tin này với nhau để tạo thành một chương trình duy nhất, hoàn chỉnh và có thể thực thi được (*.EXE, *.ELF, *.Mach-O).

      Các trình liên kết phổ biến: ld (GNU), lld (LLVM), link.exe (MSVC).

      Trình liên kết luôn đi kèm với trình biên dịch (gcc đi kèm ld, clang thường dùng lld hoặc ld hệ thống, MSVC đi kèm link.exe), do đó bạn không cần phải cài đặt trình liên kết riêng rẽ.

    2. Build system

      Build system là công cụ có nhiệm vụ tự động hóa biên dịch nhiều tập tin, quản lý dependencies, hỗ trợ build cross-platform.

      • CMake: Công cụ phổ biến, được xem như tiêu chuẩn cho dự án C/C++.
      • Make: Công cụ truyền thống, thường dùng trên Unix/Linux.
      • Meson: Công cụ hiện đại với cú pháp đơn giản, có thể kết hợp với Ninja để gia tăng tốc độ.
  3. Trình soạn thảo - Editor

    Trình soạn thảo cung cấp môi trường để bạn viết mã nguồn, bạn có thể sử dụng bất kỳ trình soạn thảo văn bản nào ví dụ như notepad++, Sublime Text, Vim / Neovim, Emacs, v.v.

    Trong thực tế, mỗi IDE đều tích hợp sẵn một trình soạn thảo, cho phép bạn viết mã nguồn trực tiếp trong môi trường làm việc; đồng thời bổ sung nhiều tính năng giúp bạn lập trình nhanh chóng, dễ dàng và hạn chế lỗi.

  4. Gỡ lỗi & phân tích

    1. Trình gỡ lỗi - Debugger

      Trình gỡ lỗi là công cụ cho phép lập trình viên thiết lập các điểm dừng (breakpoint); chạy chương trình từng bước; quan sát trạng thái cũng như giá trị của biến, thanh ghi, ngăn xếp (stack). Đây là công cụ đặc biệt hiệu quả giúp lập trình viên xác định chính xác dòng mã gây lỗi.

      gdb - GNU Debugger: gdb là công cụ gỡ lỗi thường đi kèm gcc, được sử dụng trên Linux, macOS hoặc Windows (qua MinGW/MSYS2). gdb hỗ trợ đặt breakpoint, in giá trị biến, theo dõi call stack.

      lldb - LLVM Debugger: lldb là công cụ hiện đại của gdb, tốc độ cao, thông báo dễ hiểu, thường đi kèm clang và là công cụ gỡ lỗi mặc định trên macOS (tích hợp sẵn trong Xcode).

      Visual Studio Debugger: Visual Studio Debugger được tích hợp trực tiếp trong IDE Visual Studio, có giao diện trực quan (watch variables, autos, locals, call stack).

    2. Phân tích hiệu năng - Profiling

      Profiling là công cụ giúp xác định các thành phần của chương trình tốn nhiều CPU, bộ nhớ, hoặc gây nghẽn hiệu năng. Một số công cụ phổ biến: Valgrind/Callgrind (Linux), Perf (Linux), Instruments (macOS).

  5. Các thành phần khác

    • Công cụ định dạng và phân tích mã nguồn: clang-format, clang-tidy, cppcheck.
    • Công cụ kiểm thử: Unity, CMocka, Check.
    • Công cụ quản lý thư viện: vcpkg (MSVC/clang/gcc), Conan.
  6. Cài đặt và cấu hình môi trường phát triển

    Như đã trình bày bên trên, có nhiều công cụ hỗ trợ phát triển ứng dụng bằng ngôn ngữ C. Để quyết định sử dụng công cụ gì bạn cần xem xét nhiều yếu tố, có thể kể đến như:

    • Đặc điểm của dự án và mục tiêu triển khai.
    • Chức năng soạn thảo, biên dịch, gỡ lỗi, kiểm thử và triển khai cũng như khả năng tự động hóa các công việc đó.
    • Khả năng tích hợp với công nghệ khác.
    • Khả năng mở rộng và bảo trì ứng dụng.
    • Hiệu suất và tài nguyên hệ thống.
    • Chuẩn hóa trong nhóm hoặc tổ chức.
    • Năng lực và trình độ chuyên môn của nhân sự tham gia dự án.

    Khóa học này có mục tiêu là tìm hiểu ngôn ngữ lập trình C và hướng tới các bạn bắt đầu học lập trình, do đó chúng ta sẽ dùng Visual Studio Code kết hợp với trình biên dịch MinGW-w64; Các chuyên đề cụ thể chúng tôi sẽ có hướng dẫn riêng. Dưới đây là hướng dẫn các bước cài đặt và cấu hình môi trường.

    1. Cài đặt Visual Studio Code

      Tham khảo cài đặt tại Hướng dẫn cài đặt Visual Studio Code.

    2. Cài đặt và cấu hình MinGW-w64

      Có nhiều phương pháp cài đặt và cấu hình MinGW-w64, ở đây chúng ta dùng WinLibs. Bạn có thể tải WinLibs từ internet hoặc theo liên kết WinLibs.

      Giải nén tập tin tải về sau đó sao chép thư mục mingw64 vào thư mục lưu trữ WinLibs, ví dụ là C:\winlibs.

      Thiết lập biến môi trường

      • Mở cửa sổ Run (Nhấn tổ hợp phím Window + R), nhập lệnh sysdm.cpl rồi enter.
      • Chọn Tab Advanced\Environment Variables...
      • Ở phần System variables, tìm biến Path và nhấp Edit...
      • Nhấp New và thêm dòng C:\winlibs\mingw64\bin (chính là đường dẫn tới thư mục lưu trữ WinLibs bên trên).
      • Nhấp OK để lưu.
    3. Cấu hình dự án

      Tạo thư mục của dự án, giả sử là LearnC.

      Khởi động Visual Studio Code, cài đặt extension C/C++ (by Microsoft).

      Mở thư mục dự án (LearnC), bên trong thư mục dự án tạo các thư mục như hình dưới đây

      Learn C Language
      • \.vscode: Thư mục chứa các tập tin cấu hình của dự án.
      • \include: Thư mục chứa các tập tin khai báo nguyên mẫu của hàm (function prototype), macro, cấu trúc, biến toàn cục, hằng số, v.v.
      • \src: Thư mục chứa các tập tin mã nguồn (implementation) của chương trình.
      • \build: Thư mục chứa các tập tin được sinh ra sau khi biên dịch bao gồm các tập tin *.obj (hoặc *.o), *.exe (hoặc *.out).

      Bên trong thư mục .vscode, tạo tập tin tasks.json với cấu hình như sau:

      
      	{
      		"version": "2.0.0",
      		"tasks": [
      			{
      				"label": "Build LearnC",
      				"type": "shell",
      				"command": "gcc",
      				"args": [
      				"-g",
      				"src/*.c",
      				"-Iinclude",
      				"-o",
      				"build/LearnC"
      				],
      				"group": {
      				"kind": "build",
      				"isDefault": true
      			},
      				"problemMatcher": ["$gcc"]
      			}
      		]
      	}
      	

      Bên trong thư mục .vscode, tạo tập tin launch.json với cấu hình như sau:

      
      	{
      		"version": "0.2.0",
      		"configurations": [
      			{
      				"name": "Debug LearnC",
      				"type": "cppdbg",
      				"request": "launch",
      				"program": "${workspaceFolder}/build/LearnC.exe",
      				"args": [],
      				"stopAtEntry": false,
      				"cwd": "${workspaceFolder}",
      				"environment": [],
      				"externalConsole": true,
      				"MIMode": "gdb",
      				"miDebuggerPath": "C:/winlibs/mingw64/bin/gdb.exe",
      				"setupCommands": [
      					{
      						"description": "Enable pretty-printing for gdb",
      						"text": "-enable-pretty-printing",
      						"ignoreFailures": true
      					}
      				],
      				"preLaunchTask": "Build LearnC"
      			}
      		]
      	}
      	

      Bên trong thư mục .vscode, tạo tập tin c_cpp_properties.json với nội dung như sau (Chú ý kiểm tra đường dẫn và thư mục phù hợp với cấu hình của bạn).

      
      	{
      		"configurations": [
      			{
      				"name": "Win64",
      				"includePath": [
      				"${workspaceFolder}/include",
      				"C:/winlibs/mingw64/include",
      				"C:/winlibs/mingw64/lib/gcc/x86_64-w64-mingw32/14.2.0/include"
      				],
      				"defines": [],
      				"compilerPath": "C:/winlibs/mingw64/bin/gcc.exe",
      				"cStandard": "c11",
      				"intelliSenseMode": "windows-gcc-x64"
      			}
      		],
      		"version": 4
      	}
      	

      Kiểm tra kết quả sau khi cấu hình

      • Bên trong thư mục src, tạo tập tin main_thread.c với mã nguồn như sau:
      • 
            /*--------------------------------------------
            *Project: Learn C
            *Version 1.0
            *Author: hoctotlamhay.vn
            *Description: Entry point (Main thread)
            --------------------------------------------*/
            #include <stdio.h>
            int main() {
                printf("Hello, welcome to hoctotlamhay.vn!\n");
                return 0;
            }
            
      • Biên dịch ứng dụng: Nhấn tổ hợp phím Ctrl + Shift + B, nếu biên dịch thành công bạn sẽ thấy tập tin LearnC.exe trong thư mục \LearnC\build.