1.指標的概念:指標(pointer)是程式語言中的乙個物件,利用位址,它的值直接指向(points to)存在電腦儲存器中另乙個地方的值。由於通過位址能找到所需的變數單元,可以說,位址指向該變數單元。因此,將位址形象化的稱為"指標"(位址就是記憶體的實體地址)。
使用指標的目的:要通過指標能夠找到被指的變數,或者說要通過指標間接訪問被指向的變數。
2**.指標變數的定義**:一般形式:
型別識別符號 *指標變數名;
例如:
int *pint; //乙個指向整型變數的指標
long *plong; //乙個指向長整型變數的指標
float *pfloat; //乙個指向浮點型變數的指標
char *pchar; //乙個指向字元型變數的指標
int *pint1,*pint2; //一次可以定義多個指標變數,每個變數名前都要加*號
說明:在定義指標時,乙個*號只能代表乙個指標;乙個型別的指標只能指向同型別的變數,不能指向其他型別的變數。
3.變數的值和變數的位址
int a=10;
int *ptr=null; //指標初始化,讓其指向空,不這樣做的話可能成為野指標,造成記憶體洩漏
ptr=&a;
4.指標變數的初始化
指標變數使用前,必須進行初始化,並且只能賦位址;如果乙個指標在定以後沒有初始化,應該給他賦乙個空值,避免出現使用未被初始化的指標引起系統混亂(野指標)。
5.指標變數的賦值
①可以把乙個變數的位址直接賦值給乙個指標變數;
②在定義指標變數時,星號代表該變數是乙個指標變數,而在指標賦值時,不能在指標變數名前加*號;
③賦值時不允許把乙個數值賦給指標變數;
④指標變數的值可以改變,相當於指標指向的改變。
6.指標變數的大小:
是指標變數占用記憶體的大小(位元組數)。在32位機上,所有指標型別變數占用記憶體位元組數都為4(因為32位機就是 4位元組 * 8個二進位制位/位元組計算出來的);如果在64位機上,指標占用記憶體大小就是8個位元組。
9.指標運算:
①指標與整數的的加減運算,會進行指標指向位址的偏移:
p+n=p+nsizeof(指向型別);
p-n=p-nsizeof(指向型別);
②指標與指標之間,只有減法運算:
pn-pn1=(pn-pn1)/sizeof(指向型別);
如:
int arr[5]=;
int *pn1,*pn2;
pn1=&arr[0]; //設arr[0]的位址是1000
pn2=&arr[3]; //設arr[3]的位址是1012
printf("%d\n",pn2-pn1); //計算結果為3,實際運算過程為(1012-1000)/4
③指標間的比較運算:就是位址值的比較。上面的例子中(pn110.指標與一維陣列:用指標訪問陣列元素的幾種方式。
①陣列名實際上就是乙個指向該陣列中第乙個元素的指標。
int arr[5]=;
int *p=null;
p=&arr[0]; //等同於p=arr;
②在實際陣列前面加乙個&與使用變數相同;
③在陣列名後面加偏移量,改變指向的陣列元素(指標指向位置的偏移量)
p=&arr[1];
p++; //此時p的指向為arr[2]的位址,相當於p=&arr[2]
④如果指標已經指向陣列中的乙個元素,則p+1指向陣列的下乙個元素。
訪問陣列元素的兩種方法:
eg1:用乙個整型變數接收
int arr[5]=;
int nval1=arr[0];
int nval2=arr[1];
eg2:用指標訪問
int arr[5]=;
int *p=arr;
int nval1=*arr; //相當於nval1=arr[0],陣列名相當於首位址,加*號就是第乙個元素的值
int nval2=*(p+1); //相當於nval2=arr[1],p指向陣列首位址,加1則向後偏移乙個元素,再取*就是該指向的內容,即值
11.const修飾的指標
①const在星號左邊:修飾的是指標指向的記憶體。
a.指標可以改變指向
b.不可以通過指標改變其指向記憶體的值
②const在星號右邊:修飾的是指標變數本身。
a.指標不可以改變指向
b.可以通過指標改變其所指向記憶體的值
③星號左右兩邊都有const
a.指標不可以改變指向
b.不可以通過指標改變其所指向記憶體的值
例子:
const int *p; //值不可以改變
int const *p; //值不可以改變
int *const p; //指向不可以改變
const int *const p;//指向和值均不可改變
12.指標與字串
字元陣列表示的字串,可以用字元指標指向它,這樣這個指標就可以表示這個字串(指標指向的是字串的首位址,與①②③指標和一維陣列類似)。
13.指標與函式
①指標變數作為函式引數:將指標變數以實參的形式傳遞給函式,進行的是位址傳遞,所以在函式中可以改變實參的值。
②陣列名作為函式的形參和實參:進行的位址傳遞(陣列作引數進行傳遞時,相當於指標,其記憶體大小也會退化為指標記憶體的大小)。
指標傳遞的優點在於:可以跨棧傳遞,在函式內部可以修改實參的值。
③函式的返回值是乙個指標:那麼函式的返回值型別必須定義為乙個指標型別。
14.指向函式的指標
定義指向函式的指標變數的格式為:
①.資料型別 (*指標變數名) (形參列表)
float (*p)(float x, float y); //括號不能省略,這是定義了乙個指向函式的指標變數
float *p(float x,float y); //這是乙個返回值為指標型別的函式宣告
15.指標與二維陣列
用指標訪問二位陣列:
int array[2][3]=,};
int (*p)[2][3]=null;
p=&array; //*p==array,p[0]=*p
array[0][0]==(*p)[0][0];
p[0][0][0]==array[0][0];
p[0][0][1]==array[0][1];
p[0]==array;
p[0][0]==array[0]==*(p[0]+0);
p[0][1]==array[1]==*(p[0]+1);
//看到這裡是不是一臉懵??看看下面的你就懂了!
p+1; //跨過6*4個位元組,p是指向二維陣列的指標,偏移將是乙個二維陣列的長度
p[0]+1; //跨過3*4個位元組,p[0]是指向一維陣列的指標
p[0][0]+1; //跨過4個位元組,p[0][0]是指向陣列元素的指標
p[0][0][0]+1; //二位陣列第乙個元素值加1,這是取的素組元素的值
16.指標的指標(二維指標、多維指標)
如果乙個指標變數存放的又是另乙個指標變數的位址,則稱這個指標變數為指向指標的指標變數。
int number=10;
int *p=&number; //那麼*p==number
int *pp=&p; //那麼*pp==p, *(*pp)==number
17.陣列指標
定義方式:型別名稱 (*指標名) [陣列長度]
int a[5]=;
int (*p)[5]=&a;
定義時不能省略括號,因為[ ]的優先順序比*高,如果沒有括號就成了指標陣列。陣列指標定義時的陣列長度、元素型別必須與指向的陣列長度、型別保持一致。
int (*p)[5]; //指向陣列長度為5的整型陣列的指標
char *(*p)[10]; //指向陣列型別為char *,長度為10的陣列指標
int *p[10]; //乙個型別為int *,長度為10的陣列
陣列指標指向的是整個陣列,而不是陣列元素,所以指標運算p+1相當於p+1*sizeof(陣列名)。
int (*p)[5]; //*(p+1)跳過5*sizeof(int)個記憶體位置
int *p; //p+1指向下乙個元素,即指向記憶體加sizeof(int)即4個位元組
訪問陣列元素的方式:
int arr[5]=;
int (*p)[5]=&arr;
int *p1=arr;
(*p)[1]==p[0][1]==2;
arr[1]==*(arr+1)==2;
*(p1+1)==p1[1]==2;
指標確實有點難理解,不過多用一下,實戰一下對理解指標有莫大益處。 C語言學習筆記 指標基礎
在程式中使用的變數,常量,甚至函式等資料都會被載入到記憶體,而在記憶體中每乙個位元組都會有乙個位址位對應,指標變數就是用來儲存這些位址的變數 c語言中,定義變數時,在變數名 前 寫乙個 星號,這個變數就變成了對應變數型別的指標變數,指標變數因其所佔記憶體不同也分多種型別,此特性在指標運算時顯得尤為重...
c語言筆記 指標基礎
char pa 定義乙個指向字元型的指標變數 int pb 定義乙個指向整型的指標變數 char pa a int pb f char pa a int pb f printf c,d n pa,pb 綜合舉個栗子 define crt secure no warnings 這個是vs2017特有的...
三 學習筆記 c語言基礎 指標
1.定義指標變數 資料在記憶體中的位址也稱為指標,如果乙個變數儲存了乙份資料的指標,我們就稱它為指標變數。int a 1 int p a 通過指標變數p獲取資料 printf d p 星號 主要有三種用途 1 表示乘法,例如int a 1,b 2,c c a b 這是最容易理解的 2 表示定義乙個指...