اشاره گر در واقع متغیری است که آدرس حافظه متغیر دیگری را نگه می دارد.
1var ex *T
در بالا ما یک متغیری تعریف کردیم که مقدار داخل آدرس حافظه متغیری T را با استفاده از *
را نگه می دارد.
در اشاره گر ۲ تا اپراتور داریم که هر کدام از این ها را در کنار یک متغیر بزاریم به آدرس حافظه یا مقدار داخل خانه حافظه متغیر قبلی دسترسی پیدا می کنیم :
&
با استفاده از این می توانیم آدرس حافظه متغیر فرضا x را به متغیر دیگری بدهیم (y := &x
)*
با استفاده از این می توانیم به مقدار داخل خانه حافظه متغیر فرضا x دسترسی پیدا کنیم (x*
)
برای اینکه یک اشاره گر تعریف کنیم ۲ روش وجود دارد :
- استفاده از تابع
new
- استفاده از اپراتور
&
(آمپرسند)
2.1.1 استفاده از تابع new #
یک اشاره گر
با استفاده از تابع new
بصورت زیر راه اندازی می شود :
در بالا ما متغیر a را از نوع int اشاره گر تعریف کردیم و سپس داخل آدرس حافظه a مقدار ۱۰ را قرار دادیم.
توجه کنید مقدار پیش فرض یک متغیر از نوع اشاره گرnil
می باشد. و اگر جایی شما متغیر از نوع اشاره گر بصورتnil
بفرستید ممکن است panic از نوع nil pointer بر بخورید و پروژه کاملا متوقف شود.
2.1.2 استفاده از اپراتور ‘&’ #
برای دریافت آدرس حافظه یک متغیر از &
استفاده می شود :
در زیر یک نمونه کد مثال زدیم توجه کنید :
1package main
2
3import "fmt"
4
5func main() {
6 var b *int
7 a := 2
8 b = &a
9
10 fmt.Println(b)
11 fmt.Println(*b)
12 b = new(int)
13 *b = 10
14 fmt.Println(*b)
15}
در خروجی بالا 0xc0000b0018
آدرس حافظه متغیر a می باشد.
2.1.3 اپراتور * اشاره گر #
اپراتور * برای می توانیم برای عملیات زیر استفاده کنیم :
- گرفتن مقدار یک آدرس حافظه که با استفاده از اشاره گر ذخیره شده است.
- تغییر مقدار یک آدرس حافظه
1package main
2
3import "fmt"
4
5func main() {
6 a := 2
7 b := &a
8 fmt.Println(a)
9 fmt.Println(*b)
10
11 *b = 3
12 fmt.Println(a)
13 fmt.Println(*b)
14
15 a = 4
16 fmt.Println(a)
17 fmt.Println(*b)
18}
در بالا a
و b*
هر دور به یک متغیر دارند اشاره می کنند. بنابرین تغییر مقدار داخل خانه حافظه روی هر دو متغیر تاثیر میگذارد.
2.1.4 اشاره گر به یک اشاره گر #
شما می توانید یک متغیر اشاره گر تعریف کنید و متغیر اشاره گر دیگری را بهش اختصاص دهید.
در بالا متغیر a مقدارش ۲ می باشد و آدرسش در حافظه 0xXXXXXX
است و در مقدار متغیر b ما اشاره کردیم به آدرس حافظه متغیر a و در ادامه در متغیر c به آدرس حافظه متغیر b اشاره کردیم که آدرسش در حافظه 0xYYYYYY
است.
زمانیکه شما بخواهید مقدار c را چاپ کنید کافیه c**
را استفاده کنید تا مقدار را ۲ را که داخل خانه حافظه متغیر a قرار دارد را چاپ کند.
به مثال زیر توجه کنید :
1package main
2
3import "fmt"
4
5func main() {
6 a := 2
7 b := &a
8 c := &b
9
10 fmt.Printf("a: %d\n", a)
11 fmt.Printf("b: %x\n", b)
12 fmt.Printf("c: %x\n", c)
13
14 fmt.Println()
15 fmt.Printf("a: %d\n", a)
16 fmt.Printf("*&a: %d\n", *&a)
17 fmt.Printf("*b: %d\n", *b)
18 fmt.Printf("**c: %d\n", **c)
19
20 fmt.Println()
21 fmt.Printf("&a: %d\n", &a)
22 fmt.Printf("b: %d\n", b)
23 fmt.Printf("&*b: %d\n", &*b)
24 fmt.Printf("*&b: %d\n", *&b)
25 fmt.Printf("*c: %d\n", *c)
26
27 fmt.Println()
28 fmt.Printf("b: %d\n", &b)
29 fmt.Printf("*c: %d\n", c)
30}
1$ go run main.go
2a: 2
3b: c000018078
4c: c00000e028
5
6a: 2
7*&a: 2
8*b: 2
9**c: 2
10
11&a: 824633819256
12b: 824633819256
13&*b: 824633819256
14*&b: 824633819256
15*c: 824633819256
16
17b: 824633778216
18*c: 824633778216
توجه کنید زبان گو همانند زبان c استفاده از اشاره گر حسابی (Pointer Arithmetic) امکان پذیر نمی باشد و با خطای زیر مواجه خواهید شد :