一征懈、指針簡(jiǎn)介
1、什么是指針揩悄?
指針是一個(gè)變量卖哎,其值為另一個(gè)變量的地址,即內(nèi)存地址的直接地址删性。做個(gè)比喻亏娜,假設(shè)將你比作變量,那么你身份證上的住址就是指針蹬挺,根據(jù)你身份證上的地址可以找到你维贺,即指針存的內(nèi)容是你身份證上的住址。
指針有兩種含義巴帮,一是作為數(shù)據(jù)類型溯泣,二是作為實(shí)體。
指針作為實(shí)體榕茧,是一個(gè)用來保存一個(gè)內(nèi)存地址的計(jì)算機(jī)語言中的變量垃沦。指針一般出現(xiàn)在比較底層的程序設(shè)計(jì)語言中,如C語言用押。高級(jí)語言如Java一般避免用指針肢簿,而是引用。指針作為數(shù)據(jù)類型只恨,可以從一個(gè)函數(shù)類型译仗、一個(gè)對(duì)象類型或者一個(gè)不完備類型中導(dǎo)出。從中導(dǎo)出的數(shù)據(jù)類型稱之為被引用類型(referenced type)官觅。指針類型描述了一種對(duì)象纵菌,其值為對(duì)被引用類型的實(shí)體的引用。
指針可以用來有效地表示復(fù)雜的數(shù)據(jù)結(jié)構(gòu),可以用于函數(shù)參數(shù)傳遞并達(dá)到更加靈活使用函數(shù)的目的休涤。使C語言程序的設(shè)計(jì)具有靈活咱圆、實(shí)用笛辟、高效的特點(diǎn)。
2序苏、*與&操作符
取地址運(yùn)算符(&):取變量的地址手幢,即返回操作數(shù)的內(nèi)存地址。&var 讀作"var 的地址"忱详。
間接尋址運(yùn)算符(*):返回操作數(shù)所指定地址的變量的值围来。
3、如何使用指針匈睁?
使用指針時(shí)會(huì)頻繁進(jìn)行以下幾個(gè)操作:
- 定義一個(gè)指針變量监透;
- 把變量地址賦值給指針;
- 訪問指針變量中可用地址的值航唆。
這些是通過使用一元運(yùn)算符 * 來返回位于操作數(shù)所指定地址的變量的值胀蛮。
#include <stdio.h>
int main (){
int var = 20; /* 實(shí)際變量的聲明 */
int *ip;/* 指針變量的聲明 */
ip = &var; /* 在指針變量中存儲(chǔ) var 的地址 */
printf("Address of var variable: %x\n", &var );
/* 在指針變量中存儲(chǔ)的地址 */
printf("Address stored in ip variable: %x\n", ip );
/* 使用指針訪問值 */
printf("Value of *ip variable: %d\n", *ip );
return 0;
}
當(dāng)上面的代碼被編譯和執(zhí)行時(shí),它會(huì)產(chǎn)生下列結(jié)果:
Address of var variable: bffd8b3c
Address stored in ip variable: bffd8b3c
Value of *ip variable: 20
4糯钙、指針運(yùn)算符
C 指針是一個(gè)用數(shù)值表示的地址粪狼。因此,您可以對(duì)指針執(zhí)行算術(shù)運(yùn)算任岸≡匍可以對(duì)指針進(jìn)行四種算術(shù)運(yùn)算:++、--演闭、+不跟、-。
假設(shè) ptr 是一個(gè)指向地址 1000 的整型指針米碰,是一個(gè) 32 位的整數(shù)窝革,讓我們對(duì)該指針執(zhí)行下列的算術(shù)運(yùn)算:
ptr++
在執(zhí)行完上述的運(yùn)算之后,ptr 將指向位置 1004吕座,因?yàn)?ptr 每增加一次虐译,它都將指向下一個(gè)整數(shù)位置,即當(dāng)前位置往后移 4 個(gè)字節(jié)吴趴。這個(gè)運(yùn)算會(huì)在不影響內(nèi)存位置中實(shí)際值的情況下漆诽,移動(dòng)指針到下一個(gè)內(nèi)存位置。如果 ptr 指向一個(gè)地址為 1000 的字符锣枝,上面的運(yùn)算會(huì)導(dǎo)致指針指向位置 1001厢拭,因?yàn)橄乱粋€(gè)字符位置是在 1001。
5撇叁、NULL 指針
在變量聲明的時(shí)候供鸠,如果沒有確切的地址可以賦值,為指針變量賦一個(gè) NULL 值是一個(gè)良好的編程習(xí)慣陨闹。賦為 NULL 值的指針被稱為空指針楞捂。NULL 指針是一個(gè)定義在標(biāo)準(zhǔn)庫中的值為零的常量薄坏。請(qǐng)看下面的程序:
#include <stdio.h>
int main (){
int *ptr = NULL;
printf("ptr 的值是 %x\n", ptr );
return 0;
}
當(dāng)上面的代碼被編譯和執(zhí)行時(shí),它會(huì)產(chǎn)生下列結(jié)果:
ptr 的值是 0
二寨闹、指針與數(shù)組
1胶坠、區(qū)別
C++/C程序中,指針和數(shù)組在不少地方可以相互替換著用繁堡,讓人產(chǎn)生一種錯(cuò)覺沈善,以為兩者是等價(jià)的。數(shù)組是連續(xù)分配一串單元椭蹄,數(shù)目開始定義的時(shí)候就必須固定下來矮瘟,看起來整潔,但是寫的程序是死程序塑娇,容易浪費(fèi)內(nèi)存。指針是存放一個(gè)地址值劫侧,表示指向某一個(gè)單元埋酬,可以用指針來索引單元。數(shù)組可以完成棧烧栋,堆写妥,樹等等的操作,它在編程時(shí)候的好處是非常的靈活审姓,在構(gòu)建思路的時(shí)候有很大的靈活性珍特。
2、指針數(shù)組與數(shù)組指針
指針數(shù)組:array of pointers魔吐,即用于存儲(chǔ)指針的數(shù)組扎筒,也就是數(shù)組元素都是指針。
數(shù)組指針:a pointer to an array酬姆,數(shù)組名本身就是一個(gè)指針嗜桌,指向數(shù)組的首地址,即指向數(shù)組的指針辞色。
int* a[4] 骨宠; /* 指針數(shù)組
表示:數(shù)組a中的元素都為int型指針
元素表示:*a[i] *(a[i])是一樣的,因?yàn)閇]優(yōu)先級(jí)高于*/
int (*a)[4] 相满;/* 數(shù)組指針
表示:指向數(shù)組a的指針
元素表示:(*a)[i] */
#include <stdio.h>
int main(void)
{
int c[4]={1,2,3,4};
int *a[4]; //指針數(shù)組
int (*b)[4]; //數(shù)組指針
b=&c;
//將數(shù)組c中元素賦給數(shù)組a
for(int i=0;i<4;i++)
{
a[i]=&c[i];
}
//輸出看下結(jié)果
printf("%d",*a[1]);//輸出2就對(duì)
printf("%d",(*b)[2]);//輸出3就對(duì)
return 0;
}
三层亿、指針與字符串
C語言中沒有特定的字符串類型,我們通常是將字符串放在一個(gè)字符數(shù)組中立美。字符數(shù)組歸根結(jié)底還是一個(gè)數(shù)組匿又,使用指針的方式來輸出字符串:
#include <stdio.h>
int main(){
char str[] = "http://www.reibang.com/";
char *pstr = str;
int len = strlen(str), i;
//使用*(pstr+i)
for(i=0; i<len; i++){
printf("%c", *(pstr+i));
}
printf("\n");
//使用pstr[i]
for(i=0; i<len; i++){
printf("%c", pstr[i]);
}
printf("\n");
//使用*(str+i)
for(i=0; i<len; i++){
printf("%c", *(str+i));
}
printf("\n");
return 0;
}
四、指針與函數(shù)
函數(shù)指針:本身是一個(gè)指針悯辙,指向一個(gè)函數(shù)入口地址琳省,通過該指針可調(diào)用其指向的函數(shù)迎吵,使用函數(shù)指針可實(shí)現(xiàn)回調(diào)函數(shù)。
#include <stdio.h>
void inc(int *val)
{
(*val)++;
}
int main(void)
{
void (*fun)(int *);
int a=3;
fun=inc;//fun是一個(gè)函數(shù)指針
(*fun)(&a);
printf("%d" , a);
}
指針函數(shù):本身是一個(gè)函數(shù)针贬,其返回值是一個(gè)指針击费。
#include <stdio.h>
float *find(float(*pionter)[4],int n);//函數(shù)聲明
int main(void)
{
static float score[][4]={{60,70,80,90},{56,89,34,45},{34,23,56,45}};
float *p;
int i,m;
printf("Enter the number to be found:");
scanf("%d",&m);
printf("the score of NO.%d are:\n",m);
p=find(score,m-1);
for(i=0;i<4;i++)
printf("%5.2f\t",*(p+i));
return 0;
}
float *find(float(*pionter)[4],int n)/*定義指針函數(shù)*/
{
float *pt;
pt=*(pionter+n);
return(pt);
}
五、指針與引用
- 引用總是指向一個(gè)對(duì)象,沒有所謂的 null reference 桦他。所有當(dāng)有可能指向一個(gè)對(duì)象也有可能不指向?qū)ο髣t必須使用指針蔫巩。由于C++ 要求 reference 總是指向一個(gè)對(duì)象所以 reference要求有初值.由于沒有所謂的 null reference 所以在使用前不需要進(jìn)行測(cè)試其是否有值,而使用指針則需要測(cè)試其的有效性快压。
- 指針可以被重新賦值而reference則總是指向最初或地的對(duì)象圆仔。
- 必須使用reference的場(chǎng)合.Operator[]操作符由于該操作符很特別地必須返回 [能夠被當(dāng)做ssignment 賦值對(duì)象] 的東西,所以需要給他返回一個(gè) reference。
- 其實(shí)引用在函數(shù)的參數(shù)中使用很經(jīng)常蔫劣。格式如下:
void Get***(const int& a){} //這樣使用了引用又可以保證不修改被引用的值
區(qū)別:
- 指針是一個(gè)實(shí)體指向一塊內(nèi)存坪郭,它的內(nèi)容是所指內(nèi)存的地址;引用是某塊內(nèi)存的別名脉幢;
- 引用使用時(shí)無需解引用(*)歪沃,指針需要解引用;
- 引用只能在定義時(shí)被初始化一次嫌松,之后不可變沪曙;指針可變;
- 引用“從一而終”萎羔;
- 引用沒有 const液走,指針有 const,const 的指針不可變贾陷;
- 引用不能為空缘眶,指針可以為空;
- sizeof 引用”得到的是所指向的變量(對(duì)象)的大小髓废,而“sizeof 指針”得到的是指針本身(所指向的變量或?qū)ο蟮牡刂?的大邪跽浮;typeid(T) == typeid(T&) 恒為真瓦哎,sizeof(T) == sizeof(T&) 恒為真砸喻,但是當(dāng)引用作為成員時(shí),其占用空間與指針相同(沒找到標(biāo)準(zhǔn)的規(guī)定)蒋譬;
- 指針和引用的自增(++)運(yùn)算意義不一樣割岛。