Bài giảng Tin học đại cương - Phần 8: Con trỏ

1/26/2011  
Ni dung  
Nhc li vtchc bnhca máy tính  
Biến con trỏ  
Con trvà cu trúc  
Con trvà hàm  
Chương 8  
CON TRỎ ‐ POINTER  
Con trvà cu trúc  
Con trvà cp phát bnhớ đng  
Nhc li vtchc bnhmáy tính  
Trong máy tính, bnhtrong :  
chia thành các ô nh  
Các ô nhớ được đánh địa chkhác nhau  
Kích thước ca mi ô nhlà 1 byte  
Địa chô nhớ  
11111111  
11111110  
11111101  
10010101  
11010101  
10010100  
10000101  
Nhc li tchc bnhca máy tính  
00000000  
00010101  
1
1/26/2011  
#include <stdio.h>  
#include <stdlib.h> //cho ham system()  
Nhc li vtchc bnhmáy tính  
Khi khai báo 1 biến, các ô nhsẽ đưc cp phát cho biến  
đó  
int A; // 4 byte  
int main()  
{
int a, b;  
A=5;  
double c,d;  
a=5; b=7;  
c=3.5; d=10.0;  
printf("Gia tri a=%d, dia chi %#x\n",a,&a);  
printf("Gia tri b=%d, dia chi %#x\n",b,&b);  
printf("Gia tri a=%f, dia chi %#x\n",c,&c);  
printf("Gia tri a=%f, dia chi %#x\n",d,&d);  
system("pause");  
Biến A  
Biến A được lưu trtrong 4 ô  
bt đầu ti địa ch10001111  
Giá trca biến A là 5 (4 ô nhớ  
cha giá tr5)  
Ly địa chô nh(đầu tiên)  
cp phát cho biến: dùng  
toán t&  
&A trv10001111  
10001111  
10001110  
5
10001101  
10001100  
10001011  
10001010  
return 0;  
10001001  
10001000  
}
Biến con trỏ  
Biến con trỏ ‐ Pointer Variable: giá trca biến là mt địa  
chô nh.  
Kích thước 1 biến con trphthuc vào các platform  
(môi trường ng dng):  
Platform 16 bit là 2 byte.  
Platform 32 bit là 4 byte.  
Platform 64 bit là 8 byte.  
Biến con trỏ  
Khai báo biến con trỏ  
KieuDuLieu *TenBien;  
int *pInt;  
float *pFloat;  
2
1/26/2011  
0x23FF74  
0x23FF73  
0x23FF72  
0x23FF71  
0x23FF70  
0x23FF6F  
0x23FF6E  
0x23FF6D  
0x23FF6C  
0x23FF6B  
0x23FF6A  
0x23FF69  
0x23FF68  
0x23FF67  
0x23FF66  
0x23FF65  
Biến con trỏ  
Kích thước biến con trkhông phthuc vào kiu dliu  
Truy cp vào giá trca vùng nhớ đang trbi con tr: dùng toán  
t*  
100  
int A;  
int *pInt;  
A=5;  
*pInt là giá trvùng nhtrbi con trpInt  
0x23FF74  
0x23FF74  
pInt = &A;  
*pInt = 7;  
int *p2;  
p2 = pInt;  
*p2 = 100;  
int A=5;  
int *pInt;  
pInt = &A;  
printf("Dia chi A = %#x, Gia tri pInt = %#x Dia chi pInt = %#x\n",  
&A, pInt, &pInt);  
printf("Gia tri A = %d, gia tri vung nho tro boi pInt = %d\n",A,*pInt);  
*pInt = 7;  
printf("Gan *pInt = 7\n");  
printf("Gia tri A = %d, gia tri vung nho tro boi pInt = %d\n",A,*pInt);  
c
'('  
Biến con trỏ  
Biến con trtrong biu thc  
#include <stdio.h>  
int main (void)  
{
int i1, i2;  
int *p1, *p2;  
i1 = 5;  
p1 = &i1;  
i2 = *p1 / 2 + 10;  
p2 = p1;  
#include <stdio.h>  
int main (void)  
{
char_pointer  
char c = 'Q';  
char *char_pointer = &c;  
printf ("%c %c\n", c, *char_pointer);  
c = '/';  
printf ("%c %c\n", c, *char_pointer);  
*char_pointer = '(';  
printf ("i1 = %i, i2 = %i, *p1 = %i, *p2 = %i\n",  
i1, i2, *p1, *p2);  
printf ("%c %c\n", c, *char_pointer);  
return 0;  
return 0;  
}
}
3
1/26/2011  
Con trhng và hng con trỏ  
char c = 'X';  
Khai báo biến con trthông thường  
char *charPtr = &c;  
charPtr là hng con tr, nó không ththay đổi được  
giá tr(không thtrvào ô nhkhác)  
Có ththay đổi giá trca ô nhcon trỏ đang trỏ đến  
char * const charPtr = &c;  
charPtr = &d; // not valid  
charPtr là con trhng (con trti 1 hng s)  
không ththay đổi giá trô nhtrti bi con trỏ  
(có thcho con trtrsang ô nhkhác)  
const char *charPtr = &c;  
*charPtr = 'Y'; // not valid  
Con trvà cu trúc  
const char * const *charPtr = &c;  
Hng con trtrti hng s: không thay đổi được  
cgiá trcon trvà giá trô nhmà nó trỏ đến  
todaysDate  
.month  
11  
Con trvà cu trúc  
struct date  
{
Con trvà cu trúc  
Truy cp vào trường biến cu trúc thông qua con trỏ  
(* TênConTr).TênTrường  
.date  
27  
.year  
2010  
int month;  
int day;  
int year;  
};  
TênConTrỏ‐>TênTrường  
datePtr  
todaysDate  
.month  
1  
1  
datePtr = &todaysDate;  
datePtr>month = 1;  
(*datePtr).day = 1;  
datePtr>year = 2011;  
.date  
.year  
struct date todaysDate ={11,27,2010};  
2011  
struct date *datePtr;  
datePtr = &todaysDate;  
datePtr  
4
1/26/2011  
#include <stdio.h>  
struct intPtrs  
int main (void)  
{
Con trvà cu trúc  
Cu trúc cha con trỏ  
int *p1;  
int *p2;  
};  
{
struct date  
{
int month;  
#include <stdio.h>  
int main (void)  
{
pointers  
p1  
int day;  
int year;  
struct intPtrs  
{
};  
p2  
struct date today = {11,27,2010}, *datePtr;  
datePtr = &today;  
int *p1;  
int *p2;  
100  
97  
printf ("Today's date is %i/%i/%.2i.\n",datePtr>month,  
};  
i1  
i2  
datePtr>day, datePtr>year % 100);  
struct intPtrs pointers;  
int i1 = 100, i2;  
pointers.p1 = &i1;  
pointers.p2 = &i2;  
*pointers.p2 = 97;  
datePtr>month = 1;  
(*datePtr).day = 1;  
datePtr>year = 2011;  
printf ("Today's date is %i/%i/%.2i.\n",datePtr>month,  
printf ("i1 = %i, *pointers.p1 = %i\n", i1, *pointers.p1);  
printf ("i2 = %i, *pointers.p2 = %i\n", i2, *pointers.p2);  
return 0;  
datePtr>day, datePtr>year % 100);  
return 0;  
}
}
#include <stdio.h>  
Con trvà cu trúc  
int main (void)  
{
Danh sách liên kết – linked list: mt trong nhng cu trúc  
phc tp được xây dng tquan hcon trvà cu trúc  
struct node  
{
int value;  
struct entry *pNext;  
N1  
value  
5
};  
pNext  
struct node  
{
struct node N1, N2, N3;  
int i;  
int value;  
struct node *pNext;  
N1.value = 5; N2.value = 7; N3.value = 100;  
7
N2  
N3  
value  
N1.pNext = &n2;  
N2.pNext = &n3;  
i = N1.pNext>value;  
printf ("%i ", i);  
printf ("%i\n", N2.pNext>value);  
return 0;  
};  
pNext  
100  
value  
pNext  
}
5
1/26/2011  
Con trvà hàm  
Tham sca hàm có thlà con tr, và hàm có thtrvề  
giá trkiu con trỏ  
Thay đổi giá trị  
vùng nhớ  
void Absolute(int *x)  
{
if(*x<0)
}
int main()  
{
Truyn vào  
địa chỉ  
Con trvà hàm  
int a=6;  
printf("Before call function Absolute, a = %d\n",a);  
printf("After call function Absolute, a = %d\n",a);  
}
void Exchange(int x, int y)  
{
Con trvà hàm  
Con trvà hàm  
//exchange value of x and y, huh ?  
int tmp;  
tmp=x;  
x=y;  
y=tmp;  
Giá trcác biến  
không thay đổi?  
Cách truyn tham sca hàm  
}
Khi khai báo hàm, các tham sca hàm là tham shình thc  
Khi gi hàm, ta truyn vào các giá tr, biến, đó là các tham số  
thc sự  
Mt bn copy ca các tham sthc sự được gán cho các  
tham shình thc ca hàm, do đó mi thay đổi giá trtrên  
các tham shình thc trong khi thc hin hàm sbmt sau  
khi hàm thc hin xong (giá trtham sthc skhông đổi)  
int main()  
{
int x=5, y=16;  
printf("Before function call: x = %d, y = %d\n",x,y);  
Exchange(x,y);  
printf("After function call: x = %d, y = %d\n",x,y);  
return 0;  
}
6
1/26/2011  
void Exchange2(int *x, int *y)  
{
Con trvà hàm  
Con trvà hàm  
//it really exchange value of x and y  
int tmp;  
tmp=*x;  
*x=*y;  
*y=tmp;  
}
Khi truyn tham scho hàm là con trỏ  
Mt bn copy ca con trcũng được to ra và gán cho tham số  
hình thc ca hàm.  
Cbn copy và con trthc này đều cùng tham chiếu đến mt  
vùng nhduy nht, nên mi thay đổi giá trvùng nhớ đó (dù  
dùng con trnào) là như nhau ging và được lưu li  
int main()  
{
Sau khi kết thúc thc hin hàm, giá trca con trkhông đổi,  
nhưng giá trvùng nhmà con trtrỏ đến có thể được thay  
đổi (nếu trong hàm ta thay đổi giá trnày)  
int x=5,y=16;  
printf("Before function call: x = %d, y = %d\n",x,y);  
Exchange2(&x,&y);  
printf("After function call: x = %d, y = %d\n",x,y);  
Truyn tham scon trkhi ta mun giá trvùng nhớ đưc  
thay đổi sau khi thc hin hàm  
return 0;  
}
struct list  
{
Con trvà hàm  
int data;  
struct list *pNext;  
};  
Hàm trvcon trỏ  
struct list * searchList(struct list *pHead, int key)  
{
while(pHead!=(struct list*)0) //or NULL  
{
if(key==pHead>data)  
Con trvà mng  
return pHead;  
else  
pHead=pHead>pNext;  
}
return (struct list*)0; //or NULL  
}
7
1/26/2011  
Con trvà mng  
Con trvà mng  
Tên mng là mt con trhng trvào phn tử đầu tiên  
int values[6]={2,5,4,7,5,12};  
ca mng  
int *pt;  
pt  
pt  
pt = values; // same as &value[0]  
int values[6]={2,5,4,7,5,12};  
values[0]  
values[0]  
values[1]  
values[2]  
values[3]  
values[4]  
values[5]  
2
5
7
*(pt)=7; //same as values[0]=7  
int *pt;  
values[1]  
values[2]  
values[3]  
values[4]  
values[5]  
5
pt = values; // same as &value[0]  
*(pt+3)=25; //same as values[3]=25  
4  
7
2
25  
3
12  
pt = &values[2];//pt points to  
values[2] address  
Ta có thddàng dùng con  
trỏ để truy cp vào các phn  
ttrong mng  
*pt = 2;//same as values[2]=2;  
5  
12  
*(pt+2) = 3;//same as values[4]=3;  
Con trvà mng  
Con trvà mng  
Mt sthao tác  
Các phép toán quan hvi con trỏ  
int values[6]={2,5,4,7,5,12};  
int *pt;  
Có thsdng các toán tcon hvi kiu con trỏ  
Các phép toán đó slà so sánh các địa chô nhvi nhau  
Kiu giá trtrvlà TRUE (khác 0) và FALSE (bng 0)  
pt = values; cho con trtrvào phn tử đầu tiên trong mng  
(cha địa chca phn tử đầu tiên)  
pt>= &values[5];  
pt==&values[0];  
*(pt+i) truy cp ti giá trphn tcách phn tử  
đang trbi con tr݅ phn tử  
pt=pt+n; //or pt+=n; cho pt trti địa chca phn tử  
cách địa chca phn thin ti ݊ phn tử  
pt++;  
pt‐‐;  
Cho con trdch chuyn cách 1 phn tử  
(tc là sizeof(kieudulieu) ô nh)  
8
1/26/2011  
Con trvà mng  
Con trvà mng  
Khi truyn vào mng ta chtruyn địa chca phn tử đầu  
tiên trong mng, do đó hàm arraySum có thviết li là  
int arraySum (int Array[], const int n)  
{
int sum = 0, *ptr;  
int * const arrayEnd = array + n;  
for ( ptr = Array; ptr < arrayEnd; ++ptr )  
int arraySum (int *Array, const int n)  
{
sum += *ptr;  
return sum;  
}
int sum = 0;  
int * const arrayEnd = Array + n;  
for ( ; Array < arrayEnd; ++Array )  
sum += *Array;  
return sum;  
}
int main (void)  
{
int values[10] = { 3, 7, 9, 3, 6, 1, 7, 9, 1, 5 };  
printf ("The sum is %i\n", arraySum (values, 10));  
return 0;  
}
Con trvà mng  
Con trvà mng  
char *days[] = { "Sunday", "Monday", "Tuesday", "Wednesday",  
"Thursday", "Friday", "Saturday" };  
void copyString (char to[], char from[])  
{
int i;  
for ( i = 0; from[i] != '\0'; ++i )  
to[i] = from[i];  
to[i] = '\0';  
}
void copyString (char *to, char *from)  
{
for ( ; *from != '\0'; ++from, ++to )  
*to = *from;  
*to = '\0';  
}
9
1/26/2011  
Con trvà mng  
Sdng con trỏ để tìm độ dài ca xâu ký tự  
int stringLength (const char *string)  
{
const char *cptr = string;  
while ( *cptr )  
++cptr;  
return cptr string;  
}
Con trvà cp phát bnhớ động  
int main (void)  
{
printf ("%i ", stringLength ("stringLength test"));  
printf ("%i ", stringLength (""));  
printf ("%i\n", stringLength ("complete"));  
return 0;  
}
Con trvà cp phát bnhớ động  
Con trvà cp phát bnhớ động  
Cp phát tĩnh  
Trong nhiu trường hp ti thi đim lp trình ta chưa  
biết trước kích thước bnhcn dùng để lưu trdliu.  
Ta có th:  
Khai báo mng vi kích thước ti đa có thti thi đim biên  
dch (cp phát bnhtĩnh)  
Sdng mng vi kích thước biến đổi ti thi đim chy (ch  
có trong C99)  
Sdng mng cp phát bnhớ động  
Kích thước bnhcp phát được xác định ngay ti thi đim  
biên dch chương trình và không ththay đổi trong quá trình  
chy chương trình  
Vic qun lý và thu hi bnhớ được thc hin tự động, người  
lp trình không cn quan tâm  
Slà rt lãng phí bnhnếu không dùng hết dung lượng được  
cp  
Bnhớ được ly tphn DATA, do đó dung lượng bnhớ  
được cp phát tĩnh là có gii hn  
int A[1000];  
double B[1000000]; //not enough memory  
10  
1/26/2011  
Con trvà cp phát bnhớ động  
Con trvà cp phát bnhớ động  
Cp phát bnhớ động trong C: dùng 2 hàm malloc và calloc  
Cp phát bnhớ đng  
Bnhớ được cp phát ti thi đim thc hin chương trình,  
nên có ththay đổi được trong mi ln chy  
Vic qun lý và thu hi bnhsdo người lp trình đảm  
nhim  
(trong thư vin <stdlib.h>)  
Hàm trvề đa chca ô nhớ đu tiên trong vùng nhxin cp phát,  
do đó dùng con trỏ để cha địa chnày  
Trvcon trNULL nếu cp phát không thành công  
pointer=(dataType*) calloc(sizeofAnElement, noElements);  
pointer = (dataType*) malloc(sizeofAnElement * noElements);  
Tiết kim bnhhơn so vi cp phát tĩnh (vì chcn cp phát  
đủ dùng)  
Bnhcp phát được ly phn bnhri (HEAP) nên dung  
lượng bnhcó thcp phát ln hơn so vi cp phát tĩnh  
Nếu không thu hi bnhsau khi dùng xong thì sdn đến rò  
rbnh(memory leak), có thgây ra hết bnhớ  
double *pt;  
pt = (double *) calloc(sizeof(double),10000);  
int *pInt;  
pInt = (int*) malloc(sizeof(int)*10000);  
Con trvà cp phát bnhớ động  
Con trvà cp phát bnhớ động  
#include <stdlib.h>  
Hàm calloc  
Cn 2 tham slà kích thước 1 phn t(theo byte) và slượng  
phn tử  
Khi cp phát stự động đưa giá trcác ô nhớ được cp phát v0  
#include <stdio.h>  
...  
int *intPtr;  
...  
Hàm malloc  
Chcn 1 tham slà kích thước bnh(theo byte)  
Không tự đưa giá trcác ô nhv0  
intptr = (int *) calloc (sizeof (int), 1000);  
if ( intPtr == NULL )  
{
fprintf (stderr, "calloc failed\n");  
exit (EXIT_FAILURE);  
}
Hàm sizeof  
Trvkích thước ca 1 kiu dliu, biến (tính theo byte)  
11  
1/26/2011  
Con trvà cp phát bnhớ động  
Gii phóng bnhsau khi đã sdng xong: hàm free  
Con trvà cp phát bnhớ động  
struct entry  
{
int value;  
struct entry *next;  
};  
free(pointer);  
Trong đó pointer là con trcha địa chỉ đầu ca vùng nhớ đã  
cp phát  
struct entry *addEntry (struct entry *listPtr)  
{
int *intPtr;  
...  
intptr = (int *) calloc (sizeof (int), 1000);  
....  
// find the end of the list  
while ( listPtr>next != NULL )  
listPtr = listPtr>next;  
// get storage for new entry  
listPtr>next = (struct entry *) malloc (sizeof (struct entry));  
// add null to the new end of the list  
if ( listPtr>next != NULL )  
(listPtr>next)>next = (struct entry *) NULL;  
return listPtr>next;  
free(intptr);  
}
12  
pdf 12 trang Thùy Anh 26/04/2022 5960
Bạn đang xem tài liệu "Bài giảng Tin học đại cương - Phần 8: Con trỏ", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

File đính kèm:

  • pdfbai_giang_tin_hoc_dai_cuong_phan_8_con_tro.pdf