Lệnh điều kiện if ... Khai báo mảng của các kiểu dữ liệu mảng là 1 tập hợp các ptử cùng kiểu dữ liệu: 7... Lệnh điều kiện if .... • Khi “biến” có giá trị = với “giá trị” ở case thì các
Trang 1HƯỚNG DẪN LẬP TRÌNH C
CHƯƠNG 1: Cơ bản Lập Trình C
1. Lịch Sử Của C++ 2
2. 1 chương trình C 2
3. Các kiểu dữ liệu 2
4. Khai báo Biến 2
5. BiỂU THỨC (EXPRESSION) 3
6. Khai báo mảng của các kiểu dữ liệu 3
7. Nhập xuất cơ bản 3
8. Hàm Con 4
9. Lệnh điều kiện if else if else 4
10. Lệnh switch( ) 5
11. Lệnh vòng lặp while(điều kiện lặp) 5
12. Lệnh vòng lặp do{} while() 5
13. Lệnh vòng lặp for 5
14. Xử lý Hàm 6
CHƯƠNG 2: Mảng 1 chiều 1. Định nghĩa 7
2. Truyền mảng vào hàm 7
3. Kĩ thuật tìm 7
4. Kỹ thuật đặt lính canh 7
5. Kĩ thuật liệt kê vị trí 8
6. Kĩ thuật tính tổng 8
7. Kĩ thuật đếm 8
8. Kĩ thuật thêm 8
9. Kĩ thuật xoá 8
10. Một số bài tập minh hoạ 9
CHƯƠNG 3: Ma trận – Con trỏ 1. Ma trận 12
2. Con Trỏ 12
3. Một số bài tập minh hoạ 13
CHƯƠNG 4: Trừu tượng hoá dữ liệu 1. Định nghĩa 15
2. Nhập – Xuất 15
3. Các bài tập minh hoạ 15
CHƯƠNG 5: Đệ Quy – Độ phức tạp của thuật toán (tham khảo) 1. Đệ quy 18
2. Độ phức tạp thuật toán 19
CHƯƠNG 6: Tìm kíêm 1. Tìm kíêm tuyến tính 20
2. Tìm kiếm nhị phân 20
CHƯƠNG 7: Sắp Xếp Mảng 1. Sắp xếp tuần tự (InterchangeSort) 21
2. Sắp xếp chèn (InsertionSort) 21
3. Sắp xếp chọn (SelectionSort) 21
4. Sắp xếp nổi bọt (BubbleSort) 22
5. Một số bài tập minh hoạ 22
6. Sắp xếp ma trận tăng dần 23
Trang 21. Danh sách liên kết đơn 24
2. Danh sách liên kết kép (tham khảo) 25
3. Bài tập minh hoạ 26
CHƯƠNG 9: STACK & QUEUE (tham khảo)
3. Cây Nhị Phân Tìm Kiếm 30
CHƯƠNG 11: Chuyển qua lại các Dạng Cấu Trúc
CHƯƠNG 1: Cơ bản Lập Trình C
1 Lịch Sử Của C++
thống cho hệ điều hành Unix.
2 CHƯƠNG trình C gồm 3 phần chính:
3 Các kiểu dữ liệu: Có 2 loại:
• Lưu ý : Các kiểu mới tuỳ theo đề bài sẽ có thay đổi (VD MaSV là kiểu char[5]), 2 kiểu trên là thường đc sử
dụng.
4 Khai báo Biến:
• Biến mặt nạ: &”tên biến” = “biến” : chỉ là 1 tên gọi khác của biến kia, tức nếu có xử lý trên biến mặt nạ thì biến kia cũng bị thay đổi y như vậy, do đó cũng chỉ là 1 tên khác
2
a
b
c
Trang 3Khai báo như vậy có nghĩa:
- ta khai báo 1 biến số nguyên a, gán cho a = 5
- Sau đó ta đặt 1 tên khác cho a, là b
- khi lệnh a++ đc thực hiện thì a = b = 6
- Và khi b++ đc thực hiện thì a = b = 7
- Khi printf a và b đều cho ra kết quả là 7
- Nếu xuất ra địa chỉ của a và b thì ta sẽ thấy chúng cùng địa chỉ, b chỉ là 1 tên khác của a
giống biến 2 Những gì xảy ra cho “biến 1” ko ảnh hưởng gì “biến 2”
5 BiỂU THỨC (EXPRESSION)
6 Khai báo mảng của các kiểu dữ liệu (mảng là 1 tập hợp các ptử cùng kiểu dữ liệu):
7 Nhập xuất cơ bản:
• Nhập: scanf(“ … ”, &… ); và gets(…);
• Xuất : printf(“ % ”, … ); hoặc printf(“ 1 câu văn ”); hoặc printf(“ 1 câu văn % ”, …);
Trang 4printf(“So nguyen vua nhap la : %d,” n);
printf(“Chuoi vua nhap la : %s”,s);
getch();
}
4 Các câu lệnh nhập
Các câu lệnh xuất
Trang 58 Hàm Con: có thể chuyển VD trên thành 1 CT có 2 hàm con, đó là hàm nhập & xuất
Dòng
#include<conio.h>
#include<stdio.h>
void nhap(int &n, char* &s){
printf(“ Moi nhap so nguyen n “);
void xuat(int n, char *s){
printf(“So nguyen vua nhap la : %d,” n);
printf(“Chuoi vua nhap la : %s”,s);
trùng tên với trong hàm con (dòng 3 và dòng 18), VD hàm
nhập ta có thể sửa lại như sau và vẫn đúg:
void nhap(int &a, char* &b){
printf(“ Moi nhap so nguyen n “);
9 Lệnh điều kiện if else if else:
<Xử lý>; if( điều kiện ) <Xử lý>;
VD: tb = 8 thì sẽ bỏ qua 2 if đầu và xuất ra “Khá” VD: tb = 2 thì sẽ bỏ qua 3 if đầu và xuất ra “Loại”.
Trang 6• “biến” có thể trong 3 kiểu dữ liệu: int / long / char
• Hàm switch đc dùng thay cho if else if else khi số if else lớn, khó nhìn Nhưng cũng có mặt hạn chế là ko dùng cho float / chuỗi,
và ko so sánh đc.
• Khi “biến” có giá trị = với “giá trị” ở case thì các lệnh xử lý ở case
đó sẽ đc thực thi đến khi gặp lệnh break
ngoặc đều thuộc vòng lặp, sẽ đc
thực hiện đến khi nào đk lặp sai
(tức a <= b)
Nếu ko có { } thì lệnh gần while nhất sẽ thuộc vòng lặp & sẽ đc thực hiện đến khi nào đk lặp sai (tức a <= b)
Nếu có { } thì các lệnh trg dấu ngoặc đều thuộc vòng lặp,
13 Lệnh vòng lặp for(“biểu thức 1” ; ”biểu thức 2” ; ”biểu thức 3”) :
xảy ra biểu thức 1 -> so sánh trong biểu thức 2 -> thực thi các xử lý vòng for -> xử lý trog biểu thức 3
còn a++ chỉ xảy ra sau khi vòng for dừng
thuộc vòng for do có
dấu “;” cuối vòng for
6
Trang 7Lúc này nếu trong void main ta gọi đến hàm tong() , thì sau khi khai báo x = 5, y = 3,
CT sẽ gọi đến hàm xuly(x,y) … lúc này trước khi vào thân hàm xuly, sẽ xảy ra các
câu lệnh sau:
int a = x;
int b = y;
=> ta gán 2 bíên khác, là a và b, có giá trị bằng với x và y => Khi xử lý a,b trong hàm
xuly thì x,y ở ngoài ko thay đổi giá trị ban đầu Khi ta xuất a, b ra màn hình thì
Lúc này nếu trong void main ta gọi đến hàm tong() , thì sau khi khai báo x = 5, y = 3,
CT sẽ gọi đến hàm xuly(x,y) … lúc này trước khi vào thân hàm xuly, sẽ xảy ra các
Dù cho tên biến trong và ngoài hàm có giống nhau, nhưng nếu đó ko phải khai báo
biến mặt nạ, thì cũng ko làm thay đổi khi ra khỏi hàm VD bên:
Biến x thay đổi trong hàm xuly sẽ làm x ngoài hàm tong thay đổi theo Nhưng biến y thì ko
Trong TH này, kiểu khai báo x ta gọi là khai báo tham số (thay đổi sau lới gọi hàm), y
ta gọi là khai báo tham trị (ko thay đổi sau lời gọi hàm)
Trang 8CHƯƠNG 2: Mảng 1 chiều
1 Định nghĩa: Mảng 1 chiều thực chất là 1 tập hợp các biến có cùng kiểu, có địa chỉ sát bên nhau VD : thay vì khai
báo a,b,c,d,e,f,g,h là các biến số nguyên, ta có thể khai báo int a[8] Ta sẽ có a[0], a[1], ,a[7] là các biến int cũng
giống như a,b,c,d,e,f,g,h, nhưng dễ dàng quản lý bởi vòng for: for( int i=0; i<n; i++ )
2 Truyền mảng vào hàm: Khi truyền vào hàm con, ta luôn truyền theo cách tham số: thay đổi cả trong & ngoài
hàm VD về nhập xuất mảng:
#include<conio.h>
#include<stdio.h>
#define MAX 50
void nhap(int a[ ], int &n){
printf(“ Moi nhap n “);
scanf(“%d”,&n);
printf(“Moi nhap mang ”);
for( int i=0; i<n; i++ )
nhap1ptu(a[i]);
}
void xuat(int a[ ], int n){
printf(“Mang vua nhap: ”);
for( int i=0; i<n; i++ )
void nhap(float a[ ], int &n){
printf(“ Moi nhap n “);
scanf(“%d”,&n);
printf(“Moi nhap mang ”);
for( int i=0; i<n; i++ )
nhap1ptu(a[i]);
}
void xuat(float a[ ], int n){
printf(“Mang vua nhap: ”);
for( int i=0; i<n; i++ )
xuat1ptu(a[i]);
}void main(){
void nhap(sv a[ ], int &n){
printf(“ Moi nhap n “);
scanf(“%d”,&n);
printf(“Moi nhap mang ”);
for( int i=0; i<n; i++ )
nhap1ptu(a[i]);
}
void xuat(sv a[ ], int n){
printf(“Mang vua nhap: ”);
for( int i=0; i<n; i++ )
xuat1ptu(a[i]);
}void main(){
sv a[MAX];
int n;
nhap(a,n);
getch();
lưu sự thay đổi này để dùng cho các hàm sau đó như hàm xuất mảng
for(int i = vt; i<n; i++)
if( a[i] < dnn && a[i] > 0 )
for(int i = vt; i<n; i++)
if( xetngto(a[i]) && a[i] > ln )
for(int i=0; i<n; i++)
if( a[i] > a[t] )
for(int i = vt; i<n; i++)
if( a[i] < a[vt] && a[i] > 0 )
vt = i;
return vt;
}
8
Trang 95 Kĩ thuật liệt kê vị trí: Thay vì return như kĩ thuật tìm vị trí đầu, cuối, với mỗi ptử thoã yêu cầu, ta xuất ra màn
hình vị trí của nó VD: liệt kê vị trí các ptử max, liệt kê vị trí các ptử dương min, hay liệt kê các ptử ngtố
void lietke_ptu_lonhon_k(int a[], int n, int k)
{
for(int i = vt; i<n; i++)
if( a[i] > k ) printf("%5d",a[i]);
void lietke_vitri_ptu_max(int a[], int n)
{
int t = ptu_max(a,n);
for(int i=0; i<n; i++)
if(a[i] == t) printf("%5d",i);
void them_ptu(int a[],int &n, int k, int t)
for(int i=0; i<n; )
if( a[i] == ln ) xoavitri(a,n,i);
}
Trang 1010 Một số bài tập minh hoạ:
#include<conio.h>
#include<stdio.h>
#define maximum 100
void nhap(float a[],int &n) {
printf("Nhap vao tong cac phan tu :");
scanf("%d", &n);
printf("Bat dau nhap cac ptu cua mang : \n");
for( int i=0; i<n; i++) {
printf("Ptu thu %d : ",i+1 );
scanf("%f",&a[i]);
}
}
void xuat(float a[], int n) {
for(int i=0; i<n; i++)
void nhap(int a[],int &n) {
printf("Nhap vao tong cac phan tu, luu y phai <=100 va >0 :");
scanf("%d", &n);
printf("Bat dau nhap cac ptu cua mang : \n");
for( int i=0; i<n; i++) {
printf("So thu %d : ",i+1 );
scanf("%d",&a[i]);
}
}
void xuat(int a[], int n) {
for(int i=0; i<n; i++)
if(s==0) printf("\nMang ko co ptu chinh phuong ");
else printf("\nTong cac ptu chinh phuong: %ld",s);
void nhap(float a[],int &n) {
printf("Nhap vao tong cac phan tu:");
scanf("%d", &n);
printf("Bat dau nhap cac ptu cua mang : \n");
for( int i=0; i<n; i++) {
printf("So thu %d : ",i+1 );
scanf("%f",&a[i]);
}
}
void xuat(float a[], int n) {
for(int i=0; i<n; i++)
printf("%4.1f",a[i]);
}
int demchiahetbay(float a[], int n) {
int dem=0;
for(int i=0; i<n; i++)
if ( a[i] – (int) a[i] == 0 )
if( a[i]%7==0 && a[i]>0 )
printf("\nMang vua nhap : "); xuat(a,n);
int dem = demchiahetbay(a,n);
printf("\nMang co %d ptu duong chia het cho 7 ",dem);
getch();
}
10
Trang 11• Đếm số lượng số nguyên tố trong mảng các số nguyên
#include<conio.h>
#include<stdio.h>
#include<math.h>
#define maximum 100
void nhap(int a[],int &n) {
printf("Nhap vao tong cac phan tu :");
scanf("%d", &n);
printf("Bat dau nhap cac ptu cua mang : \n");
for( int i=0; i<n; i++) {
printf("So thu %d : ",i+1 );
printf("\nMang vua nhap : "); xuat(a,n);
int dem = demnguyento(a,n);
printf("\nMang co %d so nguyen to.",dem);
void nhap(float a[],int &n) {
printf("Nhap vao tong cac phan tu :");
scanf("%d", &n);
printf("Bat dau nhap cac ptu cua mang : \n");
for( int i=0; i<n; i++) {
printf("So thu %d : ",i+1 );
scanf("%f",&a[i]);
}
}
void xuat(float a[], int n) {
for(int i=0; i<n; i++)
printf("%4.1f",a[i]);
}
int tontaichan(float a[], int n) {
for(int i=0; i<n; i++)
if( a[i] – (int) a[i] == 0 )
if(t==0) printf("\nMang ko co gia tri chan.");
else printf("\nMang co gia tri chan.");
printf("Bat dau nhap cac ptu cua mang : \n");
for( int i=0; i<n; i++) {
printf("So thu %d : ",i+1 );
scanf("%d",&a[i]);
}
}
void xuat(int a[], int n) {
for(int i=0; i<n; i++)
printf("%4d",a[i]);
}
int kttang(int a[], int n) {
for(int i=0; i<n-1; i++)
if(t==0) printf("\nMang ko co tinh tang dan.");
else printf("\nMang co tinh tang dan.");
getch();
}
Trang 12• Xoá các ptử âm trong mảng số thực
#include<conio.h>
#include<stdio.h>
#define maximum 100
void nhap(float a[],int &n) {
printf("Nhap vao tong cac phan tu:"); scanf("%d", &n);
printf("Bat dau nhap cac ptu cua mang : \n");
for( int i=0; i<n; i++) {
printf("So thu %d : ",i+1 );
scanf("%f",&a[i]);
}
}
void xuat(float a[], int n) {
for(int i=0; i<n; i++)
printf("%4.1f",a[i]);
}
void xoavitri(float a[], int &n,int vitrixoa) {
for (int i=vitrixoa; i<n; i++)
a[i]=a[i+1];
n=n-1;
}
void xoaam(float a[], int &n) {
for(int i=0; i<n; )
void nhap(int a[],int &n) {
printf("Nhap vao tong cac phan tu:"); scanf("%d", &n);
printf("Bat dau nhap cac ptu cua mang : \n");
for( int i=0; i<n; i++) {
printf("So thu %d : ",i+1 );
scanf("%d",&a[i]);
}
}
void xuat(int a[], int n) {
for(int i=0; i<n; i++)
void xoavitri(int a[], int &n,int vitrixoa) {
for (int i=vitrixoa; i<n; i++)
for(int i=0; i<n;)
if( xet_so_nto(a[i])==1 ) xoavitri(a,n,i);
Trang 13printf("Bat dau nhap cac ptu: \n");
for( int i=0; i<m; i++ )
for( int j=0;j<n; j++ ) {
printf(“\na[%d][%d] = ”,i,j);
scanf(“%d”,&a[i][j]) }
• Các kĩ thuật đếm, tính tổng, tìm kiếm, đặt cơ hiệu thực tương tự mảng 1 chiều, chỉ khác ở 2 vòng for
2 Con Trỏ:
• Định nghĩa: Con trỏ đơn giản chỉ là địa chỉ của một vị trí bộ nhớ và cung cấp cách gián tiếp để truy xuất dữ liệu
trong bộ nhớ VD:
• Cấp phát: cách dễ nhất là dùng new: KDL *<tên con trỏ> = new KDL[bề rộng vùng cấp phát]
động: sử dụng mảng động giúp giảm chi phí bộ nhớ hơn mảng tĩnh.VD:
• Gỉai phóng bộ nhớ: Dùng delete: delete <tên con trỏ>
Trang 153 Một số bài tập minh hoạ:
#include<conio.h>
#include<stdio.h>
#define mx 30
void nhaphangcot( int &m, int &n ) {
printf("Nhap vao so hang ma tran :"); scanf("%d", &m);
printf("Nhap vao so cot ma tran :"); scanf("%d", &n);
}
void nhap( float a[][mx],int m, int n ) {
printf("Bat dau nhap cac ptu cua ma tran \n");
for( int i=0; i<m; i++ )
for( int j=0;j<n; j++ ){
printf(“a[%d][%d] = ”,i,j);
scanf(“%f”,&a[i][j]);
}}
void xuat( float a[][mx], int m, int n ) {
for( int i=0; i<m; i++ ) {
void nhaphangcot( int &m, int &n ) {
printf("Nhap vao so hang ma tran:"); scanf("%d", &m);
printf("Nhap vao so cot ma tran:"); scanf("%d", &n);
}
void nhap( int a[][mx],int m, int n ) {
printf("Bat dau nhap cac ptu cua ma tran \n");
for( int i=0; i<m; i++ )
for( int j=0;j<n; j++ ){
printf(“a[%d][%d] = ”,i,j);
scanf(“%d”,&a[i][j]);
}}
void xuat( int a[][mx], int m, int n ) {
for( int i=0; i<m; i++ ) {
void nhaphangcot( int &m, int &n ) {
printf("Nhap vao so hang ma tran:"); scanf("%d", &m);
printf("Nhap vao so cot ma tran:"); scanf("%d", &n);
}
void nhap( float a[][mx],int m, int n ) {
printf("Bat dau nhap cac ptu cua ma tran \n");
for( int i=0; i<m; i++ )
for( int j=0;j<n; j++ ){
printf(“a[%d][%d] = ”,i,j);
scanf(“%f”,&a[i][j]);
}}
void xuat( float a[][mx], int m, int n ) {
for( int i=0; i<m; i++ ) {
if(kq==0) printf("\nMa tran ko co ptu ngto ");
else printf("\nSo cac ptu ngto la : %d",kq);
getch();
Trang 16• Đếm số lượng số âm trên 1 hàng trong ma trận các số nguyên
#include<conio.h>
#include<stdio.h>
#define mx 30
void nhaphangcot( int &m, int &n ) {
printf("Nhap vao so hang ma tran:"); scanf("%d", &m);
printf("Nhap vao so cot ma tran:"); scanf("%d", &n);
}
void nhap( int a[][mx],int m, int n ) {
printf("Bat dau nhap cac ptu cua ma tran \n");
for( int i=0; i<m; i++ )
for( int j=0;j<n; j++ ){
printf(“a[%d][%d] = ”,i,j);
scanf(“%d”,&a[i][j]);
}}
void xuat( int a[][mx], int m, int n ) {
for( int i=0; i<m; i++ ) {
void am_hang( int a[][mx], int m, int n ) {
for( int i=0; i<m; i++ ) {
void nhaphangcot( int &m, int &n ) {
printf("Nhap vao so hang ma tran:"); scanf("%d", &m);
printf("Nhap vao so cot ma tran:"); scanf("%d", &n);
}
void nhap( float a[][mx],int m, int n ) {
printf("Bat dau nhap cac ptu cua ma tran \n");
for( int i=0; i<m; i++ )
for( int j=0;j<n; j++ ){
printf(“a[%d][%d] = ”,i,j);
scanf(“%f”,&a[i][j]);
}}
void xuat( float a[][mx], int m, int n ) {
for( int i=0; i<m; i++ ) {
int tontai_le( float a[][mx], int m, int n ) {
for( int i=0; i<m; i++ )
if(kq==1) printf("\nMa tran co ptu le ");
else printf("\nMa tran toan chan.");
void nhaphangcot( int &m, int &n ) {
printf("Nhap vao so hang ma tran:"); scanf("%d", &m);
printf("Nhap vao so cot ma tran:"); scanf("%d", &n);
}
void nhap( float a[][mx],int m, int n ) {
printf("Bat dau nhap cac ptu cua ma tran \n");
for( int i=0; i<m; i++ )
for( int j=0;j<n; j++ ){
printf(“a[%d][%d] = ”,i,j);
scanf(“%f”,&a[i][j]);
}}
void xuat( float a[][mx], int m, int n ) {
for( int i=0; i<m; i++ ) {
for( i=0;i<m; i++ )
if(kq == 0) printf("\nMa tran ko co gia tri am");
else printf("\nGia tri am MAX la %d",kq);getch();
}
16
Trang 18CHƯƠNG 4: Trừu tượng hoá dữ liệu
1 Định nghĩa:
kiểu dữ liệu đơn giản thành 1 kiểu phức tạp hơn, nhằm mô tả 1 đối tượng trong thế giới thực
• VD: Ta khai báo kiểu dữ liệu sv, gán a là 1 sv: sv a Ta có a là 1 biến có kiểu sv _ 1 sinh viên, có họ tên,
điểm trung bình, năm sinh …
ở nhập float & thêm tên đối tượng của struct VD: Ta khai báo: sv x;
void nhap(sv &x){
biến t kiểu float Và trước khi gets(…) phải có flushall(); Khi xuất ra hay sử dụng thì bình thường.
3 Các bài tập minh hoạ
void nhap( ps &p ){
printf("\nNhap tu cua phan so : "); scanf("%d",&p.tu);
printf("Nhap mau cua phan so : "); scanf("%d",&p.mau);
printf("\tNhap phan so 1 : "); nhap(m);
printf("\tNhap phan so 2 : "); nhap(p);
printf("\nPhan so vua nhap la : "); xuat(m); xuat(p);