• Trường hợp ta không khai báo kiểu dữ liệu trả về thì chương trình dịch của C sẽ ngầm hiểu rằng kiểu dữ liệu trả về của hàm là kiểu int. Dòng đầu hàm.[r]
(1)Nội dung
Phần 3: Lập trình C
• Chương 1: Tổng quan ngơn ngữ C
• Chương 2: Kiểu liệu biểu thức C • Chương 3: Cấu trúc lập trình C
• Chương 4: Mảng xâu ký tự • Chương 5: Cấu trúc
• Chương 6: Hàm
• Chương 7: Tệp liệu
(2)Mảng
• Khái niệm mảng
(3)Khái niệm mảng
• Thực tế, thường gặp đối tượng có tính chất chung
– Tháng năm
– Điểm trung bình sinh viên lớp
• Các đối tượng nhóm lại tên
• Phần tử đặc trưng tên nhóm thứ tự nhóm
– Tháng thứ năm: Tháng – Sinh viên thứ 17 lớp:…
• Số thứ tự nhóm: Chỉ số phần tử
(4)Khái niệm mảng
• Kiểu mảng kiểu liệu gồm số hữu hạn thành phần Các thành
phần có kiểu, gọi kiểu sở kiểu thành phần.
(5)Mảng
• Khái niệm mảng
• Khai báo sử dụng mảng • Các thao tác thường gặp
(6)Khai báo
Cú pháp
kiểu_dữ_liệu tên_mảng [kích_thước_mảng];
• kiểu_dữ_liệu: kiểu liệu phần tử trong mảng
• tên_mảng: tên mảng
• kích_thước_mảng: số phần tử mảng Ví dụ
// khai báo mảng 10 phần tử có kiểu liệu int
(7)Cấp phát nhớ
• Các phần tử mảng cấp phát các ô nhớ nhớ
• Biến mảng lưu trữ địa nhớ trong vùng nhớ cấp phát
• Ngơn ngữ C đánh số phần tử mảng 0
– Phần tử thứ i mang_nguyen xác định mang_nguyen[i-1]
7
mang_nguyen[0] mang_nguyen[1] ……… mang_nguyen[9]
(8)Truy cập đến thành phần mảng
• Truy cập vào phần tử mảng thơng qua tên mảng số phần tử phần tử mảng
tên_mảng[giá_trị_chỉ_số_phần_tử]
– Chú ý: số
Ví dụ
– int a[10]; //mảng nguyên có 10 phần tử
(9)Mảng nhiều chiều
• Mỗi phần tử mảng mảng
=> mảng nhiều chiều
• Ví dụ
– int a[6][5] ; //mảng a gồm phần tử phần tử mảng gồm số nguyên int
• a[0]: Phần tử mảng a, mảng chiều • a[i][j] :Phần tử thứ j+1 mảng a[i]
– int b[3][4][5]; // mảng b gồm phần tử, phần tử mảng hai chiều gồm phần tử Mỗi phần tử mảng hai chiều mảng gồm số nguyên int b mảng chiều
(10)Khởi tạo giá trị cho mảng
Các phần tử mảng khởi tạo giá trị khai báo
• int a[4] = {1,4,6,2};
• int b[2][3]={ {1,2,3}, {4,5,6} }; Chú ý
– Số lượng giá trị khởi tạo không lớn số lượng phần tử mảng
– Nếu số lượng nhỏ hơn, phần tử lại khởi tạo giá trị
– Có thể xác định kích thước mảng thông qua số giá trị khởi tạo để trống kích thước mảng – int array1 [8] = {2, 4, 6, 8, 10, 12, 14, 16};
(11)Mảng
• Khái niệm mảng
• Khai báo sử dụng mảng • Các thao tác thường gặp
(12)Nhập liệu cho mảng
Dùng hàm scanf() Ví dụ
int a[10];//Mảng nguyên 10 phần tử • Nhập liệu cho phần tử a[1]:
scanf(“%d”, & a[1]);
• Nhập liệu cho toàn phần tử mảng sử dụng vòng lặp for
for(int i=0; i < 10; i++) scanf(“%d”, & a[i]);
(13)Ví dụ
#include <stdio.h> #define MONTHS 12 int main(){
int rainfall[MONTHS], i;
for ( i=0; i < MONTHS; i++ ){
printf(“Nhap vao phan tu thu
%d: “, i+1); scanf("%d", &rainfall[i] );
}
return 0; }
(14)Lưu ý
• Trường hợp số phần tử mảng khơng biết trước (chỉ biết chương trình
đang thực hiện) mà biết trước số phần
tử tối đa tối đa
– khai báo mảng với kích thước tối đa
– sử dụng biến lưu số phần tử thực mảng
• Ví dụ:
(15)#include<stdio.h> #include<conio.h> void main(){
int a[100]; int n, i;
do{
printf(“\n Cho biet so phan tu cua mang: “); scanf(“%d”,&n);
}while (n>100||n<=0); for(i = 0; i < n; i++){
printf(“a[%d] = ", i); scanf("%d",&a[i]); }
getch(); }
(16)Xuất liệu mảng
Dùng hàm printf()
– int a[10];
– Hiện thị phần tử thứ 5: printf(“%d”,a[4]);
– Để hiển thị tất phần tử: Vòng lặp for
Ví dụ
– Hiển thị phần tử
– Hiển thị tất phần tử, phần tử dòng
– Hiển thị tất phần tử dòng, cách vị trí
(17)Xuất liệu mảng
#include <stdio.h> #define MONTHS 12 void main(){
int rainfall[MONTHS], i;
for ( i=0; i < MONTHS; i++ ){
printf(“Nhap vao phan tu thu %d: “, i+1); scanf("%d", &rainfall[i] );
}
} 17
for ( i=0; i < MONTHS; i++ )
printf( "%4d ” , rainfall[i]); for ( i=0; i < MONTHS; i++ )
printf( "%d\n” , rainfall[i]); for ( i=0; i < MONTHS; i++ ){
(18)(19)Nhập đưa hình ma trận
1 #include <stdio.h> void main(){
3 int A[20][20], m,n,i,j;
4 printf("Nhap so hang : "); scanf("%d",&m); printf("Nhap so cot : "); scanf("%d",&n); printf("\n");
7 for ( i=0; i < m; i++ ) for(j=0; j < n; j++) {
9 printf("Nhap phan tu [%d,%d]: ", i+1,j+1); 10 scanf("%d", &A[i][j] );
11 }
12 printf("\n\n MA TRAN DA NHAP \n\n"); 13 for ( i=0; i < m; i++ ){
14 for(j=0; j < n; j++)
15 printf( "%4d" ,A[i][j]); 16 printf("\n");
17 }
(20)(21)Tìm giá trị lớn nhất, nhỏ nhất
• Tìm giá trị lớn nhất
– Giả sử phần tử phần tử – Lần lượt so sánh với phần tử lại – Nếu lớn => so sánh tiếp
– Nếu nhỏ => coi phần tử phần tử lớn tiếp tục so sánh
– Cách làm?
• Tìm giá trị nhỏ nhất: tương tự
(22)Các thao tác mảng
max = rainfall[0];
for(i = 1; i < n; i++) if(max < a[i])
max = a[i];
(23)Tìm kiếm mảng
• Bài tốn
– Cho mảng liệu a giá trị k
– Tìm phần tử mảng a có giá trị (giống) với k Nếu có in vị trí (chỉ số) phần tử Ngược lại thơng báo khơng tìm thấy
• Cách làm
– Duyệt toàn phần tử mảng – Nếu a[i] (giống) k lưu lại số i
– Sử dụng biến để xác định tìm thấy hay khơng tìm thấy
(24)Tìm kiếm mảng
• Phân tích
– Duyệt tồn phần tử
• Vịng lặp for (while, while)
– Lưu lại i a[i] (giống) k
• Sử dụng mảng lưu số
– Biến xác định tìm thấy hay khơng tìm thấy
• Biến nhận giá trị
(25)Tìm kiếm mảng(1)
#include <stdio.h> #include <conio.h> void main(){
int a[100], chi_so[100];
int n;//n la số phần tử mảng int i, k, kiem_tra;
printf(“ Nhap vao so phan tu cua mang: “); scanf(“%d”,&n);
(26)Tìm kiếm mảng(2)
kiem_tra = 0;
// Duyệt qua tất phần tử for(i = 0;i<n;i++)
if(a[i] = = k) {
chi_so[kiem_tra] = i; kiem_tra ++;
(27)Tìm kiếm mảng(3)
if(kiem_tra > 0){
printf(“Trong mang co %d phan tu co gia tri bang %d”,kiem_tra,k);
printf(“\nChi so cua cac phan tula:“); for(i = 0;i < kiem_tra;i++)
printf(“%3d”,chi_so[i]); } else
printf(“\n Trong mang khong co phan tu nao co gia tri bang %d”,k); getch();
}
(28)Sắp xếp mảng
• Bài tốn
– Cho mảng a gồm n phần tử Sắp xếp phần tử mảng a theo thứ tự tăng
(29)Sắp xếp mảng
• Giải thuật xếp
– Sắp xếp thêm dần (insertion sort) – Sắp xếp lựa chọn (selection sort) – Sắp xếp bọt (bubble sort)
– Sắp xếp vun đống (heap sort) – Sắp xếp nhanh (quick sort)
– Sắp xếp trộn (merge sort) – …
(30)Giải thuật xếp lựa chọn
• Tìm phần tử nhỏ chưa xếp trong mảng
(31)Ý tưởng
• Lần xếp thứ 1
– So sánh a[0] với a[i], i = n-1
a[0] > a[i] => đổi chỗ a[0] a[i] – Thu a[0] phần tử nhỏ
• Lần xếp thứ 2
– So sánh a[1] với a[i], i = n-1
a[1] > a[i] => đổi chỗ a[1] a[i] – Thu a[1] phần tử nhỏ thứ
(32)Ý tưởng
• Lần xếp thứ k
– So sánh a[k-1] với a[i], i = k n-1
a[k-1] > a[i] => đổi chỗ a[k-1] a[i] – Thu a[k-1] phần tử nhỏ thứ k
• …
• Lần xếp thứ n-1
– So sánh a[n-2] a[n-1]
a[n-2] > a[n-1] => đổi chỗ a[n-2] a[n-1] – Thu a[n-2] phần tử nhó thứ n-1 => lại
(33)Minh họa
• A = { 12, 5, 3, };
Lượt Lượt Lượt
12 3 3 3
5 12 4 4
3 5 12 5
4 4 5 12
(34)Giải thuật
//Khai bao cac bien int a[100];
int i, j, tmp; //Sap xep
for (i = 0; i < n-1; i++){
for (j = i+1; j <n ; j++) if ( a[i] > a[j]){
(35)Ví dụ
• Nhập vào từ bàn phím mảng số
nguyên m số phần tử nhập từ bàn phím
• Hiển thị phần tử vừa nhập vào • Sắp xếp mảng m theo thứ tự tăng dần
trong có hiển thị phần tử lượt xếp.
(36)Chương trình (1)
#include <stdio.h> #include <conio.h> void main(){
int m[100];
int n; // n la số phần tử mảng int i, j, k;
// Nhập giá trị liệu cho mảng m printf(“Cho biet so phan tu co mang:“);
(37)Chương trình (2)
// nhập giá trị cho phần tử for(i = 0;i<n;i++){
printf(“\nCho biet gia tri cua m[%d]=“,i); scanf(“%d”,&m[i]);
}
// Hiển thị mảng vừa nhập vào
printf(“Mang truoc sap xep\n“); for(i=0;i<n;i++)
printf(“%3d”,m[i]);
(38)Chương trình (3)
for(i = 0; i<n-1; i++){ for(j = i+1; j<n; j++){
if(m[j]<m[i]){
temp = m[j];
m[j] = m[i];m[i] = temp; }
printf(“\n luot sap xep thu %d”,i+1); for(k = 0;k < n ;k++)
printf(“%3d”,m[k]); }
(39)Bài tập
1 Nhập vào dãy số, tính đưa hình
1 Tổng tích dãy số
2 Các số chia hết cho lớn 10 Đếm số nằm đoạn [100,1000]
2 Nhập vào dãy số; tìm số chẵn nhỏ dãy
3 Nhập dãy số; đếm xem có số thỏa mãn điều kiện xi=(xi-1+xi+1)/2
4 Đọc vào dãy số có n phần từ (n<100) Đọc số x số k nguyên Chèn x vào vị trí k dãy Nếu k>n, chèn x vào vị trí n+1
5 Nhập vào n dãy số (x1,x2,…xn) ;(y1,y2, yn) tính
39 1 1 i 2 n i
i sin ) ( ) ) x
cosx ) n i n i i i
i b x y c y
(40)Bài tập
1 Nhập vào từ bàn phím dãy số nguyên (<100 phần tử) Sắp xếp dãy theo nguyên tắc: Bên số chẵn chia hết cho Bên duới số lẻ chia hết
cho số lại Đưa dãy hình
2 Viết chương trình nhập vào từ bàn phim dãy số (<100 phần tử) Đưa số bé vị trí số số bé
3 Nhập vào dãy số (<100 phần tử) xếp theo thứ tự tăng dần Nhập thêm vào số chèn số nhập vào vị trí
(41)Bài chữa
#include<stdio.h> #include<conio.h>
void main(){ int A[100]; int N, i;
//Nhập liệu
printf("So phan tu : "); scanf("%d",&N); for(i=0; i < N; i ++){
printf("A[%d] = ",i);scanf("%d",&A[i]); }
//Xử lý mảng: chèn, xóa, xếp,… //Đưa Dữ liệu
for(i=0; i < N; i ++) printf("%4d",A[i]); getch();
}
(42)Sắp xếp số chẵn chia hết lên đầu dãy
{ int d = 0, t;
for(i=0;i < N; i++) if(A[i]%6==0){
t=A[i];
A[i]=A[d]; A[d] = t; d++;
}
for(i=d;i < N; i++) if(A[i]%3 != 0){
t=A[i];
A[i]=A[d]; A[d] = t; d++;
}
(43)Sắp xếp tăng dần chèn vị trí
{ int k = 0,i, j, t;
for(i=0;i < N - 1; i++) for(j=i+1;j < N ; j++)
if(A[i] > A[j]){
t = A[j];A[j] = A[i];A[i]=t; }
printf("Phan tu moi:"); scanf("%d",&k); i = N;
while( (i > 0) &&(A[i-1] > k) ){ A[i] = A[i-1];
i ; }
A[i] = k; N++;
}
(44)Xóa phần tử chia hết cho 5
{
int d = 0, i;
for(i=0;i < N; i++)
if(A[i] % != 0){ A[d] = A[i]; d++;
(45)Bài tập
1 Viết chương trình nhập vào ma trận vng, phần tử ngun, sau
1 Đưa ma trận tam giác duới Đưa ma trận tam giác
2 Nhập M, N (M, N < 30) ma trận MxN Đưa ma trận hình
1 Tìm hàng/cột có tổng phần tử lớn
2 Tìm số lớn nhất/nhỏ vị trí ma trận Đưa ma trận S kích thước thỏa mãn
(46)Nhập vào ma trận vuông,
#include <stdio.h> void main(){
int A[20][20], N,i,j;
printf("Nhap kich thuoc :"); scanf("%d",&N); printf("\n");
for ( i=0; i < N; i++ )
for(j=0; j < N; j++) {
printf("Nhap phan tu [%d,%d]:", i+1,j+1); scanf("%d", &A[i][j] );
}
printf("\n\n MA TRAN DA NHAP \n\n"); for ( i=0; i < N; i++ ){
for(j=0; j < N; j++)
printf( "%4d" ,A[i][j]); printf("\n");
(47)Nhập vào ma trận vuông,
printf("\n\n MA TRAN TAM GIAC TREN \n\n"); for ( i=0; i < N; i++ ){
for(j=0; j < N; j++) if(j >= i)
printf( "%4d" ,A[i][j]); else
printf("%4c",32); printf("\n");
}
printf("\n\n MA TRAN TAM GIAC DUOI \n\n"); for ( i=0; i < N; i++ ){
for(j=0; j <= i; j++)
printf( "%4d" ,A[i][j]); printf("\n");
}
(48)Xâu kí tự
• Khái niệm xâu kí tự
• Khai báo sử dụng xâu • Các hàm xử lý kí tự
(49)Khái niệm xâu kí tự
• Xâu kí tự (string) dãy kí tự viết liên tiếp nhau
– Độ dài xâu số kí tự có xâu – Xâu rỗng xâu khơng có kí tự
• Ví dụ: “Tin hoc”, “String”
• Lưu trữ: kết thúc xâu kí tự ‘\0’ hay NUL (mã ASCII 0)
49
(50)Khái niệm xâu kí tự: Lưu ý
• Xâu kí tự >< mảng kí tự
– Tập hợp kí tự viết liên tiếp nhau
• Truy nhập phần tử xâu ký tự (là ký tự)
giống truy nhập vào phần tử mảng
– Xâu kí tự có kí tự kết thúc xâu, mảng kí tự khơng có kí tự kết thúc xâu
• Xâu kí tự độ dài >< kí tự (“A” =’A’ ?)
– ‘A’ kí tự, lưu trữ byte
(51)Xâu kí tự
• Khái niệm xâu kí tự
• Khai báo sử dụng xâu • Các hàm xử lý kí tự
• Các hàm xử lý xâu
(52)Khai báo
• Cú pháp
char tên_xâu [số_kí_tự_tối_đa];
• Lưu ý:
– Để lưu trữ xâu có n kí tự cần mảng có kích thước n+1
• Ví dụ
– Để lưu trữ xâu “Tin hoc” phải khai báo xâu có số phần tử tối đa
(53)Truy cập vào phần tử xâu
Giống truy nhập tới phần tử mảng ký tự
• Cú pháp:
tên_xâu [chỉ_số_của_kí_tự]
• Ví dụ
char quequan[10];
Giả sử xâu có nội dung “Ha noi”
quequan[0] lưu trữ ‘H’
quequan[1] ‘a’
quequan[5] ‘i’
(54)Ví dụ: Nhập vào xâu đếm số ký tự ‘*’
#include <stdio.h> #include <conio.h> void main(){
char Str[100]; int d=0, i=0;
printf("Nhap xau ky tu: "); gets(Str); while(Str[i] != '\0'){
if(Str[i]=='*') d++;
i++; }
printf("Ket qua : %d",d); getch();
}
54
Tính chiều dài xâu d=0;
(55)Xâu kí tự
• Khái niệm xâu kí tự
• Khai báo sử dụng xâu • Các hàm xử lý kí tự
• Các hàm xử lý xâu
(56)Các hàm xử lý kí tự
Tệp tiêu đề : ctype.h
(57)Các hàm chuyển đổi chữ hoa/chữ thường
• int toupper(int ch): chuyển kí tự thường
thành kí tự hoa
toupper(‘a’) => ‘A’
• int tolower(int ch): chuyển kí tự hoa thành kí
tự thường
tolower(‘B’) => ‘b’
Ví dụ
do{
………
printf(“Tiep tuc <C/K>? :”); fflush(stdin);
(58)Các hàm kiểm tra chữ hoa/chữ thường
• int islower(int ch):
– Kiểm tra chữ thường Hàm trả giá trị
khác ch chữ thường, ngược lại trả về 0
• printf("%d ",islower('A')); 0
• int isupper(int ch):
– Kiểm tra chữ hoa Hàm trả giá trị khác nếu ch chữ hoa, ngược lại trả 0
(59)Các hàm kiểm tra chữ cái/chữ số
• int isalpha(int ch):
– Kiểm tra xem kí tự tham số có phải chữ hay khơng (‘a’…’z’,’A’, ’Z’) Hàm trả khác đúng, ngược lại tả giá trị
• printf("%d ",isalphắÁ)); 1
• int isdigit(int ch):
– Kiểm tra kí tự tham số có phải chữ số (‘0‘,‘1‘, ‘9‘) hay không Hàm trả khác đúng, ngược lại tả giá trị
• printf("%d ",isdigit('A')); 0
(60)Các hàm kiểm tra ký tự đặc biệt
• int iscntrl(int ch):
– Kiểm tra kí tự điều khiển (0-31) Hàm trả về khác đúng, ngược lại tả giá trị bằng 0
• int isspace(int ch):
– Kiểm tra kí tự dấu cách (mã 32), xuống dòng (‘\n’ 10), đầu dòng (‘\r’ 13), tab
(61)Ví dụ: Nhập xâu đếm từ
#include <stdio.h> #include <conio.h> #include <ctype.h> int main(){
char Str[100]; int d=0, i=0;
printf("Nhap xau ky tu: "); gets(Str); if(Str[0] == '\0') printf(“ Xau rong "); else{
if( ! isspace(Str[0]) ) d=1; i=1;
while(Str[i] != '\0'){
if( isspace(Str[i-1] ) && (! isspace(Str[i])) ) d++; i++;
}
printf("Ket qua : %d",d); }
(62)Xâu kí tự
• Khái niệm xâu kí tự
• Khai báo sử dụng xâu • Các hàm xử lý kí tự
(63)Vào xâu kí tự
• Tệp tiêu đề: stdio.h / conio.h
• Nhập xâu kí tự
– gets(tên_xâu);
– scanf(“%s”,&tên_xâu);
• Hiển thị xâu kí tự
– puts(tên_xâu);
– printf(“%s”,tên_xâu);
• Sự khác gets scanf?
(64)Các hàm xử lý xâu kí tự
Tệp tiêu đề: string.h
(65)Các hàm xử lý xâu kí tự
• size_t strlen(char[] xâu)
– Trả độ dài xâu
– printf("%d ",strlen("Hello world")); 11
• char[] strcpy(char[] đích, char[] nguồn)
– chép xâu, trả giá trị xâu nguồn – printf("%s ",strcpy(Str,"Hello")); Hello
– printf("%s", Str); Hello
• int strcmp(char[] xâu_1, char[] xâu_2)
– So sánh hai xâu
– Trả giá trị hai xâu giống nhau; – Giá trị < 0: xâu_1 < xâu_2
– Giá trị >0: xâu_1 > xâu_2
(66)Các hàm xử lý xâu kí tự
• char[] strcat(char[] xđích, char[] nguồn)
– Ghép nối xâu nguồn vào sau xâu đích, trả lại xâu kết
char Str[20];
strcpy(Str,"Hello ");
printf("%s ",strcat(Str,"world")); Hello world
(67)Các hàm xử lý xâu kí tự
• Khái niệm trỏ
– Con trỏ biến chứa địa biến khác – Khai báo Type * tên_biến
– Toán tử & dùng để lấy địa biến – Toán tử * dùng tham khảo tới giá trị biến mà
con trỏ tới – Ví dụ
int N; int * ptr ptr = & N;
* ptr N (*ptr+=10 N+=10)
(68)Các hàm xử lý xâu kí tự
• char * strchr (char * s, int c)
– Trả trỏ trỏ tới vị trí xuất ký tự c s Nếu khơng có trả trỏ null
strcpy(Str,"Hello world");
printf("%s ",strchr(Str,‘o')); o world
• char* strstr(char * s1, char * s2
– Trả trỏ trỏ tới vị trí xuất chuỗi s2 s1 Nếu không tồn tại, trả trỏ null
(69)Các hàm xử lý xâu kí tự (tiếp)
Tệp tiêu đề: stdlib.h
• int atoi(char[] str):
– Chuyển xâu kí tự thành số nguyên tương ứng
• int atol(char[] str):
– Chuyển thành số long int
• float atof(char[] str):
– Chuyển thành số thực
• Thất bại hàm: trả 0
(70)Ví dụ: Đảo ngược xâu ký tự
#include<stdio.h> #include<conio.h> #include<string.h> main(){
char s[100],c; int i, n;
printf("Nhap xau: ");gets(s); n =strlen(s);
for(i=0;i <n/2;i++){ c = s[i];
s[i] = s[n-i-1]; s[n-i-1]=c;
}
(71)Kiểm trả xâu ký tự đối xứng
#include<stdio.h> #include<conio.h> #include<string.h> main(){
char s[20]; int i,n;
printf("Nhap vao xau ki tu: ");gets(s); n=strlen(s);
for(i=0;i<n/2;i++)
if(s[i]!=s[n-1-i]) break;
if(i==n/2)
printf("Xau doi xung"); else
printf("Xau khong doi xung");
(72)Đếm số lần xuất chữ xâu #include<stdio.h> #include<conio.h> #include<ctype.h> #include<string.h> main(){ char s[20]; int dem[26]; int i,n;
printf("Nhap vao xau ki tu: ");gets(s); for(i=0;i<26;i++) dem[i]=0;
n=strlen(s); for(i=0;i<n;i++)
if(isalpha(s[i]))
dem[ tolower(s[i ]) - 'a‘ ]++; for(i=0;i<26;i++)
if(dem[i]!=0)
(73)Mảng xâu ký tự
• Xâu ký tự kiểu phần tử mảng • Khai báo
char DS[100][30];
Mảng có tối đa 100 phần tử, phần tử là xâu có độ dài tối đa 30
• Sử dụng
– Như mảng bình thường
– Mỗi phần tử mảng sử dụng xâu ký tự
(74)Nhập vào DSSV gặp tên rỗng, in DS
#include <stdio.h> #include <string.h> void main(){
int i, n;
char DS[100][30];
printf("Nhap DSSV (<100), go Enter de thoat \n"); n =0;
do{
printf("Ten sinh vien[%d]: ",n+1); gets(DS[n]);
if(DS[n][0] !='\x0') n++; else break;
if(n==100) break; }while(1);
printf(" \n\n DS sinh vien vua nhap \n"); for(i=0;i<n;i++) printf("%s\n",DS[i]); }
(75)(76)Nhập vào DS sinh viên, in DS sắp
#include <stdio.h> #include <string.h> void main(){
int i, j, N;
char DS[100][30], str[30];
//Nhap DS lop
printf("So sinh vien : "); scanf("%d",&N);
fflush(stdin);
for(i=0;i < N;i++){
printf("Ten sinh vien[%d]: ",i); gets(DS[i]);
(77)Nhập vào DSSV, in DS (tiếp)
//sap xep theo phuong thuc noi bot
for(i = 0; i < N - 1; i ++)
for(j = i +1; j < N; j ++)
if(strcmp(DS[i],DS[j]) > 0){ strcpy(str,DS[i]);
strcpy(DS[i],DS[j]); strcpy(DS[j],str); }
printf("\nDS sinh vien vua nhap \n"); for(i=0;i < N;i++)
printf("%s\n",DS[i]);
(78)Nhập vào DSSV, in DS (tiếp)
//Sap xep theo tên, roi theo ho&dem ho
char ten_i[30],ten_j[30]; for(i = 0; i < N - 1; i ++)
for(j = i +1; j < N; j ++){
strcpy(ten_i,strrchr(DS[i],32)); strcpy(ten_j,strrchr(DS[j],32));
if(strcmp(ten_i,ten_j) > 0){ strcpy(str,DS[i]);
strcpy(DS[i],DS[j]); strcpy(DS[j],str); }
(79)(80)Nội dung
Phần 3: Lập trình C
• Chương 1: Tổng quan ngơn ngữ C
• Chương 2: Kiểu liệu biểu thức C • Chương 3: Cấu trúc lập trình C
• Chương 4: Mảng xâu ký tự • Chương 5: Cấu trúc
• Chương 6: Hàm
• Chương 7: Tệp liệu
(81)Nội dung
• Khái niệm cấu trúc
• Khai báo sử dụng cấu trúc • Xử lý liệu cấu trúc
(82)Khái niệm cấu trúc
• Kiểu liệu cấu trúc (struct)
– Là kiểu liệu phức hợp, bao gồm nhiều thành phần thuộc kiểu liệu khác
– Các thành phần: gọi trường liệu (field) – Các thành phần kiểu cấu trúc, không
được truy nhập theo số (mảng) mà theo tên trường
– Có thể coi biến cấu trúc tập hợp
thành biến phần tử rời rạc
• Ví dụ
(83)Nội dung
• Khái niệm cấu trúc
• Khai báo sử dụng cấu trúc • Xử lý liệu cấu trúc
(84)Khai báo sử dụng cấu trúc
• Khai báo kiểu liệu cấu trúc • Khai báo biến cấu trúc
(85)Khai báo kiểu liệu cấu trúc
• Khai báo kiểu cấu trúc struct tên_cấu_trúc{
<khai báo trường > }
• Ví dụ
struct sinh_vien{
char ma_so_sinh_vien[10];
char ho_va_ten[30]; float diem_tinDC;
}
struct point_3D{ float x;
float y; float z; }
(86)Khai báo biến cấu trúc
• Cú pháp:
struct tên_cấu_trúc tên_biến_cấu_trúc;
• Ví dụ:
struct sinh_vien a, b, c; • Kết hợp khai báo
struct [tên_cấu_trúc] {
(87)Khai báo biến cấu trúc
• Các cấu trúc khai báo lồng struct diem_thi {
float dToan, dLy, dHoa; }
struct thi_sinh{
char SBD[10];
char ho_va_ten[30];
struct diem_thi ket_qua; } thi_sinh_1, thi_sinh_2;
(88)Khai báo biến cấu trúc
• Có thể khai báo trực tiếp trường liệu cấu trúc bên cấu trúc khác
struct thi_sinh{
char SBD[10];
char ho_va_ten[30];
struct [diem_thi]{
float dToan, dLy, dHoa; } ket_qua;
(89)Khai báo biến cấu trúc
• Có thể gán giá trị khởi đầu cho biến cấu trúc, theo nguyên tắc kiểu mảng Ví dụ: struct Date{ int day; int month; int year; }; struct{ char Ten[20]; struct Date NS;
} SV = {“Tran Anh", 20, 12, 1990 }; 89
struct{ char Ten[20]; struct Date{ int day; int month; int year; } NS;
(90)Định nghĩa kiểu liệu với typedef
• Mục đích
– Đặt tên cho kiểu liệu cấu trúc
– Giúp khai báo biến “quen thuộc” sai
• Cú pháp
typedef struct <tên_cũ> <tên_mới>; • Ví dụ
typedef char message[80]; typedef long mask;
(91)Định nghĩa kiểu liệu với typedef
• Với kiểu cấu trúc
typedef struct tên_cũ tên_mới typedef struct [tên_cũ] {
<khai báo trường >; } danh_sách_các_tên_mới;
• Chú ý:
– cho phép đặt tên_mới trùng tên_cũ
(92)Ví dụ
struct point_3D{ float x, y, z; }
struct point_3D M;
typedef struct point_3D toa_do_3_chieu; toa_do_3_chieu N;
typedef struct { float x, y, z; }point_3D;
(93)Ví dụ
typedef struct point_2D { float x, y;
}point_2D, diem_2_chieu, ten_bat_ki; point_2D X;
diem_2_chieu Y; ten_bat_ki Z;
=> point_2D, diem_2_chieu, ten_bat_ki các tên cấu trúc, tên biến
(94)Nội dung
• Khái niệm cấu trúc
(95)Xử lý liệu cấu trúc
• Truy cập trường liệu
• Phép gán biến cấu trúc
(96)Truy cập trường liệu
• Cú pháp
tên_biến_cấu_trúc.tên_trường
• Lưu ý
– Dấu “.” toán tử truy cập vào trường dữ liệu cấu trúc
(97)Ví dụ
#include <stdio.h> void main(){
struct{
char Ten[20]; struct Date{
int day; int month; int year; } NS;
} SV = {"Tran Anh", 20,12, 1990 }; printf(" Sinh vien %s (%d/%d/%d)",
SV.Ten,SV.NS.day,SV.NS.month,SV.NS.year); }
(98)Ví dụ
Xây dựng cấu trúc biểu diễn điểm không gian chiều Nhập giá trị cho biến kiểu cấu trúc này, sau hiển thị giá trị trường liệu biến hình.
– Cấu trúc: tên điểm, tọa độ x, tọa độ y
(99)Ví dụ
#include<stdio.h> #include<conio.h> typedef struct{
char ten[5]; int x,y;
}toado;
void main(){ toado t;
printf("Nhap thong tin toa do\n"); printf("Ten diem: ");gets(t.ten);
printf("Toa x: ");scanf("%d",&t.x); printf("Toa y: ");scanf("%d",&t.y); printf("Gia tri cac truong\n");
printf("%-5s%3d%3d\n",t.ten,t.x,t.y); getch();
(100)Phép gán biến cấu trúc
• Muốn chép liệu từ biến cấu trúc này sang biến cấu trúc khác kiểu
– gán trường hai biến cấu trúc => “thủ công”
– C cung cấp phép gán hai biến cấu trúc kiểu:
(101)Phép gán biến cấu trúc
• Ví dụ
– Xây dựng cấu trúc gồm họ tên điểm TĐC sinh viên
– a, b, c biến cấu trúc – Nhập giá trị cho biến a – Gán b=a,
– gán trường a cho c – So sánh a, b c ?
(102)Phép gán biến cấu trúc
#include<stdio.h> #include<conio.h> typedef struct{
char hoten[20]; int diem;
}sinhvien;
void main(){
sinhvien a,b,c;
printf("Nhap thong tin sinh vien\n"); printf("Ho ten: ");gets(a.hoten);
(103)Phép gán biến cấu trúc
b=a;
strcpy(c.hoten,a.hoten); c.diem=a.diem;
printf(“Bien a: ");
printf("%-20s%3d\n",a.hoten,a.diem); printf(“Bien b: ");
printf("%-20s%3d\n",b.hoten,b.diem); printf(“Bien c: ");
printf("%-20s%3d\n",c.hoten,c.diem); getch();
(104)(105)Ví dụ
1. Lập trình đọc vào danh sách khơng q 100 sinh viên gồm: Họ tên, năm sinh
1 Đưa DS sinh viên sinh năm 1990 Đưa DSSV xếp theo thứ tự ABC
2. Lập trình đọc vào DS thí sinh gồm Họ tên, điểm thi mơn Tốn, Lý,Hóa, kết thúc nhập khi gặp sinh viên có tên rỗng
1 Đọc tiếp vào điểm chuẩn; đưa danh sách thí sinh trúng tuyển (khơng có điểm liệt - 0)
2 Đưa thí sinh cao điểm
(106)Bài 1 #include <stdio.h> #include <string.h> typedef struct{ char Ten[30]; int NS; }SinhVien; void main(){
SinhVien DS[100], SV; int N,i,j;
printf("Nhap So sinh vien : "); scanf("%d",&N); fflush(stdin);
for ( i=0; i < N; i++ ){ fflush(stdin);
printf("Nhap du lieu cho sinh vien %d: \n", i+1); printf("Ho ten : "); gets(DS[i].Ten);
printf("Nam sinh :");scanf("%d", &DS[i].NS);
(107)Bài 1(tiếp)
printf("\n\n DANH SACH SINH VIEN\n\n"); for(i = 0; i < N; i ++)
if(DS[i].NS ==1990)
printf("%s\n",DS[i].Ten);
for(i = 0; i < N - 1; i ++) for(j = i+1; j < N; j ++)
if(strcmp(DS[i].Ten,DS[j].Ten) > 0){ SV= DS[i];
DS[i]=DS[j]; DS[j] = SV; }
printf("\n\n DANH SACH SINH VIEN DA SAP XEP\n\n"); for(i = 0; i < N; i ++)
printf("%s\n",DS[i].Ten);
(108)Bài 2
#include <stdio.h> #include <string.h> typedef struct{
char Ten[30]; struct{
int T, L, H, S; } DT;
}SinhVien; void main(){
SinhVien DS[100], TK, SV; int N,i,j,K;
(109)Bài (tiếp)
N = 0;
do{
printf("\nNhap DL cho sv thu %d\n",N+1); printf("Ten SV : "); gets(DS[N].Ten);
if(strlen(DS[N].Ten)==0) break;
else{
printf("Diem thi T L H cua SV %s : ",DS[N].Ten); scanf("%d%d%d",&DS[N].DT.T,&DS[N].DT.L,&DS[N].DT.H); fflush(stdin);
DS[N].DT.S = DS[N].DT.T + DS[N].DT.L + DS[N].DT.H; N++;
}
}while(1);
printf("\n\n DANH SACH SINH VIEN\n\n");
printf(" Ten SV Toan Ly Hoa Tong \n"); for(i = 0; i < N; i ++)
printf("%-20s%5d%5d%5d%6d\n",DS[i].Ten,
(110)Bài (tiếp)
printf("\n\nDiem Chuan : ");scanf("%f",&C);
printf("\n\n DANH SACH SINH VIEN TRUNG TUYEN \n\n"); for(i = 0; i < N; i ++)
if( (DS[i].DT.S >= C)&&
(DS[i].DT.T*DS[i].DT.L*DS[i].DT.H > 0)) printf("%s\n",DS[i].Ten);
TK = DS[0];
for(i = 1; i < N; i ++)
if(DS[i].DT.S > TK.DT.S) TK = DS[i];
(111)Bài (tiếp)
printf("\nSO nguoi trung tuyen:"); scanf("%d",&K); for(i = 0; i < N - 1; i ++)
for(j = i+1; j < N; j ++)
if(DS[i].DT.S < DS[j].DT.S ){ SV= DS[i];
DS[i]=DS[j]; DS[j] = SV; }
while((K>0)&&(DS[K-1].DT.S==DS[K].DT.S))K ; if(K>0){
printf("Diem Chuan La : %4d",DS[K-1].DT.S); printf("\n\n Danh Sach sinh vien trung tuyen \n"); for(i=0; i < K; i++)
printf("%s\n",DS[i].Ten); }
(112)Nội dung
Phần 3: Lập trình C
• Chương 1: Tổng quan ngơn ngữ C
• Chương 2: Kiểu liệu biểu thức C • Chương 3: Cấu trúc lập trình C
• Chương 4: Mảng xâu ký tự • Chương 5: Cấu trúc
• Chương 6: Hàm
• Chương 7: Tệp liệu
(113)Nội dung
Khái niệm hàm
Khai báo sử dụng hàm Phạm vi biến
Truyền tham số
(114)Khái niệm chương trình con
• Khái niệm
– Là chương trình nằm chương trình lớn nhằm thực nhiệm vụ cụ thể
• Vai trị
(115)• Phân loại chương trình con
– Hàm: trả giá trị thủ tục khơng – Trong C:
• Chỉ cho phép khai báo chương trình hàm • Sử dụng kiểu “void” với ý nghĩa “không kiểu
liệu cả” để chuyển thủ tục dạng hàm
Thủ tục (procedure)
Chương trình
Hàm (function)
Phân loại chương trình con
(116)• Phân loại hàm
Hàm tự viết
(Người dùng định nghĩa)
HÀM
Hàm chuẩn (Có thư viện)
(117)Nội dung
Khái niệm hàm
Khai báo sử dụng hàm Phạm vi biến
Truyền tham số
(118)Khai báo hàm
• Ví dụ:
– Chương trình in bình phương số tự nhiên từ đến 10
– Gồm hàm:
• Hàm binhphuong(int x): trả bình phương
của x
• Hàm main(): với số nguyên từ đến
10, gọi hàm binhphuong với giá trị đầu
(119)#include<stdio.h> #include<conio.h>
int binhphuong(int x){ int y;
y = x * x; return y; }
void main(){ int i;
for (i=0; i<= 10; i++)
printf(“%d ”, binhphuong(i)); getch();
}
Khai báo chương trình
Gọi chương trình
Khai báo hàm
(120)[<kiểu_giá_trị_trả_về>] tên_hàm ([DS_tham_số]) {
[<Các_khai_báo>] [<Các_câu_lệnh>] [return Biểu_thức;] }
(121)[<kiểu_giá_trị_trả_về>] tên_hàm ([DS_tham_số])
• Các thơng tin trao đổi bên bên hàm
– Tên hàm,
– Các tham số đầu vào
• Hàm cần thơng tin để hoạt động – Tham số đầu giá trị trả
• hàm cung cấp thơng tin cho mơi trường
• Dịng đầu hàm phân biệt hàm với nhau,
– hàm có dịng đầu hàm giống
Dòng đầu hàm
(122)Tên hàm:
• Có thể định danh hợp lệ
• Tuy nhiên tên hàm nên mang nghĩa gợi ý chức công việc mà hàm thực
• Ví dụ hàm có chức tính trả bình phương số thực x nên có tên
binh_phuong
• Trong C, hàm khơng đặt tên trùng
(123)Tham số hàm:
• Các thơng tin cần cho hoạt động hàm thơng tin, kết tính tốn hàm trả lại
– Tham số chứa liệu vào cung cấp cho hàm
– Tham số chứa liệu mà hàm tính tốn
• Các tham số sử dụng khai báo hàm tham số hình thức
– Khai báo tham số hình thức: kiểu liệu tham số tên tham số
• Các tham số cung cấp cho hàm trình thực tham số thực
– Kiểu liệu tham số thực phải giống kiểu liệu tham số hình thức tương ứng với tham số thực đó,
• Một hàm có một, nhiều khơng có tham số
– Nếu có nhiều tham số, phải phân cách với dấu phẩy – tham số phải có cặp dấu ngoặc đơn sau tên hàm
Dòng đầu hàm
(124)Kiểu liệu trả hàm
• Thông thường hàm sau thực trả giá trị kết tính tốn Để sử dụng giá trị ta cần phải biết thuộc kiểu liệu
– Kiểu liệu đối tượng tính tốn hàm trả gọi kiểu liệu trả hàm
• Trong C, kiểu liệu trả hàm kiểu liệu (kiểu liệu có sẵn kiểu liệu người dùng tự
định nghĩa) không kiểu liệu mảng
• Nếu kiểu liệu trả kiểu void hàm khơng trả giá trị
• Trường hợp ta khơng khai báo kiểu liệu trả chương trình dịch C ngầm hiểu kiểu liệu trả hàm kiểu int.
(125)• Danh sách câu lệnh
• Thường có lệnh return
• Thực lệnh
– Thực xong tất câu lệnh có thân hàm
– Gặp lệnh return
• Cú pháp chung: return biểu_thức;
• Khi gặp lệnh return
– Tính tốn giá trị biểu_thức,
– Lấy kết tính tốn làm giá trị trả cho lời gọi hàm – Kết thúc việc thực hàm, trở chương trình gọi – Nếu return khơng có phần biểu_thức,
• Kết thúc thực hàm mà khơng trả giá trị
Thân hàm
(126)Sử dụng hàm
• Cú pháp:
tên_hàm (danh_sách_tham_số); • Ví dụ: N = binhphuong(0);
N= binhphuong(1);
• Lưu ý:
–Gọi hàm thơng qua tên hàm tham số thực cung cấp cho hàm
–Nếu hàm nhận nhiều tham số tham số ngăn cách dấu phẩy
–Các tham số hàm nhận giá trị từ tham số truyền vào
(127)Tìm ƯSCLN dãy số
# include <stdio.h>
int uscln(int a, int b) { while (a !=b){
if(a > b) a = a- b; else b = b - a;
}
return a; }
void main(){
int A[100], N, i, r;
printf("So phan tu : "); scanf("%d",&N); for(i=0; i < N; i++){
printf("A[%d] = ",i+1); scanf("%d",&A[i]); }
r = A[0];
for(i = 1; i < N; i++) r = uscln(r,A[i]);
printf("Ket qua %d \n",r);
(128)Nội dung
Khái niệm hàm
Khai báo sử dụng hàm Phạm vi biến
(129)• Phạm vi: khối lệnh, chương trình con, chương trình
chính
• Biến khai báo phạm vi sử dụng phạm vi
• Trong phạm vi biến có tên khác
• Tình
– Trong hai phạm vi khác có hai biến tên Trong phạm vi nằm phạm vi kia?
#include<stdio.h> #include<conio.h>
int i;
int binhphuong(int x){
int y;
y = x * x; return y; }
void main(){
int y;
for (int i=0; i<= 10; i++){ y = binhphuong(i);
printf(“%d ”, y); }
}
Phạm vi biến
(130)• Phân loại biến
– Biến tồn cục: biến khai báo
chương trình chính, đặt sau khai báo tệp tiêu đề
– Biến cục bộ: biến khai báo lệnh khối chương trình con, đặt trước câu lệnh
• Ghi nhớ
– Hàm main() chương trình nơi chương trình bắt đầu
– Biến khai báo hàm main() biến cục bộ, có phạm vi hàm main()
Phân loại biến
(131)• Biến static
– Xuất phát: biến cục khỏi phạm vi nhớ dành cho biến giải phóng
– Yêu cầu lưu trữ giá trị biến cục cách lâu dài => sử dụng từ khóa static
– So sánh với biến toàn cục? – Cú pháp:
static <kiểu_dữ_liệu> tên_biến;
Câu lệnh static register
(132)# include <stdio.h> # include <conio.h> void fct() {
static int count = 1;
printf("\n Day la lan goi ham fct lan thu %2d", count++);
}
void main(){ int i;
for(i = 0; i < 10; i++) fct(); getch();
}
Câu lệnh static register
(133)Câu lệnh static register
Day la lan goi ham fct lan thu Day la lan goi ham fct lan thu Day la lan goi ham fct lan thu Day la lan goi ham fct lan thu Day la lan goi ham fct lan thu Day la lan goi ham fct lan thu Day la lan goi ham fct lan thu Day la lan goi ham fct lan thu Day la lan goi ham fct lan thu Day la lan goi ham fct lan thu 10
(134)Câu lệnh static, register
• Biến register
– Thanh ghi có tốc độ truy cập nhanh RAM, nhớ
– Lưu biến ghi tăng tốc độ thực chương trình
– Cú pháp
register <kiểu_dữ_liệu> tên_biến;
(135)Nội dung
Khái niệm hàm
Khai báo sử dụng hàm Phạm vi biến
Truyền tham số
(136)Ví dụ
# include <stdio.h> # include <conio.h> void swap(int a, int b) { int x = a;
a = b; b = x; return; }
void main(){
int a = 5, b = 100;
printf("Truoc: a=%d, b=%d \n\n",a,b); swap(a,b);
printf("Sau : a=%d, b=%d\n\n",a,b); return;
(137)Truyền theo trị truyền theo biến
• Truyền theo trị
– Dựa nguyên tắc truyền biến truyền
– Những câu lệnh thay đổi giá trị tham số hình thức khơng ảnh hưởng tới biến truyền
• Truyền theo biến
– Tham số truyền thực biến thao tác thi hành trực tiếp với biến
– Những câu lệnh thay đổi giá trị tham số hình thức ảnh hưởng tới biến truyền
(138)Truyền theo biến
• Thực chất truyền theo địa biến
• Khai báo hàm
– Khai báo trỏ, trỏ tới đối tượng có kiểu muốn truyền vào
– Ví dụ: void swap (int *pa, int *pb);
• Truyền tham số
(139)Ví dụ
# include <stdio.h> # include <conio.h>
void swap(int * pa, int * pb) {
int x = *pa;
*pa = *pb;
*pb = x;
return; }
void main(){
int a = 5, b = 100;
printf("Truoc: a=%d, b=%d \n\n",a,b);
swap(&a,&b);
printf("Sau : a=%d, b=%d\n\n",a,b); return;
(140)Nội dung
Phần 3: Lập trình C
• Chương 1: Tổng quan ngơn ngữ C
• Chương 2: Kiểu liệu biểu thức C • Chương 3: Cấu trúc lập trình C
• Chương 4: Mảng xâu ký tự • Chương 5: Cấu trúc
• Chương 6: Hàm
• Chương 7: Tệp liệu
(141)Bài tập
1 Viết hàm tìm bội số chung nhỏ hai số nguyên dương a,b tham số hàm
2 Viết chương trình tìm bội số chung nhỏ dãy số nguyên dương a1, a2, …, an Dãy số có khơng q 100 phần tử, n
nhập vào từ bàn phím
3 Viết chương trình cho người dùng nhập vào từ bàn phím dãy số người dùng nhập số -1 Lưu dãy số vào mảng Đưa số dãy số có giá trị nằm
trong khoảng [a,b] với a,b số nguyên
(142)Bài tập
5 Đưa giá trị lớn dãy gọi max, giá trị nhỏ dãy gọi
6 Thống kê vào mảng số số có giá trị 1,2, … max
7 Cho người dùng nhập vào từ bàn phím xâu ký tự người dùng nhập xâu rỗng
8 Đếm số xâu có độ dài n, n nguyên nhập vào từ bàn phím
9 Xác định độ dài xâu dài gọi max_len
(143)Bài tập
Địa email chuỗi ký tự có dấu @ phân cách tên tài khoản tên miễn Ví dụ
tuananh@gmail.com
Tên tài khoản tên miền khơng có dấu cách Viết chương trình C thực hiện:
-Nhập từ bàn phím chuỗi ký tự
-Kiểm tra chuỗi có địa email khơng đưa thơng báo
-Đưa tên tài khoản tên miền trường hợp chuỗi địa email
(144)Bài tập
Một quan có khơng 50 xe, Mỗi hồ sơ xe gồm: Nhãn hiệu xe, biển số, tên hãng, dung tích xi lanh
Viết chương trình C thực hiện:
-Xây dựng kiểu liệu để lưu hồ sơ xe
-Nhập hồ sơ xe cho quan Quá trình nhập dừng đủ 50 xe người nhập trả lời “No” hỏi
(145)Bài tập
Nhập từ bàn phím xâu, q trình nhập dừng gặp ký tự # độ dài xâu vượt 50 Các từ ngăn cách nhiều ký tự trắng
-Có từ bắt đầu chữ “H”?
-Đưa hình theo thứ tự ngược lại sau xóa hết ký tự trắng xây Ví dụ:
Xâu ban đầu: “thi chuyen he” Xâu đưa ra: “ehneyuhciht”
(146)