日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言基础指针知识点总结

發(fā)布時(shí)間:2024/3/12 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言基础指针知识点总结 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

指針入門,這一篇文章應(yīng)該就夠了。如有錯(cuò)誤或不足,還望多多指正。

文章目錄

  • 一、 基本概念
    • 1.1 地址
    • 1.2 指針
    • 1.3 為什么要使用指針這個(gè)東西呢
    • 1.4 指針變量的定義
      • 1.4.1 `*`
      • 1.4.2 `&`
      • 1.4.3 定義的關(guān)鍵
  • 二、指針與數(shù)組
    • 2.1 指向數(shù)組元素的指針
      • 2.1.1 數(shù)組元素地址賦值給指針變量
      • 2.1.2 指針運(yùn)算
        • 2.1.2.1 數(shù)組元素指針加或減
        • 2.1.2.2 數(shù)組元素指針之間加減(注意,只有加減沒有乘除)
        • 2.1.2.3
    • 2.2 指針數(shù)組
  • 三、指針與函數(shù)
    • 3.1 返回值是指針的函數(shù)
    • 3.2 指向函數(shù)的指針變量
  • 四、指針和結(jié)構(gòu)體
    • 4.1 結(jié)構(gòu)體變量成員的引用
    • 4.2 指針與結(jié)構(gòu)體

一、 基本概念

1.1 地址


地址:這里以int類型為例,

因?yàn)橐粋€(gè)int類型4個(gè)字節(jié)Byte(32位和64位機(jī)器中)
所以可以簡單理解為這個(gè)int占了四個(gè)綠色小方框。

那么此時(shí),這個(gè)int變量的地址就是1000,即第一個(gè)綠色小方框右邊的數(shù)字。
即就是:這個(gè)綠色方框在內(nèi)存中所處的位置。

1.2 指針

指針:還是這個(gè)例子

那指針就是一個(gè)變量,比如這個(gè)變量名就叫p吧。
那這個(gè)p是個(gè)啥東西呢?
把這個(gè)1000存到p里去,即,把int類型變量a的地址存進(jìn)新的變量p中。
那么p這個(gè)變量就是一個(gè)指向a的指針。

通俗理解下就是:
小明是個(gè)舔狗,喜歡小a,但是他比較害羞,不敢直接找小a。
所以小明就找到了小p。為什么找小p呢,因?yàn)樾有小a家的地址。
這樣小明就可以把給小a送的東西放小a家門口了。

這里的小a和小p就相當(dāng)于例子中的int類型的a變量和指向a的指針p。
我只要找到了p就相當(dāng)于找到了a

1.3 為什么要使用指針這個(gè)東西呢

首先我們要明白一直知識(shí)點(diǎn):

需要說明一下的是指針類型存儲(chǔ)的是所指向變量的地址:
所以32位機(jī)器只需要32bit,而64位機(jī)器需要 64bit

由此可知,在一臺(tái)電腦上,所有指針大小都是一樣的。
那么,當(dāng)我們定義了一些非常復(fù)雜龐大的結(jié)構(gòu)體,比如這個(gè)結(jié)構(gòu)體有50個(gè)字節(jié)(Byte)。
這時(shí)候,向函數(shù)中傳入?yún)?shù)的時(shí)候,是直接把這個(gè)50個(gè)字節(jié)的數(shù)據(jù)的副本傳遞到形參上快?
還是,直接傳遞32bit或者64bit的指針快呢??

很明顯,傳入指針可以大大大大提高運(yùn)算的效率。

1.4 指針變量的定義

剛才說了,指針變量是來保存別的變量地址的一種變量。那該如何定義呢?
如何讓計(jì)算機(jī)一眼認(rèn)出來這一串?dāng)?shù)字是地址,而不是普通的數(shù)字呢?

基本格式:
基本類型 *指針變量名 = &變量名;
(也可以先省略=后面的內(nèi)容,先只定義,不賦值,但是還是建議定義的時(shí)候就進(jìn)行賦值)

//定義變量: int a = 666; char b = 'b';//定義指針變量: //1.告訴計(jì)算機(jī)這是一個(gè)保存int類型數(shù)據(jù)地址的指針變量 int *pa = &a;//2.告訴計(jì)算機(jī)這是一個(gè)保存char字符類型數(shù)據(jù)地址的指針變量 char *pb= &b;

上面的代碼,我定義了兩個(gè)指針變量,一個(gè)是p一個(gè)是p2。
看見了兩個(gè)奇怪的符號(hào)*和&

1.4.1 *

這個(gè)符號(hào),為取值運(yùn)算符
啥是取值運(yùn)算符呢?

就是,我現(xiàn)在有了指針,指針里存的是一個(gè)變量的地址,
我現(xiàn)在要通過地址取到這個(gè)變量的值。

注意:指針里存的是地址,就是通過這個(gè)地址找到這個(gè)地址住的誰。
舉例
比如上面的代碼中,pa這個(gè)變量存的是a的地址,變量a中存的是666。
那么*pa就可以相當(dāng)于666。

所以可以明確一點(diǎn)。取值運(yùn)算符會(huì)和指針變量連用。
為啥呢?
因?yàn)槲覀円ㄟ^地址取地址所指向的變量中存放的值呀!

如果還不明白沒關(guān)系,在說完&后我對(duì)上面的代碼解釋說明一下。

1.4.2 &

這個(gè)符號(hào),為取地址運(yùn)算符

這個(gè)就很簡單了。一個(gè)int變量名叫a存的是666
我給a前面加上&,變成
&a
那么這個(gè)&a就不是666啦。而是,存666的那個(gè)內(nèi)存的地址。

所以我們又可以明確一點(diǎn)。取地址運(yùn)算符會(huì)和一般變量(非指針變量)連用。
為啥呢?
因?yàn)橹羔樧兞恳呀?jīng)是地址了,一般情況我們不需要取地址的地址,即指針的地址。
我們要的是什么。是普通變量的地址。

所以,下面這個(gè)代碼可以這么理解:

int a = 666; int *pa = &a;

先定義一個(gè)int變量a 里面存著666.
第二行咱們叢后往前看:
&a是取地址,所以說,=后面就是一個(gè)地址。
然后我們理解pa = &a:
這其實(shí)就相當(dāng)于pa里面存的是變量a的地址。
然后,pa前面加上*構(gòu)成了*pa
*pa是什么,是把pa地址中存的整型變量a取出來了。
所以*pa其實(shí)就是666,相當(dāng)于一個(gè)整型變量。
然后,最前面是int。int后面的*pa也可以理解為一個(gè)int類型的變量。

(這是我本人的一種理解方式,只希望大家能更快理解這個(gè)式子,可能底層并不是我這樣的,哈哈)

1.4.3 定義的關(guān)鍵

  • 最好定義的時(shí)候就對(duì)指針進(jìn)行賦值
  • int類型的指針只能存int類型變量的地址,char類型的指針只能存char類型的地址,要對(duì)應(yīng)起來

二、指針與數(shù)組

指針與數(shù)組分成兩個(gè)方面:

一、指向數(shù)組元素的指針
二、指針數(shù)組(數(shù)組元素是指針)

2.1 指向數(shù)組元素的指針

2.1.1 數(shù)組元素地址賦值給指針變量

首先我們要知道

數(shù)組名,其實(shí)就是這個(gè)數(shù)組下標(biāo)為0的數(shù)組元素的地址。
這個(gè)地址也就是這個(gè)數(shù)組的地址。

所以,數(shù)組給指針復(fù)試和數(shù)組元素給指針賦值很不一樣。
因?yàn)?#xff0c;指針只能存地址。
數(shù)組名本身就保存的地址,所以就直接可以給指針變量賦值。
數(shù)組的元素保存的就是具體的內(nèi)容了,可能為int可能為char。
所以,數(shù)組元素賦值的時(shí)候,就要先用取地址符&得到這個(gè)元素的地址,然后再給指針變量賦值。

int c[10], d[20]; int *p, *q=&c[0];p = &c[3];//數(shù)組c下標(biāo)為3的元素賦值給指針P p = d;//整個(gè)數(shù)組的地址賦值給指針p

2.1.2 指針運(yùn)算

眾所周知,數(shù)組,存在內(nèi)存中一片地址連續(xù)的區(qū)域中
即就是說,數(shù)組,在邏輯上是一個(gè)元素挨著一個(gè)元素,在物理存儲(chǔ)上也是一個(gè)元素挨著一個(gè)元素的。

2.1.2.1 數(shù)組元素指針加或減

所以,當(dāng)指針變量指向數(shù)組元素時(shí),指針變量加/減一個(gè)整數(shù)n,表示指針向后/前移動(dòng)n個(gè)元素!

注意,這里+n是移動(dòng)一個(gè)元素,不是移動(dòng)n個(gè)字節(jié)
當(dāng)然,移動(dòng)幾個(gè)元素就指針的具體值就增加或減少這個(gè)幾個(gè)元素所占的字節(jié)數(shù)
比如:int 數(shù)組中,指針指向某個(gè)元素,然后給這個(gè)指針+2
那么這個(gè)指針本身的值就應(yīng)該加幾?
一個(gè)int元素占4個(gè)字節(jié),倆就是8個(gè)字節(jié),
那么地址字節(jié)值就要加8

看例子:

int c[20]; int *p1 = &c[9]; p1--; p1+=3;

2.1.2.2 數(shù)組元素指針之間加減(注意,只有加減沒有乘除)

相減得到的這個(gè)數(shù)字是這兩個(gè)地址之間相差的字節(jié)數(shù)。
然后,用這個(gè)字節(jié)數(shù),除以每個(gè)元素所占的字節(jié)數(shù)。
就可以得出這兩個(gè)地址之間相差幾個(gè)元素。

2.1.2.3

我們?cè)趶?fù)習(xí)一下:
數(shù)組名,就是這個(gè)數(shù)組的首地址,也是這個(gè)數(shù)組中下標(biāo)為0元素的地址。

好了,那如果我們把這個(gè)數(shù)組的首地址保存在一個(gè)指針變量中,然后對(duì)這個(gè)指針變量直接+或者-
這樣是不是就可以遍歷數(shù)組了呢?

C語言將數(shù)組元素中的[ ]稱為變址運(yùn)算符
一維數(shù)組元素b[j]的表示形式等價(jià)于*(b+j)
(大家不要忘記*是取值運(yùn)算符哦,就是把這個(gè)地址中存的具體的值取出來)

舉例:

int b[20],*p = b; //數(shù)組元素b[j]還有下面兩種表示方式 //*(p+j) //*(b+j) //p[j] 注意:指針變量也是可以帶下標(biāo)的,但是一般只有在數(shù)組上才這么用

**注意:**數(shù)組名b是符號(hào)常量,所以,不能給b賦值。這個(gè)b就類似于函數(shù)的名字一樣,我們不能隨便改變已經(jīng)定義好的函數(shù)的名字。

空指針:

C語言設(shè)置了一個(gè)指針常量NULL,稱為空指針。空指針不指向任何存儲(chǔ)單元。
空指針可以賦值給任何指針類型的變量。

2.2 指針數(shù)組

整形數(shù)組中,數(shù)組元素都是整型
字符數(shù)組中,數(shù)組元素都是字符
指針數(shù)組中,數(shù)組元素都是指針

int i = 1; int j = 2; int k = 3; int l = 4; int *p[4] = {&i, &j, &k, Kl};//單目運(yùn)算符,同優(yōu)先級(jí)的情況下,叢右往左進(jìn)行運(yùn)算 //[]先與p結(jié)合,表示這是一個(gè)數(shù)組 //*再與p[]結(jié)合,表示這個(gè)數(shù)組元素類型是指針 //最后加上前面的int,表示這個(gè)int類型的指針

注意區(qū)分兩個(gè)概念:

int (*p)[5]; //這里*先與p結(jié)合,表示p是一個(gè)指針,這個(gè)指針指向這個(gè)數(shù)組,這個(gè)數(shù)組是int類型的數(shù)組int *p[5];//這個(gè)表示指針數(shù)組,每個(gè)元素都是指針,上面說過了

三、指針與函數(shù)

3.1 返回值是指針的函數(shù)

指針函數(shù):
函數(shù)的返回值的類型既可以是整型(若沒有設(shè)定,則默認(rèn)為整型),實(shí)型,字符型,也可以是指針型。
返回值為指針類型的函數(shù)又稱為指針類型的函數(shù),建成指針函數(shù)。

具體定義格式如下:
類型名 *函數(shù)名(參數(shù)表)

int *a(int x) //解釋一下 //這里函數(shù)名先和()結(jié)合,表示這是一個(gè)函數(shù) //然后a()再和前面的*結(jié)合,表示這是一個(gè)指針類型的函數(shù)。 //最后與前面的int結(jié)合,表示這是int指針類型的函數(shù),返回值是指針//(這個(gè)過程有點(diǎn)類似前面的指針數(shù)組,可以翻上去復(fù)習(xí)一下)

3.2 指向函數(shù)的指針變量

c語言的每個(gè)函數(shù)的編譯的時(shí)候,都分配了一段連續(xù)的內(nèi)存空間和一個(gè)入口地址,
這個(gè)入口地址就稱為“指向函數(shù)的指針”,即函數(shù)指針。

可以用一個(gè)變量來存儲(chǔ)函數(shù)指針,這個(gè)變量就稱為“指向函數(shù)的指針變量”或者函數(shù)指針變量。

通過函數(shù)指針變量 就可以調(diào)用所指向的函數(shù),改變它的值就可以動(dòng)態(tài)調(diào)用不同的函數(shù)。

一般定義形式
類型說明符 (*變量名)()
eg:

int (*p)(); //說明一下: //p先和*結(jié)合(括號(hào)的運(yùn)算優(yōu)先級(jí)高),表明該變量名是指針變量 //然后(*p)后面的括號(hào)表示該指針變量指向一個(gè)函數(shù) //最前面的int 表明這個(gè)函數(shù)返回值類型為Int //這個(gè)變量p是專門用來存放整型函數(shù)的入口地址的
  • 函數(shù)指針變量定義時(shí),并不指向哪一個(gè)具體的函數(shù),而是指向空指針。

那如何通過函數(shù)指針變量調(diào)用函數(shù)呢?

那就是讓函數(shù)指針變量p指向一個(gè)具體的函數(shù),即將某個(gè)函數(shù)的入口地址賦值給這個(gè)指針變量。

那一般函數(shù)的入口地址在哪里呢?

函數(shù)名就代表函數(shù)的入口地址,是函數(shù)指針類型的符號(hào)常量。(這里和數(shù)組有點(diǎn)類似,數(shù)組名也是數(shù)組的地址。)

//ok 比如現(xiàn)在有個(gè)函數(shù),函數(shù)名叫abc,就可以對(duì)函數(shù)指針變量p賦值了 p = abc;

那賦值給函數(shù)指針變量p以后,如何使用p來調(diào)用這個(gè)函數(shù)呢?

還記得我們的取值運(yùn)算符*嗎?
本來調(diào)用函數(shù)應(yīng)該是這樣的
函數(shù)名();
那現(xiàn)在,函數(shù)名的位置用*函數(shù)指針變量名來代替就可以啦
剩下的就和普通函數(shù)的使用方式基本一樣啦。

四、指針和結(jié)構(gòu)體

4.1 結(jié)構(gòu)體變量成員的引用

typedef struct student{char name[21];int age;char sex;float score; };student st1; //現(xiàn)在給第一個(gè)學(xué)生的年齡賦值 st1.age = 20; //普通結(jié)構(gòu)體引用成員的時(shí)候使用. //.前面是定義的結(jié)構(gòu)體變量,.后面是要引用的結(jié)構(gòu)體中的成員

4.2 指針與結(jié)構(gòu)體

結(jié)構(gòu)體類型是一種構(gòu)造類型,與簡單類型(int、float和char等)一樣,也可以定義為指針變量,定義方法也相同。

typedef struct student{char name[21];int age;char sex;float score; }student,*stu; //這里解釋一下*stu,就是student類型的指針變量,即這個(gè)指針指向一個(gè)student結(jié)構(gòu)體 stu q = null; //這里定義的這個(gè)p直接就是一個(gè)指針類型的變量,因?yàn)閟tu在typedef語句中就背定義為指針了student s; student *p = s; q = p; //下面有這幾種方法可以訪問student的成員age(別的成員訪問方式類似) s.age = 10; (*p).age = 10; p->age = 10; q->age = 10;

**注意:**如果用結(jié)構(gòu)體指針在不加取值運(yùn)算符*的情況下想直接訪問結(jié)構(gòu)體成員要用到->

總結(jié)

以上是生活随笔為你收集整理的C语言基础指针知识点总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。