14-一級指針和多級指針-指趣學(xué)院

指針基本概念

  • 什么是地址

    • 生活中的地址:


    • 內(nèi)存地址:


  • 地址與內(nèi)存單元中的數(shù)據(jù)是兩個(gè)完全不同的概念

    • 地址如同房間編號, 根據(jù)這個(gè)編號我們可以找到對應(yīng)的房間
    • 內(nèi)存單元如同房間, 房間是專門用于存儲數(shù)據(jù)的
  • 變量地址:

    • 系統(tǒng)分配給"變量"的"內(nèi)存單元"的起始地址
int num = 6; // 占用4個(gè)字節(jié)
//那么變量num的地址為: 0ff06

char c = 'a'; // 占用1個(gè)字節(jié)
//那么變量c的地址為:0ff05

什么是指針

  • 在計(jì)算機(jī)中所有數(shù)據(jù)都存儲在內(nèi)存單元中,而每個(gè)內(nèi)存單元都有一個(gè)對應(yīng)的地址, 只要通過這個(gè)地址就能找到對應(yīng)單元中存儲的數(shù)據(jù).

  • 由于通過地址能找到所需的變量單元汪诉,所以我們說該地址指向了該變量單元窗看。將地址形象化的稱為“指針”

  • 內(nèi)存單元的指針(地址)和內(nèi)存單元的內(nèi)容是兩個(gè)不同的概念。



什么是指針變量

  • 在C語言中,允許用一個(gè)變量來存放其它變量的地址, 這種專門用于存儲其它變量地址的變量, 我們稱之為指針變量


  • 示例:

    int age;// 定義一個(gè)普通變量
    num = 10;
    int *pnAge; // 定義一個(gè)指針變量
    pnAge = &age;

定義指針變量的格式

  • 指針變量的定義包括兩個(gè)內(nèi)容:
    • 指針類型說明,即定義變量為一個(gè)指針變量;
    • 指針變量名;


  • 示例:
char ch = 'a';
char *p; // 一個(gè)用于指向字符型變量的指針
p = &ch;  
int num = 666;
int *q; // 一個(gè)用于指向整型變量的指針
q = #  
  • 其中,*表示這是一個(gè)指針變量
  • 變量名即為定義的指針變量名
  • 類型說明符表示本指針變量所指向的變量的數(shù)據(jù)類型

指針變量的初始化方法

  • 指針變量初始化的方法有兩種:定義的同時(shí)進(jìn)行初始化和先定義后初始化
    • 定義的同時(shí)進(jìn)行初始化
int a = 5;
int *p = &a;
    • 先定義后初始化
int a = 5;
int *p;
p=&a;
    • 把指針初始化為NULL
int *p=NULL;
int *q=0;
  • 不合法的初始化:
    • 指針變量只能存儲地址, 不能存儲其它類型
int *p;
p =  250; // 錯(cuò)誤寫法
    • 給指針變量賦值時(shí),指針變量前不能再加“*”
int *p;
*p=&a; //錯(cuò)誤寫法
  • 注意點(diǎn):

    • 多個(gè)指針變量可以指向同一個(gè)地址


  • 指針的指向是可以改變的

int a = 5;
int *p = &a;
int b = 10;
p = &b; // 修改指針指向
  • 指針沒有初始化里面是一個(gè)垃圾值,這時(shí)候我們這是一個(gè)野指針
    • 野指針可能會導(dǎo)致程序崩潰
    • 野指針訪問你不該訪問數(shù)據(jù)
    • 所以指針必須初始化才可以訪問其所指向存儲區(qū)域



訪問指針?biāo)赶虻拇鎯臻g

  • C語言中提供了地址運(yùn)算符&來表示變量的地址腰耙。其一般形式為:
    • &變量名;
  • C語言中提供了*來定義指針變量和訪問指針變量指向的內(nèi)存存儲空間
    • 在定義變量的時(shí)候 * 是一個(gè)類型說明符,說明定義的這個(gè)變量是一個(gè)指針變量
int *p=NULL; // 定義指針變量
    • 在不是定義變量的時(shí)候 *是一個(gè)操作符,代表訪問指針?biāo)赶虼鎯臻g
int a = 5;
int *p = &a;
printf("a = %d", *p); // 訪問指針變量

指針類型

  • 在同一種編譯器環(huán)境下,一個(gè)指針變量所占用的內(nèi)存空間是固定的。


  • 雖然在同一種編譯器下, 所有指針占用的內(nèi)存空間是一樣的,但不同類型的變量卻占不同的字節(jié)數(shù)

    • 一個(gè)int占用4個(gè)字節(jié)彤恶,一個(gè)char占用1個(gè)字節(jié),而一個(gè)double占用8字節(jié)越驻;
    • 現(xiàn)在只有一個(gè)地址叽掘,我怎么才能知道要從這個(gè)地址開始向后訪問多少個(gè)字節(jié)的存儲空間呢楣铁,是4個(gè),是1個(gè)更扁,還是8個(gè)民褂。
    • 所以指針變量需要它所指向的數(shù)據(jù)類型告訴它要訪問多少個(gè)字節(jié)存儲空間



二級指針

  • 如果一個(gè)指針變量存放的又是另一個(gè)指針變量的地址,則稱這個(gè)指針變量為指向指針的指針變量。也稱為“二級指針”
    char c = 'a';
    char *cp;
    cp = &c;
    char **cp2;
    cp2 = &cp;
    printf("c = %c", **cp2);
  • 多級指針的取值規(guī)則
int ***m1;  //取值***m1
int *****m2; //取值*****m2

練習(xí)

  • 定義一個(gè)函數(shù)交換兩個(gè)變量的值
  • 寫一個(gè)函數(shù)疯潭,同時(shí)返回兩個(gè)數(shù)的和與差

數(shù)組指針的概念及定義

  • 數(shù)組元素指針
    • 一個(gè)變量有地址,一個(gè)數(shù)組包含若干元素,每個(gè)數(shù)組元素也有相應(yīng)的地址, 指針變量也可以保存數(shù)組元素的地址
    • 只要一個(gè)指針變量保存了數(shù)組元素的地址, 我們就稱之為數(shù)組元素指針


    printf(“%p %p”, &(a[0]), a); //輸出結(jié)果:0x1100, 0x1100
  • 注意: 數(shù)組名a不代表整個(gè)數(shù)組,只代表數(shù)組首元素的地址赊堪。
  • “p=a;”的作用是“把a(bǔ)數(shù)組的首元素的地址賦給指針變量p”,而不是“把數(shù)組a各元素的值賦給 p”

指針訪問數(shù)組元素

    int main (void)
{
      int a[5] = {2, 4, 6, 8, 22};
      int *p;
      // p = &(a[0]); 
      p = a;
      printf(“%d %d\n”,a[0],*p); // 輸出結(jié)果: 2, 2
}

  • 在指針指向數(shù)組元素時(shí),允許以下運(yùn)算:
    • 加一個(gè)整數(shù)(用+或+=),如p+1
    • 減一個(gè)整數(shù)(用-或-=),如p-1
    • 自加運(yùn)算,如p++,++p
    • 自減運(yùn)算,如p--,--p
  • 如果指針變量p已指向數(shù)組中的一個(gè)元素,則p+1指向同一數(shù)組中的下一個(gè)元素,p-1指向同 一數(shù)組中的上一個(gè)元素衅鹿。
  • 結(jié)論: 訪問數(shù)組元素,可用下面兩種方法:
    • 下標(biāo)法, 如a[i]形式
    • 指針法, *(p+i)形式
  • 注意:
    • 數(shù)組名雖然是數(shù)組的首地址截粗,但是數(shù)組名所所保存的數(shù)組的首地址是不可以更改的
    int x[10];
    x++;  //錯(cuò)誤
    int* p = x;
    p++; //正確

指針與字符串

  • 定義字符串的兩種方式
    • 字符數(shù)組
char string[]=”I love lnj!”;
printf("%s\n",string);
    • 字符串指針指向字符串
// 數(shù)組名保存的是數(shù)組第0個(gè)元素的地址, 指針也可以保存第0個(gè)元素的地址
char *str = "abc"
  • 字符串指針使用注意事項(xiàng)
    • 可以查看字符串的每一個(gè)字符
har *str = "lnj";
for(int i = 0; i < strlen(str);i++)
{
  printf("%c-", *(str+i)); // 輸出結(jié)果:l-n-j
}
    • 不可以修改字符串內(nèi)容
//   + 使用字符數(shù)組來保存的字符串是保存棧里的,保存棧里面東西是可讀可寫,所有可以修改字符串中的的字符
//   + 使用字符指針來保存字符串,它保存的是字符串常量地址,常量區(qū)是只讀的,所以我們不可以修改字符串中的字符
char *str = "lnj";
*(str+2) = 'y'; // 錯(cuò)誤
    • 不能夠直接接收鍵盤輸入
// 錯(cuò)誤的原因是:str是一個(gè)野指針,他并沒有指向某一塊內(nèi)存空間
// 所以不允許這樣寫如果給str分配內(nèi)存空間是可以這樣用 的
char *str;
scanf("%s", str);

指向函數(shù)指針

  • 為什么指針可以指向一個(gè)函數(shù)固灵?
    • 函數(shù)作為一段程序胧辽,在內(nèi)存中也要占據(jù)部分存儲空間喻粹,它也有一個(gè)起始地址
    • 函數(shù)有自己的地址凑保,那就好辦了烦感,我們的指針變量就是用來存儲地址的忠蝗。
    • 因此可以利用一個(gè)指針指向一個(gè)函數(shù)增淹。其中椿访,函數(shù)名就代表著函數(shù)的地址。
  • 指針函數(shù)的定義
    • 格式: 返回值類型 (*指針變量名)(形參1, 形參2, ...);
    int sum(int a,int b)
    {
        return a + b;
    }

    int (*p)(int,int);
    p = sum;
  • 指針函數(shù)定義技巧

    • 1虑润、把要指向函數(shù)頭拷貝過來
    • 2成玫、把函數(shù)名稱使用小括號括起來
    • 3、在函數(shù)名稱前面加上一個(gè)*
    • 4拳喻、修改函數(shù)名稱
  • 應(yīng)用場景

    • 調(diào)用函數(shù)
    • 將函數(shù)作為參數(shù)在函數(shù)間傳遞
  • 注意點(diǎn):

    • 由于這類指針變量存儲的是一個(gè)函數(shù)的入口地址哭当,所以對它們作加減運(yùn)算(比如p++)是無意義的
    • 函數(shù)調(diào)用中"(指針變量名)"的兩邊的括號不可少,其中的不應(yīng)該理解為求值運(yùn)算,在此處它 只是一種表示符號
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市冗澈,隨后出現(xiàn)的幾起案子钦勘,更是在濱河造成了極大的恐慌,老刑警劉巖亚亲,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件彻采,死亡現(xiàn)場離奇詭異腐缤,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)肛响,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進(jìn)店門岭粤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人终惑,你說我怎么就攤上這事绍在。” “怎么了雹有?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵偿渡,是天一觀的道長。 經(jīng)常有香客問我霸奕,道長溜宽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任质帅,我火速辦了婚禮适揉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘煤惩。我一直安慰自己嫉嘀,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布魄揉。 她就那樣靜靜地躺著剪侮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪洛退。 梳的紋絲不亂的頭發(fā)上瓣俯,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天,我揣著相機(jī)與錄音兵怯,去河邊找鬼彩匕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛媒区,可吹牛的內(nèi)容都是我干的驼仪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼驻仅,長吁一口氣:“原來是場噩夢啊……” “哼谅畅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起噪服,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎胜茧,沒想到半個(gè)月后粘优,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體仇味,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年雹顺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了丹墨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,030評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡嬉愧,死狀恐怖贩挣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情没酣,我是刑警寧澤王财,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站裕便,受9級特大地震影響绒净,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜偿衰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一挂疆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧下翎,春花似錦缤言、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至郑口,卻和暖如春鸳碧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背犬性。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工瞻离, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人乒裆。 一個(gè)月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓套利,卻偏偏與公主長得像,于是被迫代替她去往敵國和親鹤耍。 傳聞我的和親對象是個(gè)殘疾皇子肉迫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 指針是C語言中廣泛使用的一種數(shù)據(jù)類型。 運(yùn)用指針編程是C語言最主要的風(fēng)格之一稿黄。利用指針變量可以表示各種數(shù)據(jù)結(jié)構(gòu)喊衫; ...
    朱森閱讀 3,446評論 3 44
  • 第十章 指針 1. 地址指針的基本概念: 在計(jì)算機(jī)中,所有的數(shù)據(jù)都是存放在存儲器中的杆怕。一般把存儲器中的一個(gè)字節(jié)稱為...
    堅(jiān)持到底v2閱讀 1,070評論 2 3
  • 太陽下族购, 每一個(gè)影子壳贪, 清晰可見。 塵世中的你啊寝杖, 可曾看清自己的影子……
    小劇在成長閱讀 293評論 0 2
  • 你總是在我快跟你失聯(lián)的時(shí)候發(fā)消息給我违施,說我最想聽的話,講我最關(guān)注的事瑟幕,我還能說什么呢磕蒲?
    遠(yuǎn)方安然閱讀 113評論 0 0