c lects (7)
TRANSCRIPT
Заагч
Хичээл 8
Pointer - Заагч
Заагч нь санах ойн хаяг хадгалах хувьсагч
P нь C хувьсагчийг зааж байна гэдэг
C
7 3 4… …
173172 174 175 176 177 178 179 180 181
174 3 4… …
P
833832 834 835 836 837 838 839 840 841
Заагч хувьсагчийг зарлах
Заагч –г зарлахдаа хувьсагчийн өмнө нь * тэмдэг бичиж өгдөг.
type *variable_name;
Заалгах
& энэ оператор нь хувьсагчийн хаягийг буцаадаг.
Жишээ нь: P = &C;
C –н хаягийг заагч хувьсагч P-д оноолоо гэсэн үг. Тэгээд P нь C-г зааж байна гэдэг
Заагчийг хэвлэхдээ, %p формат ашиглана.
Заалгах
int C;int *P; /* Заагчаар зарлах */
C = 7;
P = &C;C
7 3 4… …
173172 174 175 176 177 178 179 180 181
174 3 4… …
P
833832 834 835 836 837 838 839 840 841
Хаягийн дотор орох
* операторыг ашиглана. Заагчийн зааж байгаа зүйл рүү
хандах боломжийг олгоно Хэлбэр нь: *P = 7;
C ( P –н зааж байгаа хаяг дахь) байгаа газар 5-г онооно
Хаягийн дотор орох
printf(“%d”, *P); /* Prints out ‘7’ */
*P = 177;printf(“%d”, C); /* Prints out ‘177’ */P = 177; /* Энэ бол буруу шүү!! */
C
7 3 4… …
173172 174 175 176 177 178 179 180 181
174 3 4… …
P
833832 834 835 836 837 838 839 840 841
177
177
Жишээ
Заагч алхам алхмаар
int x=1, y=2, z[10]={5,6,7};int *ip; /* ip нь заагч int-г заана */
ip = &x; /* ip now points to x */printf("ip now points to x that contains the value %d\n",*ip);y = *ip; /* y is now 1 */printf("y is now %d\n",y);*ip = 0; /* x is now 0 */printf("x is now %d\n",x);ip = &z[2]; /* ip now points to z[2] */printf("ip now points to z[2] that contains the value %d\n",*ip);*ip = 1; /* z[2] is now 1 */printf("z[2] is now %d\n", z[2]);printf("ip is %p\n", ip);
x y
z ip
1 2
364
5 6 7
Z[0] Z[1] Z[2]
120 248
364 368 372
…
564 772
Заагч алхам алхмаар
int x=1, y=2, z[10]={5,6,7};int *ip; /* ip нь заагч int-г заана */
ip = &x; /* ip now points to x */printf("ip now points to x that contains the value %d\n",*ip);y = *ip; /* y is now 1 */printf("y is now %d\n",y);*ip = 0; /* x is now 0 */printf("x is now %d\n",x);ip = &z[2]; /* ip now points to z[2] */printf("ip now points to z[2] that contains the value %d\n",*ip);*ip = 1; /* z[2] is now 1 */printf("z[2] is now %d\n", z[2]);printf("ip is %p\n", ip);
x y
z ip
1 2
364
5 6 7
Z[0] Z[1] Z[2]
120 248
364 368 372
120
564 772
Заагч алхам алхмаар
int x=1, y=2, z[10]={5,6,7};int *ip; /* ip нь заагч int-г заана */
ip = &x; /* ip now points to x */printf("ip now points to x that contains the value %d\n",*ip);y = *ip; /* y is now 1 */printf("y is now %d\n",y);*ip = 0; /* x is now 0 */printf("x is now %d\n",x);ip = &z[2]; /* ip now points to z[2] */printf("ip now points to z[2] that contains the value %d\n",*ip);*ip = 1; /* z[2] is now 1 */printf("z[2] is now %d\n", z[2]);printf("ip is %p\n", ip);
x y
z ip
1 2
364
5 6 7
Z[0] Z[1] Z[2]
120 248
364 368 372
120
564 772
Заагч алхам алхмаар
int x=1, y=2, z[10]={5,6,7};int *ip; /* ip нь заагч int-г заана */
ip = &x; /* ip now points to x */printf("ip now points to x that contains the value %d\n",*ip);y = *ip; /* y is now 1 */printf("y is now %d\n",y);*ip = 0; /* x is now 0 */printf("x is now %d\n",x);ip = &z[2]; /* ip now points to z[2] */printf("ip now points to z[2] that contains the value %d\n",*ip);*ip = 1; /* z[2] is now 1 */printf("z[2] is now %d\n", z[2]);printf("ip is %p\n", ip);
x y
z ip
1 1
364
5 6 7
Z[0] Z[1] Z[2]
120 248
364 368 372
120
564 772
Заагч алхам алхмаар
int x=1, y=2, z[10]={5,6,7};int *ip; /* ip нь заагч int-г заана */
ip = &x; /* ip now points to x */printf("ip now points to x that contains the value %d\n",*ip);y = *ip; /* y is now 1 */printf("y is now %d\n",y);*ip = 0; /* x is now 0 */printf("x is now %d\n",x);ip = &z[2]; /* ip now points to z[2] */printf("ip now points to z[2] that contains the value %d\n",*ip);*ip = 1; /* z[2] is now 1 */printf("z[2] is now %d\n", z[2]);printf("ip is %p\n", ip);
x y
z ip
1 1
364
5 6 7
Z[0] Z[1] Z[2]
120 248
364 368 372
120
564 772
Заагч алхам алхмаар
int x=1, y=2, z[10]={5,6,7};int *ip; /* ip нь заагч int-г заана */
ip = &x; /* ip now points to x */printf("ip now points to x that contains the value %d\n",*ip);y = *ip; /* y is now 1 */printf("y is now %d\n",y);*ip = 0; /* x is now 0 */printf("x is now %d\n",x);ip = &z[2]; /* ip now points to z[2] */printf("ip now points to z[2] that contains the value %d\n",*ip);*ip = 1; /* z[2] is now 1 */printf("z[2] is now %d\n", z[2]);printf("ip is %p\n", ip);
x y
z ip
0 1
364
5 6 7
Z[0] Z[1] Z[2]
120 248
364 368 372
120
564 772
Заагч алхам алхмаар
int x=1, y=2, z[10]={5,6,7};int *ip; /* ip нь заагч int-г заана */
ip = &x; /* ip now points to x */printf("ip now points to x that contains the value %d\n",*ip);y = *ip; /* y is now 1 */printf("y is now %d\n",y);*ip = 0; /* x is now 0 */printf("x is now %d\n",x);ip = &z[2]; /* ip now points to z[2] */printf("ip now points to z[2] that contains the value %d\n",*ip);*ip = 1; /* z[2] is now 1 */printf("z[2] is now %d\n", z[2]);printf("ip is %p\n", ip);
x y
z ip
0 1
364
5 6 7
Z[0] Z[1] Z[2]
120 248
364 368 372
120
564 772
Заагч алхам алхмаар
int x=1, y=2, z[10]={5,6,7};int *ip; /* ip нь заагч int-г заана */
ip = &x; /* ip now points to x */printf("ip now points to x that contains the value %d\n",*ip);y = *ip; /* y is now 1 */printf("y is now %d\n",y);*ip = 0; /* x is now 0 */printf("x is now %d\n",x);ip = &z[2]; /* ip now points to z[2] */printf("ip now points to z[2] that contains the value %d\n",*ip);*ip = 1; /* z[2] is now 1 */printf("z[2] is now %d\n", z[2]);printf("ip is %p\n", ip);
x y
z ip
0 1
364
5 6 7
Z[0] Z[1] Z[2]
120 248
364 368 372
372
564 772
Заагч алхам алхмаар
int x=1, y=2, z[10]={5,6,7};int *ip; /* ip нь заагч int-г заана */
ip = &x; /* ip now points to x */printf("ip now points to x that contains the value %d\n",*ip);y = *ip; /* y is now 1 */printf("y is now %d\n",y);*ip = 0; /* x is now 0 */printf("x is now %d\n",x);ip = &z[2]; /* ip now points to z[2] */printf("ip now points to z[2] that contains the value %d\n",*ip);*ip = 1; /* z[2] is now 1 */printf("z[2] is now %d\n", z[2]);printf("ip is %p\n", ip);
x y
z ip
0 1
364
5 6 7
Z[0] Z[1] Z[2]
120 248
364 368 372
372
564 772
Заагч алхам алхмаар
int x=1, y=2, z[10]={5,6,7};int *ip; /* ip нь заагч int-г заана */
ip = &x; /* ip now points to x */printf("ip now points to x that contains the value %d\n",*ip);y = *ip; /* y is now 1 */printf("y is now %d\n",y);*ip = 0; /* x is now 0 */printf("x is now %d\n",x);ip = &z[2]; /* ip now points to z[2] */printf("ip now points to z[2] that contains the value %d\n",*ip);*ip = 1; /* z[2] is now 1 */printf("z[2] is now %d\n", z[2]);printf("ip is %p\n", ip);
x y
z ip
0 1
364
5 6 1
Z[0] Z[1] Z[2]
120 248
364 368 372
372
564 772
Заагч алхам алхмаар
int x=1, y=2, z[10]={5,6,7};int *ip; /* ip нь заагч int-г заана */
ip = &x; /* ip now points to x */printf("ip now points to x that contains the value %d\n",*ip);y = *ip; /* y is now 1 */printf("y is now %d\n",y);*ip = 0; /* x is now 0 */printf("x is now %d\n",x);ip = &z[2]; /* ip now points to z[2] */printf("ip now points to z[2] that contains the value %d\n",*ip);*ip = 1; /* z[2] is now 1 */printf("z[2] is now %d\n", z[2]);printf("ip is %p\n", ip);
x y
z ip
0 1
364
5 6 1
Z[0] Z[1] Z[2]
120 248
364 368 372
372
564 772
Заагч алхам алхмаар
int x=1, y=2, z[10]={5,6,7};int *ip; /* ip нь заагч int-г заана */
ip = &x; /* ip now points to x */printf("ip now points to x that contains the value %d\n",*ip);y = *ip; /* y is now 1 */printf("y is now %d\n",y);*ip = 0; /* x is now 0 */printf("x is now %d\n",x);ip = &z[2]; /* ip now points to z[2] */printf("ip now points to z[2] that contains the value %d\n",*ip);*ip = 1; /* z[2] is now 1 */printf("z[2] is now %d\n", z[2]);printf("ip is %p\n", ip);
x y
z ip
0 1
364
5 6 1
Z[0] Z[1] Z[2]
120 248
364 368 372
372
564 772
Нийтлэг алдаа анхааруулга
Заагчид илэрхийлэл болон тогтмол оноож болохгүй
Ямар нэг хувьсагчийн хаягийг өөрчилж болохгүй(үүнийг бид тодорхойлохгүй!).
Дараах нь алдаанууд: i = &3; j = &(k+5); k = &(a==b); &a = &b; &a = 150;
Аргументыг утгаар дамжуулах
Бид энэ хүртэл функц руу аргументыг утгаар“by value” нь дамжуулж байсан
Утгаар дамжиснаар функц эх хувийг өөрчилж чаддаггүй
Буруу Swap
swap нь хоёр хувьсагч хүлээн аваад тэгээрийн утгуудыг хооронд солих гэж байна даан ч эх хувь үл өөрчлөгдөнө.
void swap(int x, int y) {
int tmp = x;
x = y;
y = tmp;
}
Үүнийг хэрхэн засах вэ?
Үүний тулд хаягуудыг нь хүлээн авч болно void swap(int *x, int *y)
{ … *x ба *y хооронд нь
соль… } Бид одоо swap(&x, &y) гэж дуудах
хэрэгтэй; Энэ нь хаягаар дамжуулж байна
Swap зөв боллоо
void swap(int *x, int *y) { int tmp = *x;
*x = *y;*y = tmp;
}
Scanf –д бид юу хийгээд байв аа?
scanf(“%d”, &a); ийм бичлэгийг бид мэднэ
scanf –д бид үнэндээ хаягийг дамжуулж байсан байна, иймд scanf хувьсагчийн доторх зүйлийг өөрчилж чадаад байсан байна шүү дээ.
Дасгал
Бодит тоо хүлээн аваад түүний бүхэл ба бутархай хэсгийг буцаах функц бич.
Энэ функцээ ашигласан жишээ програм бич.
Заагч ба Массив
S массивын энхий элемент S[0]нь түүний хаягийг хадгалж байдаг
S нь үнэндээ бол S[0]-г заах заагч юм
int S[10];
int *P; P=S; /* P ба S нь адил */
P ба S хоёул S[0]-г заана
Заагч-массив төстэй
Массив бол заагчийн нэг хэлбэр юм! Массив тодорхойлогдоход санах ойн
тодорхой хэсэгт зай авч байрлана. Массив хувьсагч массивын эхлэлийг
заана. Заагчийг зарламагц анхны утгыг
оноодоггүй (ердийн хувьсагчтай адилхан биш)
Заагчийн aрифметик
Заагчийг нэмэгдүүлж мөн хорогдуулж болно
Хэрэв p нь ямар нэг төрлийн заагч бол, p+1 нь яг ийм төрлийн дараагийн хувьсагчийн хаяг болно
p++, p+i, болон p += i гэж үйлдэл хийж болдог
Заагч арифметик -жишээ
Хэрэв p ба q нь массив дахь элементүүдийг зааж байгаа бол q-p нь p ба q хооронд байх элементийн тоо юм.
Заагчийн арифметик болон тооны арифметик хоёр нь ялгаатай зүйлүүд.
Жишээ – ptr_arithmetic.c
Заагчийн арифметик strcpy
void my_strcpy(char *dest, char *src){
while (*src != '\0'){
*dest = *src;dest++;src++;
} *dest = '\0';
}
Strcpy – алхам алхмаар
‘y’ ‘e’ ‘s’ ‘\0’ ‘%’
src
dest
‘!’ ‘!’ ‘!’ ‘!’ ‘!’
void my_strcpy(char *dest, char *src){
while (*src != '\0'){
*dest = *src;dest++;src++;
} *dest = '\0';
}
void my_strcpy(char *dest, char *src){
while (*src != '\0'){
*dest = *src;dest++;src++;
} *dest = '\0';
}
Strcpy – алхам алхмаар
‘y’ ‘e’ ‘s’ ‘\0’ ‘%’
src
dest
‘y’ ‘!’ ‘!’ ‘!’ ‘!’
void my_strcpy(char *dest, char *src){
while (*src != '\0'){
*dest = *src;dest++;src++;
} *dest = '\0';
}
Strcpy – алхам алхмаар
‘y’ ‘e’ ‘s’ ‘\0’ ‘%’
src
dest
‘y’ ‘!’ ‘!’ ‘!’ ‘!’
Strcpy – алхам алхмаар
‘y’ ‘e’ ‘s’ ‘\0’ ‘%’
src
dest
‘y’ ‘!’ ‘!’ ‘!’ ‘!’
void my_strcpy(char *dest, char *src){
while (*src != '\0'){
*dest = *src;dest++;src++;
} *dest = '\0';
}
Strcpy – алхам алхмаар
‘y’ ‘e’ ‘s’ ‘\0’ ‘%’
src
dest
‘y’ ‘!’ ‘!’ ‘!’ ‘!’
void my_strcpy(char *dest, char *src){
while (*src != '\0'){
*dest = *src;dest++;src++;
} *dest = '\0';
}
void my_strcpy(char *dest, char *src){
while (*src != '\0'){
*dest = *src;dest++;src++;
} *dest = '\0';
}
Strcpy – алхам алхмаар
‘y’ ‘e’ ‘s’ ‘\0’ ‘%’
src
dest
‘y’ ‘e’ ‘!’ ‘!’ ‘!’
void my_strcpy(char *dest, char *src){
while (*src != '\0'){
*dest = *src;dest++;src++;
} *dest = '\0';
}
Strcpy – алхам алхмаар
‘y’ ‘e’ ‘s’ ‘\0’ ‘%’
src
dest
‘y’ ‘e’ ‘!’ ‘!’ ‘!’
Strcpy – алхам алхмаар
‘y’ ‘e’ ‘s’ ‘\0’ ‘%’
src
dest
‘y’ ‘e’ ‘!’ ‘!’ ‘!’
void my_strcpy(char *dest, char *src){
while (*src != '\0'){
*dest = *src;dest++;src++;
} *dest = '\0';
}
Strcpy – алхам алхмаар
‘y’ ‘e’ ‘s’ ‘\0’ ‘%’
src
dest
‘y’ ‘e’ ‘!’ ‘!’ ‘!’
void my_strcpy(char *dest, char *src){
while (*src != '\0'){
*dest = *src;dest++;src++;
} *dest = '\0';
}
Strcpy – алхам алхмаар
‘y’ ‘e’ ‘s’ ‘\0’ ‘%’
src
dest
‘y’ ‘e’ ‘s’ ‘!’ ‘!’
void my_strcpy(char *dest, char *src){
while (*src != '\0'){
*dest = *src;dest++;src++;
} *dest = '\0';
}
void my_strcpy(char *dest, char *src){
while (*src != '\0'){
*dest = *src;dest++;src++;
} *dest = '\0';
}
Strcpy – алхам алхмаар
‘y’ ‘e’ ‘s’ ‘\0’ ‘%’
src
dest
‘y’ ‘e’ ‘s’ ‘!’ ‘!’
Strcpy – алхам алхмаар
‘y’ ‘e’ ‘s’ ‘\0’ ‘%’
src
dest
‘y’ ‘e’ ‘s’ ‘!’ ‘!’
void my_strcpy(char *dest, char *src){
while (*src != '\0'){
*dest = *src;dest++;src++;
} *dest = '\0';
}
Strcpy – алхам алхмаар
‘y’ ‘e’ ‘s’ ‘\0’ ‘%’
src
dest
‘y’ ‘e’ ‘s’ ‘!’ ‘!’
void my_strcpy(char *dest, char *src){
while (*src != '\0'){
*dest = *src;dest++;src++;
} *dest = '\0';
}
Strcpy – алхам алхмаар
‘y’ ‘e’ ‘s’ ‘\0’ ‘%’
src
dest
‘y’ ‘e’ ‘s’ ‘\0’ ‘!’
void my_strcpy(char *dest, char *src){
while (*src != '\0'){
*dest = *src;dest++;src++;
} *dest = '\0';
}
Дасгал
Дараах зарлалт бүхий функц бич:void replace_char(char *str,
char c1,
char c2);
Энэ нь str мөрөнд байх c1 бүрийг c2-р солино. [] операторыг ашиглахгүй!
Бодолт
char_replace.c
2D хэмжээст массивийг функцэд дамжуулах
Функц нь массивыг дараах байдлаар хүлээн авдаг –int func(int arr[]);
Хоёр хэмжээст массивыг –int func2(int arr2D[][]); гэж авах уу?
Энэ бол алдаа!
2D хэмжээст массивийг функцэд дамжуулах
int func2(int arr[][4]); Хоёр хэмжээст массив нь үнэндээ
массивын массив юм int arr[3][4] – энэ нь дараах 3
элементтэй массив юм. 4 бүхэл тоог агуулах массив
2D хэмжээст массивийг функцэд дамжуулах
2D хэмжээст массивийг функцэд дамжуулахадаа хэмжээсийг нь тодорхой бичиж өгнө
Энэ бол зөв зарлалт int func2(int arr[3][4]);
‘3’ нь утга болоод өөр ямар нэг зүйлийг агуулахгүй
Дасгал
MatMul функц бич – оролт –A, B, C гэсэн гурван квадрат
матриц үйлдэл – C нь A ба B –ийн үржвэр
Хоёр матрицыг хүлээн аваад тэдгээрийн үржвэрийг дэлгэцэнд хэвлэх програм бич
Solution
mat_mul.c