วิธีใช้ GCC กับภาษา C

วิธีการ Compile ภาษา C โดยใช้ Gnu GCC compilerในกรณีที่มีไฟล์ภาษา C หนึ่งไฟล์ สามารถ Compile ออกมาเป็นโปรแกรมได้โดยใช้คำสั่งตามนี้

ในกรณี Windows (compile เพื่อให้ output ออกมาเป็นไฟล์ exe)

gcc –o ชื่อโปรแกรม.exe ชื่อไฟล์..c

หรือ

gcc ชื่อไฟล์..c –o ชื่อโปรแกรม.exe

ในกรณี Linux (compile เพื่อให้ output เป็นไฟล์ที่ไม่ต้องมีนามสกุล หรือจะเป็นไฟล์ที่มีนามสกุล.out ก็ได้เช่นกัน)

gcc –o ชื่อโปรแกรม ชื่อไฟล์..c

หรือ

gcc –o ชื่อโปรแกรม.out ชื่อไฟล์..c

หรือ

gcc ชื่อไฟล์..c –o ชื่อโปรแกรม

หรือ

gcc ชื่อไฟล์..c –o ชื่อโปรแกรม.out

จะเห็นว่าสามารถสลับตำแหน่งการเรียงคำสั่งได้


ตัวอย่างเช่นถ้าเรามีไฟล์ helloworld.c

#include <stdio.h>

int main (void)
{
    printf("HELLO WORLD\n");
    return 0;
}

Compile helloworld.c ใน Windows

gcc –o helloworld.exe helloworld.c
helloworld.exe

Complie helloworld.c ใน Linux

gcc –o helloworld helloworld.c
./helloworld

ส่วนในกรณีที่ ไฟล์ C ของเรามีการ include header file เข้ามาด้วย เวลาใช้คำสั่ง gcc ก็ไม่ต้องสนใจไฟล์ header .h ให้เราทำการ compile แค่ไฟล์ .c ตามปกติ
ตัวอย่างเช่น
helloworld2.c

#include <stdio.h>
#include "helloworld2.h"

int main (void)
{
    printf("%s\n", HELLO);
    return 0;
}

helloworld2.h

#define HELLO "HELLO WORLD 2"

Complie helloworld.c ใน Windows

gcc –o helloworld2.exe helloworld2.c
helloworld2.exe

การเก็บ Code เก่าไว้ ในภาษา C

หากมีการแก้ไข Code บางส่วน แล้วเราต้องการที่จะเก็บ Code เก่าบางส่วนเอาไว้เพื่อเอาไว้อ้างอิง ในอนาคตในภาษา C ซึ่งมีอยู่หลายวิธี

หลายๆคนอาจจะใช้วิธีการ Block comment แต่การ Block comment นั้นมีข้อเสียตรงที่ หากใน Code ของเรามี Block comment อยู่ก็จะให้เกิด syntax error ได้ ตามตัวอย่างด้านล่างนี้

#include <stdio.h>

int main(void)
{

 
 /*   /* Month */
    printf("This month is May\n");

    printf("This month is Jul\n"); */
 

    /* Day of week */
    printf("This day is Monday\n");

    return 0;
}

อีกวิธีหนึ่งก็คือการใช้ #ifdef NOT_DEFINE แล้วปิดด้วย #endif ก็สามารถทำได้เช่นกัน แต่ก็มีข้อเสียตรงที่ต้องระวังหากมีใครไปเปิดปิด ค่า Define ของเรา ก็จะทำให้ code ที่เราปิดไว้ทำงานขึ้นมาได้

จึงมีอีกวิธีหนึ่งก็คือการใช้ #if 0 แล้วปิดด้วย #endif ซึ่ง compiler จะ compile #if 0 ออกมาเป็น เท็จเสมอทำให้ code ที่เราปิดไว้ไม่ถูก compile นั้นเอง
ตัวอย่างการใช้ #if 0

#include <stdio.h>

int main(void)
{
    #if 0
    /* Month */
    printf("This month is May\n");

    printf("This month is Jul\n");
    #endif

    /* Day of week */
    printf("This day is Monday\n");

    return 0;
}

แต่ข้อเสียของ #if 0 ก็มี นั้นคือ ไม่สามารถใช้กับ code ที่เขียนไม่ถูกต้องได้ เช่น การเขียนภาษาอื่นที่ไม่ใช่ภาษา C หรือ การใส่เครื่องหมาย double quote(“) หรือ single quote (‘) ที่ไม่ครบ หรือการใช้ block comment ที่ไม่ครบ block ก็จะทำให้เวลาใช้ #if 0 แล้วทำให้ compile แล้ว error
ตัวอย่าง

Double quote(“) ไม่ครบ

#include <stdio.h>

int main(void)
{

    #if 0
    /* Month */
    printf(This month is May\n");

    printf("This month is Jul\n");
    #endif

    /* Day of week */
    printf("This day is Monday\n");

    return 0;
}

Block comment ไม่ได้ปิดท้าย

#include <stdio.h>

int main(void)
{

    #if 0
    /* Month
    printf("This month is May\n");

    printf("This month is Jul\n");
    #endif

    /* Day of week */
    printf("This day is Monday\n");

    return 0;
}

อีกวิธีก็คือการใช้ Line comment ข้อเสียของวิธีนี้ก็คือ ต้องใช้ความสามารถของ IDE หรือ Text editor ช่วยในการ comment ในกรณีที่ code มีหลายๆบรรทัด ซึ่งส่วนใหญ่จะมีฟังชั่นเหล่านี้อยู่แล้ว
Line comment short cut ใน Sublime Text ก็คือ (Ctrl + /)
Line comment short cut ใน Notepad++ ก็คือ (Ctrl + k)
ตัวอย่าง Line comment

#include <stdio.h>

int main(void)
{


    // /* Month*/
    // printf("This month is May\n");

    // printf("This month is Jul\n");


    /* Day of week */
    printf("This day is Monday\n");

    return 0;
}

ดังนั้นหากจะต้องการที่จะเก็บ Code เก่าบางส่วนเอาไว้เพื่อเอาไว้อ้างอิง ก็ขอแนะนำให้ใช้ Line comment หรือหันมาใช้พวก Version control ดีกว่า

ขนาดของตัวแปรใน ภาษา C ในแต่ละ CPU

ขนาดของตัวแปรใน ภาษา C หรือ C++ นั้นจะขึ้นอยู่กับชนิดของ CPU และ Complier ซึ่งอาจจะเหมือนกันหรือต่างกันก็ได้ เรามาดูกันดีกว่าว่าแต่ละ CPU มีการกำหนดขนาดตัวแปรที่แตกต่างกันอย่างไร

ขนาดของตัวแปรใน x86

ขนาดของตัวแปร ใน CPU ARM 32 bit

อ้างอิงจาก ARM Compiler Reference

ขนาดของตัวแปรใน MCU TI MSP430

อ้างอิงจาก slaa534 MSP430 Embedded Application Binary Interface

จะเห็นได้ว่า แต่ละ CPU จะมีขนาดของตัวแปรที่กำหนดแตกต่างกันไป ดังนั้นการเขียนโปรแกรมในภาษา C หรือ C++ แล้วนำเอาไปใช้งานในแต่ละ CPU จึงต้องระมัดระวัง เนื่องจากขนาดของตัวแปรที่แตกต่างกันอาจจะทำให้โปรแกรมของเราทำงานได้ไม่ถูกต้องก็ได้

ค่าสูงสุดและต่ำสุดของตัวแปร Real ในภาษา C

เราสามารถหาค่าสูงสุดและต่ำสุดของตัวแปร ตัวเลขจำนวนจริง (Real) แต่ละชนิดในภาษา C ได้จากค่า Define ที่อยู่ใน ไฟล์ float.h

ตารางด้านล่างนี้แสดง Define ที่ใช้สำหรับกำหนดค่าสูงสุด (Max) หรือต่ำสุด (Min) และความละเอียด (Precision)

ซึ่งสามารถนำเอาค่า Define มา print แสดงค่าได้ โดย Include ไฟล์ float.h ดัง Source code ตัวอย่าง

#include <stdio.h> /* For command line input and output */
#include <float.h> /* For limits on floating-point types */

int main(void)
{
    printf("min float is %.6e\n", FLT_MIN);
    printf("max float is %.6e\n", FLT_MAX);
    printf("float provide %u decimal digits precision.\n\n", FLT_DIG);

    printf("min double is %.15e\n",DBL_MIN);
    printf("max double is %.15e\n", DBL_MAX);
    printf("double provide %u decimal digits precision.\n\n", DBL_DIG);

    printf("min long double is %.18Le\n", LDBL_MIN);
    printf("max long double is %.18Le\n", LDBL_MAX);
    printf("long double provide %u decimal digits precision.\n",LDBL_DIG);

    return 0;
}

จะได้ผลลัพธ์ดังนี้ (Windows 7 32 bit, gcc 4.9.2)

สำหรับใครที่ลองเอา Code ไปรันแล้วเจอค่าขึ้น -1.#QNAN e+000 ดังรูป

วิธีแก้ไขก็คือเวลาที่เรา Compile ให้กำหนด standard ด้วย เช่น –std=c99 เวลา compile กับ gcc

สำหรับคนที่ใช้ Code Block ก็ให้เข้าไป Setting ค่าที่ setting complier ให้ ติ๊กถูก “Have gcc follow the 1999 ISO C language standard [-std=c99]”

ค่าสูงสุดและต่ำสุดของแต่ละตัวแปร integer ในภาษา C

เราสามารถหาค่าสูงสุดและต่ำสุดของตัวแปร ตัวเลขจำนวนเต็ม (Integer) แต่ละชนิดในภาษา C ได้จากค่า Define ที่อยู่ใน ไฟล์ limit.h
ตารางด้านล่างนี้แสดง Define ที่ใช้สำหรับกำหนดค่าสูงสุด (Max) หรือต่ำสุด (Min)

ซึ่งสามารถนำเอาค่า Define มา print แสดงค่าได้ โดย Include ไฟล์ limit.h ดัง Source code ตัวอย่าง

#include <stdio.h>
#include <limits.h> /* For limits on integer types */

int main(void)
{
    //unsigned char
    printf("min unsigned char = 0\n");
    printf("max unsigned char max = %u\n",UCHAR_MAX);
    printf("size unsigned char = %d\n\n", sizeof(unsigned char));
     //char
    printf("min char = %d\n",CHAR_MIN);
    printf("max char = %d\n", CHAR_MAX);
    printf("size char = %d byte\n\n\n",sizeof(char));

    //unsigned int
    printf("min unsigned int = 0\n");
    printf("max unsigned int  = %u\n", UINT_MAX);
    printf("size unsigned int  = %d\n\n", sizeof(unsigned int));
    //int
    printf("min int = %d\n", INT_MIN);
    printf("max int = %d\n", INT_MAX);
    printf("size int = %d byte\n\n\n", sizeof(int));


    //unsigned short
    printf("min unsigned short = 0\n");
    printf("max unsigned short = %u\n", USHRT_MAX);
    printf("size unsigned short = %d\n\n", sizeof(unsigned short));
    //short
    printf("min short = %d\n",SHRT_MIN);
    printf("max short = %d\n",SHRT_MAX);
    printf("size short = %d byte\n\n\n",sizeof(short));
    

    //unsigned long
    printf("min unsigned long = 0\n");
    printf("max unsigned long =  %lu\n",ULONG_MAX);
    printf("size unsigned long = %d\n\n",sizeof(unsigned long));
    //long
    printf("min long = %ld\n",LONG_MIN);
    printf("max long = %ld\n",LONG_MAX);
    printf("size long = %d byte\n\n\n", sizeof(long));


    //unsigned logn long
    printf("min unsigned long long = 0\n");
    printf("max unsigned long long = %llu\n", ULLONG_MAX);
    printf("min unsigned long long = %d\n\n", sizeof(unsigned long long));
    //logn long
    printf("min long long = %lld\n", LLONG_MIN);
    printf("max long long = %lld\n", LLONG_MAX);
    printf("size long long = %d byte\n\n\n", sizeof(long long));
    
    return 0;
}

จะได้ผลลัพธ์ดังนี้ (Windows 7 32 bit, gcc 4.9.2)

min unsigned char = 0
max unsigned char max = 255
size unsigned char = 1

min char = -128
max char = 127
size char = 1 byte

min unsigned int = 0
max unsigned int = 4294967295
size unsigned int = 4

min int = -2147483648
max int = 2147483647
size int = 4 byte

min unsigned short = 0
max unsigned short = 65535
size unsigned short = 2

min short = -32768
max short = 32767
size short = 2 byte

min unsigned long = 0
max unsigned long = 4294967295
size unsigned long = 4

min long = -2147483648
max long = 2147483647
size long = 4 byte

min unsigned long long = 0
max unsigned long long = 18446744073709551615
min unsigned long long = 8

min long long = -9223372036854775808
max long long = 9223372036854775807
size long long = 8 byte

การอ้างอิงที่อยู่ของการ Include Header file

การ Include header file ที่เราสร้างขึ้นมาโดยใช้ #include “file” แต่ว่าหากเราจะอ้างอิงที่อยู่ของ header file ในกรณีที่อยู่คนละ folder นั้นเราสามารถทำได้ โดยแบ่งได้เป็น 2 แบบ

แบบที่ 1 include header file ที่อยู่ใน folder ที่อยู่ใน level มากกว่า (folder ย่อยลึกเข้าไป)
จะใช้เครื่องหมายทับ \ ในการระบุ folder ย่อยๆเข้าไป โดยยึดจุดอ้างอิงจาก file .c ของเรา
สมมติว่าเรามี File ตามที่อยู่นี้
D:\Desktop\helloworld1.c
และ
D:\Desktop\test\helloworld1.h
เราสามารถ Include ได้โดย

#include <stdio.h>
#include "test/helloworld1.h"

int main (void)
{
    printf("%s\n", HELLO);
    return 0;
}

และแบบที่ 2 include header file ที่อยู่ใน folder ที่อยู่คนละ level
จะใช้เครื่องหมาย.จุดจุด .. ในการระบุ folder ที่ต้องออกมา 1 ชั้น โดยยึดจุดอ้างอิงจาก file .c ของเรา เช่นกัน

สมมติว่าเรามี File ตามที่อยู่นี้
D:\Desktop\main\helloworld2.c
และ
D:\Desktop\test\helloworld2.h
เราสามารถ Include ได้โดย

#include <stdio.h>
#include "../test/helloworld2.h"

int main (void)
{
    printf("%s\n", HELLO);
    return 0;
}

และอีกกรณี ก็คือ ต้องอ้างอิงออกไปมากกว่า 1 ชั้น โดย .. จะใช้แทนการอ้างอิงออกจาก folder นั้น 1 ชั้น
D:\Desktop\main\submain\helloworld3.c
และ
D:\Desktop\test\helloworld3.h

#include <stdio.h>
#include "../../test/helloworld3.h"

int main (void)
{
    printf("%s\n", HELLO);
    return 0;
}

หลักการใช้ #include

เราสามารถ แบ่งการ Include ในภาษา C ได้เป็น 2 แบบ นั้นก็คือ

#include <file>

และ

#include "file"

สังเกตได้ว่าจะแตกต่างกันที่เครื่องหมาย “” และ < >

เราจะใช้ < >

#include <file>

สำหรับการ include ไฟล์ ที่อยู่ใน folder ของ compiler เช่น header files (.h) ที่เป็นมาตรฐาน string.h, stdio.h, math.h หรือ library ที่เป็นมาตรฐานมากับ compiler อยู่แล้ว เหล่านี้เป็นต้น

ส่วน “”

#include "file"

จะเป็นการ include header file ที่ไม่ได้อยู่ใน folder compiler หรือ เป็น header file (.h) ที่เราสร้างขึ้นมาเอง

การใช้ #include ที่ไม่ถูกต้องอาจจะทำให้ compile แล้วเกิด warning หรือ error ก็ได้ขึ้นอยู่กับ compiler แต่ละตัว ดังนั้นควรจะใช้ #include ให้ถูกต้องกันด้วยละ

มารู้จักการ Comment ในภาษา C

เราสามารถแบ่ง การ comment ในการเขียนโปรแกรมภาษา C ออกได้เป็น 2 แบบ นั้นก็คือ Line comment กับ Block comment

Line comment จะสามารถ comment ได้ เพียงบรรทัดเดียวต่อครั้งโดยใช้ เครื่องหมายทับ 2 ตัว (//) หน้าบรรทัดที่เราอยาก comment
ตัวอย่าง Line comment

#include <stdio.h>

int main(void)
{

    // This is 
    // block 
    // comment
    printf("Hello world\n");

    return 0;
}

Block comment สามารถ comment code ได้หลายบรรทัดในครั้งเดียว โดยใช้ เครื่องหมาย ทับแล้วตามด้วยเครื่องหมายดอกจัน (/*) เพื่อเปิด comment และ เครื่องหมายดอกจันแล้วตามด้วยเครื่องหมายทับ(*/) เพื่อ ปิด comment
ตัวอย่าง Block comment

#include <stdio.h>

int main(void)
{

    /* This is 
    block 
    comment */ 
    printf("Hello world\n");

    return 0;
}

แต่การใช้ Block comment มีข้อควรระวังก็คือ code ที่เราจะ comment นั้นห้ามมี block comment อยู่ (ห้าม block comment ซ้อนกัน) จะทำให้ compile ไม่ผ่านได้
ตัวอย่าง Block comment ที่ compile ไม่ผ่าน

#include <stdio.h>

int main(void)
{

    /* This is 
    /*block */
    comment */ 
    printf("Hello world\n");

    return 0;
}

ตัวเลขจำนวนจริง (Real number) VS ตัวเลขจำนวนเต็ม (Integer number)

ในภาษา C เราสามารถแบ่งตัวแปรที่เป็นตัวเลขออกได้เป็น 2 ประเภทนั้นก็คือ ตัวเลขจำนวนจริง (Real number) และ ตัวเลขจำนวนเต็ม (Integer number)


ตัวเลขจำนวนจริง ก็คือ ตัวเลขที่เราวัดได้จากค่าจริงๆเช่น ส่วนสูงของเรา 180.23 เซนติเมตร, ต้นไม้สูง 10.23 เมตร หรือ ความเร็ว 64.53 กิโลเมตรต่อชั่วโมง เป็นต้นเราจะเห็นได้ว่าตัวเลขเหล่านี้ล้วนแล้วแต่เป็นค่าที่มีทศนิยม เพราะค่าเหล่านี้ล้วนแต่เป็นค่าที่วัดได้จริงๆ ดังนั้นในภาษา C หรือในภาษาโปรแกรมมิ่งทางคอมพิวเตอร์ จึงเรียกว่าว่าเป็น ตัวเลขจำนวนจริง Real number นั้นเอง


ตัวเลขจำนวนเต็ม ก็คือตัวเลขที่ไม่มีจุดทศนิยมนั้นเอง ตัวอย่างของ ตัวเลขจำนวนเต็ม(Integer number) เช่น รถ 3 คัน, จักรยาน 3 คัน, คน 1581 คน, บ้าน 1 หลัง เหล่านี้เป็นต้น

ทีนี้เพื่อนๆก็คงจะรู้จักกับตัวเลขในภาษา C ทั้ง 2 ประเภทกันแล้ว ว่าแต่ละประเภทเป็นอย่างไรและแตกต่างกันอย่างไร