Tìm hiểu ngôn ngữ lập trình C

Phan Thái Châu

15/11/2020

Share

Ngôn ngữ C

Tất tần tật kiến thức về ngôn ngữ lập trình C

Giới thiệu về ngôn ngữ C

Là một ngôn ngữ lập trình cấp cao, nhưng cũng có khả năng thực hiện những thao tác điều khiển hệ thống như Assembler nên được gọi là ngôn ngữ cấp trung gian (Middle level language). Với đặc tính tổng quát và linh hoạt, C chứng tỏ là một ngôn ngữ lập trình đa dụng, tiện lợi và hiệu quả trong lĩnh vực lập trình hệ thống lẫn lập trình ứng dụng.

Xuất xứ của ngôn ngữ C

Ngôn ngữ C do Dennis Ritchie viết xong vào năm 1972 tại phòng thí nghiệm Bell Telephone (thuộc công ty AT & T của Mỹ). C có nguồn gốc từ ngôn ngữ BCPL do Martin Richards đưa ra năm 1967 và ngôn ngữ B do Ken Thompson phát triển từ ngôn ngữ BCPL năm 1970 khi viết hệ điều hành Unix. Đến năm 1985, ngôn ngữ C được Viện tiêu chuẩn hoá của Mỹ (American National Standard Institute) chuẩn hoá lại gọi là ANSI C.

Đặc điểm của ngôn ngữ C

C có những đặc điểm cơ bản sau đây:

– Tính động (compact): C chỉ có 32 từ khóa chuẩn và 40 toán tử chuẩn mà hầu hết được biểu diễn bởi các dãy ký tự ngắn gọn.

– Tính cấu trúc (structured): C có một bộ lệnh lặp, điều khiển, chuyển điều khiển phù hợp với lập trình có cấu trúc.

– Tính tương thích (compactable):C có bộ lệnh tiền xử lý và các thư viện chuẩn giúp cho chương trình viết bằng ngôn ngữ C có thể tương thích khi chuyển từ máy tính này sang máy tính kiểu hoàn toàn khác.

– Tính linh động (flexible):Là ngôn ngữ rất linh động về ngữ pháp, C chấp nhận nhiều cách thể hiện mà không có ở những ngôn ngữ lập trình khác, giúp cho kích thước mã lệnh có thể thu gọn lại để chương trình thực thi nhanh hơn.

Biên dịch 

C được biên dịch bằng nhiều bước và cho phép biên dịch nhiều tập tin chương trình riêng rẽ thành những tập tin đối tượng (object) và nối các đối tượng lại với nhau (link) thành một chương trình thực thi thống nhất.

Ngôn ngữ C
Ngôn ngữ C

Các thành phần cơ bản trong ngôn ngữ C

Ngôn ngữ C được xây dựng từ một bộ ký tự, các ký tự đó được kết hợp lại thành các từ, các từ tạo thành các câu, tất cả đều tuân theo một cú pháp rất chặt chẽ.

Bộ ký tự

  • Bộ chữ hoa             A,B,C, … ,Z
    • Bộ chữ thường a,b,c, … ,z
  • Bộ chữ số thập phân 0,1,2, … ,9
  • Các ký hiệu toán học: +, – , * , / , % , = , !=, >, <
  • Các ký hiệu khác ,  ;  :  _  !  #  [ ]  { } ()  ?  & $  ^  ‘  “

Tên và cách đặt tên

Khi lập trình thường phải đặt tên (định danh) cho các biến, hằng, kiểu, tên hàm (chương trình con), … Tên đặt trong C được bắt đầu bằng một chữ cái, sau đó là các chữ số hay dấu gạch nối và không được có dấu khoảng trống. C có phân biệt chữ hoa chữ thường trong một tên đặt. Khi viết chương trình ta nên đặt tên sao cho nói lên được ý nghĩa của đối tượng mà tên biểu thị, điều này giúp ta viết chương trình được dễ dàng và người khác đọc chương trình cũng thoải mái, dễ hiểu, dễ kiểm chứng.

Từ khóa (keyword)

Là các từ riêng của C, có ngữ nghĩa đã được xác định, người lập trình không được dùng nó vào các việc khác như việc đặt tên mới trùng với tên các từ khoá.

Các từ khóa trong C++
Các từ khóa trong C++

Chú thích trong chương trình

Khi viết chương trình nên đưa vào các câu chú thích để làm cho chương trình rõ ràng, dễ hiểu. Điều này cũng giúp cho việc sửa đổi nâng cấp chương trình sau này được dễ dàng. Có hai cách chú thích:

Cách 1: đặt dấu // trước dòng muốn chú thích

Cách 2: bao đoạn cần chú thích giữa hai dấu /*    */

Lời chú thích có thể đặt ở bất kỳ vị trí nào trong chương trình, nếu chương trình dài phức tạp thì nên đưa chú thích vào trước mỗi đoạn lệnh để giải thích.

Dấu kết thúc lệnh

Mỗi câu lệnh trong phần thân chương trình  phải được kết thúc bằng dấu chấm phẩy (;)

Các kiểu dữ liệu cơ bản trong ngôn ngữ C

Là tập hợp các giá trị mà một biến thuộc kiểu đó có thể nhận được và một số các phép toán được sử dụng trên đó. Tuỳ thuộc vào dữ liệu kiểu gì mà khi nạp vào bộ nhớ để xử lý sẽ chiếm một kích thước nhất định (tính bằng byte).

Dưới đây là bảng phân loại các kiểu dữ liệu cơ bản trong C:

Tên kiểu Ý nghĩa Kích thước Phạm vi
char Ký tự 1 byte -128 → 127
unsigned char Ký tự không dấu 1 byte 0 → 255
unsigned short Số nguyên ngắn không dấu 2 bytes 0 → 65535
enum Số nguyên có dấu 2 bytes -32768 → 32767
short int Số nguyên có dấu 2 bytes -32768 → 32767
int Số nguyên có dấu 2 bytes -32768 → 32767
unsigned int Số nguyên không dấu 2 bytes 0 → 65535
long Số nguyên dài có dấu 4 bytes -2147483648 → 2147483647
unsigned long Số nguyên dài không dấu 4 bytes 0 → 4294967295
float Số thực độ chính xác đơn 4 bytes 3.4 E-38 → 3.4 E+38
double Số thực độ chính xác kép 8 bytes 1.7 E-308 → 1.7 E+308
long double Số thực có độ chính xác hơn double 10 bytes 3.4 E-4932 →             1.1 E+4932

Biến và hằng trong lập trình C

Biến (variable)

Biến là tên tượng trưng cho một vùng nhớ mà dữ liệu có thể lưu trữ trên đó để sử dụng lại. Biến thường được dùng để chứa giá trị dữ liệu nhập vào từ bàn phím hoặc giá trị kết quả của các lệnh tính toán trong khi chương trình thực hiện. Muốn sử dụng biến phải khai báo trước.

Cách 1: Khai báo biến

Kiểu_dữ_liệu   Tên_biến;

 Cách 2: Khai báo biến và khởi tạo giá trị ban đầu

Kiểu_dữ_liệu   Tên_biến = giá_trị;

Ví dụ:      int  a, b;                        // khai báo hai biến kiểu số nguyên

float  x=0.1;      // khai báo biến kiểu số thực và gán giá trị 0.1

Hằng (constant)

Hằng cũng là tên tượng trưng cho một vùng nhớ lưu trữ dữ liệu nhưng giá trị dữ liệu sẽ giữ nguyên không thay đổi trong suốt quá trình chương trình thực hiện. Muốn sử dụng hằng phải khai báo trước như sau:

Cách 1: Khai báo hằng

const   Tên_hằng = giá_trị;

Cách 2: Khai báo hằng và qui định kiểu của hằng

const  Kiểu_dữ_liệu Tên_hằng = giá_trị;

Ví dụ:      const  tygia = 20500;      // khai báo hằng có giá trị nguyên 20500

const  float  PI = 3.14;    // khai báo hằng kiểu số thực bằng 3.14

Lệnh gán và nhập xuất

Lệnh gán (=)

Dùng để gán giá trị cho biến. Giá trị gán có thể là hằng hoặc biểu thức. Lệnh gán làm cho biến thay đổi giá trị lưu trữ bên trong biến.

Tên_biến = giá_trị;

Tên_biến = biểu_thức;

               n = 1;                // gán cho biến n giá trị 1Ví dụ:      int  n, m;           // khai báo hai biến kiểu nguyên

m = n*2 + 1;     // gán cho biến m giá trị biểu thức n*2+1 => m=3

n = n + 1;          // gán n thêm 1 cộng vào giá trị hiện có => n=2

Lệnh nhập, xuất  

Dùng để nhập giá trị gõ từ bàn phím chứa vào trong biến (lệnh cin) và xuất giá trị của biểu thức ra màn hình (lệnh cout). Hai lệnh nhập xuất này thuộc về thư viện iostream.h

cin >> Tên_biến;

cout << biểu_thức;

Ví dụ:      float  r, s;                         // khai báo hai biến kiểu thực

cout<<”nhập bán kính:”;    // xuất ra dòng chữ “nhập bán kính:”

cin>>r;                             // nhập giá trị từ bàn phím chứa vào r

s = r*r*3.14;                     // tính diện tích hình tròn gán cho s

cout<<”diện tích:”<<s;       // xuất dòng chữ “diện tích:” và giá trị

// của biến s kế tiếp theo sau

Viết chương trình với ngôn ngữ C++

Cấu trúc cơ bản của một chương trình C

Để giúp cho việc lập trình dễ dàng thuận lợi, ta sẽ bắt đầu tìm hiểu một chương trình viết trong C ở dạng đơn giản như sau:

#include<thư_viện>

void  main()

{ khai_báo_biến;

nhập_dữ_liệu;

xử_lý;

xuất_kết_quả;

}

Một số ví dụ minh họa

Ví dụ 1: nhập hai số và tính tổng bình phương của hai số này: A = x2 + y2, ta đi qua các bước:

– Bước 1: Nhập vào 2 số x và y

– Bước 2: Tính A = x*x + y*y

– Bước 3: Xuất A

– Bước 4: Ngừng thuật toán.

Chương trình sẽ viết như sau:

#include<iostream.h>

#include<conio.h>

void  main()

{ int  x, y, A;                                // khai báo 3 biến kiểu số nguyên

clrscr();                                     // lệnh xóa màn hình của thư viện conio.h

cout<<”nhập 2 số:”;                    // lệnh xuất của thư viện iostream.h

cin>>x>>y;                               // lệnh nhập của thư viện iostream.h

A=x*x + y*y;                            // lệnh gán tổng bình phương cho biến A

cout<<”tổng bình phương:”<<A; // lệnh xuất kết quả tính được

getch();                                     // lệnh chờ nhập 1 phím thuộc thư viện conio.h

}

Ví dụ 2: viết chương trình xuất ra dòng chữ “Kỹ thuật lập trình” rồi xuống dòng xuất tiếp dòng chữ “với ngôn ngữ C++” và chờ nhấn một phím thì kết thúc.

#include<iostream.h>

#include<conio.h>

void  main()

{ clrscr();                                     // lệnh xóa màn hình của thư viện conio.h

cout<<”Kỹ thuật lập trình”;         // lệnh xuất của thư viện iostream.h

cout<<”\n”;                               // lệnh xuất có tác dụng xuống dòng

cout<<”với ngôn ngữ C++”;

getch();                                     // lệnh chờ nhập 1 phím thuộc thư viện conio.h

}

Ví dụ 3: nhập bán kính hình tròn, tính chu vi và diện tích hình tròn, ta đi qua các bước:

– Bước 1: Nhập vào bán kính r

– Bước 2: Tính CV = r*2*PI

– Bước 3: Tính DT = r*r*PI

– Bước 4: Xuất CV và DT

– Bước 5: Ngừng thuật toán.

Chương trình sẽ viết như sau:

#include<iostream.h>

#include<conio.h>

void  main()

{ float  r, CV, DT;                        // khai báo 3 biến kiểu số thực

const  PI=3.14;                          // khai báo hằng PI=3.14

clrscr();                                     // lệnh xóa màn hình

cout<<”nhập bán kính:”;

cin>>r;

CV=r*2*PI;                               // lệnh gán tính chu vi

DT=r*r*PI;                               // lệnh gán tính diện tích

cout<<”chu vi hình tròn:”<<CV;

cout<<endl;

cout<<”diện tích hình tròn:”<<DT;

getch();

}

Toán tử và biểu thức

Toán tử số học

Sử dụng với số nguyên thì kết quả cho ra số nguyên, sử dụng với số thực thì kết quả cho ra số thực. Riêng toán tử % chỉ dùng với số nguyên.

Toán tử Định nghĩa Ví dụ
+ Cộng 5 + 7 → 12
Trừ 8.5 – 6 → 2.5
* Nhân 4 * 9 → 36
/ Chia lấy thương 7/2 → 3 7.0/2 → 3.5
% Chia lấy dư (số nguyên) 7%2 → 1

Toán tử số học

Sử dụng với bất kỳ kiểu nào và kết quả cho ra là 0 (sai) hoặc 1 (đúng):

Toán tử Định nghĩa Ví dụ
< Nhỏ hơn 5 < 7 → 1
> Lớn hơn 8.5 > 16 → 0
== Bằng ‘A’ == ‘B’ → 0
<= Nhỏ hơn hoặc bằng 2 <= 7 → 1
>= Lớn hơn hoặc bằng 5 >= 10/2 → 1
!= Khác 7/3 != 2 → 0

Toán tử luận lý (logic)

Sử dụng để nối các mệnh đề logic và kết quả cho ra là 0 (sai) hoặc 1 (đúng):

Toán tử Định nghĩa Ví dụ
! Phủ định !(5<7) → 0
&& (8.5>16) && (‘A’<’B’) → 0
|| Hoặc (‘A’==‘B’) || (10/2 <=5) → 1

Toán tử tăng giảm

Sử dụng với biến kiểu số nguyên để tăng hoặc giảm giá trị của biến 1 đơn vị:

Toán tử Định nghĩa Ví dụ
++ Tăng 1 x++ → giá trị biến x tăng thêm 1
Giảm 1 y– → giá trị biến y giảm đi 1

Toán tử điều kiện

Sử dụng để xét các điều kiện là đúng hay sai ? nếu điều kiện là đúng (1) thì kết quả cho ra là giá trị của biểu thức thứ nhất, ngược lại nếu điều kiện là sai (0) thì kết quả cho ra giá trị của biểu thức thứ 2:

(Điều_kiện) ? Biểu_thức_1 :  Biểu_thức_2

Ví dụ:      float  a=1, b=3, c;             // khai báo ba biến kiểu thực

c=(a>b)? (a+b) : (a-b);       // vì (a>b) là sai nên c được gán (a-b)

cout<<c;                           // xuất ra giá trị của c là -2

cout<<((c<b) ? a : b);        // vì (c<b) là đúng nên xuất ra giá trị a

Chuyển kiểu biểu thức

Khi thực hiện các phép tính toán số học thường xảy ra các chuyển đổi kiểu các toán hạng để tính toán. Có hai loại chuyển đổi kiểu:

Chuyển đổi kiểu tự động: trong một biểu thức, nếu việc tính toán xảy ra với các toán hạng có kiểu khác nhau hoặc để kết quả cuối cùng có thể thực hiện được C sẽ tự động chuyển đổi kiểu theo quy định sau:

int → long → float → double → long double

Chuyển đổi kiểu bắt buộc: sử dụng một trong hai cú pháp sau:

(kiểu_dữ_liệu) biểu_thức

kiểu_dữ_liệu (biểu_thức)

Ví dụ:      int  a=7, b=2;                    // khai báo hai biến kiểu nguyên

float  c=a/b;                      // vì a và b là số nguyên nên c là 3

float  d=(float)a/b;             // biến d sẽ bằng 3.5 vì đã chuyển giá

// trị của a thành số thực trước khi chia

BÀI TẬP

Mô tả thuật toán để giải quyết các bài toán sau đây rồi mã hóa chương trình:

  1. Nhập vào số lượng, đơn giá. Tính thành tiền và thuế VAT 10% của thành tiền rồi xuất ra.
  2. Nhập hai số. Xuất ra tổng, hiệu, tích, thương của hai số đã nhập.
  3. Nhập một số nguyên gồm hai chữ số. Xuất ra số nguyên với hai chữ số đảo ngược lại. (ví dụ nhập vào số 47 thì xuất ra số 74)
  4. Nhập một số nguyên có ba chữ số. Tính tổng các chữ số và xuất ra.
  5. Nhập giờ và phút thuê máy, nhập giờ và phút trả máy. Tính thời gian thuê và tiền phải trả, biết rằng 1 giờ thuê là 3000.
  6. Nhập ba số. Xuất ra ba số theo trật tự từ nhỏ đến lớn.
  7. Nhập bốn số. Xuất ra số có giá trị lớn nhất và số có giá trị nhỏ nhất trong bốn số đã nhập vào.
  8. Nhập vào tổng số giây. Đổi số giây thành giờ, phút và giây rồi xuất ra.
  9. Nhập vào ba số. Tính trung bình cộng của ba số và xuất ra trung bình cộng.
  10. Nhập vào hai phân số, mỗi phân số gồm tử và mẫu. Tính tổng và tích hai phân số rồi xuất kết quả dạng số thập phân.

HƯỚNG DẪN

Bài tập 3: Thuật toán nhập một số nguyên gồm hai chữ số, xuất ra số nguyên với hai chữ số đảo ngược lại. Ta đi qua các bước:

– Bước 1: Nhập vào số n.

– Bước 2: Tính số hàng chục c=n/10

– Bước 3: Tính số hàng đơn vị d=n%10

– Bước 4: Xuất d,c.

– Bước 5: Ngừng thuật toán.

Chương trình sẽ viết như sau:

#include<iostream.h>

#include<conio.h>

void  main()

{ int  n, c, d;                                 // khai báo 3 biến kiểu số nguyên

clrscr();                                     // lệnh xóa màn hình

cout<<”nhập 1 số gồm 2 chữ số:”;

cin>>n;

c=n/10;                                     // lệnh gán tính số hàng chục

d=n%10;                                   // lệnh gán tính số hàng đơn vị

cout<<”Kết quả:”<<d<<c;

getch();

}

Bài tập 6: Thuật toán nhập ba số, xuất ra ba số theo trật tự từ nhỏ đến lớn. Ta đi qua các bước:

– Bước 1: Nhập vào ba số a, b, c.

– Bước 2: Tính số lớn nhất m1 qua hai bước nhỏ sau đây:

+ Bước 2.1: m1 = (a>b)?a:b

+ Bước 2.2: m1 = (m1>c)?m1:c

– Bước 3: Tính số lớn thứ ba m3 qua hai bước nhỏ sau đây:

+ Bước 3.1: m3 = (a<b)?a:b

+ Bước 3.2: m3 = (m3<c)?m3:c

– Bước 4: Tính số lớn thứ hai m2=(a!=m1 && a!=m3)?a:((b!=m1 && b!=m3)?b:c)

– Bước 5: Xuất m3, m2, m1

– Bước 6: Ngừng thuật toán.

Chương trình sẽ viết như sau:

#include<iostream.h>

#include<conio.h>

void  main()

{ int  a, b, c;                                    // khai báo 3 biến kiểu số nguyên

clrscr();                                        // lệnh xóa màn hình

cout<<”nhập 3 số:”;

cin>>a>>b>>c;

int  m1=(a>b)?a:b;                        // lệnh gán tính số lớn nhất

m1=(m1>c)?m1:c ;

int  m3=(a<b)?a:b;                        // lệnh gán tính số lớn thứ ba

m3=(m3<c)?m3:c ;

int  m2=(a!=m1 && a!=m3)?a:((b!=m1 && b!=m3)?b:c);

cout<<”Kết quả:”<<m3<<”   “<<m2<<”   “<<m1;

getch();

}

Bài tập 10: Thuật toán nhập vào hai phân số, tính tổng và tích hai phân số, xuất ra kết quả dạng số thập phân. Ta đi qua các bước:

– Bước 1: Nhập vào phân số thứ nhất gồm tu1 và mau1

– Bước 2: Nhập vào phân số thứ hai gồm tu2 và mau2

– Bước 3: Tính tích của tử tichtu=tu1*tu2

– Bước 4: Tính tích của mẫu tichmau=mau1*mau2

– Bước 5: Tính tổng qui đồng của tử tong=tu1*mau2 + tu2*mau1

– Bước 6: Xuất tích hai phân số float(tichtu)/tichmau

– Bước 7: Xuất tổng hai phân số float(tong)/tichmau

– Bước 8: Ngừng thuật toán.

Chương trình sẽ viết như sau:

#include<iostream.h>

#include<conio.h>

void  main()

{ int  tu1, mau1, tu2, mau2;              // khai báo 4 biến kiểu số nguyên

clrscr();                                        // lệnh xóa màn hình

cout<<”Nhập phân số thứ nhất:”;

cout<<”tử số:”;

cin>>tu1;

cout<<”mẫu số:”;

cin>>mau1;

cout<<”Nhập phân số thứ hai:”;

cout<<”tử số:”;

cin>>tu2;

cout<<”mẫu số:”;

cin>>mau2;

int  tichtu=tu1*tu2;                        // lệnh tính tích hai tử số

int  tichmau=mau1*mau2;              // lệnh tính tích hai mẫu số

int  tong=tu1*mau2 + tu2*mau1;    // lệnh tính tổng qui đồng hai tử số

cout<<”Tích hai phân số:”<<float(tichtu)/tichmau;

cout<<”Tổng hai phân số:”<<float(tong)/tichmau;

getch();

}