CHƯƠNG 4: HÀM
1. Khái niệm hàm
1.1Khái niệm và phân loại
Một chương trình viết trong ngôn ngữ C là một dãy các hàm, trong đó có một
hàm chính(hàm main). Hàm chia các bài toán lớn thành các công việc nhỏ, có thể có
những đoạn chương trình viết lặp đi lặp lại nhiều lần, để tránh rườm rà và mất thời
gian khi viết chương trình; người ta thường phân chia chương trình thành nhiều
module, mỗi module giải quyết một công việc vào đó. Thứ tự các hàm trong chương
trình là bất kỳ, song chương trình bao giờ cũng đi thực hiện từ main().
53 trang |
Chia sẻ: phuongt97 | Lượt xem: 509 | Lượt tải: 0
Bạn đang xem trước 20 trang nội dung tài liệu Giáo trình Lập trình cơ bản (Phần 2), để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
i chương trình
3.2 Tên mảng là 1 hằng địa chỉ
[] tương đương với *(+)
&[] tương đương với (+)
Trong đó là biến con trỏ, là 1 biểu thức số nguyên.
Ví dụ: giả sử có khai báo:
#include
#include
#include
int main()
{
int *a;
84
Giáo trình: Lập trình cơ bản Trường Cao đẳng nghề Yên Bái
int i;
clrscr();
a=(int*)malloc(sizeof(int)*10);
for (i=0;i<10;i++)
a[i] = 2*i;
printf(“truy cap theo kieu mang:”);
for (i=0;i<10;i++)
printf(“%d”,a[i]);
printf(“truy cap theo kieu con tro:”);
for (i=0;i<10;i++)
printf(“%d”,a + i);;
getch();
retrun 0;
}
Với khai báo ở trên, hình ảnh của con trỏ a trong bộ nhớ
3.3 Con trỏ trỏ tới các phần tử của mảng 1 chiều
Giả sử con trỏ ptr chỉ đến phần tử a[i] nào đó của mảng a thì:
ptr + j chỉ đến phần tử đứng sau a[i], tức là a[i + j]
ptr - j chỉ đến phần tử đứng trước a[i], tức là a[i - j]
Ví dụ:
Giả sử có 1 mảng mang_int, cho con trỏ contro_int chỉ đến phần tử thứ 5 trong
mảng. In ra các phần tử của contro_int & mang_int.
#include
#include
#include
85
Giáo trình: Lập trình cơ bản Trường Cao đẳng nghề Yên Bái
int main()
{
int i, mangint[10];
int *controint;
clrscr()
for(i=0;i<=9;i++)
mangint[i]=i*2;
controint=&mangint[5];
printf(“\n noi dung cua mang int ban dau=”);
for (i=0;i<=9;i++)
printf(“%d”, mangint[i]);
printf(“\n noi dung cua contro int ban dau=”);
for (i=0;i<=5;i++)
printf(“%d”, controint[i]);
for i=0;i<5;i++)
controint [i]++;
printf(“\n -----------------------------------------
“);
printf(“\n noi dung cua mang int sau khi tang 1=”);
for (i=0;i<=9;i++)
printf(“%d”, mangint[i]);
printf(“\n noi dung cua contro int sau khi tang
1=”);
for (i=0;i<5;i++)
printf(“%d”, controint[i]);
for i=0;i<5;i++)
if(controint !=null)
free(controint);
getch();
return 0;
}
Kết quả của chương trình
86
Giáo trình: Lập trình cơ bản Trường Cao đẳng nghề Yên Bái
4. Con trỏ và hàm
Khi tham số hình thức của hàm là một con trỏ thì theo nguyên tắc gọi hàm ta
dùng tham số thực tế là 1 con trỏ có kiểu giống với kiểu của tham số hình thức. Nếu
lúc thực thi hàm ta có sự thay đổi trên nội dung vùng nhớ được chỉ bởi con trỏ tham
số hình thức thì lúc đó nội dung vùng nhớ được chỉ bởi tham số thực tế cũng sẽ bị
thay đổi theo.
Ví dụ: xét hàm hoán vị được viết như sau:
#include
#include
void hoanvi(int *a, int *b)
{
int c=*a;
*a=*b;
*b=c;
}
int main()
{
int m=20, n=30;
clrscr();
printf(“truoc khi goi ham m=%d, n=%d\n”,m,n);
hoanvi(&m,&n);
printf(“sau khi goi ham m=%d, n=%d”,m,n);
getch();
return 0;
}
87
Giáo trình: Lập trình cơ bản Trường Cao đẳng nghề Yên Bái
Kết quả thực thi chương trình
Truớc khi gọi hàm Khi gọi hàm Sau khi gọi hàm
m=20 , n=30 a=&m; b=&n; Con trỏ a,b bị giải phóng
Lúc này m,n đã thay đổi:
*a=m; *b=n; m=30, n=20
&m, &n m=20 , n=30
Đổi chỗ ta được &m, &n
a=30, b= 20
m = 30 , n= 20
&m, &n
BÀI TẬP THỰC HÀNH
Bài tập 1
Khai báo 1 biến nguyên a và biến trỏ kiểu nguyen p, cho p trỏ đến a. in ra màn
hình địa chỉ của a, nội dung trong p, địa chỉ của biến trỏ p.
#include
#include
#include
void main()
{
int a, *p;
clrscr();
p=&a;
printf("\nDia chi cua bien nho a= %x",&a);
printf("\nNoi dung cua bien tro p= %x",p);
printf("\n dia chi cu bien tro p= %x",&p);
getch();
}
Bài tập 2
88
Giáo trình: Lập trình cơ bản Trường Cao đẳng nghề Yên Bái
Viết chương trình nhập vào từ bàn phím n số nguyên, cấp phát một vùng nhớ
động để lưu trữ n số nguyên đó, hiện các số vừa nhập, tính tổng, trung bình cộng,
max, min của dãy số đó.
#include
#include
#include
void main()
{
clrscr();
int *a,n ,i;
printf("\n nhap so luong phan tu n= ");
scanf("%d",&n);
// cap phat bo nho
a=(int*)malloc(n*sizeof(int));
//nhap du lieu
for(i=0;i<n;i++)
{
printf("\n Nhap so thu %d ",i+1);
scanf("%d",a+i);
}
// hien du lieu
printf("\n day so vua nhap la: ");
for(i=0; i<n; i++)
{
printf(" %d",*(a+i));
}
//tinh tong
int tong=0;
for(i=0; i<n; i++)
{
tong=tong + *(a+i);
}
printf("\n tong cua day so do la: %d",tong);
89
Giáo trình: Lập trình cơ bản Trường Cao đẳng nghề Yên Bái
//tinh tb cong
printf("\n Trung binh cong cua day do la:
%f",tong/(n*1.0));
// tim max
int max= *a;
for(i=0; i<n; i++)
{
if(max< *(a+i))
max= *(a+i);
}
printf("\n so lon nhat la: %d",max);
//tim min
int min = *a;
for(i=0; i<n; i++)
{
if(min >*(a+i))
min = *(a+i);
}
printf("\n so nho nhat la: %d", min);
getch();
}
90
Giáo trình: Lập trình cơ bản Trường Cao đẳng nghề Yên Bái
Chương 7 : CHUỖI KÝ TỰ
1. Khái niệm
Trong C không có kiểu xâu, do vậy ngôn ngữ C sử dụng mảng để lưu trữ chuỗi ký
tự, mỗi phần tử của mảng sẽ là một kiểu dữ liệu kiểu char
Chuỗi ký tự là một dãy các ký tự hoặc một mảng các ký tự. Các ký tự được lưu
theo thứ tự từ trái sang phải của chuỗi và bắt đầu bằng phần tử có chỉ số 0 cho đến
hết chuỗi. Kết thúc chuỗi là ký tự ‘\0’ (còn được gọi là ký tự NULL trong bảng mã
ASCII).
Các hằng chuỗi ký tự được đặt trong cặp dấu nháy kép ””.
2. Khai báo
2.1 Khai báo theo mảng
Cú pháp: char [Chiều dài tối đa]
VD: Trong chương trình, ta có khai báo:
char Ten[12];
Trong khai báo trên, bộ nhớ sẽ cung cấp 12+1 bytes để lưu trữ nội dung của chuỗi
ký tự Ten; byte cuối cùng để lưu ký tự ‘\0’ để chấm dứt chuỗi.
Ghi chú:
Chiều dài tối đa của biến chuỗi là một hằng nguyên nằm trong khoẳng từ 1 đến
255 bytes.
Chiều dài tối đa không nên khai báo thừa để tránh lẵng phí bộ nhớ, nhưng cũng
không nên khai báo thiếu.
2.2 Khai báo theo con trỏ
Cú pháp: char *;
VD: Trong chương trình, ta có khai báo:
char *Ten;
Trong khai báo trên, bộ nhớ sẽ dành 2 bytes để lưu trữ địa chỉ của biến con trỏ
Ten đang chỉ đến, chưa cung cấp nơi để lưu trữ dữ liệu. Muốn có chỗ để lưu trữ dữ
liệu, ta phải gọi đến hàm malloc() hoặc calloc có trong alloc.h, sau đó mới gán dữ liệu
cho biến.
91
Giáo trình: Lập trình cơ bản Trường Cao đẳng nghề Yên Bái
3. Các thao tác trên chuỗi
3.1 Nhập chuỗi từ bàn phím
Để nhập một chuỗi ký tự từ nàn phím, ta sử dụng hàm gets() với cú pháp như
sau:
gets()
VD: char Ten[20];
gets(Ten);
Ta cũng có thể sử dụng hàm scanf() để nhập dữ liệu cho biến chuỗi, tuy nhiên
lúc này ta chỉ có thể nhập được một chuỗi không có dấu khoẳng trắng.
Ngoài ra, hàm cgets() (trong conio.h) cũng được sử dụng để nhập chuỗi.
Chú ý:
Nếu trước lệnh nhập chuỗi có lệnh nhập số thì phải xóa vùng đệm bàn phím
trước khi nhập chuỗi bằng lệnh sau:
fflush(stdin);
Ví dụ
int n;
char s[50];
printf(“nhap so n =”);
scanf(“%d”,&n);
printf(“nhap chuoi s = ”);
fflush(stdin); gets(s);
3.2 Xuất chuỗi ra màn hình
Để xuất chuỗi (biểu thức chuỗi) lên màn hình, ta sử dụng hàm puts(), với cú pháp
như sau:
puts()
VD: Nhập vào một chuỗi và hiển thị trên màn hình chuỗi vừa nhập.
#include
#include
#include
int main()
{
92
Giáo trình: Lập trình cơ bản Trường Cao đẳng nghề Yên Bái
char Ten[12];
printf(“Nhap chuoi:”); gets(Ten);
printf(“Chuoi vua nhap”);puts(Ten);
getch();
return 0;
}
Ngoài ra, ta có thể sử dụng hàm printf(), cputs() (trong conio.h) để hiển thị
chuỗi lên màn hình.
3.3 Một số hàm xử lý chuỗi
Hàm cho biết độ dài thực sự (số ký tự) của chuỗi ký tự lưu trong mảng
int strlen(s);
ví dụ:
char s[100] = “Ha Noi Viet Nam”;
int a = strlen(s);
sẽ trả về độ dài thực của sâu s gán vào biến nhớ a, cụ thể là a = 15
Lệnh gán chuỗi từ sâu này vào sâu khác
strcpy(s1, s2 );
sẽ thưc hiện chép chuỗi ký tự trong sâu s2 vào s1.
Chú ý:
Trong ngôn ngữ C không thể sử dung phép gán ( = ) để gán hai chuỗi do đó phải
sử dụng lệnh strcpy này.
Lệnh nối hai sâu lại với nhau
strcat( s1,s2);
sẽ thưc hiện nối sâu S2 vào sâu S1
ví dụ:
char s1[100] = “Ha Noi”;
char s2[100] =”Viet Nam”;
strcat (s1,s2);
kết quả xâu s1 sẽ thay đổi và đó là:”Ha NoiViet Nam”
Lệnh chuyển sâu thành chữ hoa
strupr(s);
93
Giáo trình: Lập trình cơ bản Trường Cao đẳng nghề Yên Bái
Lệnh chuyển sâu thành chữ thường.
strlwr(s);
3.4 Một số thao tác cơ bản trên chuỗi
Đêm ký tự, đếm từ
Cho một chuỗi s và đếm xem trong chuỗi có bao nhiêu chữ thỏa mãn một điều
kiện nào đó:
int dem = 0
for( i =0; i<strlen(s);i++)
if(s[i] thỏa mãn điều kiện) dem ++;
printf(“so ky tu dem duoc la: %d”,dem) ;
Thuật toán đếm số từ co trong chuỗi s theo tiêu chuẩn nhận biết đầu từ( là
cặp ký tự thỏa mãn ký tự trước là dấu cách, ký tự sau khác dấu cách).
int dem;
if(s[0] = = ‘ ’ ) dem = 0 ;
else dem = 1;
for( i = 1;i < strlen(s);i++ )
{
if(s[i] = =’ ’&& s[i+1]!=’ ’)
dem ++;
}
printf(“so tu dem duoc là: %d”,dem) ;
Chuẩn hóa chuỗi ký tự
Một chuỗi ký tự ở dạng chuẩn nếu không có dấu cách ở đầu, không có dấu cách
ở cuối và giữa hai từ có duy nhất một dấu cách.
Thuật toán chuẩn hóa được chia làm 3 bước như sau
Bước 1: Xóa dấu cách ở đầu
int i = 0 ;
while (s[i] = =’ ’&&i < strlen(s))
{
i++ ;
strcpy(&s[0],&s[i]);
94
Giáo trình: Lập trình cơ bản Trường Cao đẳng nghề Yên Bái
}
Bước 2: Xóa dấu cách thừa giữu hai từ
int i = 0;
while(i<strlen(s)-1)
{
if(s[i] == ‘ ‘&& s[i+1] == ‘ ‘ )
strcpy(&s[i],&s[i+1]);
i++;
}
Bước 3: xóa dấu cách ở cuối chuỗi
while(s[strlen(s)-1] ==’ ’ ) s[strlen(s)-1]= ‘\0’;
Tách từ
+ Tách từ đầu tiên
i=0;
while(s[i] = =' ')i++;
for(j=0;(i<strlen(s))&&(s[i]!=' ');i++,j++)
tudau[j] = s[i];
tudau[j]='\0';
Tách từ cuối cùng
i = strlen(s)-1;
while(s[i] = =' ')i--;
j=i;
while(s[i]!=' ')i--;
i++;
for(int x = 0;i<=j;i++)
{
tucuoi[x] = s[i];
x++;
}
tucuoi[x] = '\0';
95
Giáo trình: Lập trình cơ bản Trường Cao đẳng nghề Yên Bái
96
Giáo trình: Lập trình cơ bản Trường Cao đẳng nghề Yên Bái
BÀI TẬP THỰC HÀNH
Bài tập 1
Lập trình đọc vào một sâu. Đọc vào từ bàn phím một kí tự bất kì, rồi đếm xem
số lần xuất hiện ký tự này trong sâu. Báo kết quả ra màn hình.
#include
#include
#include
int dem(char s[],char a)
{
int d=0;//so ki tu
int l=strlen(s);
for(int i=0;i<l;i++)
{
if(s[i] == a)
d++;
}
return d;
}
void main()
{
int i;
char s[100],ch;
clrscr();
printf("\n nhap vao mot cau: ");
fflush(stdin);gets(s);
printf("\n Nhap vao mot ki tu bat ki:");
ch = getche();
//dem so lan xuat hien cua ki tu
printf("\nki tu %c xuat hien %d lan trong xau
",ch,dem(s,ch));
getch();
}
97
Giáo trình: Lập trình cơ bản Trường Cao đẳng nghề Yên Bái
Bài tập 2
Viết chương trình đọc vào một xâu. Đếm số từ của một sâu. Từ được hiểu là
xâu khác rỗng và không có dấu cách.
#include
#include
#include
int sotu(char S[])
{
int dem=0,n;
n=strlen(S);
if(S[0]!=' ')dem=1;
for(int i=1;i<n;i++)
{
if(S[i]= =' '&& S[i+1]!=' ')dem++;
}
return dem;
}
void main()
{
int i;
char s[100];
clrscr();
printf("\n nhap vao mot sau ki tu: ");
fflush(stdin);gets(s);
//dem so tu cua mot sau
printf("sau ban vua nhap co: %d tu",sotu(s));
getch();
}
98
Giáo trình: Lập trình cơ bản Trường Cao đẳng nghề Yên Bái
Bài tập 3
Lập trình đọc vào một câu từ bàn phím rồi đưa ra màn hình dưới dạng một cột.
thí dụ đọc vào TIÊN HỌC LỄ HẬU HỌC VĂN kết quả đưa ra thành
TIÊN
HỌC
LỄ
HẬU
HỌC
VĂN
#include
#include
#include
void hien(char s[])
{
int l=strlen(s),n=0;
while(s[n]= =' ')n++;
for(int i = n ; i<l ; i++)
{ if(s[i]!=' ')
printf("% c",s[i]);
else
printf("\n");
}
}
void main()
{ int i;
char s[100];
clrscr();
printf("\n nhap vao mot cau: ");
fflush(stdin);gets(s);
printf("hien cau moi tu tren mot dong la:\n");
hien(s);
getch();
}
99
Giáo trình: Lập trình cơ bản Trường Cao đẳng nghề Yên Bái
Bài tập 4
Nhập vào từ bàn phím họ tên của một người. Hiện tên và họ của người đó lên
màn hình.
#include
#include
#include
void main()
{
char s[100],ten[10],ho[10];
int i=0,j=0;
clrscr();
printf("\n nhap vao ten cua mot nguoi: ");
fflush(stdin);gets(s);
// tach ho
while(s[i]= =' ')i++;
do{
ho[j]=s[i];
i++; j++;
}while(s[i]!=' ');
ho[j]='\0';
printf("\n ho cua nguoi nay la: %s",ho);
// tach ten
j=0;
i=strlen(s);
while(s[i]= =' ')i--;
int i1=i;
while(s[i1]!=' ')i1--;
do{
ten[j]=s[i1];
i1++; j++;
}while(i1<=i);
ten[j]='\0';
printf("\n ten cua nguoi nay la: %s",ten);
getch(); }
100
Giáo trình: Lập trình cơ bản Trường Cao đẳng nghề Yên Bái
PHỤ LỤC
HƯỚNG DẪN DEBUG TRÊN MÔI TRƯỜNG BORLAND C
Mặc dù chương trình không còn lỗi nhưng khi chạy chương trình vẫn ra kết quả
sai, những lỗi đó có thể là:
• Dùng chấm phẩy sau: if, else, for, while, mà chưa thực hiện lệnh.
• Định dạng nhập xuất sai hay khai báo sai kiểu dữ liệu.
• Chia cho 0.
• Không có điều kiện dừng (điều kiện dừng sai).
• Phân tích thuật toán thiếu (chưa vét hết các trường hợp) hoặc sai.
Các thao tác debug:
Nhấn F7 hoặc F8 để chạy từng bước (nếu không có lỗi khi biên dịch)
- F7: Đi từng lệnh của hàm con nếu có gọi hàm.
- F8: không vào chi tiết từng lệnh khi gọi đến hàm con (chỉ đưa ra kết quả của hàm
con).
Quan sát vệt sáng để biết chương trình đang thực hiện đến vị trí lệnh nào.
- Nhấn Ctrl+F7 (hoặc nhấn phím Insert nếu đã có cửa sổ Watch): Nhập vào biến
cần theo dõi giá trị các biến khi thực hiện xong lệnh hay hàm nào đó.
101
Giáo trình: Lập trình cơ bản Trường Cao đẳng nghề Yên Bái
- Có thể xóa biến trên cửa sổ Watch bằng cách chọn biến trên cửa sổ Watch và
nhấn phím Delete.
- Nếu không thấy cửa sổ hiển thị giá trị biến (Watch) nhấn Alt+W+W hoặc vào
menu Window chọn Watch.
Nếu muốn bỏ qua một đoạn nào đó (tức không cần kiểm tra đọan đó) thì
nhấn F4 để chương trình thực thi tới vị trí dòng của dấu nháy rồi dừng lại đó (dấu
nháy phải tại vị trí những dòng phía sau của vệt sáng, nhấn F6 để chuyển qua lại các
cửa sổ).
- Muốn thay đổi giá trị của biến ta dùng phím Ctrl+F4 để hiển thị cửa sổ.
102
Giáo trình: Lập trình cơ bản Trường Cao đẳng nghề Yên Bái
Nhập vào tên biến ở ô Expression, chọn nút Evaluate (hoặ nhấn Enter), ô Result
sẽ hiển thị kết quả tại thời điểm đó, sau đó nhập giá trị mới cho biến tại ô New Value
Enter (dùng phím tab để di chuyển vị trí chọn).
Ngoài ra có thể đánh dấu để chương trình thực thi đến vị trí đánh dấu (khi chưa chạy
từng bước) dùng phím F8 để đánh dấu ngay vị trí dấu nháy. Vị trí đánh dấu sẽ có vệt
sáng màu đỏ.
Có thể đánh dấu nhiều vị trí khác nhau. Nhấn Ctrl+F9 để chương trình thực thi
đến vị trí đánh dấu theo thứ tự từ trên xuống dưới, đồng thời cũng có thể dùng phím
F7 hoặc F8 giống như trên để chạy từng bước.
103
Giáo trình: Lập trình cơ bản Trường Cao đẳng nghề Yên Bái
Ngoài ra, có thể dùng phím ALT+F5 để xem kết quả xuất trong quá trình debug
(để kiểm tra nhập xuất).
Trong quá trình chạy từng bước có thể kết thúc bằng cách nhấn Ctrl+F2.
Các thao tác liên quan đến cửa sổ Watch
- Di chuyển cửa sổ Watch: Chọn cửa sổ Watch, nhấn Ctrl+F5. Sau đó dùng phím
mũi tên để di chuyển cửa sổ tới vị trí mới. Nhấn phím Enter.
- Thay đổi kích thứơc cửa sổ Watch (khi đang chọn bằng Ctrl+F5 trên cửa sổ
Watch) nhấn Shift + phím mũi tên rồi nhấn phím Enter.
TÀI LIỆU THAM KHẢO
PHẠM VĂN ẤT: “Kỹ thuật lập trình C: cơ sở và nâng cao”. Nhà Xuất BảnKhoa Học
Kỹ Thuật – 1996.
Lê Mạnh Thạnh, Giáo trình môn lập trình C, NXB Giáo dục, 2000;
Nguyễn Linh Giang, Nguyễn Xuân Thực, Lê Văn Thái, Giáo trình kỹ thuật lập trình
C, NXB Giáo dục, 2005;
Ngô Trung việt, Giáo trình ngôn ngữ lập trình C và C++ , NXB Giao thông vận tải,
1995;
B. Kernighan and D. Ritchie, The C programming language, Prentice Hall, 1990.
104
Các file đính kèm theo tài liệu này:
- giao_trinh_lap_trinh_co_ban_phan_2.pdf