C ติดตั้งเครื่องมือและคอมไพล์โปรแกรมแรก
เราต้องมีคอมไพเลอร์ ตัวหลักมี 2 ตัวคือ GCC (GNU) และ Clang (LLVM) — โค้ดในซีรีส์นี้ใช้ได้กับทั้งคู่
ติดตั้ง
Linux (Ubuntu/Debian):
sudo apt update
sudo apt install build-essential gdb valgrindbuild-essential มี gcc, make และไลบรารีมาตรฐาน
macOS:
xcode-select --installได้ clang (แต่พิมพ์ gcc ก็เรียก clang ให้)
Windows: ทางที่แนะนำที่สุดคือ WSL2 (wsl --install แล้วทำตามขั้น Ubuntu ด้านบน) เพราะบทหลัง ๆ ใช้ POSIX ทางเลือก: MSYS2 (pacman -S mingw-w64-ucrt-x86_64-gcc) หรือ MinGW-w64
เช็ค:
gcc --versiongcc (Ubuntu 13.2.0-23ubuntu4) 13.2.0โปรแกรมแรก
สร้างไฟล์ hello.c
#include <stdio.h>
int main(void)
{
printf("Hello, C!\n");
return 0;
}#include <stdio.h>— ดึงส่วนหัวของไลบรารี standard I/O เข้ามา (มีprintf)int main(void)— จุดเริ่มของโปรแกรม ทุกโปรแกรม C มีmainหนึ่งตัวvoidแปลว่าไม่รับ argumentprintf(...)— พิมพ์ข้อความ ต้องใส่\nเองถ้าอยากขึ้นบรรทัดใหม่return 0;— บอก OS ว่าโปรแกรมจบปกติ (ไม่ใช่ 0 = มีข้อผิดพลาด)
คอมไพล์และรัน
gcc hello.c -o hello
./helloHello, C!gcc hello.c— ไฟล์ต้นทาง-o hello— ตั้งชื่อไฟล์ผลลัพธ์ (ถ้าไม่ใส่ จะได้ชื่อa.out)./hello— รัน (ต้องมี./บอกว่าอยู่โฟลเดอร์ปัจจุบัน)
คอมไพเลอร์ทำอะไรบ้าง — 4 ขั้นตอน
hello.c
│ 1. Preprocess — จัดการ #include, #define, #if -> hello.i (โค้ด C ล้วน ๆ ที่ขยายแล้ว)
▼
│ 2. Compile — แปลงเป็นภาษา assembly -> hello.s
▼
│ 3. Assemble — แปลง assembly เป็นภาษาเครื่อง -> hello.o (object file)
▼
│ 4. Link — รวม hello.o กับ libc (ที่มี printf) -> hello (executable)
▼
helloดูแต่ละขั้นได้:
gcc -E hello.c # หยุดหลัง preprocess (พ่นออกจอ)
gcc -S hello.c # ได้ hello.s
gcc -c hello.c # ได้ hello.o
gcc hello.o -o hello # link อย่างเดียวปกติเราสั่งบรรทัดเดียวให้ทำครบทั้ง 4 ขั้น แต่การรู้ว่ามีขั้นอะไรบ้างช่วยเข้าใจ error: error ตอน compile ต่างจาก error ตอน link (เช่น undefined reference to 'foo' = link หาฟังก์ชันไม่เจอ)
flag ประจำตัว — ใช้ทุกครั้ง
gcc -std=c17 -Wall -Wextra -g hello.c -o hello| flag | ทำอะไร |
|---|---|
-std=c17 | ตรึงมาตรฐานเป็น C ปี 2017 (หรือ c11) — ค่าเริ่มต้นของ gcc ต่างกันตามรุ่น (เก่า = gnu11/gnu17, gcc 15 = gnu23) เราตรึงไว้เพื่อให้ทุกบทเรียนสม่ำเสมอ |
-Wall | เปิดคำเตือนที่มีประโยชน์ (ไม่ใช่ “ทั้งหมด” อย่างที่ชื่อบอก) |
-Wextra | เปิดคำเตือนเพิ่มอีกชุด |
-g | ใส่ข้อมูล debug (ให้ gdb ใช้ได้) |
-O2 | เปิด optimization (ใช้ตอน build จริง ไม่ใช่ตอน debug) |
เปิด -Wall -Wextra แล้วแก้ทุก warning — warning ของ C มักชี้บั๊กจริง เช่น “ใช้ตัวแปรก่อน initialize”, “return type ไม่ตรง”
ตัวช่วยจับบั๊กหน่วยความจำ (บทที่ 15, 29):
gcc -std=c17 -Wall -Wextra -g -fsanitize=address,undefined hello.c -o helloลองทำให้ warning โผล่
#include <stdio.h>
int main(void)
{
int x;
printf("%d\n", x); // ใช้ x ที่ยังไม่ได้กำหนดค่า
return 0;
}gcc -O1 -Wall -Wextra hello.c -o hellohello.c:6:5: warning: 'x' is used uninitialized [-Wuninitialized]การตรวจ uninitialized ของ GCC ทำงานตอนวิเคราะห์ dataflow ของ optimizer — ต้องเปิด optimization อย่างน้อย -O1 ถ้าคอมไพล์ -O0 (ค่าเริ่มต้น) มักไม่เตือน และผลอาจต่างกันตามรุ่น compiler ด้วย ถ้าไม่ใส่ -Wall เลยก็เงียบสนิท แล้วโปรแกรมพิมพ์ค่าขยะออกมา — เครื่องมือที่จับได้แน่นอนกว่าคือ -fsanitize=memory (Clang) หรือ valgrind
รวบเป็น alias หรือ Makefile
พิมพ์ flag ทุกครั้งเหนื่อย — ตั้ง alias ชั่วคราว:
alias cc17='gcc -std=c17 -Wall -Wextra -g'
cc17 hello.c -o helloบทที่ 27 เราจะใช้ Makefile จัดการเรื่องนี้อย่างเป็นระบบ
เรื่องที่คนมักพลาด
- ลืม
./ตอนรัน — พิมพ์helloเฉย ๆ shell หาใน PATH ไม่เจอ ต้อง./hello - ไม่ใส่
-Wall -Wextra— พลาด warning ที่ชี้บั๊กจริง เปิดไว้เสมอ undefined reference to 'sqrt'ตอน link — ฟังก์ชันคณิตศาสตร์อยู่ใน libm ต้องเติม-lmท้ายคำสั่ง- แก้โค้ดแล้วรัน
./helloเลย โดยลืมคอมไพล์ใหม่ — ยังได้ผลลัพธ์เก่า ต้องgcc ...ก่อนทุกครั้ง gccบน Windows ไม่มี — ติดตั้ง WSL หรือ MSYS2 อย่าใช้ Dev-C++ / Turbo C ที่เก่ามาก- วางลำดับ flag ผิด — library (
-lm,-lfoo) ต้องมา หลัง ไฟล์ที่ใช้มัน
สรุป
- ติดตั้ง GCC/Clang:
build-essential(Linux),xcode-select --install(macOS), WSL (Windows) - คอมไพล์:
gcc file.c -o progแล้วรัน./prog - 4 ขั้น: preprocess → compile → assemble → link — error แต่ละขั้นต่างกัน
- ใช้
-std=c17 -Wall -Wextra -gทุกครั้ง และแก้ทุก warning -fsanitize=address,undefinedเพื่อจับบั๊กหน่วยความจำ
บทถัดไปว่าด้วยโครงสร้างโปรแกรม C ให้ละเอียด — #include, main, return, และ printf กับ format specifier