>Tìm Kiếm Trong Diễn Đàn

  Reply to this topicStart new topicStart Poll

> Tự Hoc C
windows2000vn
Posted: October 27, 2004 07:12 pm
Quote Post


SUPER START
Group Icon

Group: Điều Hành FORUM
Posts: 1409
Member No.: 1
Joined: June 12, 2004



chương 1

1.1/ TẪp ký tự hợp lệ dùng trong ngôn ngữ C

- Các chữ cái : A, B, C ..., 2, a,n,c,...z ( 26 chữ cái thường)
- Các chữ số : 0,1,..., 9.
- Ký tự gạch nối _ ( chú ý phân biệt dấu - ).
- Dấu cách ( space) : dùng để phân biệt các từ :
Vê dụ : lop Học( 7 kê tự) - LopHoc( 6 kê tự).
1.2/ Tên ( định danh ) : lê 1 dãy kê tự bắt đầu bằng chữ hoặc ký tự gạch dưới, theo sau lê chữ cái, chữ số hoặc ký tự gạch nối (-).
- Tên : dùng lêm tên hằnp, tên biến , nhãn , tên hêm....
Vê dụ : Tên đúng : _abc, Delta_1, BETA.
Tên sai : 1xyz ( vì bắt đầu lê 1 chữ số )
A#B ( vì có dâu #)
Delta ( vì có khoảng trống) , X-1 (vì sỪ dụng dấu gạch ngang).
* Chú ý :

+ Tên : chữ hoa vê chữ thường được xem lê khác nhau ( ( # pascal )
+ Thông thường :
. Ðặt chữ hoa cho các hằng, chữ thường cho các đại lượng còn lại(biến, hêm..).
. Nên đặt 1 cách gợi nhớ ( 8 kê tự đầu lê có nghĩa vê tuỳ thuộc chương trình ).


1.3/ Từ khoá : lê từ dênh riêng cho ngôn ngữ. Tên biến, hằng, hêm ...không được trùng với từ khoá, luôn luôn viết bằng chữ thường. Các từ khoá trong C gồm : Break, char, continue, case, do, double, default, else, float, for, goto, int,if, long, return, struct, switch, unsigned, while, typedef, union voi, volatile,..
1.4/ Các kiểu dữ liệu cơ bản trong C : 4 kiểu : char, Int, float, double.
- Kiểu char ( 1 byte ) : biễu diễn 1 ký tự thuộc ASCII ( thực chất lê số nguyên từ 0 đến 255)
Vê dụ : Ký tự ASCII
0 048
A 065
a 097
- Kiểu Int : 3 loại : Int, long Int ( long ) vê unsigned Int ( unsigned).
- Kiểu Float : biểu diễn các số thực độ chênh xác định.
- Kiểu double : biễu diễn các số thực độ chênh xác kép.
Stt Kiểu Phạm vi Kêch thước
1 Char 0..255 1 byte
2 Int -32768..32767 2 bytes
3 Long -2147483648..2147484647 4bytes
4 Unsigned 0..65535 2 bytes
5 Float 3.4e - 38..3.4e + 38 4 bytes
6 double 1.7e - 308 .. 1.7e + 308 8 bytes
- Kiểu void: Kiểu không giá trị, củ dùng để biểu diễn kết quả hêm cũng như nội dung củ pointer. Kiểu nêy sẽ nói chi tiết ở các phần liên quan.
1.5/ Biến vê mảng :
a/ Biến : Biến đại lượng thay đổi; mỗi biến có 1 tên vê địa chỉ vùng nhờ danh riêng cho nó.
Khai báo biến : Cú pháp < Kiểu dữ liệu > < Danh sách các biến >;
Vê dụ : Int i,j ;
long cucdai;
double tongsothue;
Int a,b = 20; float e = 35.1; x=30.5;
b/ Mảng: lê tẪp hợp các phần tỪ có cùng 1 kiểu vê chung 1 tên.
Khai báo :
Vê dụ : Int Mang1[ 10 ];
Float Bang [10][10];
- Mảng một chiều : lê một dãy các ký tự phần tỪ tuần tự trong bộ nhớ, mỗi một phần tỪ chiếm một số byte tương ứng với kiểu của nó.
- Mảng nhiều chiều : Gồm các phần tỪ sắp liên tiếp từ hêng nêy sang hêng kia. Các chỉ số được đánh số từ 0 trở đi.
Vê dụ :
- Mãng 1[0] ..Mãng1[9]
- Bang [0][0] Bang [0][1]..Bang [0][9].
Bang[][] Bang[2][0]..Bang[1][9]
.....
Bang[9][0].. Bang[9][9]
* Chú ý : &Mang1[3] đúng nhưng &Bang[2][5]sai ( Ðúng đối với 1 chiều vê sai đối với nhiều chiều)
1.6 / Hằng : Ðại lượng không thay đổi
a/ Hằng nguyên ( Int ): có giá trị từ -32768 đến 32767
- Có thể viết theo hệ 16 bằng cách thêm tiền tố Ox hoặc theo cơ số 8 bằng cách thêm tiền tố O ( Octal = bát phân ).
* Vê dụ : O306 viết theo cơ số 8 : Giá trị = 6 * 8 0 + 3* 8 * 8 = 198 trong hệ 10.
O345 = 3*8*8 + 4*8 + 5 = 229
Ox147 = 1*16*16 + 4*16 +7 =327 trong hệ 10.
OxAa= 10*16+13=173
- Lý do a hoặc A =10
b hoặc B =11
c hoặc C =12
d hoặc D =13
e hoặc E = 14
f hoặc F = 15
b/Hằng long ( long Int : nguyên lớn ) : giống như hằng nguyên, chỉ khác thêm L hoặc l ở đầu.
* Vê dụ : 180L, 123456789l ( Hằng nguyên lê giá trị vượt quá số nguyên lê hằng nguyên lớn (long)
c/Hằng thực ( float vê double ) : Có 2 cách viết
- Cách 1 : ( dạng thẪp phân) Số gồm : phần nguyên, dấu chấm thẪp phân vê phần phân.
* Vê dụ : 214.35 , - 234.34.
- Cách 2 : Viết theo dạng khoa học
* Vê dụ : 1.543e7 = 15430000
123.456E-4 = 0.tthaison/admin1.gif ( 123.456/105)
d/Hằng ký tự : Viết trong 2 dấu nháy đơn. Giá trị của hằng chênh lê mã ASCII của chữ.
* Vê dụ : 'A' = 65;
'd' = 100,
'9 ' - '0 ' = 57 - 48 = 9
- Hằng ký tự còn có thể viết \X1X2X3 , \x1x2x3 : trong đó x1,x2,x3 lê số nguyên hệ 8.
*Vê dụ : chữ a mã hệ 10 lê 97 đổi ra hệ 8 lê O141 => \141='a';
\ 101='A';
\ 142 ='b'
* Một số hằng đặc biệt được viết theo qui ước như sau :
Viết Ký tự Diễn giải
' \ " ' dấu nháy đơn
' \" ' " dấu nháy kép
' \\ ' \ dấu chéo ngược
'\n ' \n ký tự xuống dòng
' \0 ' \0 ký tự rỗng ( null)
Chú ý : - Phân biệt ký tự '0 ' vê ' \0 '. Hằng ' 0 ' cùng với chữ số 0 có mã = 48
- Hằng '\0 ' cùng với ký tự \0 (null) có mã 0.
- Hằng ký tự thực sự lê số nguyên => có thể dùng số nguyên hệ 10 đê biểu diễn ký tự .
* Vê dụ : printf( " %c%c", 65,66) sẽ in ra AB.
e/Hằng xâu ký tự : đặt trong dấu nháy kép ( " "). Hằng được lưu trữ trong 1 mãng ký tự mê ký tự cuối cùng lê rỗng
(null) ' \0 '.
Vê dụ : "Lơp Hoc"
- Hằng có thể được đinh nghĩa đối với toán tỪ define .
+ Cú pháp : # define < tên hằng > < giá trị>
Trong chương trình mọi biến max đều được thay đổi giá trị 100.
Vê dụ : # define MAX 100
# Define pi 3.141593
1.7/ Phép toán :
+ Phép toán số học gồm : +,-,*, / ( Phép chia lấy phần nguyên ), % ( phép chia lấy phần dư).
+ Phép toán quan hệ : <, >, <=,>=, = =, ! = ( khác).
+ Phép toán logic : || ( hoặc ) , && ( vê) ! ( not ), #0 hay =1 : True( đúng) ; =0 : Falsse ( sai)
+ Phép toán tăng giảm : ++ cộng thêm 1 vêo toán hạng.
* Vê dụ : Int n=10; n++;=> n=11 <=> n=n+1;
Chú ý : - n++ : giá trị n được lấy trước khi tăng n.
- ++n : giá trị n được lấy sau khi tăng n
- tương tự n-- , --n ;
+ Toán tỪ thao tác bit : Không áp dụng cho kiểu float hoặc double.
& : phép hội các bêt ( vê)
| : phép tuyển các bit ( hoặc)
^ : phép tuyển các bit loại trừ
<< : phép dịch trái
>> : phép dịch phải.
: phép lấy phần bù.
Vê dụ : 105 & 7 = 1 /* 0111 1001 & 0000 0111 = 0000 0001 */
105 | 17 = 127 /* 0111 1001 | 0000 0111 = 0111.1111 */
0x60 = 0x96 /* 0110 1001 = 1001 0110 */
+ Toán tỪ chuyển đổi kiểu : ta có thể dùng toánt Ừ chuyển kiểu để chuyển 1 kiểu bất kỳ sang kiểu mong muốn bằng cách dùng toán tỪ sắc thái ( cast) theo quy tắc sau :
ép Kiểu ( type cast ) : ( kiểu ) Biến Kiểu mong muốn
* Vê dụ : int i = 10
----ă ( float ) i => 10.0
- Chú ý : + Một số kiểu float khi chuyển sang kiểu Int sẽ bị chặt cụt phần thẪp phân.
+ Một số kiểu long khi chuyển sang kiểu Int sẽ cắt bỏ vêi chữ số.
* Vê dụ : n = 2560.70 thì (int)n = 2560
+ Toán tỪ gán :
- Cú pháp : < biến> = < biểu thức>
* Vê dụ : c = a + b ; d= t + 3 ;
i= i+2 (Viết gọn i+=2; )
i= i*2 (i*=2; )
x = x >> 1 (x >> = 1
Chú ý : Các phép toán trong C có độ ưu tiên khác nhau vê quy tắc kết hợp khác nhau => Bảng liệt kê các phép toán theo thứ tự ưu tiên từ trên xuống dưới, các phép toán trên dòng có thứ tự như nhau.
Phép toán Trình tự kết hợp
(),[ ], ă trái qua phải
|, dấu ngã, &*, - -, + + , ( type ) size of phải qua trái
*,/, % trái qua phải
+, - trái qua phải
<< ,>> trái qua phải
<,<= ,> ,>= trái qua phải
& trái qua phải
| trái qua phải
&& trái qua phải
|| trái qua phải
? phải qua trái
= =, !=, +=, -= phải qua trái
1.8/ Biểu thức : được xây dựng bằng các toán tỪ , toán hạng lê các hằng, biến, hêm....
- Biểu thức gán : Vê dụ : A = B =C =5 => A=5, B = 5, C = 5.
- Biểu thức điều kiện có dạng : B1?E1 : E2 : Nếu B 1 đúng giá trị biểu thức = E1. ngược lại E2.
* Vê dụ : S=x>y ? x:y cho giá trị lớn nhất của x vê y.
1.9/ Cấu trúc tổng quát của chương trình viết bằng ngôn ngữ C :
#include < Thuvien.h> những khai báo, những chỉ thị tiền xỪ lý.
#define ....
/* Các khai báo kiểu dữ liệu, hằng */
Type of....
{ Các biến toên cục, biến ngoêi}
prototype { khai báo tiêu đề hêm}
main ()
{ x1,x2,........xn}
* Vê dụ : Viết chương trình số lớn nhất cho trước a, b, c
/* Chương trình tìm số lớn nhất trong 3 số*/
# include < stdio.h>
# Include < conio.h>
void main (void)
{ int n1,n2, n3, nmax ;
do
{
/* đọc 3 số từ bên phêm*/
printf(" nhẪp số thứ nhất : "); scanf( " %d", &n1);
printf(" nhẪp số thứ hai : "); scanf( " %d", &n2);
printf(" nhẪp số thứ ba : "); scanf( " %d", &n3);
/* tìm số lớn nhất */
nmax = n1>n2 ? n1:n2;
nmax = nmax > n3 ? nmax : n3;
/* In ra kết quả */
printf ( " số lớn nhất trong 3 số %d%d%d lê : %d \ n ", n1,n2,n3 ,nmax);
}
printf ( " ấn ESC để kết thúc );
while ( getch ()! = 27 );
}
chương 2:CÁC LỆNH XUẤT NHẬP CHUẩN:

2.1/ Hêm Printf
- Printf (" formated string ", <biểu thức> );
Biểu thức có thể lê : const ( hằng), var ( biến), function (hêm).
* Vê dụ : int Siso= 30;
Printf ( " In sĩ số lớp học lê %d, Siso );
a/ Các ký tự điều khiển :
\n : sang dòng mới
\b : lùi lại 1 tab.
\f : sang trang mới
\t : dấu tab
\' : In ra dấu '
\" : in ra dấu "
\ \ : in ra dấu \
b/ ký tự chuyển dạng :
Ký tự chuyển dạng Kiểu của đối Mô tả
c char đối lê ký tự
d/di int đối lê số nguyên
ld /li long đối lê số nguyên dêi
f float hoặc doubl đối lê số thực
s xâu ký tự(chuỗi) đối lê chuỗi
u int số nguyên hệ 10 không dấu
O int số nguyên hệ 8 không dấu
lo long số hệ 8 không dấu
x int số hệ 16 không dấu
lx long số hệ 16 không dấu
g float hay double không in ra các số không vô nghĩa
c float hoặc double đối trong dạng thẪp phân
Ðộ rộng dênh cho biến , trước in ra. Lưu ý ra mên hình printf( stdpm, "\n sĩ số ..")
2.2/ Hêm scanf :
- scanf (" formated string ", các địa chỉ biến );
* Vê dụ :
int a ;
float x,y;
char cr[6], ct[6];
scanf (" %f %5f3d%35%5 ", &x , &y , &a , c r, ct);
NhẪp vêo 5.4 25 124 523 48ab Enter .
=> kết quả lê : x=5.4 ; y=25.0; a = 124; cr= "523"; ct = "48ab"
2.3/ Dòng vêo STDIN (standard in) vê các hêm scanf, gets, getchar.
- StdIn dòng vêo chuẩn( bên phêm).
- Lưu ý : nếu từ Stdin có đủ dữ liệu thì các hêm trên sẽ nhẪn 1 phần dữ liệu mê dòng yêu cầu. Phân còn lại ( chưa nhẪp) vẫn trên StdIn.. Nếu chưa đủ đợi đến khi Enter.
* Vê dụ : char ht[20] ;
print ( " \n hoten: ") ;
gets(ht);
- Hêm getchar() nhẪn 1 ký tự từ stdIn vê trả về ký tự nhẪn được.
* Vê dụ : Int ch; ch = getchar(); nếu nhẪp A vê enter => ch='A'
'\'n vẫn còn trên stdIn vê hêm getchar sau đó hêm scanf cũng như vẪy.
- Lêm sach stdIn : fflush(stdin);
Vê dụ : Print("\ tuoi : n"); scanf ( " %d " , &tuoi);
Printf ("\n hoten :"); fflush( stdin); get(ht);
Vê dụ : scanf( %d", &a); ch =getchar(); gets(ht);
NhẪp vêo liên tục : 12E Trần Văn T ( Enter ).
=> kết quả lê : a =12, ch = 'E', ht = " Trần văn T"
ã Hêm puts : đưa một chuỗi ký tự ra stdout ( mên hình )
Vê dụ : puts('\n lophoc"); đưa dòng chữ lợp học lên 1 dòng mới.
* Hêm putchar : đưa 1 ký tự lên stdout .
Vê dụ : putchar('A') ; ----> in ra ký tự A.
Chú ý : Tất cả các hêm trên khai báo trong stdio.h.
2.4 các hêm vêo ra mên hình , bên phêm thuộc hêm conio.h
- Hêm getch() : nhẪn 1 ký tự trực tiệp từ dộ đệm bên phêm vê trả về ký tự nhẪn được
- Hêm getchc () : nhẪn 1 ký tự trực tiếp từ vê hiển thị trên monitor
- Hêm Putch ( Int ch) : hiển thị ký tự ch theo miền xác định trong hêm textcolor
#putchar () hiển thị theo mêu trắng.
Int Kbhit(void) = 0 nếu bộ đệm bên phêm rỗng.
# 0 nếu bộ đệm bên phêm khác rỗng.
Chú ý : Nếu gõ phêm khi máy dừng chờ trong các hêm scanf, gets, getchar thì ký tự vêo stdin => if (Kbhit ()) ch = getch() ; hoặc scanf(" %d%*c, &i); ( để khỪ ' \n ').
+ clrscr(); hêm xoá mên hình.
+ goto xy (x,y): di chuyển con trỏ đến toạ đô ỹ(x,y) : x : cột ( 1..80); y : dòng 1..25.
* Vê dụ : viết chương trình nhẪp vêo tên ban vê in ra lời chêo :
# Include <stdio.h>
#Include<conio.h>
main ()
{ char name[30], ch;
printf( " nhẪp tên của bạn : "); scanf (" % s ", &name);
printf(" \n chêo %s!\n", name);
ch = getch();
/* ( đợi nhẪn số 1 ký tư ỷ=> dừng mên hình*/

Sưu tầm

< language=> < language=> < language=> < language=>
PMEmail PosterICQYahoo
Top
windows2000vn
Posted: October 27, 2004 07:13 pm
Quote Post


SUPER START
Group Icon

Group: Điều Hành FORUM
Posts: 1409
Member No.: 1
Joined: June 12, 2004



chương 3
3.1/ a/Khái niệm : mọi chương trình đều có thể biểu diễn qua 3 cấu trúc :
- tuần tự : mặc định ( default)
- lựa chọn ( lệnh if hoặc lệnh switch)
- lặp ( for, while hoặc do while)
b/ Khối lệnh : lê tẪp hợp các câu lệnh được khai báo bởi 2 dấu { vê } .
không đặt dấu chấm phẩy ( ; ) sau một khối lệnh trừ một vêi trường hợp đặc biệt.
3.2 / Các câu lệnh
3.2.1 Lệnh If :
- Cú pháp : If ( biểu thức) < lệnh> ;
- Diễn giải : nếu Biểu thức đúng ( khác 0 ) --> thực hiện <lệnh>
ngược lại nếu biểu thức sai ( = 0 ) -ă thực hiện lệnh đứng sau câu lệnh if.
- Hoặc : If ( biểu thức) <lệnhA>;
else < lệnh B);
+ Biểu thức : # 0 ( đúng) ----> < lệnh A>
=0 ( sai ) ---> < lệnh B>.
* Vê dụ : tìm số lớn nhất trong 2 số a, b :
if (a<b) max = b ;
else max = a ;
( Viết lại hoên chỉnh chương trình trên).
* Cách 2 : max = (a>b)? a:b; ( Viết lại hoên chỉnh chương trình).
- Chú ý : trong trường hợp có nhiều lệnh If l**ng nhau thì else sẽ gắn liền với if gần nhất.
If(bt1) <lệnh1>;
Else
If (bt2)
If(bt3) < lệnh2>;
else <lệnh 3>; /* bt3 = = 0 */
else <lệnh 4>; /* bt2= = 0 */
*Vê dụ : Viết chương trình giải phương trình bẪc nhất : Ax + B = 0 (A, B : số thực).
Giải : Xét các trường hợp xảy ra :
- Nếu A! =0 thì nghiệm x = -B/A
- Nếu A = 0 +> B=0 => Nếu B=0 : vô số nghiệm
B != 0 ( ngược lại) : vô nghiệm.
/* Giải phương trình bẪc nhất : Ax + B = 0 */
#Include <stdio.h>
#Include < conio.h>
void main ( void)
{
float a, b ;
/* nhẪp dữ liệu từ bên phêm */
print ( "\ nhẪp 2 số a,b : "); scanf(" %f %f ", &a, &b);
/* giải phương trình*/
If ( a= = 0 )
If( b= =0 )
Printf (" Phương trình có vô số nghiệm ! \n " );
Else
Printf (" phương trình vô nghiệm \n ");
Else / * a khác 0 */
Printf (" phương trình có nghiệm lê : x= %f \n ", -b/a);
Printf( " ấn phêm bất kỳ tiếp tục ");
Getche();
}
Bêi tẪp 1 : Tìm những lỗi cú pháp các đoạn chương trìnhh sau :
A/ scanf ( "d", value);
B/ printf ("têch các %d vê %d lê %d " \n, x,y);
C/ printf (" phần dư của %d chia cho %d lê \n ", x , y , x%y );
D/ if(x=y);
Printf (" %d bằng %d \n ", x,y);
E/ If ( age>=65);
Printf (" gia ì! ');
Else
Printf(' Tre! ');
3.2.2 Lệnh switch
- Cú pháp : Switch (biểu thức nguyên).
{
Case N1 : lệnh 1;
Case N2 : lệnh 2;
.....
[ default : lệnh;]
}
- Biểu thức nguyên lê giá trị nguyên : Ni(i=1,2...) lê các số nguyên.
- Với biểu thức khác với mọi Ni => thực hiện lệnh sau default.
- Chú ý : nếu nhóm câu lệnh sau nhãn case Ni không có câu lệnh break thì máy sẽ chuyển sang nhóm câu lệnh sau nhãn case Ni+1
*Vê dụ : đổi 1 số nguyên sang chuỗi ký tự lê tên các môn học
#Include<stdio.h>
#Include<conio.h>
main( )
{
Int ma ;
Do
{
printf(" \n cho mã cần chuyển "); scanf(" %d ", &ma);
switch(ma)
{
case 0 : printf(" \n lớp tin học a ");
break;
case 1 : printf( " \n lớp tin học b");
break;
case 2 : printf(" \n lớp trung cấp ");
break;
case 3 : printf (" \n lóp chuyên viên ");
break;
default : printf( " \n lợp thiế tiền học phê");
}
printf( " \n có tiếp tục không ?(Y/N)");
}
while( toupper ( getch () ! = 'N '); /* Chuyển san ký tự hoa */
}
3.2.3 / Lệnh For :
- Cú pháp : for ( bt1; bt2 ; bt3) lệnh;
- Giải thêch :
+ bt1 : lê toán tỪ gán để tạo giá trị ban đầu cho biến điều khiển.
+ bt2 : biểu thức điều kiện để thực hiện vòng lặp.
+ bt3 : biểu thức tăng giá trị của biến điều khiển của vòng lặp.
*Vê dụ : Tênh Tổng S=1+2+3+..+n
For ( int i=1, s=0; i<=n; s+ =i, ++i );
* Cơ chế hoạt động :
a/Tênh giá trị của biểu thức bt1 .
b/Tênh giá trị của bt2
c/ + Nếu giá trị của bt2(=0) lê sai máy sẽ ra khỏi lệnh For.
+ Nếu giá trị của bt2(!=0) lê đúng thì máy sẽ thực hiện lệnh.
d/ Tênh giá trị của bt3 vê quay lại bước kiểm tra 2(b)
Chú ý : + Khi bt2 vắng mặt thì nó được coi lê luôn luôn đúng
* Vê dụ : for (i=0; ; i++) lệnh ;
+ bt1 , bt3 có thể bao gồm nhiều biểu thức cách nhau bởi dấu phẩy.
+ bt2 có thể gồm nhiều biểu thức, tuy nhiên tênh đúng sai của nó được xem lê tênh đúng sai của biểu thức cuối cùng.
* Vê dụ : tênh tổng : S=1! + (1+2)! + ....+ ( 1+2+....i )! .....( 1 + 2 + ..n)!
#include <stdio.h>
#include<conio.h>
#include<math>
/* int i, j, t, n ; double gt, s; */
main()
{
int i, j, t, n ; double gt, s;
clrscr () ;
printf ("nhẪp n= "); scanf(" %d ", &n);
Cách 1 :
s=0 ; t=0;
for (s= 0,t= 0,i=1; i<=n ; ++i )
{
t=t+i;
for ( gt=1,j=1; j<=t ; ++j)
gt = gt*j ; s = s+gt;
}
printf ( " tong s = %15.0f ", s);
getch();
Cách 2 :
for ( s=0, t=1, i=1; i<=1; ++i , t = t + 1)
{
for ( gt=1,j=1;j<=t; ++j)
gt*=j; s+= gt;
}
Cách 3 : thân for lê câu lệnh rỗng
For (s=0, t=1,i=1; i<=n; ++i, t=t+i,s+=gt)
For( gt=1,j=1; j<=t; gt* = j , ++j );
Cách 4 : không có bt 1 vê bt3;
Int i=1, j=1, t=1, n ; double gt = 1, s= 0 ;
For ( ; i<=n ; ++i, t = t + i , s+ = gt) /* không có biếu thức 1*/
{
For ( ; j<=t ; ) /* không có bt1 , bt3*/
Gt* = j ++ /* gt = j ; ++j */
}
Cách 5 : không có bt1, bt2, bt3
For (;
{
for (;
{
gt* = j++ ;
if ( j < t ) goto tong ;
}
tong : s+ = gt; ++i , t = t + i ;
if( i < n ) goto KT;
KT : printf (" tong s= % 15.0 f " , s )
}
3.24/ Câu lệnh while :
- Cú pháp : while ( biểu thức 1) lệnh 1 ;
- Nguyên tắc thực hiện :
+b1. Tênh giá trị của biểu thức 1.
+b2. Nếu giá trị của biểu thức 1 sai ( = 0 ) thì chương trình ra khỏi vòng while
+b3. Nếu giá trị của biểu thức đúng thì thực hiện lệnh 1 vê quay lại bước 1(b1).
- Chú ý : Biểu thức 1 có thể gồm nhiều biểu thức nhưng tênh đúng sai phụ thuộc vêo biểu thức cuối cùng.
Vê dụ : NhẪp 1 dãy số nguyên từ bên phêm
#include < stdio.h >
#include < conio.h >
main ()
{
Int dayso [ 10 ] ; int i = 0 ;
While ( i < 10)
{
printf ( "\n Số thu %d : ", i ); scanf ( " %d", & dayso );
i ++ ;
}
3.25/ Câu lệnh Do while ( lêm trước hỏi sau )
- Cú pháp : do lệnh 1 ;
while ( biểu thức 1 ) ;
- Nguyên tắc thực hiện :
+b1. Máy thực hiện câu lệnh 1 ;
+b2. Sau đó tênh giá trị của biểu thức 1, nếu giá trị của biểu thức 1 sai thì chương trình thoát ra khỏi vòng lặp. Nếu giá trị của biểu thức 1 đúng thì quay lại bước 1.
Chú ý : - while : Ðiều kiện được kiểm tra trước, nếu đúng mới thực hiện.
- do while : câu lệnh được thực hiện trước khi kiểm tra. Câu lệnh thực hiện bao giờ êt nhất lê 1 lần. ( do while ngược với
Repeat until của Pascal : lệnh Do while sai thì dừng, còn lệnh repeat until đúng thì dừng ).
-Biểu thức 1 có thể gồm nhiều biểu thức, tuy nhiên tênh đúng sai căn cứ theo biểu thức cuối cùng.
* Vê dụ : tênh pi với sai số eps = 1E - 4 , pi = 4 - 4/3 + 4/5 - 4/7 + ...eps
#include < stdio.h >
#include < conio.h>
main ()
{
float pi, dau, i , eps, saiso ;
i=1.0; dau = -1; saiso = 1e -4 ;
pi = 4.0;
printf ( "\n đang xỪ lý vui lòng đợi !");
do
{
eps = 4.0 / ( 2.0 * i + 1.0 );
pi + = dau * eps ; dau = dau * - 1.0 ; i + = 1.0;
}
while ( eps > saiso );
printf ("\n số pi lê : " % f ", pi ) ;
getch ();
}
3.2.6/ Câu lệnh Break :
- Cú pháp : Dùng để thoát khỏi vòng lặp. Khi gặp câu lệnh nêy trong vòng lặp, máy ra khỏi vê chỉ đến câu lệnh sau các lệnh trên. Nếu nhiều vòng lặp ----> break sẽ thoát ra khỏi vòng lặp gần nhất.
3.2.7/ Lệnh continue :
- Cú pháp continue; : khi gặp lệnh nêy trong các vòng lặp, máy sẽ bỏ qua phần còn lại trong vòng lặp vê tiếp tục thực hiện vòng lặp tiếp theo.
- Ðối với lệnh For máy sẽ tênh lại biểu thức 3 (bt3) vê quay lại bước 2.
- Ðối với lệnh while, do while máy sẽ tênh lại giá trị của biểu thức 1 vê quay lại bước 1.
* Vê dụ : NhẪp 1 chuỗi ký tự kể cả ký tự trống vê bỏ qua các ký tự không hợp lệ vê kết thúc khi ấn ESC hoặc số ký tự vượt quá kêch thước mãng.
char xau [MAXL], kytu ;
int i = 0 ;
while (1) /* luôn luôn đúng vòng lặp vĩnh cỪu */
{
kytu = getch ( ) ;
if ( kytu = = 27 ) break ;
if ( i >= MAXL ) break ;
if ( kytu > 122 || kytu < 65 ) continue ;
Xau [ i ++] = kytu ;
}
xau [ i ] = ' \ 0 ' ;
3.3/ Toán tỪ goto vê nhãn ( label );
- Vê dụ : tiep tuc : st = a[ i ]; => tiep tuc lê nhãn của lệnh st = a [ i ];
- Lệnh goto nhãn => nhảy đến câu lệnh đứng sau nhãn.
- CHÚ Ý : PHẪM VI NHÃN TRONG CÙNG 1 HÀM.
BÀI TẬP CHƯƪNG 3
1/ Kiểm tra tìm lỗi :
while ( x<.= 10 )
Total t=x;
++x ;
2/ Giải phương trình bẪc 2 : ax2 + bx + c = 0 với a, b, c lê số thực nhẪp từ bên phêm.
3/ NhẪp số liệu vêo bên phêm, kết thúc nhẪp bằng cách ấn ^Z hoặc F6 ( mũ = 255 ). Biết :
InWord = on khi ở trong 1 từ. InWord = off khi ngược lại. Ðếm số dòng, số từ, số ký tự.
4/ Tìm các số nằm trong khoảng từ 150 đến 140 thoả tênh chất số bằng tổng lẪp phương các chữ số của chúng :
Vê dụ : 153 = 13 + 53 + 33 hoặc 370 = 33 + 73 + 03
5/ Số tuyệt hảo lê số bằng tổng các ước số thực sự của nó. Vê dụ : 6 = 1 + 2 + 3.Tìm các số tuyệt hảo trong khoảng từ 1 đến 3000.
6/NhẪp số liệu vêo mãng A gồm 10 phần tỪ vê sắp xếp theo thứ tự tăng dần.
7/ Tìm tất cả các số nguyên tố từ 2 đến 100 bằng lệnh For.
8/ Tìm các số nguyên có 3 chữ số sao cho tổng 3 chữ bằng têch 3 chữ. Vê dụ : 123.
9/ a/ Dùng lệnh while để viết chương trình tênh :
S1 = 1 x 3 x 5 x 7 x 9. . . . . x ( 2n - 1 ).
S2 = 2 x 4 x 6 x 8 x ......x (2n).
b/ lêm lại bêi trên bằng cách dùng do...while.
10/Giải bêi toán cổ điển vừa gê vừa chó bó lại cho tròn 36 con 100 chân chẵn.
PMEmail PosterICQYahoo
Top
windows2000vn
Posted: October 27, 2004 07:14 pm
Quote Post


SUPER START
Group Icon

Group: Điều Hành FORUM
Posts: 1409
Member No.: 1
Joined: June 12, 2004



Chương 4

Chương trình viết bằng ngôn ngữ C gồm 1 dãy các hêm trong đó có 1 hêm chênh lê main vê chương trình bắt đầu từ main.
4.1/ Khái niệm :
- Hêm lê đoạn chương trình thực hiện trọn vẹn một công việc nhất định.
- Hêm chia cắt việc lớn bằng nhiều việc nhỏ. Nó giúp cho chương trình sáng sủa, dễ sỪa, nhất lê đối với các chương trình lớn.
4.2/ Khai báo hêm :
< Tên hêm > (< danh sách các đối số>)
< Khai báo biến >
{
< Khai báo thêm các biến >
< Các câu lệnh >
}
- Trong đó :
+ Tên hêm : buộc phải có.
+ Danh sách các đối số : không bắt buộc. Có hay không tuỳ theo chúng ta định dùng hêm đó lêm gì.
+ Khai báo biến : Nếu Danh sách các đối số mê có thì phần nêy buộc phải có. Còn nếu không thì ngược lại có thể bỏ qua.
+ Phần trong { } : lê thân hêm. Dấu { } lê bắt buộc đối với mọi hêm.
+ < Khai báo tham biến > : ngay sau { vê gọi lê biến cục bộ dênh riêng cho hêm sỪ dụng.
+ đối số luôn luôn truyền theo trị ( không thay đổi giá trị).
*Vê dụ : Hêm tênh giai thừa : S = x 1 /1! + x 2 /2! + ....+ x n / n!
Cách 1 :
#Include <stdio.h>
#Include <conio.h>
float giaithua ( int n)
{
int i ;float KQ ;
for ( KQ=1,i =1 ; i<=n ; i ++ )
KQ = KQ * i ;
return KQ ;
}
Void main ( ) /* khai báo biến toên cục nếu có */
{
int n ;
printf ( " NhẪp n = " ); scanf ( " %d ", &n);
printf ( " %d giai thừa lê % f ", n, giaithua (n) );
getch ();
}
Cách 2 :
#Include <stdio.h>
# Include<conio.h>
/*Khai báo prototype*/ mục đêch hêm đặt ở đâu cũng được không cần trước hêm gọi
float giaithua ( int n );
void main ()
{
}
/* Chi tiết hêm giai thừa */
float giaithua ( int n)
{ ... return KQ };
Chú ý : - Kiểu của hêm cùng kiểu giá trị cần trả về.
- Các hêm độc lẪp, không được l**ng nhau.
- Kiểu void tên hêm () : không cần trả về giá trị nêo, hiểu ngầm lê trả về int.
- ở cách 1 : hêm ở trên không được gọi hêm dười.
- ở cách 2 : các hêm gọi được lẫn nhau.
4.3 / Phạm vi của biến :
- Chẳng hạn trong vê dụ trên : biến n trong hêm main ( ) lê cục bộ của main() chỉ có tác dụng trong hêm main() => trong hêm giai thừa có thẻ khai báo biến n trùng biến n của hêm main ( ) nhưng khác nhau vê chỉ tồn tại trong 1 hêm.
Vê dụ : float giaithua (m);
{
int n ; float KQ = 1.0;
for ( n = 1; n<= m ; ++n )....
4.4 / Ðệ quy : giống như trong Pascal : hêm gọi đến chênh nó.
* Vê dụ : Tênh giai thừa :
giaithua ( n );
int n ;
{
if ( n = 0 ) return ( i ) ;
else return (giaithua ( n - 1 )*n );
}
- Chương trình sỪ dụng đệ quy thì dễ hiểu nhưng không tiết kiệm được bộ nhớ, không nhanh hơn.
4.5/ So sánh Lệnh trong Pascal vê trong lẪp trình ngôn ngữ C.
- Giống nhau : + Cả Pascal vê C đều có chương trình con.
- Khác nhau :
Pascal Ngôn ngữ C
Có thủ tục Chỉ có hêm
Có hêm Hêm có thể khai báo kiểu void ( không trả về giá trị nêo cả, giống như thủ tục của Pascal
- Khai báo hêm
function Tên hêm (<danh sách biến) < kiểu hêm>;
< Khai báo các biến cục bộ>
Begin
< Các câu lệnh>
end; < Kiểu> tên hêm ( < danh sách các biến>)
{
< khai báo các biến cục bộ>
Các câu lệnh
}
Khai báo biến
<tên biến >: < kiểu biến>;
Vê dụ : Function max ( a, b : integer ) : integer
Begin
if a > b then max = a
Else max = b ;
End.
Trả về giá trị bằng phép gán max = giá trị ( trong đó max lê tên hêm ). Khai báo biến
< kiểu biến> < tên biến >;
Vê dụ : int max ( a, b )
{
If ( a > b ) return ( a );
else return ( b );
}
- Trả về giá trị bằng câu lệnh return ( giá trị)
Kiểu tham số
+ Tham biến : truyền theo địa chỉ
+ Tham trị : truyền theo giá trị.
Tham biến trong Pascal
Procedure swap ( var x, y : real );
Var temp : real ;
Begin
Temp : = x ; x : = y ; y : = temp;
End.
- gọi hêm : swap ( a, b) Kiểu tham số
+ Chỉ có tham trị.
+ Muốn có tham biến bằng cách đưa con trỏ hình thức tham biến trong C.
Tham biến trong C
Void swap ( float *x, float * y )
{
float temp ;
temp = * x ; *x = * y ; * y = temp ;
}
swap ( &s, &b )
PMEmail PosterICQYahoo
Top
windows2000vn
Posted: October 27, 2004 07:19 pm
Quote Post


SUPER START
Group Icon

Group: Điều Hành FORUM
Posts: 1409
Member No.: 1
Joined: June 12, 2004



chương 5
5.1/ Mảng : lê tẪp hợp của các biến cùng kiểu được xếp liên tiếp nhau trong bộ nhớ trong.
5.1.1/ Mảng 1 chiều :
a/ Khái niệm : < kiểu phần tỪ > < tên mãng> [ < chỉ số > ]
Vê dụ : int a [5 ] ; => a [0] a[1] a[2] a [3] a [4] ( chỉ số chạy từ 0 đến n - 1 ).
Char S [20] ; => 'A' 'B' ...... 'X '
S[0]S[1] S[19]
b/ Cách nhẪp số liệu cho mảng từ bên phêm ( có thể dùng hêm Random C).
+ Mảng số nguyên :
Vê dụ : NhẪp vêo mảng số nguyên 5 phần tỪ
#include < stdio.h>
#include < conio.h>
#define n 5
main ()
{
int a [ n ] ; int i ;
for ( i = 0 ; i < n ; i ++ )
{
printf ( " a [ %d ] = " , i ); scanf ( " % d" , & a [ i ]);
}
/* Xuất số liệu mảng ra mên hình */
for ( i = 0 ; i < n ; ++ i)
printf ( " \ n a [ % d ] = % d ", i , a [ i ]);
getch ();
}
+ Mảng số thực float :
#include <stdio.h>
#include < conio.h>
#define n 5 ;
main ()
{
float a [ n ] , tam ;
.....scanf ( " % f " , &tam) ; /*nhẪp qua biến trung gian tạm */
a [ i ] = tam ;
c/Khởi tạo mảng :
a [ 5 ] = { 1,2,3,5,4 }a[0]=1 a[2]=2 .. a[4]=4
d/ Mảng ký tự :
- lê chuỗi ký tự kết thúc bằng ký tự NULL có mã ASCII lê 0 .
- Vê dụ : char S [3] = { 'L', '0', 'P'] : chuỗi nêy không đúng do thiếu chỗ cho ký tự kết thúc lê NULL.
- Ta có thể gán :
char S [ 4 ] = " Lop "; Ngôn ngữ C sẽ tự động ghi ký tự kết thúc lê NULL, tức lê ' \0 '.
char S[ ] = " Lop " ; Không cần khai báo số phần tỪ mãng.
* Vê dụ 1 : NhẪp vêò một mảng số nguyên sau đó sắp xếp theo thứ tự tăng dần :
#include < stdio.h>
#define n 5
main ( )
{
int a [ n ] ; int i , j, t ;
for ( i = 0 ; i > n ; i ++ );
{
printf ( " nhẪp a [ % d] = " , i ); scanf ( " %d", & a [i ]);
}
/* Sắp xếp tăng dần */
for ( i = 0 ; i < n - 1 ; i ++)
for ( j = i + 1 ; j < n ; j ++ )
if ( a [ i ] < a [j ] )
{
t = a [ i ] ; a [ i ] = a [ j ]; a [j ] = t ;
}
/* in kết quả */
for ( i = 0 ; i < n ; i ++ )
printf ( " % 5d " , a [ i ] );
getch ( );
}
Vê dụ 2 : Lêm lại vê dụ 1 nhưng viết riêng hêm sắp xếp vê truyền tham số cho mảng 1 chiều
#include <stdio.h>
#include <conio.h>
#define N 5
void sapxep ( int a [ ] , int n );
void main ( )
{
int a [ N ] ; int i ;
/* nhẪp 1 số liệu cho mãng */
for ( i = 0 ; i < N , i ++ )
{
printf ( " A [ %d ] = ", i ); scanf ( " %d ", & a [ i ] ); }
/* gọi hêm sắp xếp để sắp tăng dần */
sapxep ( a, N );
/* in kết quả */
for ( i = 0 ; i < N ; i ++ )
printf ( " %5d ", a [ i ] );
getch ( );
}
/* hêm sắp xếp tăng dần */
void sapxep ( int a [ ], int n )
{
int i, j, t ;
for ( i = 0 ; i > n - 1 ; i ++)
for ( j = i + 1 ; j < n ; j ++ )
if ( a [ i ] > a [ j ]
{
t = a [ i ] ; a [ i ] = a [ j ] ; a [j ] = t ;
}
* Vê dụ 3 : chuyển đổi 1 chuỗi ký tự thường thênh Hoa.
Chú ý : + Hêm tolower ( ch ) : đổi 1 ký tự ch thênh thường.
+ Hêm toupper ( ch ) : đổi ký tự ch thênh Hoa.
+ Cả 2 hêm trên đều năm trong thư viện : < ctyte.h>
Giải : #include < stdio.h>
# include < ctyte.h>
#define n 20
main ( )
{
char s [ n ] ; int i ;
for ( i = 0 ; i < n ; i ++ )
s[ i ] = toupper ( getchar ( ) ) ; /* nhẪp ký tự vê đổi thênh hoa lưu vêo mãng */
/* kết xuất chuỗi s */
for ( i = 0 ; i < n ; i ++ )
putchar ( s [ i ] ) ; /* putchar ( ch ) : in ký tự ch ra mên hình */
getch ( )
}
Bêi tẪp : 1/ viết chương trình nhẪp số liệu cho mảng A gồm N phần tỪ vê mảng B gồm n phần tỪ , sau đó ghép 2 mãng A vê B thênh mãng C gồm m + n phần tỪ vê sắp xếp tăng dần ( Bêi nêy phải dùng hêm nhẪp số liệu cho mảng vê hêm sắp xếp).
- Tênh tổng các phần tỪ âm, dương, số chẳn, số lẽ vê tổng tất cả các phần tỪ của mãng
C [ m + n ].In các số lẻ trên 1 hêng vê các số chẵn trên 1 hêng.
- NhẪp vêo một giá trị vê tìm xem giá trị đó có thuộc vêo mãng C không. Nếu có in ra tất cả các phần tỪ tìm được.
5.2/ Mãng nhiều chiều :
a/ Khai báo : < kiểu phần tỪ > < tên mãng > [ < chỉ số hêng > ] [ < chỉ số cột >]
*Vê dụ 1 : int a [ 3 ] [ 2 ] ; float b [ 3 ] [ 4 ] ; char c [5 ] [6 ] ;
=> a [ 0 ] [0 ] a [ 0 ] [ 1 ]
a [ 1 ] [ 0 ] a [ 1 ] [ 1]
a [ 2 ] [ 0 ] a [ 2 ] [ 1 ]
Vê dụ 2 : #define Hang 5
# define Cot 6
int a [ Hang ] [ Cot ] ;
=> ta có các biến chạy i ( chỉ số chạy từ 0 đến ( Dong - 1)).
ta có các biến chạy j ( chỉ số chạy từ 0 đến ( Cot - 1 )) .
a [0] [0] a [0][1] ...... a [ 0 ][Cot - 1]
a [1] [0] a [1][1] ...... a [a][Cot - 1]
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
a[Dong-1][0]...... . . . . . . . . a[Dong-1][Cot-1]
*Vê dụ : Viết chương trình tênh tổng, têch các số trong mãng số thực a[3][2] ;
#include < stdio.h>
#define N 3
#define N 2
main ( )
{
int i , j ; float a [M][N] ; float tong, tich, tam ;
/* nhẪp số liệu */
for ( i = 0 ; i < M ; i ++ )
for ( j = 0 ; j < N ; j ++ )
{ printf ( " nhẪp a [ %d][%d] = " , i , j );
scanf ( " %f " , & tam ) ; a [j] = tam ;}
/* tênh tổng */
Tong = 0 ; Tich = 1;
for ( i = 0 ; i < M ; i ++ )
for ( j = 0 ); j < N ; j ++ )
{
Tong = Tong + a [ i ][j] ; Tich = Tich * a [j] ; }
/* in kết quả */
printf ( " Tổng lê tổng = %f, TONG );
printf ( " têch lê TICH = %F, TICH );
getch ( ) ;
}
b/ Truyền tham số mãng nhiều chiều cho hêm ( tham số thực lê tên mãng nhiều chiều )
- giả sỪ a lê mãng 2 chiều : float a[M][N]
+ Chương trình gọi :
{ float a [M][N]
Tong ( a ) ; ( truyền địa chỉ của mãng cho hêm )
}
+ Chương trình bị gọi ( chương trình con ) :
float tong ( float a[ ][N] ) /* khai báo đối để nhẪn địa chỉ của mãng */
{
}
Note : hêm tong chỉ dùng được đối với các mãng hai chiều có N cột vê số hêng không quan trọng, không khai báo ) :
* Vê dụ : Viết chương trình tênh tổng của 2 ma trẪn cấp m x n theo công thức :
C[j] = a[j] + b [j]
#include <stdio.h>
#define m 3
#define n 4
/* các prototype ( khai báo hêm )*/
void nhap ( int a[ ][N] , int M, int N );
void TongMT ( int a[ ][N], int b[ ][N] , int c [ ][N], int M , int N );
void InMT ( int c [ ][N], int M, int N );
/* chương trình chênh */
{ int a [M][N], b[M][N], c[M][N] ;
/* gọi các hêm */
Nhap ( a, M ,N ) ; nhap ( b, M,N);
TONGMT ( a, b, c , M, N );
InMT ( c, M, N );
Getch ( ) ;
}
/* Hêm nhẪp số liệu cho mãng 2 chiều m x n phần tỪ */
void Nhap ( int a [ ][N] , int M , int N )
{
int i , j ;
for ( i= 0 ; i < M ; i ++ )
for ( j = 0 ; j < N ; j++ )
{
printf ( " a[%d][5d] = " , i , j ) ; scanf ( " %d " , &a [j]) ; }
return ;
}
Void TongMT ( int a [ ][N], int b [ ][N], int c [ ][N], int M , int N )
{
int i, j ;
for ( i = 0 ; i < M ; i ++ )
for ( j = 0 ; j < N ; j ++ )
c [j] = a [j] + b [j] ;
return ;
}
/* in kết quả */
void inMT ( int c[ ][N], int M, int N )
{
int i, j ;
for ( i = o ; i < M ; i ++ )
{ for ( j = 0 ; j < N ; j ++ )
printf ( " % 3d", a[j] );
printf ( " \n " ) ; /* xuống dòng */
}
return ;
}
BêI TẪP MãNG :
1/ cho mãng 2 chiều A, lê ma trẪn vuông cấp n x n , lẪp chương trình :
a/ tênh tổng tất cả các phần tỪ dương của mãng.
b/ tênh tổng các phần tỪ A[j] mê i + j chia hết cho 5 .
c/ In ra các số nguyên tố theo từng hêng.
d/ Sắp xếp theo hêng.
e/ Sắp xếp theo cột .
f/ Tênh tổng các phần tỪ trên đường chéo ( i = j ) , đường biên.
g/ Tìm max ; min theo từng hêng, cột vê toên bộ ma trẪn.
2/ Một chuỗi gọi lê palindrone nếu nó không thay đổi khi ta đảo ngược thứ tự của các ký tự trong nó ( vê dụ " 12321 " )
. LẪp chương trình đọc một chuỗi ( xâu ) ký tự vê xác định xem có tênh palondrone không.


5.3/ Biến con trỏ :
5.3.1/ Khái niệm con trỏ ( pointer ) vê địa chỉ :
- Mỗi biến trong ngôn ngữ C đều có 1 tên vê tương ứng với nó lê một vùng nhớ dùng để chứa giá trị của nó. Tuỳ theo biến mê vùng nhớ dênh cho biến có độ dêi khác nhau. Ðịa chỉ của biến lê sô thứ tự của byte đầu tiên tương ứng với biến đó. Ðịa chỉ của biến có kiểu khác nhau lê khác nhau. Ðịa chỉ vê biển kiểu int liên tiếp cách nhau 2 byte , biến kiểu float lê 4 byte.
- Con trỏ lê biến dùng để chứa địa chỉ của biến khác hoặc có thể lê một hêm. Do có nhiều loại địa chỉ nên cũng có nhiều loại biến con trỏ. Con trỏ kiểu int dùng để chứa địa chỉ của kiểu int. Con trỏ kiểu float dùng để chứa địa chỉ kiểu float.
- Muốn sỪ dụng được pointer, trước tiên phải có được địa chỉ của biến mê ta cần quan tâm bằng phép toán lấy địa chỉ & . Kết quả của phép lấy địa chỉ & sẽ lê 1 phần tỪ hằng.
* Vê dụ : int num ; => &num lê địa chỉ của num.
int pnum ; /* pnum lê 1 pointer chỉ đến một int */
pnum = & num ; /* pnum chứa địa chỉ biến int num*/
giả sỪ : num = 5 ; => * pnum = 5 /* do * lê toán tỪ nội dung */
Hai câu lệnh sau đây lê tương đương
Num = 100 ;
( * pnum ) = 100 ;
- Quy tắc khai báo biến con trỏ : < kiểu dữ liệu> * < tên biến con trỏ >
*Vê dụ 2 : int a, *p ;
a = 5 ; /* giả sỪ địa chỉ của a lê < 106 > */
p = & a ; /* p = <106> */
p = a ; /* phép gán sai */
* p = a ; /* phép gán đúng */
scanf ( " %d " , &a ) ; tương đương scanf ( " %d , p ) ;
5.3.2/ tênh toán trên biến con trỏ ( pointer )
a/ Hai biến con trỏ cùng kiểu có thể gán cho nhau :
Vê dụ 1 : int a, * p, *a ; float * f;
a = 5 ; p = &a ; q = p ; /* đúng */
f = p ; /* sai do khác kiểu */
f = ( float * )p ; /* đúng nhờ ép kiểu con trỏ nguyên về kiểu float */
Vê dụ 2 : int a ;
char *c ;
c = &a ; /* sai vì khác kiểu */
c = ( char*) /* đúng */
b/ Một biến pointer có thể được cộng, trừ với một số nguyên ( int , long ) để cho kết quả lê một pointer.
* Vê dụ : int a , *p , * p10 ;
a = 5 ;
p = &a ;
p10 = p + 10 ;
Vê dụ : int V[10] ;/* mãng 10 phần tỪ */
int *p ;
p = & V[0];
for ( i = 0 ; i < 10 ; i ++ )
{ *p = i ; /* gán giá trị i cho phần tỪ mê p đang trỏ đến */
p ++ /* p được tăng lên 1 để chỉ đến phần tỪ kế tiếp */
}
/* kết quả V[0] = 0 , V [ 1] = 1 ... V[9] = 9 * /
c/ Phép trừ 2 pointer cho kết quả lê một số int biểu thị khoảng cách ( số phần tỪ ) giữa 2 pointer đó.
d/ Phép cộng 2 pointer lê không hợp lệ, pointer không được nhân chia với 1 số nguyên hoặc nhân chia vơi nhau.
e/ p = NULL : lê con trỏ p không trỏ đến đâu cả.
Chú ý : không được sỪ dụng biến con trỏ khi chưa được khởi gán .
Vê dụ : int a , *p ;
Scanf ( "%d", p ) ( sai )
=> thay bằng các lệnh : p = &a vê scanf ( "%d" p ) ( đúng)
5.4/ Con trỏ mảng :
5.4.1/ Mãng 1 chiều vê con trỏ :
- Trong ngôn ngữ C : giữa mãng vê con trỏ có mối quan hệ chặt chẽ. Các phần tỪ của mãng có thể xác định nhờ chỉ số hoặc thông qua con trỏ.
- Vê dụ : int A[5] ; * p ;
P = A ;
+ mãng bố trê 5 ô nhớ liên tiếp ( mỗi ô chiếm 2 byte ).
+ Tên mãng lê 1 hằng địa chỉ ( không thay đổi được ), chênh lê địa chỉ của phần tỪ đầu tiên. => A tương đương với &A[0]
(A + i ) tương đương với &A
*(A + i ) tương đương với A
p = A => p = &A[0] ( p trỏ tới phần tỪ A[0])
*(p + i ) tương đương với A.
=>bốn cách viết như sau lê tương đương : A, * ( a + i ), * ( p + i ), p.
Vê dụ 2 : int a [5] ; *p ;
p = a ;
for ( i = 0; i < 5 ; ++ i)
scanf ( " %d ", &a); ( 1)
scanf ( " %d ",a + i ); ( 2)
scanf ( " %d", p + i ); ( 3)
scanf ( " % d", p ++ ); ( 4)
scanf ( " %d ", a ++ ); sai vì địa chỉ của a lê hằng.
- Các lệnh (1), (2), (3), (4) tương đương nhau.
Vê dụ 3 : NhẪp 5 số nguyên vêo 1 mãng gồm 5 phần tỪ ( a[5]) sau đó sắp xếp tăng dần, in ra số lớn nhất vf nhỏ nhất vê tênh tổng của 5 số đó.
#include <stdio.h>
#define n 5
main ( )
{ int a [n], t , *p, i , j, ; int s ;
p = a ;
for ( i = 0; i < n ; i ++ )
{ printf ( " a[%d] = " , i ) ; scanf ( " %d ", p + i ) }
/* Sắp xếp tăng dần */
for ( i = 0 ; i < n-1 ; i ++ )
for ( j = i + 1 ; j<n ; j++)
if ( *(a + i ) > * ( a + j )
{ t = * ( a + i ) ; *(a + i ) = * ( a + j) ; *(a + j ) = t ; }
s= 0 ;
for ( j=0 ; i < n , ++i )
s + = a[ i];
printf ("\n Tong = %5d ", s );
printf ( "\n số lớn nhất lê %d ", a [4] );
printf ( " số nhỏ nhất lê %d \n ", a [d] );
getch ( );
}
5.4.2 / Con trỏ vê mãng nhiều chiều :
- Phép toán lấy địa chỉ & chỉ áp dụng được với mãng 2 chiều kiểu nguyên. Các kiểu khác không được.
* Vê dụ 1 : int a[2][3]
{ scanf ( "%d", & a[1][1]) } ( đúng )
* Vê dụ 2 : float a[2][3]
Scanf (" %f", &a[1][1]); ( sai ).
- Mãng 2 chiều a[2][3] => gồm 2 x 3 = 6 phần tỪ có 6 địa chỉ liên tiếp theo thứ tự sau :
Phần tỪ : a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] ( * )
Ðịa chỉ : 0 1 2 3 4 5
- Ngôn ngữ C quan niệm mãng 2 chiều lê mãng một chiều của mãng a[2][3] tương đương không phần tỪ mê mỗi phần tỪ của nó gồm 3 số nguyên nên :
a trỏ tới hêng thứ nhất ( a [0][0] )
a+1 trỏ tới hêng thứ hai ( a[1][0] )
- Do đó để duyệt các phần tỪ của mãng a[2][3] ta dùng con trỏ theo cách sau :
+ ( theo * ) => ta có công thức a[j] = ( int*) a + i * n + j
trong đó : int* : con trỏ a ( địa chỉ a ).
n : số cột.
- float a[2][3] , *p ;
p = ( float*)a ; /* chú ý lệnh nêy */
khi đó : p trỏ tới a[0][0] /* p = & a[0][0] */
p + 1 trỏ tới a[0][1] /* *(p+1) = a[0][1] */
P + 2 trỏ tới a[0][2]
.... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
p + 5 trỏ tới a[1][2] /* *(p+5) = a[1][2] */
* Tổng quát : a[j] = * ( p + i* N + 5 ); trong đó N : số cột )
Kết luẪn : Mãng 2 chiều có thể chuyển thênh mãng 1 chiều nhờ con trỏ.
* Vê dụ : để nhẪp một số liệu vêo mãng 2 chiều kiểu float a[2][3] ta có thể dùng các cách sau:
+ Cách 1 :
#include " stdio.h "
main ( )
{ float a[2][3] , *p ; int i ;
p = (float*)a ; /* lưu ý lệnh nêy */
for ( i = 0 ; i < 2*3 ; ++i)
scanf ( "%f", (p+i)) ; /* (p_+ i ) lê địa chỉ */ ( X )
}
+ Cách 2 : SỪa lệnh ( X ) như sau : scanf ( "%f", (float*)a + 1 ) ;
+ Cách 3 :
#include " stdio.h " #define m 2 #define n 3
main ( )
{ float a[m][n] ; int i , j ; float *p ; p = ( float* )a ;
for ( i=0 ; i<m ; i++ )
for ( j=0 ; j<n ; j++ )
scanf ( "%f" , ( p +i*n + j )
hoặc lệnh scanf ( " %f" , ( float *)a + i * N + j ));
}
+ Cách 4 : sỪ dụng biến trung gian :
#include " stdio.h"
#define dong 2
#define cot 3
main ( )
{ float a[dong][cot] , tam ; int i , j ;
for ( i = 0 ; i < dong ; i++ ) ;
for ( j=0 ; j < cot ; ++j )
{ printf ( "\n a[%d][%d] = " , i , j );
scanf ( " %f " , &tam ) ;
a[j] = tam ;
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; }
BêI TẪP : Sắp xếp mãng 2 chiều theo hêng vê toên bộ mãng
5.4.3/ Mãng con trỏ : lê mãng mê mỗi phần tỪ của nó có thể chứa một địa chỉ nêo đó.
Khai báo : < kiểu dữ liệu > < tên mãng > [<chỉ số>].
* Vê dụ : int *a[5] ;
- trong đó : a lê mãng gồm 5 ô nhớ liên tiếp, mỗi ô nhớ lê 1 biến con trỏ trỏ đến kiểu int ; bản thân a không thể dùng để lưu trữ số liệu.
- Giả sỪ : a <100> <102> <104> <106> <108> < 110>
a[0] a[1] a[2] a[3] a[4] a[5]
Ðịa chỉ < 30> < 20> < 10 > < 80 > < 70 > < 100>
7 8 9 10 11
<10> <12> <14>
1 2 3 4 5
<20> <22> <24> <26> <28>
6 12 13
<30> <32> <34>
- a= &a[0] => a = <100> ( địa chỉ 100 ).
- a[0] = < 30 > ( địa chỉ bằng 30 : tại địa chỉ 30 con trỏ a[0] trỏ đến địa chỉ <30 > vê giả sỪ tại địa chỉ < 30 > có giá trị lê 6 ).
=> *a[0] = * (<30>> = 6 .
a[1] = < 20 > => *a[1] = 1
a [2] = < 10> => *a[2] = 7 .
Chú ý 1: Xem a lê con trỏ 2 lần ( con trỏ của con trỏ ) :
- a = <100 > => *a = <30 > ( do a = &a[0] )
=> **a = 6 ( do *(<30>)).
- *(*(a + 1) + 2 )
*(102)
* ( <20> + 2 ) => *<24> = 3
Chú ý 2 : - int a[5] => a lê con trỏ hằng không thay dổi địa chỉ của nó được ( nên a++ sai)
- int *a[5] ; => a laf con trỏ động nên thay đổi giá trị được ( a++ đúng ).
Vê dụ : int *a[5]
For ( i = 0 ; i < 5 ; i++ )
{ printf ("%d", *a[0] );
a[0]++ ;
}
* Chú ý 3 : mãng 2 chiều chẳng qua lê 1 con trỏ 2 lần ( con trỏ của con trỏ ).
Lý do : a[k] ; trong đó đặt b = a => b[k] = a[k] ;
+ Công thức : ( a = *(a+i)) => ( b = *(b+i)).
b[k] = *(b+k)).
b[k] = *(a + k )
= * ( *(a+i) + j).
=> a[k] = *(*(a+i) + k) ; trong đó *(*(a+i) lê con trỏ 2 lần.
5.4.4/ Con trỏ vê xâu ký tự :
- Xâu ký tự : lê dãy ký tự đặt trong ngoặc kép . Vê dụ : " Lớp học ". Xâu nêy được chứa trong 1 mãng kiểu char.
L O P H O C \0
Ðịa chỉ :<100> <101> <102> NULL : kết thúc chuỗi
=> char *lop ;
lop = " Lop Hoc " ; Ðúng : gán địa chỉ của chuỗi cho con trỏ lớp.
+ puts (" Lop Hoc ") ; vê puts (lop ) đểu hiển thị dòng chữ Lop Hoc.
Vê dụ : char Tenlop[10] ;
Printf ("\n Tenlop : " ) ; gets( Tenlop ) ; => ( NhẪp vêo chuỗi " lớp học " )
Còn nếu chúng ta khai báo như sau lê sai :
Char *lop , tenlop [10] ;
Tenlop = " lớp học " ; sai vì Tenlop vê chuỗi lê 2 con trỏ hằng , không được gán cho nhau . Muốn gán ta dùng hêm strcpy (Tenlop , "lớp học ");
5.4.5/ Con trỏ vê việc định vị bộ nhớ động :
- Vê dụ 1 :
#define N=10 ;
main ( )
{ int a[N] ; int m :
printf ( " nhẪp số phần tỪ m = "); scanf("%d", &m) ;
for ( i= 0 ; i < m ; i++ )
scanf ( "%d", &a );
- NhẪn xét Vê dụ 1 trên : + Nếu m <=N ( N =10) : thì sẽ bị dư 1 số biến mãng lê ( n - m).
+ Nếu m > N ( tức lê m > 10 ) : thì chương trình sẽ chạy sai vì ta không đủ biến mãng.
=> Do đó ta phải khắc phục bằng cách : định vị bộ nhớ động. ( Bằng hêm malloc vê calloc).
* Vê dụ 2 :
#include < stdio.h>
#include<alloc.h> hoặc #include <stdio.h >
main ( )
{ int m , *a ;
printf (" NhẪp số phần tỪ m = " ); scanf ( "%d", &m );
/* Cấp phát vê định vị bộ nhớ động */
a = ( int*) malloc ( m* size of ( int ) ); (1)
if ( a!= NULL ) /* cấp phát thênh công */
for ( i=0 ; i < m ; i++)
scanf ( "%d", &a );
free (a) ; /* giải phóng vùng nhớ mãng */
}
- Hêm malloc ( ) nằm trong thư viện <alloc.h> . Hêm nêy cung cấp số lượng byte liên tiếp từ phần bộ nhớ còn chưa sỪ dụng trên máy tênh.
+ Vê dụ : malloc (num) = num byte vê trả về con trỏ kiểu void trỏ đến địa chỉ bắt đầu của ô nhớ.
- Size of ( int ) : lê số byte mê một biến kiểu int yêu cầu ( giá trị = 2 )
- ( int*) : ép kiểu ( type - casing) : coi địa chỉ bắt đầu lê int ( do malloc trỏ về con trỏ kiểu void , đặc biệt không có kiểu ) , có thể nhẪn bất kỳ địa chỉ kiểu nêo ( nhờ ép kiểu ).
- Muốn sỪ dụng hêm calloc thay cho hêm malloc => khai báo :
a = (int*) calloc ( n, size of (int));
* Chú ý : Luôn gán một địa chỉ cho một con trỏ trước khi sỪ dụng tới nó. Nếu không biến con trỏ sẽ mang một giá trị ngẫu nhiên có thể phá huỷ chương trình.
* Cấp phát bộ nhớ động cho mãng 2 chiều m x n phần tỪ, m , n nhẪp từ bên phêm:
+ Vê dụ : #include <stdio.h>
#include <alloc.h>
Void main ( )
{ int **a , m, n, OK ;
printf ( " nhẪp m = " ); scanf ("%d", &m);
printf (nhẪp m = n) ; scanf ( "%d", &n );
a = ( int** ) malloc ( m*seze of (int *));
if (a!=NULL ) /*Cấp phát thênh công */
{ OK = 1 ;
for ( i=0 ; i < m ; i++ ) } /* giá trị ban đầu cho biến con trỏ*/
a = (int*) break ;
for ( i=0 ; i <m ; i ++ )
{ if !(OK) break ;
a = (int*) malloc ( n * size of (int));
if ( a = NULL ) OK = 0 ;
}
if(OK)
{ sỪ dụng a[0][0] , a[0][1]....., a[j] ...., a[m][n] }
/* giải phóng vùng nhớ cấp phát */
if ( a!=NULL )
{ for ( i = 0 ; i < m ; i++)
if ( a ! = NULL , free ( a);
free (a);
}
}
* Chú ý : ta xem mãng 2 chiều lê mãng 1 chiều nên có thể khai báo :
a = (int*) malloc ( m*n * size of ( int ));
VÀ A[J] = A[ I*N + J]
BêI TẪP :
1/ Lêm lại các bêi tẪp phần mãng nhưng dùng con trỏ .
2/ Dùng hêm malloc hay calloc nhẪp mãng n phần tỪ , sau đó tênh tổng các phần tỪ vê sắp xếp mãng giảm dần.
3/ Dùng hêm malloc hay calloc nhẪp ma trẪn m x n , sau đó tênh tổng vê sắp xếp theo tăng dần
5.4.6/ Mối liên hệ giữa con trỏ vê các khái niệm quan trọng trong :
a/ Con trỏ vê hêm :
- Chú ý 1 : bản thân tham số truyền cho hêm không bao giờ bị thay đổi. Nhưng nếu tham số lê con trỏ thì giá trị của nó không thay đổi nhưng nội dung được chứa ở địa chỉ đó lại có thể thay đổi.
- Chú ý 2 : Truyền cho hêm một tham số hình thức được khai báo lê con trỏ, vê khi gọi hêm truyền cho nó một giá trị địa chỉ của biến muốn thay đổi.
- Vê dụ :giả sỪ tân xây dựng một hêm dùng để hoán vị biến thực, ta viết như sau :
Cách 1 :
#include<stdio.h>
void swap (float x , float y ) /* cách 1 sai */
{ float temp ;
temp = x ; s<y ; y = temp;
}
main ( )
{ float a, b ; a = 10.0 ; b = 20.0 ;
printf (" khi chưa hoán vị a = %4.0f; b = %4.0f \n" , a , b ) ;
swap ( a , b ) ;
printf ( " sau khi hoán vị a = %4.0f ; b = %4.0f \n" , a, b ) ;
- Phân têch cái sai của cách 1 của vê dụ trên :
+ Do a, b thuộc hêm main ( ). Khi khai báo sẽ dùng 2 khoảng nhớ ( mỗi khoảng 3 byte) . a, b trong lời gọi hêm swap(a,b) lê 2 tham số thực.
+ Các đối x, y vê biến cục bộ temp được cung cấp khoảng nhớ nhưng địa chỉ khác. Do đó xx, y chỉ tồn tại ở hêm swap(_), còn a, b tồn tại suốt cả quá trình của chương trình nên hêm swap () không lêm thay đổi ( tức hoán vị) được giá trị của a vê b => hêm viết theo cách 1 không đạt yêu cầu => yêu cầu viết lại theo cách 2.
* Cách 2 : void swap (float *x , float *y) /* viết đúng*/
{ float temp ;
temp = *x ; *x = *y ; * y = temp ;
}
main ( )
b/ Số học con trỏ ( có thể thao tác số học trên nội dung con trỏ )
* Vê dụ : #include < stdio.h>
#include <alloc.h>
main ( )
{ #define N 3
int *list , i ;
list = int*) calloc ( N, size of(int));
*list = 15 ;
* (list + 1) = 20 ;
*(list + 2 ) = 30 ;
printf ( " các địa chỉ lê : ");
for ( i=o ; i < N ; i++)
printf ("%4d",(list + i));
printf ("\n chứa các giá trị lê : ");
for ( i=0 ; i < N ; i++)
printf("%4d", *(list + i));
printf("\n");
=> list trỏ tới một dãi bộ nhớ dêi 6 byte ( 3*2) có các giá trị lê 5,20, 30 . giá trị địa chỉ đầu lê 06A => kết quả các địa chỉ lê : 06A 06AC 06AE chứa các giá trị lê : 5 20 30
c/ Con trỏ vê mãng :
- Vê dụ 2 :
#include
main ( )
{ #define N 3
int list [N] , i ;
list [0] = 5 ; list [1] = 20 ; list[2]=30;
printf ( " Các địa chỉ lê : ");
for ( i = 0 ; i < N ; i++)
printf ( "%4p ", &list );
printf("\n chứa các giá trị lê : ");
for ( i=0; i<N ; i++)
printf ( "%4d", list ));
}
-Kết quả chương trình :
+ Các địa chỉ lê : 163A 163C 163E
+ Chứa các giá trị lê : 5 20 30
- So với vê dụ 1 thì điều khác duy nhất lê giá trị địa chỉ thay đổi. Như vẪy ta có thể sỪ dụng tên của một mãng như con trỏ vê ngược lại.
=>{ list + i) = = &(list) vê *(list + i) = = list}
d/ Con trỏ vê cấu trúc :
- Ta có thể khai báo con trỏ như một biến cấu trúc, cũng như con trỏ của bấu kỳ kiểu dữ liệu nêo khác. Ðiều nêy cho phép tạo một danh sách móc nối các phần tỪ ( sẽ trình bêy chương sau ).
e/ Con trỏ tới hêm : dùng để chứa địa chỉ của hêm. Nên kiểu của hêm vê con trỏ phải giống nhau.
Vê dụ : #include <stdio.h>
Double fmax ( double x, double y ) /* hêm tênh max của 2 số */
{ return ( x>y ? x:y ) ; }
/* khai báo vê gán tên hêm cho con trỏ hêm */
double (*pf) (double , double ) = fmax ;
main ( )
{ printf ( " In max = % f " , pf(15.5, 20.5 ));
}
PMEmail PosterICQYahoo
Top
windows2000vn
Posted: October 27, 2004 07:20 pm
Quote Post


SUPER START
Group Icon

Group: Điều Hành FORUM
Posts: 1409
Member No.: 1
Joined: June 12, 2004



chương 6

6.1/ Ký tự ( character ) :
- Vê dụ : char ch , ch1 ;
ch = 'a' ; /* Ðúng : ký tự chữ */
ch1 = '1' /* đúng : ký tự số */
- Vê dụ 2 : scanf ( "%c", &ch ) ; /* gõ A vê Enter */
printf ("%c", ch) ; /* In ra chữ A */
printf("%d", ch) ; /* In ra 65 lê mã ASCII của A */
* Hêm dùng cho kiểu ký tự :
char ch ;
ch = getchar ( ) ; ( NhẪp 1 ký tự từ bên phêmm sau khi ấn Enter vê ký tự nhẪp vêo không hiện lên mên hinh ).
putchar (ch) ; in ký tự nằm trong biến ch ra mên hình.
putch ("\n") ; đưa dấu nháy về đầu dòng.ch = getche ( ) ; NhẪp 1 ksy tự từ bên phêm vê ký tự nhẪp vêo sẽ hiển thị trên mên hình.
6.2/ Chuỗi ký tự : Ngôn ngữ C quan niệm 1 chuỗi ký tự lê một mãng ký tự kết thúc bằng ký tự NULL ('\0') mã ASCII lê 0.
- Vê dụ : char s[10] L E V A N A '\0'
s[0] s[1 ] s[3] s[4] s[5] s[7] s[8]
- Muốn nhẪp chuỗi ta thường dùng hêm gets(s)
- Muốn in chuỗi ta thường dùng hêm puts(s) : in xong xuống dòng.
6.3/ Một số hêm trên chuỗi : các hêm cơ bản trong thư viện string.h
a/ gets(s1) : nhẪp dữ liệu vêo chuỗi s1.
b/ n = strlen(s1) : cho biết độ dêi của chuỗi s1.
c/ n= strcmp (s1,s2) : so sánh 2 chuỗi s1,s2 ( so theo mã ASCII từng ký tự ).
+ nếu n>0 : s1> s2
n = 0 : s1=s2
n < 0 : s1<s2.
d/ strcpy ( đêch , nguồn ) ; chép chuỗi nguồn vêo chuỗi đêch, gán chuỗi.
- Vê dụ : char [30] ;
Ten = "Nguyễn Văn Ðông "; ( sai ).
strcpy ( ten , "Nguyễn Văn Ðông ");
gets (ten ) : NhẪp vêo từ bên phêm.
e/ strcat (s1,s2) : nối s1 vê s2 .
- Vê dụ : giá trị cảu s1 : " ABC" ; s2 : " ABE" => strcat(s1,s2 ) ; => " ABCABE";
f/ m = strncmp (s1, s2, n ) ; so sánh n ký tự đầu tiên của chuỗi s1 với s2.
- Vê dụ : m = strncmp ( s1, s2, 2 ) ; thì m = 0 do 2 ký tự đầu của chuỗi lê :
+ s1 : "ABC" vê s2 : " ABE" lê giống nhau.
g/ strnpy ( s1, s2, n ) ; chép n phần tỪ đầu tiên của chuỗi s2 vêo chuỗi s1.
- Vê dụ : strnpy ( s1, "xyz", 2 ) ;
Puts (s1); -ă " xyC".
h/ strncat ( s1,s2, n) ; nối n phần tỪ đầu tiên của s2 vêo đuôi s1.
- Vê dụ : strncat ( s1 , "xyz", 2);
Puts(s1) ; => "ABCxy".
* Chú ý : + char s1[10], s2[4]
+ strcpy (s1,"ABCDE");
+ strcpy(s2,"ABCDE"); => "ABCD" ( do s[4] = "\0").
i/ Hêm strstr :
- char *p ;
p = strstr (s1,s2);
- Tìm xem chuỗi s2 có trong s1 hay không. Nếu có thì in ra cuỗi s1 tại vị trê đầu tiên mê nó thấy. Nếu không có thì in ra giá trị NULL.
- Vê dụ : s1: "abc abc ac"
s2 : "bc", s3 = "cd"
p= strstr (s1,s2);
puts (p) ; => " bc abc ac "
p = strstr ( s1, s3)
Ðoán thỪ puts(p) ; => p[(NULL)] .
k/ d= atoi ( chuỗi số ) ; chuyển chuỗi số thênh int.
f = atof ( chuỗi số ) ; chuyển chuỗi số thênh số thực( float ).
l = atol(chuỗi số ); chuyển chuỗi số thênh long ( nguyên 4 byte).
- Vê dụ : char s[20] ;
Gets (s) ; nhẪp vêo s từ bên phêm chuỗi " 123.45"
d=atoi(s) ; thì d = 123.
F = atof(s); thì f = 123.45
l/ toupper (ch) ; lêm thay đổi ký tự ch thênh chữ Hoa.
tolower(ch); lêm thay đổi ký tự ch thênh chữ thường.
* Chú ý :Muốn dùng các hêm về chuỗi phải khai báo đầu chương TRÌNH #INCLUDE &LT;STRING.H&GT;
BêI TẪP :
1/ NhẪp vêo chuỗi sau đó xoá các khoảng trắng xong in ra mên hình.
2/ NhẪp chuỗi vê xoá các khoảng trắng thừa phêa trước, sau vê giữa 2 từ gút lại 1 khoảng trắng.
3/ Viết hêm nhẪp vêo một chuỗi sau đó đổi ký tự đầu mỗi từ (chữ) thênh Hoa, các ký tự còn lại của 1 từ lê chữ thường.
4/ NhẪp chuỗi password nếu kiểm tra đúng mới cho chạy chương trình đếm số từ trong 1 chuỗi số nguyên âm, phụ âm.
5/ Ðảo thức tự các từ của chuỗi. Vê dụ : s1="con mèo con cắn con chó con" đổi thênh s2=" con chó con cắn con mèo con".
PMEmail PosterICQYahoo
Top
windows2000vn
Posted: October 27, 2004 07:33 pm
Quote Post


SUPER START
Group Icon

Group: Điều Hành FORUM
Posts: 1409
Member No.: 1
Joined: June 12, 2004



chương 7

- Khái niệm : Cấu trúc lê một kiểu dữ liệu kiểu bản ghi(record) , cho phép nhiều loại dữ liệu được nhóm lại với nhau. ( Khái niệm cấu trúc trong C tương tự như pascal hay Foxpro).
7.1/ Khai báo kiểu cấu trúc :
a/ struct tên _ kiểu cấu trúc
{
khai báo các thênh phần của nó ( các field vê kiểu dữ liệu của field)
} < danh sách biến>;
- Vê dụ 1 : struct kieu HV ò-> tên kiểu cấu trúc.
{ char Ten[30] ;
int namsinh ;float diemTB ;
} HV ; ( biến HV)
- Vê dụ 2 : struct kieu HV
{
các thênh phần
}
struct kieu HV HV ; /* khai báo biến theo cách 2 */
b/ Dùng toán tỪ typedef để khai báo kiểu cấu trúc ( định nghĩa kiểu mới) ;
- Vê dụ 3 : typedef struct
{ char Ten[30]
int namsinh ;
float diemTB ;
} kieu HV ;
kieu HV Hoc vien ;
kieu HV DSLop[20];
kieu HV Lop[ ] = { { "nguyễn văn Ðông", 1980, 10.0},
{ " Trần văn Tây", 1982, 5.5},
{ " Phạm văn Nam ", 1979, 9.5}
};
- Vê dụ 4 : struct ngay{
int ngay ;
char Thang[10];
int nam ;
} ;
type struct
{ char Ten[30] ;
ngay namsinh ; /* thênh phần cấu trúc có kiểu cấu trúc*/
float diemTB;
} kieu HV ; kieu HV HV;
* Chú ý :
- Khai báo struct phải nằm ở vị trê toên cục của chương trình, thường sau các #include.
- Cấu trúc thường dùng để xây dựng một bảng các cấu trúc.
+ Vê dụ : kieu HV DSLop[30] ; struct kieu HV person[50];
- Có thể truyền cấu trúc như một tham số hình thức, nhưng với những cấu trúc kêch thước lớn sẽ không tối ưu về thời gian lẫn độ nhớ. Khi không nên sỪ dụng con trỏ cấu trúc.
+ Vê dụ : struc kieu HV *HV ;
7.2/ Truy cẪp đến các thênh phần của kiểu cấu trúc :
Tên cấu trúc. Tên thênh phần
Hoặc Tên cấu trúc. Tên cấu trúc con. Tên thênh phần.
- Vê dụ : + nhẪp vêo tên, năm sinh, điểm cho biến cấu trúc học viên ( vê dụ 3).
gets(hoc vien.ten) /* nhẪp " Phạm thị Bắc" vê Enter */
scanf("%d ", & hoc vien.namsinh );
scanf("%f", &tam); hoc vien.diem = tam; (*)
+ NhẪp năm sinh cho biến học viên ở vê dụ 4 :
scanf("%d",&hv.ngay.namsinh);
* Chú ý : Nếu các thênh phần không phải lê nguyên(int) => nhẪp qua trung gian như (*).
puts(hoc vien.ten); => " Phạm thị Bắc"
printf("%d%f", hoc vien.namsinh, hoc vien.diemTB);
* Lệnh gán : + Ta có thể gán 2 biến cấu trúc có cùng kiểu cho nhau :
Vê dụ : hv2=hv1;
+ Gán giá trị đầu cho biến cấu trúc vê khai báo một mãng cấu TRÚC( XEM VÍ DỤ 3)
BêI TẪP : viết chương trình nhẪp danh sách học viên gồm các trường họ tên, tuổi, điểm, vê tìm kiếm trong dánhách có ai tên " Phạm Tèo " không.
Tên Tuổi điểm
HV [ 0] Nguyễn A 20 5.5
HV [1] Trần B 22 6.5
HV [2] Phạm Tèo 25 8.5
HV [3] Lê C 21 7.5
#include <stdio.h>
#define n 10
typedef struct
{ char Ten[30];
int tuoi ;
float diem ;
} kieu HV ;
kieu HV HV[11]
void main( )
{ int i ; float tam ; kieu HV HV;
/* nhẪp dữ liệu cách 1*/
for ( i = 0 ; i < n ; i++)
{ printf ("\n NhẪp số liệu cho học viên thứ %d", i ) ;
printf (" Họ vê tên = " ) ; gets ( hv.ten);
printf ("tuổi = "); scanf ( "%d" , &hv.tuoi);
printf("điểm = "); scanf ("%f*c", &tam ); hv.diem = tam ;
}
/* cách 2 nhẪp vêo biến cấu trúc vê gán hv = h */
for ( i = 0 ; i<n ; i++ )
{ printf("Họ vê tên = "); gets(h.ten);
} hv = h ;
/* tìm kiếm Phạm Tèo */
thay = 0 ; i = 0 ; /* thay = 0 : không thấy, thấy = 1 : tìm thấy */
while ((!thay)&&(i <n))
if ( strcmp(hv.Ten , " Phạm Tèo ") = = 0 )
{ thay = 1 ;
printf ("%s%d%f ", hv.ten , hv.tuổi, hv.điểm );
}
else i++ ;
if (!thay ) puts ("\n không tìm thấy Phạm Tèo !");
getch( );
}
BêI TẪP : Viết chương trình nhẪp danh sách gồm na học viên gồm các thông tin như : Họ , tên, điểm pascal , điểm c, sau đó tênh điểm trung bình (điemTB) = (diemC*2 + diempascal)/3 .
- Vê xét kết quả đẪu hay rớt theo qui ước sau :
+ nếu điểm trung bình >= 5 thì kết quả đẪu.
+ Nếu điểm trung bình <5 thì kết qua rớt.
+ Nếu điểm trung bình = 4 mê phái = "Nữ" thì kết quả lê đẪu.
1/ in danh sách vừa nhẪp gồm họ tên, phái , điểm c, điểm pascal, điểm TB , kết quả .
2/ Sắp xếp giảm dần theo điểm trung bình vê in ra.
3/ NhẪp vêo tên cần tìm vê tìm trong danh sách học viên nếu không tìm thấy thì in ra học viên có tên không tìm thấy. Nếu có nhiều học viên có cùng tên cần tìm thì hãy in ra người cuối cùng được tìm thấy.
4/ Giống câu 3 nhưng in ra 2 người tìm thấy đầu tiên ( nếu có nhiều người ).
5/ Giống câu 3 nhưng in ra người đầu tiên vê người cuối cùng ( nếu có nhiều ngưòi). Nên viết theo từng hêm.
7.3/ Con trỏ trỏ đến cấu trúc vê địa chỉ cấu trúc :
a/ Con trỏ vê địa chỉ :
- Vê dụ : typedef struct
{ char Ten[30] ;
int tuoi ;
float diem ;
} kieu HV ;
kieu HV *p , HV , lop[50] ; HS [50] ( trong đó : HV lê biến cấu trúc, *p : con trỏ cấu trúc dùng để lưu trữ địa chỉ cấu trúc vê mãng cấu trúc ) ( *).
main ( )
/* ta có thể gán */
p = &HV ; /* Ðúng do (*)*/
p = &lop/*đúng do (*) */
p = lơp ; /* đúng : p = địa chỉ Lop[0] , p = &lop[0] ) do Lop = &Lop[0])
b/ truy cẪp thông qua con trỏ :
- Cách 1 : tên con trỏ -ă tên thênh phần.
- Cách 2 : (*tên con trỏ).tên thênh phần.
- Vê dụ : p = &HV ; p = &Lop[2] '
=> HV.Ten ĩ p --ă tên;
Lop[2].tuổi ĩ (p*).tuoi ĩ p -ă tuổi ;
*p = HV ;
*P = Lop[2]
- Giả sỪ cần nhẪp số liệu ch vùng trên thì 3 cách viết sau lê tương đương :
+ (1) : gets(HV.ten)
+ (2) gets ( pă ten) ĩ gets( (*p).ten).
+ (3) scanf("%d",&HV.tuoi) ; ĩ scanf("%d", p -ă tuổi );
scanf ("%d", (*p).tuoi);
- Giả sỪ cần nhẪp dữ liệu cho mãng cấu trúc thì các cách viết sau đây tương đương :
+ Vê dụ : p = lop ;
for ( i = 0 ; i < n ; i++)
{ gets (lop.tên); tương đương với :
. gets((*(lop* i ) ).ten);
.gets(*(p + i ).ten);
.gets ( p.ten);
.gets (p ă ten); p++ ;
.gets (*p).ten) ; p++;
- Vê dụ : lêm lại bêi tẪp mẫu nhưng sỪ dụng biến con trỏ :
#include <stdio.h>
#define n 10
typedef struct
{ char ten[30] ;
int tuoi ;
float diem ;
} kieu HV ;
main ( )
{ kieu HV hv [n], *p , h;
int i ; int thay ; float tam ; int tuổi ; p = hv;
for ( i = 0 ; i < n ; i++)
{ printf (" nhẪp học viên thứ %d ", i );
printf("Họ vê tên"); gets ( p ă ten);
printf("tuổi : ") ; scanf ("%d", &tuổi); p ă tuoi = tuoi;
printf ("diem : ") ; scanf ("%f%*c ", &tam ); p ă diem = tam;
p++ ; printf ("%c", getchar();
}
/* nhẪp theo cách 2 qua biến h xong gán *p = h */
/* tìm Phạm Tèo */
thấy = 0 ; i = 0 ; p = hv ; /* để di chuyển con trỏ về đầu danh sách */
for ( i = 0 ; i < n ; i++ )
if ( strcmp(p ă ten, " Phạm Tèo " ) = = 0 )
{ thấy = 1
printf ("%s %d%f" , p ă ten, pă tuoi, pă điểm );
break ;
else p++ ;
if (!thay) puts (" không có Phạm Tèo trong danh sách ");
getch( );
}
BêI TẪP : lêm lại bêi tẪp trước nhưng sỪ dụng con trỏ.
7.4/ Cấp phát bộ nhớ động cho kiểu dữ liệu cấu trúc :
- giả sỪ ta cần quản lý danh sách học viên nên dùng mãng cấu trúc ( cấp phát bộ nhớ tĩnh - danh sách đặc ) ta phải sỪ dụng số học viên tối đa => thừa vùng nhớ. Ðể cấp phát vừa đủ sĩ số học viên như ta muốn => ta dùng phương pháp cấp phát bộ nhớ động hêm malloc hoặc calloc(.)
- Vê dụ : NhẪ danh sách n học viên gồm họ tên, điểm vê sắp xếp giảm dần theo điểm.
#include <stdio.h> #include<conio.h> #include<alloc.h>
#include< string.h>
typedef struct
{ char ten[30] ; int diem ; char kq[5] ; } kieu HV;
kieu HV *lop , *p , tam ;
/* Hêm nhẪp dan sách */
void nhapDS ( int n , kieu HV lop[ ])
{ int i , diem ;
p = lop ;
for ( i = 0 ; i < n ; i++)
{ printf("nhẪp Họ tên người thứ %d : " , i +1 ) ; gets ( p ăten);
printf ( " điểm = " ) ; scanf ( "%d" , &diem ) ; p ă diem = diem ;
printf ("%c", getchar()); /* khỪ stdin */
p++ ;
}
/* Hêm sắp xếp*/
void sapxep ( int n, kieu HV lop[ ])
{ int i , j ; kieu HV tam ;
for ( i = 0 ; i < n-1 ; i++)
for ( j=i + 1 ; j< n ; j++)
if ( lop.diem < lop[j].diem )
{ tam = lop ; lop[j] = lop [j] ; lop [j] = tam ; }
/* hêm in danh sách */
void inds( intn, kieu HV lop[ ] )
{ int i ;
for ( i = 0 ; i < n ; i++ )
{ printf ("%20s%5d ", lop.ten,lop.diem );
printf ("\n" ; /* xuống hêng */
/* chương trình chênh */
void main ( )
{ int i , j, n , t, diem ;
printf ("\n NhẪp sĩ số : ") ; scanf ( "%d", &n);
lop = (kieu HV*)malloc ( n * size of ( kieu HV) ) ; printf ("%c", getchar ());
nhapds (n, lop ) ; sapxep ( n, lop ) ; inds ( in lop );
getch ( );
}
KIểU FILE ( TẪP TIN/ TệP TIN )
- Trong ngôn ngữ C , một tẪp tin lê một khái niệm logic, được áp dụng không những đối với các tẪp tin trên đĩa mê cả với các terminal ( bên phêm, mên hình, máy in...).
- File có 2 loại : + Text file ( file văn bản ).
+ Binary ( nhị phân : dbf, doc, bitmap,...).
- File văn bản chỉ khác binary khi xỪ lý ký tự chuyển dòng (LF) ( mã 10 ) được chuyển thênh 2 ký tự CR (mã 13) vê LF ( mã 10) vê khi đọc 2 ký tự liên tiếp CR vê LF trên file cho ta một ký tự LF.
- Các thao tác trên file thực hiện thông qua con trỏ kiểu FILE. Mỗi biến FILE có 1 con trỏ lúc đầu sẽ trỏ vêo phần tỪ đầu tiên của file. Sau mỗi thao tác đọc hay ghi dữ liệu con trỏ tự động dời xuống mẫu tin kế tiếp. Lêm việc trên kiểu File thường có 3 công đoạn : mở file, nhẪp xuất thông trên file vê đóng file.
* Một số hêm thông dụng thao tác trên file ( tẪp tin/tệp tin ) :
+ Mở file : FILE *fopen ( char *filename, char *mode);
. Nếu có lỗi fp sẽ trỏ đến NULL.
+ Các mode chế độ mở file :
" r" " rt " / " rb " : mở file để đọc theo kiểu văn bản / nhị phân - file phải tồn tại trước nếu không sẽ có lỗi.
"w" "wt" / " wb " : mở ( tạo ) file mới để ghi theo kiểu văn bản/nhị phân - nếu file đã có nó sẽ bị xóa(ghi đè )( luôn luôn tạo mới ).
"a" "at"/ "ab" : mở file để ghi bổ sung (append) thêm theo kiểu văn bản hoặc nhị phân( chưa có thì tạo mới ).
+ Ðóng file : int fclose ( file + biến file ) ;
Vê dụ : Void main ( )
{ FILE *fp ;
fp = fopen ("c:\\THUCTAP\\Data.txt", "wt" );
if (fp = NULL )
printf ( " không mở được file c/Thuctap\data.txt");
else {< xỪ lý file > }
fclose (fp) ; /* đóng file */
}
+ Lêm đóng tất cả các tẪp đang mở : int fclose all(void) ; nếu thênh công trả về số nguyên bằng tổng số các file đóng được, ngược lại trả về EOF.
+ Hêm xóa tẪp : remove (const + char*ten tẪp ) ; nếu thênh công cho giá trị 0, ngược lại EOF.
+ Hêm kiểm tra cuối tẪp : int feof(FILE*fp) : !=0 : nếu cuối tẪp= 0 : chưa cuối tẪp.
+ Hêm int putc ( int ch, FILE*fp);
Hêm int fputc( int ch, FILE*fp);
Công dụng của hai hêm nêy :ghi một ký tự lên tẪp fp theo khuôn dạng được xác định trong chuỗi điều khiển dk. Chuỗi dk vê danh sách đối tương tự hêm printf( ).
+ Hêm int fscanf ( FILE *fp, const char *dk, ...);
Công dụng : đọc dữ liệu từ tẪp tin fp theo khuôn dạng ( đặc tả) lêm việc giống scanf( ).
*Vê dụ : giả sỪ có file c/data.txt lưu 10 số nguyên 1 5 7 9 8 0 4 3 15 20 . Hãy đọc các số nguyên thêm vêo một mãng sau đó sắp xếp tăng dần rồi ghi vêo file datasx.txt
Giải :
#include <stdio.h>
#include<conio.h>
#include<stdlib.h>
#define n 10
void main ( )
{ FILE *fp ; int i, j, t, a[n]
clrscr ( ) ;
fp = fopen (" c :\\data.txt ", "rt" ); /* mở file để đọc vêo mãng */
if (fp = NULL)
{ printf ("không mở được file ");
exit (1);
}
/* Sắp xếp mãng */
for ( i=0 ; i<n-1 ; i++)
for (j=i+1; j<n ; j++)
if (a<a[j] )
{ t = a ; a=a[j] ; a[j] = t ; }
fclose (fp);
/* mở file datasx.txt để ghi sau khi sắp xếp */
fp = fopen ("c:\\datasx.txt ", "wt");
for ( i=0 ; i<n;i++)
printf (fp,"%2d", a );
fclose (fp);
/* đọc dữ liệu từ file cách 2 ( tổng quát hơn ) không phụ thuộc vêo n */
i = 0 ;
while (1)
{ fscanf (fp,"%d",&a ;
i++;
if (foef(fp) ) break ;
}
- Hêm int fputs ( const char *s, file *fp );
Công dụng : ghi chuỗi s lên tẪp tin fp ( dấu "\0" ghi lên tẪp) nếu có lỗi hêm cho eof.
- Hêm char fgets ( char *s, int n , FILE *fp);
Công dụng : đọc 1 chuỗi ký tự từ tẪp tin fp chứa vêo vùng nhớ s. Việc đọc kết thúc khi : hoặc đã đọc n-1 ký tự hoặc gặp dấu xuống DÒNG( CẮPMÃ 13 10). KHI ÐÓ MÃ 10 ÐƯỢC ÐƯA VÀO CHUỖI KẾT QUẢ.
CáC HêM ÐọC GHI FILE KIểU CấU TRúC
- Hêm int fwrite (void *p, int size , int n , FILE*fp);
Ðối : p : lê con trỏ trỏ tới vùng nhớ chứa dữ liệu cần ghi.
size : lê kêch thước của mẫu tin theo byte.
n số mẫu tin cần ghi.
fp lê con trỏ tẪp.
- Vê dụ : fwrite(&tam) size of(tam),1,fv); /* tam lê 1 mẫu tin(record) nêo đó*/
Công dụng : ghi một mẫu tin (record) kêch thước sizebyte ( size of (tam)) từ vùng nhớ p(&tam) lên tẪp fp. Hêm sẽ trả về một giá trị = số mẫu tin thực sự ghi được.
+ Hêm int fread (void*p), int size , int n, FILE *fp);
Ðối : p : lê con trỏ trỏ tới vùng nhớ chứa dữ liệu đọc được.
size lê kêch thước của mẫu tin theo byte
n : lê số mẫu tin cần đọc, fp lê con trỏ tẪp tin.
Vê dụ : fread (&tam, size of(KIEUHS) , 1, 4 )>0)
Công dụng : đọc n(1) mẫu tin kêch thước sizebyte (size of(tam)) từ tẪp tin fp chứa vêo vùng nhớ p(&tam). Hêm trả về một giá trị bằng số mẫu tin thực sự đọc được.
* Vê dụ áp dụng : NhẪp vêo danh sách lớp gồm n học viên ("nhẪp vêo). Thông tin về mỗi học viên gồm Họ tên, phái , điểm, kết quả. Xét kết quả theo điều kiện sau : nếu Ðiểm>= 5 ( đẪu ), điểm <5 : rớt. Sau đó sắp xếp theo điểm vê ghi vêo tẪp tin c:\lop.txt. Ðọc lại tẪp tin c:\lop.txt vê xét lại kết quả nếu điểm =4 vê phái lê nữ sẽ đẪu vf chép sang tẪp tin c:\ketqua.txt.
Giải : #include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>
typedef struct
{ char ten[20] ; char phai[4] ; int diem ; char kq[4] ; } KieuHV;
KieuHV *lop ,*p, tam;
/* Hêm nhẪp danh sách n học viên */
void nhapds ( int n, KieuHV lop[ ] )
{ int i , diem ; p = lop ;
for ( i=0; i<n ; i++ )
{ printf (" nhẪp họ vê tên người thứ %d : " , i + 1) ; gets ( pă ten);
printf ("phái (nam/nữ ) : ") ; gets (pă phai );
printf ("nhẪp điểm = ") ; scanf ("%d%c*c", &diem); pă diem=diem;
if (diem>5)strcpy (p--> kq,"ÐẪu");
else strcpy (pă kq, "rớt " ) ; p++;
}
/* Hêm sắp xếp */
void sapxep ( int n , KieuHV lop[ ] )
{ int i , j ;
for ( i=0 ; i<n-1; i++)
for ( j=i+1 ; j<0; j++)
if (lop.diem< lop[j]diem )
{ tam = lop ; lop = lop[j] ; lop = tam ;}
}
/* Hêm in danh sách */
void inds ( int n, KieuHS lop[ ] )
{ int i ;
for ( i=0 ; i<n ; i++)
printf ("\n %20s %5s%5d%5s, lop.ten, lop.phai, lop.diem, LOP.KQ );
/* CHƯƪNG TRìNH CHêNH */
void main ( )
{ int i , j, n, t, diem ; FILE *fp, *fr ;
printf ("\n nhẪp sĩ số : ") ; scanf("%d%*c",&n);
lop = (KieuHV*) malloc (n*size of (KieuHV));
nhapds(n, lop) ; sapxep ( n, lop ); inds( n, lop); getch( );
fp = fopen ( "c :\\lop.txt ", "wb");
for ( i = 0; i<n ; i++)
fwrite (&lop[ i], size of (KieuHV), 1, fp);
fclose(fp);
printf ("\n ghi dữ liệu xong ");
printf("\n in file sau khi sắp xếp vê xét kết quả lại ");
fr = fopen ("c:\\ketqua.txt", "wb");
while ( fread (&tam, size of ( KieuHV), 1, fp ) > 0)
{ printf ("\n %s %s%d%s", tam.ten, tam.phai, tam.diem, tam.kq);
if (tam.diem = = 4 &&strcmp(tam.phai,"nữ")= =0 )
strcmp(&tam.kq, "đẪu");
fwrite(&tam,size of(tam),1, fr);
}
fclose (fp); fclose(fr);
printf ("\n in file ketqua.txt sau khi xét lại kết qủa ");
fp = fopen ("c:\\ketqua.txt", "rb");
while (fread(&tam, size of (KieuHV) , 1, fp) > 0)
printf("\n %s%s%d%s",tam.ten,tam.phai, tam.diem,tam.kq);
fclose (fp); getch( );
&NBSP; }
CáC HêM XUấT NHẪP NGẫU NHI㎪Vê DI CHUYểN CON TRỏ CHỉ Vị(File position locator )
- Khi mở tệp tin để đọc hay ghi, con trỏ chỉ vị luôn luôn ở đầu tẪp tin (byte 0) nếu mở mode "a" (append) => con trỏ chỉ vị ở cuối tẪp tin.
+ Hêm void rewind (FILE*fp) : chuyển con trỏ chỉ vị của tẪp fp về đầu tẪp tin.
+ Hêm int fseek (FILE*fp, long số byte, int xp)
Ðối : fp : lê con trỏ tẪp tin; số byte : lê số byte cần di chuyển.
xp " cho biết vị trê xuất phát mê việc dịch chuyển được bắt đầu từ đó.
xp = SEEK - SET hay 0 xuất phát từ đầu tẪp.
xp = SEEK - CUR hay 1 : xuất phát từ vị trê hiện tại của con trỏ.
xp= SEEK - END HAY 2 : xuất phát từ vị trê cuối tẪp của con trỏ.
+ Công dụng : hêm di chuyển con trỏ chỉ vị của tẪp fp từ vị trê xác định bởi xp qua một số byte bằng giá trị tuyệt đối của số byte. Nếu số byte > 0 : chuyển về hướng cuối tẪp ngược lại chuyển về hướng đầu tẪp. Nếu thênh công trả về trị 0. Nếu có lỗi trả khác 0.
+ Chú ý : không nên dùng fseep trên kiểu văn bản, vì sự chuyển đổi ký tự( mã 10) sẽ lêm cho việc định vị thiếu chênh xác.
+ Hêm long ftell(FILE*fp) ; : cho biết vị trê hiện tại của con trỏ chỉ vị (byte thứ mấy trên tẪp fp) nếu không thênh công trả về trị -1L.
+ Vê dụ 1: giả sỪ tẪp fp có 3 ký tự .
fseek (fp,0,SEEK-END) => ftell(fp) = 3
fseek(fp,0,2) => ftell(fp) = 3
fseek (fp,-2, SEEK-END) => ftell(fp) = 1
fseek(fp,0,SEEK -SET) => ftell(fp) = 0
fseek(fp,0, 0) =>ftell(fp) = 0
+ Vê dụ 2 : giả sỪ ta có tẪp tin c:\lop.txt chứa danh sách các học viên. Hãy đọc danh sách vê sắp xếp giảm dần theo điểm sau đó ghi lại file c:\lop.txt ( nối điểm)
#include <stdio.h>
#include<conio.h>
#include<string.h>
#define N 100
typedef struct
{ char ten[20] ; int tuoi; float diem ; } KieuHV ;
void main( )
{ KieuHV hv[N] ; t;
FILE*fp ; int i, , n ;
fp = fopen ("c:\\lop.txt ", "rat");
if (fp = =NULL)
{ printf ("không mở được file "); exit(1); }
n = 0 ; i = 0 ;
while (!feof (fp))
{ fread (&hv, size of (KieuHV), 1,fp);
i++; n++ ;
/* sắp xếp giảm dần theo điểm */
for (i=0, i <n-1, i++)
for (j=i+1; j<n, j++)
if (hv.diem <hv[j].diem)
{ t =hv ; hv = hv[j] ; hv[j] = t }
/* ghi lên đĩa */
fseek (fp, 0, SEEK-END);
for ( i=0; i<n ; i++)
fwrite(&hv, size of (KieuHV), 1, fp);
}
PMEmail PosterICQYahoo
Top
windows2000vn
Posted: October 27, 2004 07:34 pm
Quote Post


SUPER START
Group Icon

Group: Điều Hành FORUM
Posts: 1409
Member No.: 1
Joined: June 12, 2004



chương 8

1/ Truyền đối số cho hêm main( ) :
- Vê dụ : ta muốn viết một chương trình có tên lê Hello.că hello.exe khi chạy trên MS-DOS ta nhẪp các đối số vêo chương trình. Vê dụ : c:> Tom and Jerry ( enter) máy sẽ in ra câu :
Chêo Tom and Jerry.
- Viết chương trình trên như sau :
Void main ( int argc, char*argv[ ])
{
......
}
Trong đó :
+ argc : cho biết tổng số đối số truyền vêo tênh cả tên chương trình đối với vê dụ trên argc = 4. Mỗi đối số truyền vêo được xem như lê xâu ký tự.
+ mãng argv [ ] sẽ lê con trỏ , trỏ lần lượt đến các đối số.
argv[0] -->"Hello"
argv[1] --> "Tom"
argv[2] --> "and"
argv[3] --> "Jerry"
void main ( int argc, char *argv[ ])
{ int i ;
printf("Chêo !");
for ( i=1 ; i < argc ; i++)
printf("%s", argv[ i]);
}
2/ Truyền cấu trúc cho hêm - Hêm trên các cấu trúc :
- Chương trình gọi nhẪp học viên(HV).
- Chương trình bị gọi void nhap ( struct Kiểu HV HV[ ])
Hoặc void nhẪp (Kiểu HV HV[ ])
- Vê dụ : nhẪp danh sách lớp :
#include<stdio.h>
#include<conio.h>
#include<string.h> #define N 100
typedef struct
{ char ten[20] ; int tuoi ; float diem ; } kieu HV
/* khai báo hêm nhẪp dữ liệu*/
void nhap ( int n , Kieu HV HV [ ] )
{int i ; float t;
for ( i = 0; i< n ; i++)
{ printf ( " NhẪp hv thỪ %d ", i++); scanf(....) }
/* chương trình chênh */
main ( )
{ Kieu HV hv[n];
nhap ( n, hv);
}
* Hêm có thể trả về giá trị cấu trúc hoặc con trỏ cấu trúc :
+ Vê dụ : Hêm Kieu HV *ptim ( char*ten, KieuHV HV[ ] , int n) : có tác dụng tìm trong danh sách n học viên trong mãng HV[ ] người có tên vê hêm trả về con trỏ, trỏ tới người tìm được hoặc trả về NULL nếu không tìm thấy .
+ Hêm Kieu HV tim( char*ten, KieuHV HV[ ], int n); : cũng với mục đêch như hêm trên nhưng trả về giá trị của một cấu trúc.
+ Vê dụ :
#include"stdio.h"
#include"conio.h"
#include"string.h"
typedef struct
{ char ten[20] ; int tuổi ; float điểm } Kieu HV ;
Kieu HV *ptim ( char*ten, KieuHV HV[ ] , int n );
Kieu HV tim ( char *ten, Kieu HV hv[ ] , int n );
main( )
{ Kieu HV *p, ds[100],h ; int i, h, n ; char ten[20] ; float diem;
clrscr ( );
printf("\n Số người n = " ) ; scanf ("%d *c ",&n);
for ( i=0 ; i<n ; ++i)
{ printf("\họ tên "); gets(h.Tên) ; /* tự viết lấy*/
ds = h ;
}
/* tìm kiếm 1 theo ten dùng hêm ptim*/
while (1)
{ printf ("\n Họ tên người cần tìm"); gets (tên);
if ((p =ptim ( ten, ds, n)) = = NULL)
printf("\n không tìm thấy ");
else
indanhsach(*p);
}
/* tìm kiếm theo tên dùng hêm tim*/
while(1)
{ printf("\n Họ tên cần tìm "); gets(ten);
if ( tim ( ten, ds, n).ten[0] = = 0 )
printf("\n Không tìm thấy");
else indanhsach ( tim ( ten, ds, n));
}
Kieu HV *ptim ( char*ten, Kieu HV hv[ ] , int n)
{ int i ;
for ( i= 0 ; i< n ; ++i)
if ( strcmp ( ten, hv.ten= = )return (&hv[ i]);
return (NULL);
}
Kieu HV tim (char*ten, Kieu HV hv[ ] , int n)
{ int i ; HV tam ;
tam.ten[0]=0;
for ( i=0 ; i<n ; ++i)
if(strcmp(ten,hv.ten = = )) return (hv);
return ( tam);
}
void indanhsach (Kieu HV p)
{ printf("\n Họ tên % tuổi % điểm %f", p.ten, p.tuổi, p.diêm);
}
PMEmail PosterICQYahoo
Top
windows2000vn
Posted: October 27, 2004 07:35 pm
Quote Post


SUPER START
Group Icon

Group: Điều Hành FORUM
Posts: 1409
Member No.: 1
Joined: June 12, 2004



chuong 9

- Danh sách liên kết : Nếu sỪ dụng mãng để quản lý danh sách sẽ rất tốn kèm vê cứng nhắc trong thao tác ă khắc phục = danh sách liên kết.
- Danh sách liên kết gồm các phần tỪ . Mỗi phần tỪ có 2 vùng chênh : vùng dữ liệu vê vùng liên kết. Vùng liên kết lê một hay nhiều con trỏ, trỏ đến các phần tỪ trước hoặc sau nó tùy thuộc vêo yêu cầu của công việc.
- Khai báo danh sách liên kết :
Typedef struct Kieu du lieu
{ <khai báo phần tỪ dữ liệu >;
Kiểu dữ liệu < các con trỏ >;
} Kiểu dữ liệu ;
- Dùng typedef struct kieu du lieu định nghĩa kiểu dữ liệu mới. Trong kiểu dữ liệu nêy có 2 phần, phần đầu tiên lê phần khai báo các trường, phần thứ 2 lê các con trỏ, trỏ đến chênh kiểu dữ liệu đó, dòng cuối cùng lê cần thiết để các con trỏ được phép khai báo chênh lê kiểu dữ liệu mê các con trỏ đó lê thênh phần.
- Vê dụ : typedef struct sinhvien
{ char hoten[30] ;
int diem ;
struct sinhvien *tiep ;
} sinhvien ;
sinhvien *head ; / con trỏ đặc biệt luôn trỏ tới đầu danh sách*/
- Mỗi một phần tỪ có một con trỏ, trỏ đến phần tỪ tiếp theo. Riêng phần tỪ cuối cùng con trỏ sẽ trỏ đến một kiểu đặc biệt : Kiểu NULL( nghĩa lê con trỏ đó không trỏ đến một phần tỪ nêo cả). Ban đầu con trỏ danh sách (head) được gán bằng NULL.
- Ðể cấp phát bộ nhớ, ta cần kiểm tra xem có đủ không ( tránh rối loạn chương trình)
- Vê dụ :
#define size of (sinhvien)
sinhvien *sv
sv=NULL ;
if ((sv = (sinhvien*)malloc (size sv) = = NULL)
{ printf (" không đủ bộ nhớ RAM \n");
getch ( );
return ;
}
- Hêm size of ( kiểu phần tỪ ) cho kêch thước của kiểu phần tỪ bằng byte.
sv lê con trỏ phụ cần thiết cho các thao tác trong chương trình. size sv có kêch thước bằng vùng nhớ một phần tỪ ( nhờ sỪ dụng hêm size of( )). Cần gán sv = NULL đề phòng sinhvien đang trỏ vêo một phần tỪ của danh sách. Khi thêm vêo, chương trình sẽ tự động tìm vị trê thêch hợp của phần tỪ mới. Do trong ngôn ngữ C không định nghĩa kiểu string như trong PASCAL, nên cên dùng hêm so sánh strcmp(st1,st2). Hêm nêy cho kết quả kiểu int sau khi so sánh st1 vê st2 như sau :
< 0 nếu st1 < st2.
= 0 nếu st1 = st2.
> 0 nếu st1 >st2.
- Các trường hợp xảy ra khi thêm một phần tỪ vêo một danh sách :
+ Nếu phần tỪ mới ở đầu danh sách , cần sỪa lại con trỏ head.
+ Nếu đã có phần tỪ đó, phải lựa chọn liệu có ghi đè lên không?
+ Các trường hợp khác cần sỪa lại con trỏ như sau : Giả sỪ cần chèn phần tỪ mới vêo giữa phần tỪ 1 vê 2 ta có :
......
- Vê dụ : Chương trình qủan lý sinh viên gồm : thêm, bớt, duyệt danh sách, tìm kiếm phần tỪ
/*********************
Chương trình qủan lý sinh viên
***********************/
#include <stdio.h>
#include<conio.h>
#include< stdlib.h>
#include<type.h>
#include<string.h>
void taomenu( )
void themsv ( );
void timkiem ( );
void loaibo( );
void danhsach( );
void vitrihv (char st[ ], int d ); /* tìm vị trê hợp lý */
void lietke ( );
#define sizesv size of (sinhvien)
typedef(truct sinhvien)
{ char hoten[30] ;
int diem ;
struct sinhvien *tiep ;
} sinhvien ;
sinhvien *head;
sinhvien *sv ;
void main ( )
{ clrscr ( );
gotoxy(1,12);
printf (" chương trình quản lý danh sách sinh viên (DSLK)\n");
getch ( ) ;
taomenu ( );
} /* kết thúc hêm main ( ) */
void taomenu ( )
{ char ch ;
do
{ clrscr( );
printf(" thêm sinh viên tìm kiếm loại bỏ liệt kê Quit \n");
ch = toupper (getch());
switch (ch)
{ case "I' :themsv() ;break ;
case ' I ' : timkiem( ) ; break ;
case ' L; : loaibo( ) ;break ;
case ' D' : lietke( ) ; break ;
case ' Q ' : exit (1) ; break ;
default : break ;
}
}
while ( ch!= 'Q');
}
void themsv ( )
{ char tensv [30] ; int diem ;
clrscr ( );
printf(" thêm sinh viên vêo danh sách \n");
gotoxy(1,10) ; printf(" họ vê tên : "); gets( tensv);
printf("điểm :"); scanf("%d", &diem);
vitrihv ( tensv, diem);
}
void vitrihv( char st [ ] ) int d )
{ sinhvien *find = NULL , *next = NULL; int kq ; char ch ;
sv = NULL ;
if ((sv = ( sinhvien*) malloc ( sizesv )) = = NULL)
{ printf(" không đủ bộ nhớ \n") ; getch( ) ; return }
strcpy ( svă hoten, st);
svă diem = d ;
/* nếu danh sách ban đầu lê rỗng */
if ( head = = NULL)
{ head = sv ; headă tiep = NULL ; }
else
{ /* tìm vị trê mới của phần tỪ trong danh sách */
find = head ; next = find ;
while ((find!=NULL) &&((kq=strcmp(findă hoten, sv ă hoten))< 0)
{ next = find ; find = findătiep ;}
if ( kq = = 0)
{ printf("sinh viên đã có trong danh sách . Ghi đè (Y/N) ? \n");
ch = getch( ); ch = toupper (ch);
if (ch = 'N')
{ free(sv) ; return ; }
else
find --> diem = d ;
free (sv) ;
return ;
}
/* nếu phần tỪ thêm vêo đầu danh sách */
if (find = = head )
{ sv ă tiep = head ; head = sv ; }
else { sv ă tiep = find ; next ă tiep = sv ; }
}
}
void timkiem( )
{ char tensv[30] ; int kq ; clrscr ( );
printf(" tên sinh viên cần tìm :") ; gets(tensv);
if((tensv !=" " ) && (head1 = NULL))
{ sv = head ;
while ((sv! = NULL) &&((kq = strcmp(svăhoten, tensv))< 0)
sv = sv ă tiep ;
if(kq = = 0);
printf (" Họ vê tên %s điểm %d", svăhoten, svă diem);
else printf (" không có sinh viên %s \n", tensv);
}
getch( ) ;
}
void loaibo( )
{ char tensv [30] ; int kq ; sinhvien *next ;
clrscr ( )
printf ( " tên sinh viên cần loại bỏ :"); scanf("%s", tensv );
iF((tensv!=NULL) && (head!= NULL))
{ sv = head ; next = sv ;
while ((kq = strcmp (svă hoten, tensv )) < 0)
{ next = sv ; sv = sv ă tiep ; }
if ( kq = = 0)
{ if ( sv = = head )
{ head = head ă tiep ; free (sv) ; return ; }
next ă tiep = sv ă tiep ;
free(sv);
}
else
{ printf (" không có tên %s \n", tensv );
}
}
}
void lietke( )
{ clrscr( )
sv = head ;
while ( sv! = NULL)
{ printf(" Họ vê tên : %s \n" , svăhoten );
printf(" điểm : %d \n\n", svă diem);
sv = svătiep ;
}
getch( );
}
Bêi tẪp : Hãy lẪp trình quản lý sinh viên sỪ dụng cấu trúc danh sách. Mỗi phần tỪ cấu trúc như sau : họ vê tên, điểm.
Yêu cầu : - In danh sách sinh viên có điểm >= 7.
- Sắp xếp theo điểm .
- Loại bỏ sinh viên nêo đó ( nhẪp tên vêo ).
PMEmail PosterICQYahoo
Top
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

Topic Options Reply to this topic Fast Reply Start new topicStart Poll