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

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

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

编程问答

C语言程序设计 | 指针的进阶(一):字符指针、数组指针、指针数组、函数指针

發(fā)布時(shí)間:2024/4/11 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言程序设计 | 指针的进阶(一):字符指针、数组指针、指针数组、函数指针 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

指針的進(jìn)階(一)目錄:

  • 字符指針
  • 數(shù)組指針和指針數(shù)組
  • 函數(shù)指針

字符指針

在開(kāi)始講解這一章節(jié)之前,我們需要了解指針前面聲明的類(lèi)型的意義

類(lèi)型 * 指針名

對(duì)于指針來(lái)說(shuō),我們?cè)诮o指針進(jìn)行聲明時(shí),我們聲明的類(lèi)型并不是指針的類(lèi)型,而是指針?biāo)赶虻牡刂返念?lèi)型,也就是指針看待這段地址的方式,它該如何讀取數(shù)據(jù),它如果加一該移動(dòng)多少位,只有了解了這個(gè)才能方便理解下面的內(nèi)容

我們首先來(lái)說(shuō)的就是字符指針char*

一般我們是這樣運(yùn)用字符指針的

char a = 'a';char* p = &a;

但是我們還能以這種方式運(yùn)用

char*str = "hello world";

這時(shí)候,經(jīng)常就會(huì)有初學(xué)者以為我們的指針指向的是hello world這個(gè)字符串,但其實(shí)這里只是把字符串的首元素的地址保存到了這個(gè)指針當(dāng)中。

同時(shí)我們還需要理解這樣的指針與字符串的區(qū)別。

例如:

char str1[] = "hello";char *str2 = "world";

這里的str1是在棧上開(kāi)辟一塊內(nèi)存空間來(lái)存放hello這段字符,而這里的str2是用指針指向常量區(qū)的‘’world‘’這段字符,所以我們無(wú)法給str2進(jìn)行賦值與修改,因?yàn)槌A渴遣豢筛淖兊?#xff0c;我們也無(wú)法將這str1與str2進(jìn)行比較,因?yàn)樗麄兪潜举|(zhì)不同的兩樣?xùn)|西。
借此,在引申一個(gè)小內(nèi)容

#include<stdio.h> int main() {char str1[] = "helloworld.";char str2[] = "helloworld.";char* str3 = "helloworld.";char* str4 = "helloworld.";if(str1 == str2)printf("1\n");elseprintf("0\n"); if(str3 == str4)printf("1\n");elseprintf("0\n"); return 0; }


為什么在這里,str1與str2不同呢?
因?yàn)槲覀兘o字符串賦值時(shí),是在棧上面開(kāi)辟一個(gè)內(nèi)存空間,來(lái)給這個(gè)字符串存放一個(gè)數(shù)值,雖然他們存放的內(nèi)容是一樣的,但是它們存放在不同的內(nèi)存塊中,所以進(jìn)行比較的時(shí)候是不同的
那為什么str3和str4是相同的呢?
因?yàn)樗鼈兪亲址羔?#xff0c;它們指向的都是常量區(qū)中的hello world這段字符,它們指向的內(nèi)容一樣,所以它們相同。
這也就是為什么我們?cè)谶M(jìn)行字符串的比較的時(shí)候運(yùn)用的都是strcmp這個(gè)函數(shù)的原因。


數(shù)組指針和指針數(shù)組

在我剛剛接觸指針的時(shí)候,我經(jīng)常會(huì)搞混兩個(gè)東西,一個(gè)是數(shù)組指針,一個(gè)是指針數(shù)組,因?yàn)樗鼈兲^(guò)相似,但如果你了解了運(yùn)算符的優(yōu)先級(jí)以及我之前說(shuō)的指針如何看待類(lèi)型,你就會(huì)很快的區(qū)分它們

上圖中的兩個(gè)指針是不是特別相似?那我們?nèi)绾螀^(qū)分呢?

首先,我們先看幾個(gè)運(yùn)算符的優(yōu)先級(jí)對(duì)于p1,[] 的優(yōu)先級(jí)是很明顯高于 *的,所以它的本質(zhì)就應(yīng)該是一個(gè)數(shù)組,而剩下的int *就應(yīng)該是它所存放的數(shù)據(jù)類(lèi)型,所以它是一個(gè)存放指針元素的數(shù)組,即指針數(shù)組。
而對(duì)于p2,它的()的優(yōu)先級(jí)是很明顯高于 [] 的,所以我們應(yīng)該先去考慮括號(hào)中的內(nèi)容,括號(hào)中是一個(gè)指針 *,所以它的本質(zhì)就應(yīng)該是一個(gè)指針,而剩下的就是它所指向的地址的類(lèi)型,所以它是一個(gè)指向數(shù)組的指針,即數(shù)組指針。

如果我們要了解一個(gè)數(shù)組指針是如何作用的,我們首先要了解這樣一個(gè)知識(shí)點(diǎn)。

對(duì)于一個(gè)數(shù)組,它的數(shù)組名和&數(shù)組名有什么區(qū)別。
我們都知道數(shù)組名是這個(gè)數(shù)組的首元素的地址,但是&數(shù)組名卻不是很了解。

int main() {int arr[10] = {0};printf("%p",arr);printf("%p",&arr);return 0; }


我們查看它們的地址,卻完全的一樣,那是不是證明它們相同呢?

int main() {int arr[10] = {0};printf("%p",arr+1);printf("%p",&arr+1);return 0; }

其實(shí)不是,我們?cè)俳o它們分別+1

這里區(qū)別就顯現(xiàn)出來(lái)了,arr+1加的只是一個(gè)元素的大小,而&arr+1加了一整個(gè)數(shù)組的大小。
所以我們就能了解,&arr指向的是這一整個(gè)數(shù)組的地址。
而我們的數(shù)組指針,是一個(gè)指向數(shù)組地址的指針,所以數(shù)組指針應(yīng)該這樣指向一個(gè)數(shù)組。

int (*p)[10] = &arr;

函數(shù)指針

在了解函數(shù)指針前我們要先了解一個(gè)小的誤區(qū)


這兩個(gè)哪一個(gè)才是函數(shù)指針呢?
還是之前判斷數(shù)組指針的那個(gè)方法,我們看優(yōu)先級(jí),先看括號(hào),它是一個(gè)指針,剩下的就是它所指向的類(lèi)型,一個(gè)返回值為void的函數(shù)。
而第二個(gè)其實(shí)就是一個(gè)函數(shù)的聲明,聲明一個(gè)返回值為void*的函數(shù)

我們?cè)撊绾握{(diào)用這個(gè)函數(shù)指針呢?

無(wú)論是直接調(diào)用還是進(jìn)行解引用后調(diào)用,我們都可以直接使用這個(gè)函數(shù)

#include<stdio.h>void print() {printf("1\n"); }int main() {void (*p)();p = print;p();(*p)();return 0; }


在使用函數(shù)指針的時(shí)候,因?yàn)楹瘮?shù)的特殊性,在很多情況下代碼的可讀性會(huì)十分差,如下面這段代碼。

void(*signal(int,void(*)(int)))(int);



這是它的參數(shù)類(lèi)型

這是它的函數(shù)名
外面剩下的則是它的返回類(lèi)型。
所以它是一個(gè)參數(shù)為int 和函數(shù)指針的一個(gè)函數(shù),返回值為函數(shù)指針。
這樣的代碼讓人很難理解。
那該如何簡(jiǎn)化呢?我們可以用typedef進(jìn)行簡(jiǎn)化

typedef void(*p)();

簡(jiǎn)化完后

這樣我們的代碼可讀性就大大的提升了。

第一部分就講到這里吧

總結(jié)

以上是生活随笔為你收集整理的C语言程序设计 | 指针的进阶(一):字符指针、数组指针、指针数组、函数指针的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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