一、初步了解——指針與取地址
先看程序:
#include<cstdio> int main(void) { int num = 7; int *p = # printf("%d 的地址是 %p\n", num, p); return 0; }
上面int *p定義了一個指向int類型指針p(我們使用*符號把p聲明為指針),並初始化p使其指向int類型的變量num,這里&num中的&是取地址操作符,當&作用於一個對象上時,它返回了該對象的地址。
所以這里指針p指向了num所對應的地址。(我測試時輸出了0028FF1C)
二、如何使用指針?——解引用與指針賦值
#include<cstdio> int main(void) { int num = 7; int *p = # printf("數值%d所在的地址是 %p\n", num, p); printf("指針p所指向的地址為 %p , 該地址上所保存的值為%d\n", p, *p); *p = 100; printf("指針p所指向的地址為 %p , 該地址上所保存的值為%d\n", p, num); return 0; }
注意這里*操作符為解引用操作符,它返回指針p所指的地址所保存的值。
我們可以對*p賦值,從而改變p所指的地址上說保存的值,從而改變指向此地址的變量num的值。(num的值變為100)
當然,我們也可以給指針p賦值,使其指向另外一個地址:
#include<cstdio> int main(void) { int num = 7, another = -5; int *p = # p = &another; printf("%d\n", *p);//-5 return 0; }
三、引用
從某種意義上來說,引用完全有別於上面說介紹的內容:
#include<cstdio> int main(void) { int val = 7, val2 = 999; int &refval = val, &refval2 = val2; ///引用必須要初始化,使其綁定到一個變量上 ///修改引用的值將改變其所綁定的變量的值 refval = -12; printf("%d %d\n", val, refval);//-12,refval的值和val一樣 ///將引用b賦值給引用a將改變引用a所綁定的變量的值, ///引用一但初始化(綁定),將始終綁定到同一個特定對象上,無法綁定到另一個對象上 refval = refval2; printf("%d %d\n", val, refval);//999 return 0; }
四、補充
a)指向指針的指針:
#include<cstdio> int main(void) { int val = 7; int *p = &val; int **p2 = &p;///**聲明一個指向指針的指針 printf("val的值為%d %d",*p,**p2);///**p2為兩次解引用,可看做*(*p2) return 0; }
由於指針也要占用內存空間存放其值,所以我們也可以定義一個指向指針的指針。
b)指針與數組:
指針和迭代器非常像,我們可以說指針就是數組的迭代器:
#include<cstdio> int val[100]; int main(void) { for (int i = 0; i < 100; ++i) val[i] = i; int *p = val;///等價於int *p = &val[0]; ///數組的變量名就是一個指針 printf("%d\n", *p); ///指針p指向val的第一個元素,即val[0] int t = 100; while (t--) ///可以直接對指針進行加減運算,就和迭代器一樣 printf("%d\n", *(p++));///輸出0~99 ///指針可以做差: int *p2 = &val[10], *p3 = &val[20]; printf("%d\n", p3 - p2); //10 printf("%d\n", p2 - p3); //-10 ///還可以比比較大小: printf("%d\n", p2 < p3 ? p3 - p2 : p2 - p3); //10 return 0; }
對於多維數組,只要把指向指針的指針理解好了就行:
#include<cstdio> int val[100][100]; int main(void) { val[2][1] = 666; ///如何用指針取出val[2][1]? printf("%d", *(*(val + 2) + 1)); return 0; }