成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

C語(yǔ)言進(jìn)階:指針的進(jìn)階

浠ラ箍 / 2053人閱讀

摘要:本章節(jié)在此基礎(chǔ)上,對(duì)語(yǔ)言階段指針進(jìn)行更深層次的研究。數(shù)組指針的類(lèi)型由數(shù)組類(lèi)型決定,先找出數(shù)組的類(lèi)型去掉名就是類(lèi)型。相當(dāng)于數(shù)組指針?biāo)赶驍?shù)組的數(shù)組名。數(shù)組指針指向整個(gè)數(shù)組,將其看作二維數(shù)組并解引用得到一行的首元素,從而遍歷訪問(wèn)。

指針進(jìn)階

我們?cè)诔蹼A時(shí)就已經(jīng)接觸過(guò)指針,了解了指針的相關(guān)內(nèi)容,有:

  • 指針定義:指針變量,用于存放地址。地址唯一對(duì)應(yīng)一塊內(nèi)存空間。
  • 指針大小:固定32位平臺(tái)下占4個(gè)字節(jié),64位8個(gè)字節(jié)。
  • 指針類(lèi)型:類(lèi)型決定指針±整數(shù)的步長(zhǎng)及指針解引用時(shí)訪問(wèn)的大小。
  • 指針運(yùn)算:指針解引用,指針±整數(shù),指針-指針,指針關(guān)系運(yùn)算。

本章節(jié)在此基礎(chǔ)上,對(duì)C語(yǔ)言階段指針進(jìn)行更深層次的研究。

字符指針

字符指針,存入字符的地址,類(lèi)型為char *

字符指針的作用
  1. 指向單個(gè)字符變量
char ch = "w";const char* pch = &ch;

這種很容易理解,就是指針解引用訪問(wèn)字符變量。

  1. 指向字符串首字符
char* pc = "hello";printf("%s/n", pc);

這種是把字符串"hello"放進(jìn)指針嘛?

其實(shí)不然,類(lèi)似于數(shù)組名,該指針存的是常量字符串"hello"的首字符的地址。通過(guò)對(duì)指針解引用訪問(wèn)首字符地址,從而找到整個(gè)字符串。

char* pc = "hello";printf("%c/n", *(pc + 1));//eprintf("%s/n", pc);//helloprintf("%s/n", pc + 1);//ello

字符串本質(zhì)上還是在空間上連續(xù)存放,所以指針±整數(shù)同樣有訪問(wèn)的效果。由此也可以看出%s的用法,把地址給%s會(huì)將其后的內(nèi)容看作字符串并打印直到/0 。(所以我猜測(cè)%s的s是string的意思)

字符指針的特點(diǎn)

例題

char str1[] = "hello bit";char str2[] = "hello bit";char* str3 = "hello bit";char* str4 = "hello bit";if (str1 == str2)    printf("str1 = str2/n");//1else    printf("str1 != str2/n");//2if (str3 == str4)    printf("str3 = str4/n");//3else    printf("str3 != str4/n");//4

str1(3)==str2(4),比較的是二者其實(shí)位置地址是否相同。(地址才是真正判斷二者是否相同的要素)

答案是2和3。因?yàn)?和2是用字符串初始化數(shù)組,3和4是指針指向常量字符串。

  • str1和str2是普通的數(shù)組,是在內(nèi)存上開(kāi)辟了兩塊空間不過(guò)存放了一樣的數(shù)據(jù)。
  • str3和str4指向常量字符串,存放在內(nèi)存的常量區(qū),是不可被修改且具有唯一性即常量區(qū)只存放一個(gè)。所以str3和str4指向的都是同一個(gè)字符串。

常量區(qū)的存儲(chǔ)特點(diǎn):存放在常量區(qū)的數(shù)據(jù)不可被修改,正因?yàn)椴豢尚薷乃源嬉环菥蛪蛄恕:笃谌绻枰?,使用的是同一?shù)據(jù)。(數(shù)據(jù)還是同一個(gè)數(shù)據(jù),只是用不同的指針維護(hù))

總結(jié)

  1. 常量字符串不可被修改,存放在內(nèi)存的常量區(qū)。
  2. 具有唯一性即常量區(qū)只存放一個(gè)。
指針數(shù)組
指針數(shù)組的定義
int arr[10];//整型數(shù)組char ch[5];//字符數(shù)組float f[20];//浮點(diǎn)型數(shù)組

可見(jiàn),元素類(lèi)型也就是數(shù)組的“類(lèi)型”。

char* pch[5];int* parr[10];float* pf[20];

指針數(shù)組就是存放指針的數(shù)組。

int arr[10];int* arr[10];

整型數(shù)組的數(shù)組名arr,即首元素地址,是一級(jí)指針。

指針數(shù)組的數(shù)組名parr,也是首元素地址,不過(guò)其首元素為int*類(lèi)型變量,所以parr就是二級(jí)指針。

指針數(shù)組的使用
int arr1[] = { 1,2,3,4,5 };int arr2[] = { 2,3,4,5,6 };int arr3[] = { 3,4,5,6,7 };int* parr[] = { arr1,arr2,arr3 };for (int i = 0; i < 3; i++) {    for (int j = 0; j < 5; j++) {        //1.        printf("%d ", parr[i][j]);        //2.        printf("%d ", *(*(parr + i) + j));    }    printf("/n");}//答案1 2 3 4 52 3 4 5 63 4 5 6 7ps:parr[i] <==> *(parr+i) *(parr[i]+j) <==> *(*(parr+i)+j) <==> (*parr+i)[j] <==> parr[i][j]

通過(guò)指針數(shù)組訪問(wèn)整型數(shù)組的每個(gè)元素。parr[i][j]*(*(parr+i)+j)本質(zhì)上是等價(jià)的。

const char* pch[] = { "abcde", "bcdef", "cdefg" };for (int i = 0; i < 3; i++) {    //1.    printf("%s", pch[i]);    //2.    printf("%s", *(pch + i));    for (int j = 0; j < 5; j++) {        //3.        printf("%c", pch[i][j]);        //4.        printf("%c", *(*(pch + i) + j));    }    printf("/n");}

打印字符串使用%s更簡(jiǎn)單,若要使用%c,就是得到每個(gè)字符串的起始地址,分別向后訪問(wèn)。

從這里也可以看出數(shù)組和指針的關(guān)系,我愿稱(chēng)之為*[]的愛(ài)恨情仇!

?

數(shù)組指針

由前面的例子,不難得出,數(shù)組指針是指向數(shù)組的指針,是指針而非數(shù)組。

數(shù)組指針的定義
char ch = "w";char* pch = &ch;//字符地址存放在字符指針中int a = 10;int* pint = &a;//整型地址存放在整型指針中float f = 0.0;float* pf = &f;//浮點(diǎn)型地址存放在浮點(diǎn)型指針中

什么變量的地址存放在什么指針中。指針指向變量的類(lèi)型,決定了指針的類(lèi)型。顧名思義,數(shù)組指針指向的是數(shù)組。

遞推可得,數(shù)組的地址存放在數(shù)組指針中。且數(shù)組指針的類(lèi)型為數(shù)組的類(lèi)型再加個(gè)* 。

下面那種定義方法是對(duì)的呢?

int arr[10] = { 0 };//1.int* pa = arr;//2.&arr;//整個(gè)數(shù)組的地址int* parr = &arr;//3.int* parr[10] = &arr;//4.int(*parr)[10] = &arr;
  1. 取出的是首元素的地址,而非整個(gè)數(shù)組的地址
  2. 整型指針應(yīng)存放整型變量的地址,數(shù)組的地址無(wú)法存入整型指針中。
  3. []的優(yōu)先級(jí)比*高,故parr先與[]結(jié)合成數(shù)組名,所以parr是個(gè)指針數(shù)組。

數(shù)組指針的類(lèi)型由數(shù)組類(lèi)型決定,先找出數(shù)組的類(lèi)型int[10](去掉名就是類(lèi)型)。且不能讓[]先與parr結(jié)合,所以用()先將parr*結(jié)合,即成int(*parr)[10]。

C語(yǔ)言規(guī)定[]必須再最后面,所以不可寫(xiě)成int[10](*parr)

int* parr[10];//指針數(shù)組int(*parr)[10];//數(shù)組指針

我們前面強(qiáng)調(diào)過(guò),去掉名字就是類(lèi)型。所以int[10]是整型數(shù)組的類(lèi)型,int*[10]是指針數(shù)組的類(lèi)型,int(*)[10]是數(shù)組指針的類(lèi)型。

&數(shù)組名和數(shù)組名

之前介紹過(guò)不止一遍,所以這次只說(shuō)重點(diǎn)。

指針類(lèi)型決定了指針±整數(shù)的步長(zhǎng)。

//首元素地址+1printf("%p/n", arr);//0073FCA4printf("%p/n", arr + 1);//0073FCA8//整個(gè)數(shù)組地址+1printf("%p/n", &arr);//0073FCA4printf("%p/n", &arr + 1);//0073FCCC
  1. 首元素地址就是整型指針+1,自然只能向后訪問(wèn)4shou個(gè)字節(jié)
  2. 整個(gè)數(shù)組地址+1,即int(*)[10]型指針+1,向后訪問(wèn)了 i n t × 10 int×10 int×10即40個(gè)字節(jié)。

sizeof(arr)也代表整個(gè)數(shù)組,現(xiàn)在去理解為什么sizeof里數(shù)組名代表的是整個(gè)數(shù)組呢?數(shù)組這種結(jié)構(gòu)保存了數(shù)組的大小,sizeof求所占空間的長(zhǎng)度,那自然要嚴(yán)謹(jǐn)一些了。

數(shù)組指針的使用

遍歷數(shù)組,使用數(shù)組或是指針作形參接收就行了。且所謂的用數(shù)組接收僅是理解層面,本質(zhì)上都是指針。

void Print1(int arr[], int sz) {	for (int i = 0; i < sz; i++) {		//printf("%d ", arr[i]); 		printf("%d ", *(arr + i));			}}void Print2(int* arr, int sz) {	for (int i = 0; i < sz; i++) {		printf("%d ", arr[i]);		//printf("%d ", *(arr + i));	}}int main() {	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };	int sz = sizeof(arr) / sizeof(arr[0]);	Print1(arr, sz);	Print2(arr, sz);	return 0;}
反面用例

數(shù)組作實(shí)參,用數(shù)組或指針接收即可。數(shù)組指針使用對(duì)了很好用,但如果隨便用可能會(huì)很別扭。下面先介紹強(qiáng)行使用數(shù)組指針的用法。

//錯(cuò)誤示范void Print3(int(*pa)[10], int sz) {	for (int i = 0; i < sz; i++) {		//printf("%d ", pa[i]);		printf("%d ", *(pa + i));	}}

將整個(gè)數(shù)組地址傳過(guò)去,則用數(shù)組指針接收,然后呢,直接對(duì)pa解引用嗎?

結(jié)果顯然是錯(cuò)誤的,從結(jié)果中也可以看出打印的是十進(jìn)制下的地址,+1跳過(guò)40個(gè)字節(jié)。

這里筆者在學(xué)習(xí)的時(shí)候產(chǎn)生了個(gè)疑問(wèn),傳過(guò)去數(shù)組的地址,為什么解一層引用后還是地址呢?

&arr解引用*后相當(dāng)于找到首元素的地址,可以理解為&*相互抵消只剩下arr不就是首元素的地址嘛~

void Print4(int(*pa)[10], int sz) {	for (int i = 0; i < sz; i++) {		printf("%d ", *(*(pa)+j));	}}

倘若我們把一維數(shù)組看作是二維數(shù)組第一行。由于二維數(shù)組在內(nèi)存中是連續(xù)存放的,我們只打印二維數(shù)組的第一行,便可以避免上面的錯(cuò)誤。


style=“zoom:80%;” />

*(pa)相當(dāng)于數(shù)組指針?biāo)赶驍?shù)組的數(shù)組名。數(shù)組指針指向整個(gè)數(shù)組,將其看作二維數(shù)組并解引用得到一行的首元素,從而遍歷訪問(wèn)。

正面用例

從上面的例子也可以看出,用數(shù)組指針訪問(wèn)二維數(shù)組時(shí),效果便不錯(cuò)。

//二維數(shù)組傳參,用二維數(shù)組接收void Print1(int arr[3][5], int r, int c) {	for (int i = 0; i < r; i++) {		for (int j = 0; j < c; j++) {			//printf("%d ", arr[i][j]);			printf("%d ", *(*(arr + i) + j));		}		printf("/n");	}}

上面的例子,是正常二維數(shù)組傳參,二維數(shù)組接收的情況。下面我們用數(shù)組指針接收。

//二維數(shù)組傳參,用數(shù)組指針接收void Print2(int(*pa)[5], int r, int c) {	for (int i = 0; i < r; i++) {		for (int j = 0; j < c; j++) {            //1.            printf("%d ", pa[i][j]);            //2.			printf("%d ", *(*(pa + i) + j));		}		printf("/n");	}}int main(){	int arr[3][5] = { 1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7 };	Print2(arr, 3, 5);//二維數(shù)組首元素是首行    	return 0;}
  • 把二維數(shù)組想象成一個(gè)擁有三個(gè)元素的一維數(shù)組(每個(gè)元素也為一維數(shù)組),即一維數(shù)組的一維數(shù)組。
  • 由于其每個(gè)元素是有5個(gè)元素的一維數(shù)組,數(shù)組指針定義為int(*p)[5],指向首行這個(gè)“一維數(shù)組”。(傳參穿的是數(shù)組名)
  • 第一層循環(huán)用于“跳行”,即每次跳過(guò)5個(gè)元素。第二層循環(huán)遍歷每行“一維數(shù)組”。

  1. 用二維數(shù)組和數(shù)組指針接收的都是首行地址。
  2. 數(shù)組指針的類(lèi)型int(*)[5],和二維數(shù)組首元素地址的類(lèi)型相同。

故可得,二維數(shù)組首元素地址和數(shù)組指針是等價(jià)的,即數(shù)組指針pa就是數(shù)組名。

二維數(shù)組首元素為其首行,相當(dāng)于一個(gè)一維數(shù)組,該一維數(shù)組的地址類(lèi)型為int(*)[5]。且實(shí)參為二維數(shù)組名,降級(jí)為指向首行的指針,所以它是數(shù)組指針,類(lèi)型為int(*)[5]

數(shù)組指針指向二維數(shù)組,才是使用數(shù)組指針的正確示范。

Example

下列示例分別是什么?

//1.int arr[5];//2.int *pa1[5];//3.int (*pa2)[10];//4.int (*pa3[10])[5];
  1. 整型數(shù)組
  2. 存放整型指針的數(shù)組

*靠左靠右無(wú)所謂,pa1先和[]結(jié)合為數(shù)組,剩下int*為數(shù)組元素類(lèi)型。

  1. 指向整型數(shù)組的指針

(*pa2)*先和pa2結(jié)合為指針,剩下int[10],指向的是元素個(gè)數(shù)為10的整型數(shù)組。

  1. 存放數(shù)組指針的數(shù)組

pa3先和[10]結(jié)合為數(shù)組,剩下int(*)[5]是指向數(shù)組的指針為數(shù)組的元素。所以是個(gè)元素個(gè)數(shù)為10的數(shù)組指針數(shù)組。

逆向思考,有整型數(shù)組arr[5]和指向該數(shù)組的類(lèi)型為int(*)[5]的數(shù)組指針,還有數(shù)組指針數(shù)組pa3[10]用于存放該數(shù)組指針。

類(lèi)型辨別方法
  1. 若名稱(chēng)先和[]結(jié)合為數(shù)組,只去掉數(shù)組名就是數(shù)組類(lèi)型,去掉[n]和數(shù)組名便是其元素的類(lèi)型。
  2. 若名稱(chēng)先和*結(jié)合為指針,只去掉指針名就是指針類(lèi)型,去掉*和指針名便是指向的變量的類(lèi)型。

?

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

實(shí)踐之中不免會(huì)碰到數(shù)組和指針作函數(shù)參數(shù)而如何設(shè)計(jì)形參的問(wèn)題。

一維數(shù)組傳參

一維數(shù)組傳參,下列接收方式是否可行呢?

//1.void test(int arr[]) {}//2.void test(int arr[10]) {}//3.void test(int* arr) {}int main(){		int arr[10] = { 0 };	test(arr);	return 0;}
  1. 數(shù)組傳參數(shù)組接收,可行但其實(shí)都會(huì)降級(jí)優(yōu)化成指針,編譯器不會(huì)真正創(chuàng)建一個(gè)數(shù)組。

  2. 由于形參數(shù)組形同虛設(shè),所以數(shù)組大小無(wú)意義,任意大小或無(wú)。(有歧義)

  3. 數(shù)組傳參本質(zhì)就是首元素地址,首元素類(lèi)型為int,所以指針的類(lèi)型為int*。

所以可以看出[]*()是等價(jià)的。我愿稱(chēng)之為*[]的愛(ài)恨情仇?。ī\^▽?zhuān)蕞\)

//1.void test2(int* arr[2]){}//2.void test2(int** arr) {}int main(){		int* arr2[10] = { 0 };	test2(arr2);	return 0;}

指針數(shù)組,每個(gè)元素類(lèi)型為int*,故用二級(jí)指針接收數(shù)組名。

一維數(shù)組傳參,數(shù)組和指針接收。

二維數(shù)組傳參
//1.void test(int arr[3][5]) {}//2.void test(int arr[][]){}//3.void test(int arr[][5]){}int main() {	int arr[3][5] = { 0 };	test(arr)
            
                     
             
               

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/118796.html

相關(guān)文章

  • C語(yǔ)言進(jìn)階指針進(jìn)階續(xù)

    摘要:故使用無(wú)具體類(lèi)型,又稱(chēng)通用類(lèi)型,即可以接收任意類(lèi)型的指針,但是無(wú)法進(jìn)行指針運(yùn)算解引用,整數(shù)等。求指針?biāo)甲止?jié)而不是解引用訪問(wèn)權(quán)限大小。數(shù)組就是整個(gè)數(shù)組的大小,數(shù)組元素則是數(shù)組元素的大小,指針大小都為。 ...

    ingood 評(píng)論0 收藏0
  • 玩轉(zhuǎn)指針,手撕c語(yǔ)言——(指針進(jìn)階

    摘要:函數(shù)的返回值為指針就按照字面意思,指針函數(shù)的定義顧名思義,指針函數(shù)即返回指針的函數(shù)。 目錄 前言指針與函數(shù)函數(shù)的返回值為指針作為函數(shù)參數(shù)的指針指針函數(shù)可以改變變量...

    genedna 評(píng)論0 收藏0
  • C語(yǔ)言進(jìn)階:動(dòng)態(tài)內(nèi)存管理

    摘要:釋放不完全導(dǎo)致內(nèi)存泄漏。既然把柔性數(shù)組放在動(dòng)態(tài)內(nèi)存管理一章,可見(jiàn)二者有必然的聯(lián)系。包含柔性數(shù)組的結(jié)構(gòu)用進(jìn)行動(dòng)態(tài)內(nèi)存分配,且分配的內(nèi)存應(yīng)大于結(jié)構(gòu)大小,以滿(mǎn)足柔性數(shù)組的預(yù)期。使用含柔性數(shù)組的結(jié)構(gòu)體,需配合以等動(dòng)態(tài)內(nèi)存分配函數(shù)。 ...

    shinezejian 評(píng)論0 收藏0
  • 三文讀透指針語(yǔ)法【中篇】@指針進(jìn)階---函數(shù)指針+函數(shù)指針數(shù)組+指向函數(shù)指針數(shù)組指針

    摘要:三文讀透指針上篇本文將繼續(xù)介紹有關(guān)函數(shù)指針的相關(guān)內(nèi)容。在大型工程里,函數(shù)指針應(yīng)用還是挺普遍的。首先看閱讀下面兩段有趣的代碼出自語(yǔ)言陷阱與缺陷看看他們是什么意思代碼代碼函數(shù)指針數(shù)組函數(shù)指針數(shù)組,即存放函數(shù)指針的數(shù)組。 ...

    blastz 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

浠ラ箍

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<