You are on page 1of 21

I.

LANGUAGES AND COMPILER C

1. Các đặc điểm cơ bản để tạo nên một program/


software tốt :

- Usability(tính khả dụng ) : cho phép người sử dụng dễ dàng


sử dụng mà không cần hướng dẫn
- Correctness(tính chính xác) : sự chính xác của solution/
algorithm được sử dụng trong program/software
- Maintainability(khả năng bảo trì) : dễ dàng sửa đổi hoặc
thay thế những khiếm khuyết trong program/software
o Understandability
o Modifiability
- Portability(Tính di động ) : khả năng sử dụng
program/software trên nhiều platform(nền tảng ) khác nhau

2. C languages :

- C là một trong những ngôn ngữ phổ biến nhất được sử


dụng trên toàn cầu
- C là ngôn ngữ lập trình bậc cao ( high – level language)
- Ngôn ngữ C phân biệt chữ hoa – thường ( case sensitive)
- Trình biên dịch C(C compiler) bỏ qua tất cả các khoảng
trắng
- Trình biên dịch C bỏ qua tất cả các comment
II. BASIC CONCEPT IN C LANGUAGE

1. Variables and Data Types :


a. Variable ( biến ) :
1. Khái niệm :
o Tên của một vùng trong bộ nhớ RAM , được sử dụng để lưu trữ
thông tin.
o Có thể gán thông tin cho một biến và lấy thông tin đó ra sử dụng
o Khi một biến được khai báo , một vùng trong bộ nhớ sẽ dành
cho các biến.
o Giá trị của biến có thể thay đổi bất cứ lúc nào trong suốt quá
trình mà chương trình chạy.
2. Quy tắc đặt tên biến :
o Chỉ chứa các chữ cái, chữ số và kí tự gạch dưới ( _ ) trong bảng
mã ASCII.
o Phải bắt đầu bằng một chữ cái hoặc kí tự gạch dưới.
o Không được trùng với các từ khóa trong ngôn ngữ C.
o Phân biệt hoa thường. C là ngôn ngữ phân biệt hoa thường, do
vậy biến aBc và abc là khác nhau trong C.
Danh sách các từ khóa trong ngôn ngữ C:
| auto | break | case | char | const | continue | default | do

| double | else | enum | extern | float | for | goto | if |

| int | long | register | return | short | signed | sizeof | static

| struct | switch | typedef | union | unsigned | void | volatile |

while |
3. Khai báo biến :

o Vị trí khai báo: Biến thường được khai báo ở đầu chương
trình, đầu hàm hoặc khối lệnh.
o Có 2 loại biến theo vị trí khai báo:
o Biến toàn cục: biến khai báo ở ngoài các hàm, các khối
lệnh. Chu trình sống của chúng từ lúc bắt đầu chương
trình tới khi kết thúc chương trình.
o Biến cục bộ: biến khai báo bên trong các hàm, các khối
lệnh. Chu trình sống từ khi bắt đầu khối lệnh tới khi khối
lệnh được thực hiện xong.
o Cú pháp khai báo biến:

<kiểu dữ liệu> <danh sách biến>;


(Biến trong ngôn ngữ C luôn gắn liền với một kiểu dữ liệu).
Ví dụ:

int i,j; /* Khai báo biến i,j kiểu số nguyên */


char ch; /* Khai báo biến ch kiểu chữ cái ASCII */
char name[100]; /* Khai báo xâu kí tự tên name với độ
dài lớn
nhất là 100 kí tự */
i = j = 0; /* Gán giá trị 0 cho 2 biến i,j */
ch = 'A'; /* Gán giá trị chữ cái A in hoa cho biến ch */
b. DATA TYPES (Kiểu dữ liệu) :
1. Các kiểu giá trị trong ngôn ngữ C :
STT KIỂU VÀ MIÊU TẢ
Kiểu cơ bản: Là các kiểu dữ liệu số học và bao
1 gồm 2 kiểu chính: a) kiểu số nguyên và b) kiểu số
thực dấu chấm động.
Kiểu liệt kê: Đây là các kiểu số học và được dùng
để định nghĩa các biến mà nó có thể được gán
2
trước một số lượng nhất định giá trị số nguyên
qua suốt chương trình.
Kiểu void: Kiểu định danh void là kiểu đặc biệt
3
thể hiện rằng không có giá trị nào.

Kiểu phát triển từ cơ bản: Bao gồm các kiểu : a)


con trỏ, b) kiểu mảng, c) kiểu cấu trúc, d) kiểu
4
union và e) kiểu function (hàm).

2. Bảng các kiểu nguyên :

Kiểu Kích thước Khoảng giá trị


char 1 byte -128 tới 127 hoặc 0 tới 255
unsigned
1 byte 0 tới 255
char
signed
1 byte -128 tới 127
char
int 2 hoặc 4 -32,768 tới 32,767 hoặc
-2,147,483,648 tới
bytes
2,147,483,647
unsigned 2 hoặc 4 0 tới 65,535 hoặc 0 tới
int bytes 4,294,967,295
short 2 bytes -32,768 tới 32,767
unsigned
2 bytes 0 tới 65,535
short
-2,147,483,648 tới
long 4 bytes
2,147,483,647
unsigned
4 bytes 0 tới 4,294,967,295
long

3. Bảng các kiểu số thực dấu phẩy động :


Kích thước
Kiểu Khoảng giá trị Độ chính xác
biến
1.2E-38 tới 6 vị trí thập
float 4 byte
3.4E+38 phân
2.3E-308 tới
15 vị trí thập
double 8 byte 1.7E+308
phân
long 3.4E-4932 tới 19 vị trí thập
10 byte
double 1.1E+4932 phân

2. Nhập xuất dữ liệu trong C :


a. In dữ liệu ra màn hình :

- Cú pháp: printf("xâu kí tự…", <các biến và các số>);


- Để in giá trị của các biến, số ra màn hình, ta phải sử dụng các đặc
tả định dạng bắt đầu với % như trên nhằm đại diện cho các biến, số
(%d đại diện cho biến số nguyên number).  Các đặc tả định dạng
này không được in ra màn hình mà được thay thế bởi các biến, các
số đằng sau.

- Một số đặc tả định dạng cơ bản :


 %d: số nguyên hệ 10 có dấu
 %u: số nguyên hệ 10 không dấu
 %x: số nguyên hệ 16
 %o: số nguyên hệ bát phân
 %s: xâu kí tự
 %c: một kí tự đơn
 %f: số chấm động cố định
 %e: số chấm động (ký hiệu có số mũ)
 l : Tiền tố dùng kèm với %d, %x, %o để chỉ số nguyên dài (ví
dụ %ld)
 Để in ra kí tự % ta dùng %%.

- Định dạng dữ liệu in ra:


 % [-] [fwidth] [.p] 
 [fwidth] chiều rộng
  [-] căn lề trái
 [.p] số kí tự được in ra

b. Nhập dữ liệu từ bàn phím :


- Cú pháp: scanf ("xâu kí tự…", <các con trỏ>);
- Nhập chuỗi có khoảng trắng có 2 cách phổ biến :
o fgets(name,length,stdin);
length : độ dài lớn nhất xâu kí tự muốn nhập
name : tên biến lưu xâu kí tự
o scanf ("%[^\n]%*c", name);
III.BASIC LOGIC

1. CẤU TRÚC RẼ NHÁNH :


a. Cấu trúc rẽ nhánh dạng if…else

o Dạng đơn giản nhất :

if (<điều kiện>) <hành động>


Nếu điều kiện đúng thì thực hiện hành động
Ví dụ :
1. #include <stdio.h>
2. int main()
3. {
4. int a = 5;
5. if (a > 0) {
6. printf("%d la so duong\n",a);
7. }
8. if (a < 0) {
9. printf("%d la so am\n",a);
10. printf("a nho hon 0");
11. }
12. return 0;
13. }
o Dạng mở rộng if …else :
1. if (<điều kiện>) <hành động 1>
2. else <hành động 2>
Nếu <điều kiện> đúng thì thực hiện <hành động
1> ; nếu <điều kiện> sai thì thực hiện <hành
động 2>
Ví dụ :
1. #include <stdio.h>
2. int main()
3. { int a = -5;
4. if (a > 0)
5. printf("%d > 0\n",a);
6. else {
7. printf("%d >= 0\n", a);
8. printf("%d khong la so duong\n",a);
9. }
10.return 0;
11.}
o Dạng mở rộng if…else if…else:
1. if (<điều kiện 1>) <hành động 1>
2. else if (<điều kiện 2>) <hành động 2>
3. else <hành động 3>
Nếu <điều kiện 1> đúng thì thực hiện <hành
động 1> ; nếu <điều kiện 1> sai -> tiến hành
kiểm tra <điều kiện 2>: <điều kiện 2> đúng sẽ
thực hiện <hành động 2>; nếu <điều kiện 1>
và <điều kiện 2> đều sai thì thực hiện <hành
động 3>
Ví dụ :
1. #include <stdio.h>
2. int main() {
3. int a = 5;
4. printf("Nhap so nguyen a: ");
5. scanf("%d",&a);
6. if (a > 0)
7. printf("a la so duong\n");
8. else if (a < 0)
9. printf("a la so am\n");
10.else f("a = 0");
11.return 0;
12.}

b. Cấu trúc rẽ nhánh switch – case :

o Cú pháp :
 switch (<biểu thức nguyên>) {
 case <giá trị 1>: <hành động 1>; break; /*
có thể không có câu lệnh này*/ c
 case <giá trị 2>: <hành động 1>; break; /*
có thể không có câu lệnh này*/
 ....
 default: <hành động mặc định>; break; /*
có thể không có câu lệnh này*/
 }
Ví dụ :
1. #include < stdio.h >
2. int main() {
3. int chuSo;
4. printf("Nhap chu so: ");
5. scanf("%d", & chuSo);
6. switch (chuSo) {
7. case 0: printf("Khong");
8. break;
9. case 1: printf("Mot");
10.break;
11.case 2: printf("Hai");
12.break;
13.case 3: printf("Ba");
14.break;
15.case 4: printf("Bon");
16.break;
17.case 5: printf("Nam");
18.break;
19.case 6: printf("Sau");
20.break;
21.case 7: printf("Bay");
22.break;
23.case 8: printf("Tam");
24.break;
25.case 9: printf("Chin");
26.break;
27.default: printf("Khong phai chu so!");
28.}
29.return 0;
30.}

2. CẤU TRÚC LẶP :


a. Vòng lặp for :
o Cú pháp :
for ( init; condition; increment )
{
statement(s);
}
1. Bước init được thực thi đầu tiên, và chỉ một lần. Bước này cho
phép bạn khai báo và khởi tạo bất kỳ biến điều khiển vòng lặp
nào.
2. Tiếp theo, điều kiện được đánh giá. Nếu nó là đúng, phần thân
của vòng lặp được thực thi. Nếu nó sai, phần thân của vòng lặp
không thực thi và luồng điều khiển nhảy đến câu lệnh kế tiếp
ngay sau vòng lặp for.
3. Sau khi vòng lặp for thực hiện, luồng điều khiển nhảy ngược lại
câu lệnh tăng dần. Câu lệnh này cho phép bạn cập nhật bất kỳ
biến điều khiển vòng lặp nào. Câu lệnh này có thể để trống,
miễn là dấu chấm phẩy xuất hiện sau điều kiện.
4. Điều kiện hiện được đánh giá lại. Nếu nó là true, vòng lặp thực
hiện và quá trình lặp lại chính nó và nếu điều kiện sai, vòng lặp
for chấm dứt.

Ví dụ :
int main(){
for(int i = 0; i &lt; 3; i++){
printf("BkitSoftware!\n");
} // Continue ...
printf("Ket thuc vong lap!\n");
}

b. Vòng lặp while :


o Cú pháp :
while(condition) {
statement(s);
}

Vòng lặp lại trong khi điều kiện là đúng. Khi điều kiện trở thành
sai, điều khiển chương trình sẽ chuyển đến dòng ngay sau vòng
lặp.

Ví dụ :
int main(){
int number = 1;
while (number &lt;= 10){
if(number % 2 == 1){
printf("%d\t", number);
}
number++; }
}
c. Vòng lặp do…while :

o Cú pháp :
do {
statement(s);
} while( condition );

biểu thức điều kiện xuất hiện ở cuối vòng lặp, do đó (các) câu lệnh
trong vòng lặp thực hiện một lần trước khi điều kiện được kiểm
tra.
Nếu điều kiện là đúng, luồng điều khiển nhảy trở lại để làm, và
(các) câu lệnh trong vòng lặp thực hiện lại. Quá trình này lặp lại
cho đến khi điều kiện đã cho trở thành sai.
Ví dụ :
int main(){
int number;
do{
printf("\nNhap number = ");
scanf("%d", &amp;number);
}while(number &lt; 1);
printf("\nnumber = %d", number);
}
IV. FUNCTIONS

1. CẤU TRÚC CƠ BẢN CỦA HÀM

Cú pháp :
kiểu_trả_về tên_hàm(danh_sách_tham_số)
{ nội dung của hàm }

Trong đó :

 kiểu_trả_về: xác định kiểu dữ liệu của giá trị trả về bởi
hàm.
 tên_hàm: định danh hàm; tên hàm nên được đặt với nội
dung miêu tả hoạt động của hàm
 danh_sách_tham_số: là các tham số được truyền vào hàm
để sử dụng bên trong nội dung hàm
Ví dụ :
1. #include <stdio.h>
2. int tinhBinhPhuong(int x) {
3. int ketQua; ketQua = x*x;
4. return ketQua; }
5. int main() {
6. int i;
7. for(i = 1; i <= 10; i++) {
8. printf("Binh phuong cua %d la: %d\n", i, tinhBinhPhuong(i));}
9. return 0; }
Tham số truyền vào hàm
Trong ví dụ trên, giá trị của tham số được truyền vào hàm là i.
Khi đó, i tương đương với x bên trong hàm tinhBinhPhuong

Trả về của hàm

Cũng trong ví dụ trên, câu lệnh để trả về giá trị của hàm
là return ketQua;.

Biểu thức theo sau return chính là giá trị được trả về bởi hàm.

Và một khi hàm được trả về giá trị (gặp return) thì hàm sẽ
dừng ngay lập tức.

Kiểu dữ liệu trả về của hàm

Kiểu dữ liệu trả về của hàm có thể là một những kiểu dữ liệu cơ
bản như: int, char, float, double, void, array...

Trong đó, nếu hàm trả về kiểu dữ liệu void, thì hiểu là hàm đó
không trả về giá trị nào cả.

Ngoài ra, với hàm trả về dữ liệu kiểu void hoặc kiểu int thì bạn


có thể bỏ qua, không cần ghi kiểu dữ liệu trả về.

2. CÁCH KHAI BÁO VÀ GỌI HÀM

Khai báo hàm :


Trước khi sử dụng hàm, bạn cần phải khai báo hàm.

Sau đó, bạn có thể định nghĩa hàm luôn tại vị trí khai báo hoặc ở chỗ
khác (phía dưới phần code gọi hàm)

Ví dụ :

 #include <stdio.h>

 int tinhBinhPhuong(int x);


 int main() {

 int i;

 for(i = 1; i <= 10; i++)

 { printf("Binh phuong cua %d la: %d\n", i, tinhBinhPhuong(i));}

 return 0; }

 int tinhBinhPhuong(int x) {

 int ketQua;

 ketQua = x*x;

 return ketQua;

 }

Gọi hàm :
Sau khi khai báo hàm, bạn có thể gọi nó với tham số truyền vào
tương ứng và kết thúc bằng dấu chấm phẩy (;)

Chú ý:

 Chỉ có một giá trị duy nhất được trả về bởi hàm
 Một chương trình có thể có nhiều hàm
 Một hàm có thể được gọi bên trong một hàm khác. Hay nói cách
khác là trong một hàm có thể gọi nhiều hàm con.

Phạm vi của biến trong hàm


 Biến địa phương (local) được khai báo trong hàm và chỉ tồn tại
ở trong hàm. Sau khi hàm kết thúc, biến local sẽ bị giải phóng.
 Tham số hàm được khai báo ở phần định nghĩa hàm, nó hoạt
động tương tự như biến local.

 Biến toàn cục là biến được khai báo bên ngoài tất cả các hàm.
Nó có thời gian sống là toàn bộ chương trình.

 Chú ý: Nếu một biến được khai báo dạng static thì nó có thời


gian sống là toàn bộ chương trình.

Quy tắc phạm vi hàm


 Một đoạn code ở trong hàm là private với hàm đó.
 Hai hàm có 2 phạm vi khác nhau.
 Một hàm không thể được định nghĩa bên trong một hàm khác.

3. CÁC CÁCH TRUYỀN THAM SỐ VÀO HÀM

Truyền tham số kiểu giá trị


Trong ngôn ngữ lập trình C, mặc định khi truyền tham số vào hàm thì đó
là truyền theo kiểu tham trị (truyền tham số theo giá trị).

Khi đó, chỉ giá trị của tham số là được truyền vào hàm. Mọi thay đổi ở
trong hàm chỉ có tác dụng với biến tạm dùng để lưu những giá trị đó mà
không làm thay đổi biến gốc truyền vào.

Ví dụ :
int x = 6;
int y = 10;

void hoanDoi(int x, int y) {


int temp = x;
x = y;
y = temp;
}

hàm hoán đổi trên sẽ cho kết quả sai. Bởi vì tham số x, y được truyền
vào theo kiểu giá trị. Bạn có thể hình dung là bên trong hàm sẽ tạo ra
biến x_ là copy của x và biến y_ là copy của y.

Rồi khi hoán đổi, bạn chỉ thực hiện hoán đổi trên những biến tạm x_ và
y_. Biến truyền vào là x, y không bị thay đổi giá trị.

Truyền tham số kiểu con trỏ


Bạn có thể truyền tham số vào hàm theo kiểu con trỏ để đảm bảo việc
thay đổi ở trong hàm cũng sẽ có tác dụng với biến ở ngoài hàm.

Ví dụ :
#include <stdio.h>
// Khai bao ham truyen tham so kieu con tro
void hoanDoi(int *x, int *y) {
int temp = *x;
*x = *y;
*y = temp;
}
int main() {
int x = 9;
int y = 6;
// Hoan doi gia tri cua 2 bien
hoanDoi(&x, &y);
printf("x=%d\n", x);
printf("y=%d\n", y);
return 0;
}

Truyền tham số kiểu mảng vào hàm


Khi bạn truyền tham số kiểu mảng vào hàm thì mặc định là sẽ truyền
vào địa chỉ hàm.

Ví dụ truyền tham số kiểu mảng 1 chiều vào hàm :


#include <stdio.h>

// Khai bao ham kieu truyen vao mang

// KHONG truyen vao kich thuoc mang

void change2(int a[]) {

a[0] = 2;

// Khai bao ham kieu truyen vao mang

// CO truyen vao kich thuoc mang

void change3(int a[2]) {

a[0] = 3;

int main() {

int a[2] = {3, 4};


change2(a);

printf("kieu 2 - a[0]=%d\n", a[0]);

change3(a);

printf("kieu 3 - a[0]=%d\n", a[0]);

return 0;

V. POINTER
1. Địa chỉ của biến trong C
Để hiểu và sử dụng được con trỏ trong C, trước tiên bạn cần hiểu về khái
niệm địa chỉ ở trong C. Xem ví dụ :

 #include <stdio.h>
 int main()
 {
 int number = 5;
 printf("Gia tri cua number = %d", number);

 // truy xuất địa chỉ bằng cách thêm & trước tên biến
 printf("\nDia chi cua number = %d", &number);  
 return 0;
 }

Kết quả khi chạy chương trình :


 Gia tri cua number = 5
 Dia chi cua number = 6487580
Chú ý: 
 Bạn có thể sẽ nhận được các địa chỉ khác nhau mỗi khi
chạy code trên.
 Để nhận giá trị địa chỉ là hexa như ảnh ở đâu bài, bạn
thay %d bằng %x là được.
2. Con trỏ trong C
a. Khái niệm :
Con trỏ trong C cũng chỉ là là biến, cũng có thể khai báo, khởi tạo và lưu
trữ giá trị và có địa chỉ của riêng nó. Nhưng biến con trỏ không lưu giá
trị bình thường, nó là biến trỏ tới 1 địa chỉ khác, tức mang giá trị là 1 địa
chỉ.
Trong đó :

 Giá trị của con trỏ: địa chỉ mà con trỏ trỏ đến.
 Địa chỉ của con trỏ: địa chỉ của bản thân biến con trỏ đó.
 Giá trị của biến nơi con trỏ đang trỏ tới.
 Địa chỉ của biến nơi con trỏ đang trỏ tới = giá trị của con trỏ.

b. Cách khai báo con trỏ


Cú pháp : <kiểu dữ liệu> * <tên biến>
Trong đó :

 Kiểu dữ liệu có thể là: void, int, float, double,…


 Dấu * trước tên biến là ký hiệu báo cho trình biên dịch biết ta
đang khai báo con trỏ.
Ví dụ :
 int *p_i; // khai báo con trỏ để trỏ tới biến kiểu nguyên
 int *p, val; // khai báo con trỏ p kiểu int, biến val (không phải
con trỏ) kiểu int
 float *p_f; // khai báo con trỏ để trỏ tới biến kiểu thực
 char *p_char; // khai báo con trỏ để trỏ tới biến kiểu ký tự
 void *p_v; // con trỏ kiểu void (không kiểu)

c. Gán giá trị cho con trỏ


Cách 1 :
 int *p, value;
 value = 5;
 p = &value; // khởi tạo giá trị cho con trỏ p là địa chỉ của value
Cách 2 :
 int value = 5;
 int *p = &value; // khai báo con trỏ p và khởi tạo giá trị cho con
trỏ là địa chỉ của value
Lưu ý :

 Con trỏ khi khai báo nên được khởi tạo giá trị ngay.
 Con trỏ kiểu void là loại biến con trỏ tổng quát, nó có thể nhận
địa chỉ của biến bất kỳ ở bất cứ kiểu dữ liệu nào.
 Khởi tạo con trỏ bằng địa chỉ NULL nếu chưa cần dùng theo
cách sau: int *p = NULL. Khi đó con trỏ NULL luôn có giá
trị 0.

You might also like