5- 靈活使用指針_第1頁
5- 靈活使用指針_第2頁
5- 靈活使用指針_第3頁
5- 靈活使用指針_第4頁
5- 靈活使用指針_第5頁
已閱讀5頁,還剩51頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

教學(xué)內(nèi)容: 第1章:C語言語法基礎(chǔ)第2章:C程序設(shè)計(jì)基礎(chǔ)第3章:利用數(shù)組處理同類型的批量數(shù)據(jù)第4章:利用函數(shù)實(shí)現(xiàn)模塊化程序設(shè)計(jì)第5章:靈活使用指針第6章:結(jié)構(gòu)體、共用體、枚舉類型及其應(yīng)用第7章:常用的三種線性數(shù)據(jù)結(jié)構(gòu)第8章:利用文件進(jìn)行數(shù)據(jù)管理第9章:嵌入式技術(shù)基礎(chǔ)實(shí)踐方法C語言程序設(shè)計(jì)5.1指針的基本概念5.2指向普通變量的指針5.3指向數(shù)組的指針5.4指向字符串的指針5.5指向函數(shù)的指針5.6返回指針值的函數(shù)5.7指針數(shù)組、指向指針的指針5.8內(nèi)存動態(tài)分配與指向動態(tài)內(nèi)存區(qū)的指針變量5.9指針小結(jié) 【學(xué)習(xí)內(nèi)容】

第5章靈活使用指針第5章靈活使用指針指針1.理解指針的概念;2.掌握指向普通變量的指針及應(yīng)用;3.掌握指向數(shù)組的指針及應(yīng)用;4.掌握指向字符串的指針及應(yīng)用;5.掌握指向函數(shù)的指針及應(yīng)用;6.掌握返回指針值的函數(shù)及應(yīng)用;7.掌握指針數(shù)組和指向指針的指針及應(yīng)用;8.掌握內(nèi)存動態(tài)分配函數(shù)的使用方法?!緦W(xué)習(xí)目標(biāo)】

5.1指針的基本概念

對變量值的存、取都是通過變量的地址進(jìn)行的。

例如,scanf("%d",&i);將鍵盤上輸入的數(shù)據(jù)送給變量i對應(yīng)的地址單元中。

再如,

printf("%d",i);從變量i對應(yīng)的地址單元中取出變量i的值。

直接按照變量名(對應(yīng)一個(gè)內(nèi)存地址)進(jìn)行的訪問,稱為“直接訪問”方式。

除了采用“直接訪問”方式,還可以采用“間接訪問”方式。

可通過語句“p=&i;”將變量i的地址(2000)存放到變量p中(變量p的值就是2000)。

要讀取變量i的值,可以先找到變量p,從中取出i的地址(2000),然后到地址為2000的內(nèi)存單元取出i的值(3)。

通過變量p能夠找到變量i,可以說變量p指向了變量i,在C語言中,將地址形象地稱為“指針”。

一個(gè)變量的地址,稱為該變量的“指針”。例如,地址2000是變量i的指針,而變量p用來存放變量i的地址,稱為“指針變量”。5.2指向普通變量的指針

5.2.1定義指針變量的方法

定義指針變量的一般形式:類型標(biāo)識符*變量名;

例如:

int*p1;//p1是指向整型變量的指針變量

注意:一個(gè)指針變量只能指向同類型的變量,如p2只能指向?qū)嵭妥兞?,不能指向字符變量。float*p2;

//p2是指向?qū)嵭妥兞康闹羔樧兞縞har*p3;

//p3是指向字符變量的指針變量

所謂普通變量,是指基本數(shù)據(jù)類型(整型、實(shí)型、字符型)的變量。

變量的指針就是變量的地址。存放變量地址的變量是指針變量,用來指向另一個(gè)變量。5.2指向普通變量的指針

5.2.2指針變量的引用請牢記:指針變量中只能存放地址(指針)。

兩個(gè)有關(guān)的運(yùn)算符:(1)&:取地址運(yùn)算符。(2)*:指針運(yùn)算符(或稱“間接訪問”運(yùn)算符),取其指向單元的內(nèi)容。

例如,&a表示變量a的地址,*p表示指針變量p所指向的存儲單元的內(nèi)容(即p所指向的變量的值)。5.2指向普通變量的指針

【例5.1】通過指針變量訪問整型變量。5.2.2指針變量的引用#include<stdio.h>intmain(void){ inta=10,b=20;

int*p1,*p2;

//定義兩個(gè)指針變量,均指向整型變量

p1=&a;

//取變量a的地址,賦給指針變量p1

p2=&b;

//取變量b的地址,賦給指針變量p2printf("a=%d,b=%d\n",a,

b);printf("a=%d,b=%d\n",

*p1,*p2);//輸出指針變量指向單元的內(nèi)容printf("變量a的地址:%x\n",p1);//輸出變量a的地址printf("變量b的地址:%x\n",p2);//輸出變量b的地址}5.2指向普通變量的指針

inta;int*p;p=&a;inta;int*p=&a;

(1)等價(jià)。與說明:(2)不能直接將一個(gè)地址常數(shù)賦給一個(gè)指針變量,只有強(qiáng)制類型轉(zhuǎn)換后才能賦值:int*p=0x12345600;//錯誤int*p=(int*)0x12345600;//正確

(3)注意“*p”在定義和引用中的區(qū)別:定義時(shí):*p的前面要有類型標(biāo)識符,表示指針變量p是指向某種類型數(shù)據(jù)的;引用時(shí):*p的前面沒有類型標(biāo)識符,表示指針變量p所指向的存儲單元的內(nèi)容。5.2.2指針變量的引用5.2指向普通變量的指針

5.2.2指針變量的引用(4)inta; int*p=&a;則&*p和*&a的含義分別是什么?②*&a:先執(zhí)行&a,表示變量a的地址,也就是變量p,再執(zhí)行*運(yùn)算。因此*&a與*p等價(jià),即變量a?!?”和“*”優(yōu)先級相同,并按“自右至左”的結(jié)合性。①&*p:先執(zhí)行*p,表示變量a,再執(zhí)行&運(yùn)算。因此&*p與&a相同,即變量a的地址(p)。說明:5.2指向普通變量的指針

5.2.2指針變量的引用【例5.2】指針變量的應(yīng)用:輸入兩個(gè)整數(shù),按由大到小的順序輸出這兩個(gè)整數(shù)。#include<stdio.h>intmain(void){ inta,b;

int*p1,*p2,*p;printf("請輸入兩個(gè)整數(shù)(用空格間隔):");scanf("%d%d",&a,

&b);

p1=&a;p2=&b;if(a<b) {

p=p1;p1=p2;p2=p;

//交換指針變量的指向}printf("由大到小:%d,%d\n",*p1,*p2);}5.2指向普通變量的指針

5.2.3指針變量作為函數(shù)參數(shù)【例5.3】指針變量(變量的地址)作為函數(shù)參數(shù)。實(shí)參指針的指向

實(shí)參傳遞給形參

變量a和b的值都加1形參被釋放

指針變量作函數(shù)參數(shù),其作用是將一個(gè)變量的地址傳遞到另一個(gè)函數(shù)中。#include<stdio.h>voidfun(int*p1,int*p2);

//函數(shù)聲明intmain(void){ inta=1,b=5;

int*pa=&a,*pb=&b;

//定義指針變量printf("調(diào)用fun函數(shù)前:a=%d,b=%d\n",a,b);

fun(pa,pb);

//調(diào)用fun函數(shù),指針變量作函數(shù)參數(shù)printf("調(diào)用fun函數(shù)后:a=%d,b=%d\n",a,b);}voidfun(int*p1,int*p2)

//指針變量作形參{

(*p1)++;

//使p1指向的變量值加1

(*p2)++;

//使p2指向的變量值加1

}思考:

實(shí)參指針和形參指針指向同一個(gè)內(nèi)存單元,但它們本身是否占用相同的內(nèi)存單元?5.2指向普通變量的指針

5.2.3指針變量作為函數(shù)參數(shù)【思考與總結(jié)】

函數(shù)調(diào)用時(shí),傳遞的是變量的地址,使實(shí)參和形參指向同一個(gè)內(nèi)存單元。當(dāng)形參指向單元的值發(fā)生變化時(shí),實(shí)參指向單元的值也隨之變化。

若想通過函數(shù)調(diào)用得到n個(gè)要改變的值:可在主調(diào)函數(shù)中設(shè)n個(gè)變量,將這n個(gè)變量的地址傳遞給被調(diào)函數(shù)的形參(指針變量)。

實(shí)際上,數(shù)組名作為函數(shù)參數(shù),其本質(zhì)也如此。5.2指向普通變量的指針

5.2.3指針變量作為函數(shù)參數(shù)【例5.4】對輸入的兩個(gè)整數(shù)進(jìn)行交換并輸出。#include<stdio.h>voidswap(int*p1,int*p2);

//函數(shù)聲明intmain(void){ inta,b;printf("請輸入兩個(gè)整數(shù)(用空格間隔):");scanf("%d%d",&a,&b); printf("調(diào)用swap函數(shù)前:a=%d,b=%d\n",a,b);

swap(&a,&b);

//調(diào)用swap函數(shù),變量的地址作實(shí)參printf("調(diào)用swap函數(shù)后:a=%d,b=%d\n",a,b);}voidswap(int*p1,int*p2)

//指針變量作形參{ inttemp;

temp=*p1;*p1=*p2;*p2=temp;

}5.3指向數(shù)組的指針

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

p=&a[0];//使p指向a[0]元素

指針變量既然可以指向變量,當(dāng)然也可以指向數(shù)組元素(把某一元素的地址放到一個(gè)指針變量中)。

inta[10];//定義a為包含10個(gè)整型數(shù)據(jù)的數(shù)組

int*p;//定義p為指向整型數(shù)據(jù)的指針變量

下面兩個(gè)語句等價(jià):

int*p=&a[0]; int*p=a;

p、a、&a[0]均代表數(shù)組a的首地址(a[0]的地址)。5.3指向數(shù)組的指針

5.3.2通過指針引用數(shù)組元素

如果指針變量p已指向數(shù)組中的一個(gè)元素,則p+1指向同一數(shù)組中的下一個(gè)元素,p-1指向同一數(shù)組中的上一個(gè)元素。

(1)p+i和a+i就是a[i]的地址,即&a[i]?;蛘哒f它們指向數(shù)組a的第i個(gè)元素。

(2)*(p+i)或*(a+i)就是p+i或a+i所指向的數(shù)組元素,即a[i]。例如,*(p+5)或*(a+5)就是a[5]。即*(p+5)、*(a+5)、a[5]三者等價(jià)。(3)指向數(shù)組的指針變量也可以帶下標(biāo),如p[i]與*(p+i)等價(jià)。

實(shí)際上,在編譯時(shí),對數(shù)組元素a[i]就是按*(a+i)處理的,因此[]實(shí)際上是變址運(yùn)算符。

如果p的初值為&a[0],則:

5.3指向數(shù)組的指針

5.3.2通過指針引用數(shù)組元素【例5.5】輸出數(shù)組中的全部元素。

引用一個(gè)數(shù)組元素有兩種方法:下標(biāo)法:a[i]。指針法:*(a+i)或*(p+i)

順序訪問數(shù)組元素時(shí):第(3)種方法比第(1)、(2)種方法快,用指針變量直接指向元素,不必每次都重新計(jì)算地址。這種有規(guī)律地改變地址值(p++)能大大提高執(zhí)行效率。(1)下標(biāo)法#include<stdio.h>intmain(void){ inta[5]={1,3,5,7,9},i;

for(i=0;i<5;i++)printf("%d",

a[i]);printf("\n");}(2)通過數(shù)組名計(jì)算元素的

地址,找出元素的值#include<stdio.h>intmain(void){ inta[5]={1,3,5,7,9},i;

for(i=0;i<5;i++)printf("%d",*(a+i));printf("\n");}(3)用指針變量

指向數(shù)組元素

#include<stdio.h>intmain(void){inta[5]={1,3,5,7,9},i,*p;

for(p=a;p<a+5;p++)printf("%d",*p);

printf("\n");}for(p=a,i=0;i<5;i++,p++)5.3指向數(shù)組的指針

5.3.2通過指針引用數(shù)組元素

(1)可以通過改變指針變量的值(如p++)而指向不同的元素。而a++是錯誤的,因?yàn)閍是數(shù)組名(數(shù)組的首地址),是常量。(2)要注意指針變量的當(dāng)前值。

在使用指針變量指向數(shù)組元素時(shí),要特別注意:

從運(yùn)行結(jié)果看,沒有實(shí)現(xiàn)要求。如何改正?#include<stdio.h>intmain(void){ inti,

a[5];

int*p=a;printf("請輸入5個(gè)整數(shù):");for(i=0;i<5;i++)scanf("%d",p++);for(i=0;i<5;i++,

p++)printf("%d",

*p);printf("\n");}【例5.6】通過指針變量輸出a數(shù)組的5個(gè)元素。for(p=a,i=0;i<5;i++,p++)for(p=a;

p<a+5;p++)5.3指向數(shù)組的指針

5.3.2通過指針引用數(shù)組元素【例5.7】通過指針變量找出數(shù)組元素的最大值和最小值。#include<stdio.h>intmain(void){ inta[5]={23,

12,

34,

78,

55};

int*p,*max,*min;

//定義3個(gè)指針變量

p=max=min=a;

//將3個(gè)指針變量同時(shí)指向數(shù)組首元素for(p=a;p<a+5;p++){

if(*p>*max)max=p;

//更新max指向

if(*p<*min)min=p;

//更新min指向}printf("max=%d,min=%d\n",

*max,

*min);}5.3指向數(shù)組的指針

5.3.3用數(shù)組名作函數(shù)參數(shù)在4.4.2節(jié)曾介紹過數(shù)組名可以作函數(shù)的實(shí)參和形參。

實(shí)際上,C語言編譯系統(tǒng)都是將形參數(shù)組名作為指針變量(存放地址)來處理的,并非真正開辟一個(gè)新的數(shù)組空間。voidf(intb[

],intn)相當(dāng)于:void

f(int*b,intn)5.3指向數(shù)組的指針

普通變量、數(shù)組元素,普通變量的地址、指針變量、數(shù)組名都可以作為函數(shù)參數(shù):5.3.3用數(shù)組名作函數(shù)參數(shù)5.3指向數(shù)組的指針

5.3.3用數(shù)組名作函數(shù)參數(shù)若有一實(shí)參數(shù)組,要想通過函數(shù)調(diào)用改變此數(shù)組中元素的值,有4種形式:(1)實(shí)參和形參都用數(shù)組名(2)實(shí)參用數(shù)組名,形參用指針變量5.3指向數(shù)組的指針

5.3.3用數(shù)組名作函數(shù)參數(shù)(3)實(shí)參和形參都用指針變量

(4)實(shí)參用指針變量,形參用數(shù)組名

若有一實(shí)參數(shù)組,要想通過函數(shù)調(diào)用改變此數(shù)組中元素的值,有4種形式:5.3指向數(shù)組的指針

【例5.8】用指針變量作函數(shù)形參,改寫例4.8給出的程序。5.3.3用數(shù)組名作函數(shù)參數(shù)理解和練習(xí):【例5.9】用指針變量作為函數(shù)的參數(shù),改寫例4.10給出的排序程序。#include<stdio.h>voidchange(intb[],intn);

//函數(shù)聲明intmain(void){ inta[5]={1,

3,

5,

7,

9},i;printf("函數(shù)調(diào)用前:");for(i=0;i<5;i++)printf("a[%d]=%d",

i,

a[i]);printf("\n");

change(a,5);//調(diào)用change函數(shù),實(shí)參:數(shù)組名a、數(shù)值5printf("函數(shù)調(diào)用后:");for(i=0;i<5;i++)printf("a[%d]=%d",i,

a[i]);printf("\n");}voidchange(intb[],

intn)

//形參:數(shù)組名

b、變量n{ inti;for(i=0;

i<n;i++)

b[i]++;}*bvoidchange(int

*b,intn)

//形參:指針變量b、變量n{ int*p;for(p=b;p<b+n;p++)

(*p)++;}5.3指向數(shù)組的指針

1、二維數(shù)組元素的地址C語言中,二維數(shù)組a又可看作是一個(gè)特殊的一維數(shù)組。有3個(gè)行元素:a[0]、a[1]、a[2],而每個(gè)行元素又是一個(gè)包含4個(gè)列元素的一維數(shù)組,此時(shí)把a(bǔ)[0]、a[1]、a[2]看作一維數(shù)組名。

根據(jù)一維數(shù)組的指針知識,a+i代表元素a[i]的地址&a[i],而在二維數(shù)組中,元素a[i]是包含4個(gè)元素的一維數(shù)組,因此a+i代表第i行的首地址(起始地址)。aa+1a+2a[0]、a[1]、a[2]既然是一維數(shù)組名,而數(shù)組名代表數(shù)組首元素的地址,因此a[0]代表一維數(shù)組a[0]中第0列元素的地址,即&a[0][0]。同理,a[1]代表&a[1][0],a[2]代表&a[2][0]。據(jù)此,a[i][j]的地址&a[i][j]可用a[i]+j表示。a[0]+0a[0]+1a[0]+2a[0]+35.3.4通過指針引用多維數(shù)組5.3指向數(shù)組的指針

a[i]與*(a+i)等價(jià)!1、二維數(shù)組元素的地址5.3.4通過指針引用多維數(shù)組

(1)a與a[0]指向同一個(gè)地址,區(qū)別:a指向一維數(shù)組,而a[0]指向a[0][0]元素。a+1中的“1”代表一行中全部整型元素所占的字節(jié)數(shù)(VC中為16字節(jié)),而a[0]+1中的“1”代表一個(gè)整型元素所占的字節(jié)數(shù)(VC中為4字節(jié))。

(2)在行指針(a+i)的前面加一個(gè)*,就轉(zhuǎn)換為列指針(指向第i行第0列元素)。例如,而*a、*(a+1)分別指向數(shù)組第0行第0列的元素、第1行第0列的元素。

在列指針a[i]前面加&,就成為指向第i行的行指針。例如,&a[0]是指向第0行的行指針。5.3指向數(shù)組的指針

2、指向二維數(shù)組的指針變量(1)指向二維數(shù)組元素的指針變量5.3.4通過指針引用多維數(shù)組【例5.10】用指向數(shù)組元素的指針變量輸出3×4二維數(shù)組各元素的值。

分析:二維數(shù)組的元素在內(nèi)存中是按行順序存放的,12個(gè)元素的地址依次為a[0]~a[0]+11,因此可以用一個(gè)指向二維數(shù)組元素的指針,依次指向各個(gè)元素。#include<stdio.h>intmain(void){ inta[3][4]={{2,4,6,8},{10,12,14,16},{18,20,22,24}};

int*p=a[0];

//將a[0][0]元素的地址賦給指針變量p

for(;

p<a[0]+12;

p++){ if((p-a[0])%4==0) printf("\n");//每輸出4個(gè)值換行printf("%4d",

*p); }printf("\n");}5.3指向數(shù)組的指針

(2)指向由n個(gè)元素組成的一維數(shù)組的指針變量:(*p)[n]

指針變量p先指向第0行a[0](即p=&a[0]),則p+1指向第1行a[1],p的增值以一維數(shù)組中n個(gè)元素的長度為單位。5.3.4通過指針引用多維數(shù)組2、指向二維數(shù)組的指針變量

p是指向由4個(gè)元素組成的一維數(shù)組的指針,p的值是該一維數(shù)組的起始地址。p不能指向一維數(shù)組中的某一個(gè)元素。5.3指向數(shù)組的指針

(2)指向由n個(gè)元素組成的一維數(shù)組的指針變量:(*p)[n]5.3.4通過指針引用多維數(shù)組2、指向二維數(shù)組的指針變量【例5.11】用指向由n個(gè)元素組成的一維數(shù)組的指針變量輸出3×4二維數(shù)組各元素值。#include<stdio.h>intmain(void){ inta[3][4]={{2,4,6,8},{10,12,14,16},{18,20,22,24}};intj;int(*p)[4];//定義指向由4個(gè)元素組成的一維數(shù)組的指針變量p

for(p=a;p<a+3;

p++){for(j=0;j<4;j++)printf("%4d",

*(*p+j)); printf("\n"); }}5.3指向數(shù)組的指針

3、用指向二維數(shù)組的指針變量作函數(shù)參數(shù)5.3.4通過指針引用多維數(shù)組

用指針變量作形參,以接收實(shí)參數(shù)組名傳遞來的地址時(shí),可有兩種方法:(1)用指向二維數(shù)組元素的指針變量(列指針);(2)用指向由n個(gè)元素組成的一維數(shù)組的指針變量(行指針)。【例5.12】某測控系統(tǒng),在上午、下午和夜間3個(gè)時(shí)間段內(nèi)各檢測4次溫度,利用指向二維數(shù)組的指針,計(jì)算室內(nèi)一天內(nèi)的平均溫度,并輸出夜間檢測到的4次溫度值。intmain(void){ floatt[3][4]={{18,20,22,25},{26,24,21,19},{16,14,12,15}}//上午、下午、夜間溫度

average(*t,

12);//計(jì)算平均溫度,實(shí)參:指向t[0][0]元素的指針變量(列指針)

print(t,2);

//輸出夜間溫度值,實(shí)參:二維數(shù)組名t(首行指針)}voidaverage(float*p,intn)//求平均溫度,形參:指針變量p、變量n{ floatsum=0,

aver;float*q;for(q=p;q<p+n;q++)sum=sum+(*q);aver=sum/n;printf("一天內(nèi)的平均溫度:%5.1f\n",

aver);}voidprint(float

(*p)[4],intn)//形參p是指向具有4個(gè)元素的一維數(shù)組的指針{ intj;printf("夜間內(nèi)溫度檢測值:");for(j=0;j<4;j++)printf("%5.1f",

*(*(p+n)+j));printf("\n");}5.4指向字符串的指針

字符串廣泛應(yīng)用于嵌入式系統(tǒng)與物聯(lián)網(wǎng)軟件設(shè)計(jì)中,本節(jié)主要介紹字符串的引用方式和字符串在函數(shù)間的傳遞方式。5.4.1字符串的引用方式1、字符數(shù)組法【例5.13】用字符數(shù)組存放一個(gè)字符串,然后輸出該字符串和第4個(gè)字符。#include<stdio.h>intmain(void){ charstr[]="IloveChina!";//定義字符數(shù)組strprintf("%s\n",

str);

//用%s格式輸出str整個(gè)字符串printf("%c\n",

str[3]);

//用%c格式輸出一個(gè)字符數(shù)組元素}5.4指向字符串的指針

2、字符指針法5.4.1字符串的引用方式【例5.14】用字符指針變量輸出一個(gè)字符串和該串的第4個(gè)字符。

在C語言中,用字符數(shù)組用來存放字符串常量。因此可將字符串首元素(第1個(gè)字符)的地址賦給一個(gè)指針變量,通過指針變量來訪問字符串,該指針就是指向字符串的指針。

使用%s輸出時(shí),先輸出指針變量p所指向的一個(gè)字符,然后自動使p加1,使之指向下一個(gè)字符,再輸出一個(gè)字符,…,直到遇到字符串結(jié)束標(biāo)志'\0'為止。#include<stdio.h>intmain(void){

char*p="IloveChina!";

//定義字符指針變量p,并使其指向字符串的第1個(gè)字符printf("%s\n",

p);

//輸出整個(gè)字符串printf("%c\n",

*(p+3));

//輸出第4個(gè)字符}5.4指向字符串的指針

2、字符指針法5.4.1字符串的引用方式【例5.15】輸出字符串中n個(gè)字符后的所有字符。#include<stdio.h>intmain(void){ intn=10;

char*ps="thisisabook";

//定義字符型指針變量,并使其指向字符串的第1個(gè)字符

ps=ps+n;printf("%s\n",

ps);}5.4指向字符串的指針

5.4.2字符串在函數(shù)間的傳遞方式【例5.16】自編字符串復(fù)制的函數(shù)。

在字符串處理運(yùn)算中,可用字符數(shù)組名或字符指針變量作函數(shù)參數(shù),傳遞字符串的起始地址,在被調(diào)函數(shù)中字符串的內(nèi)容發(fā)生變化后,主調(diào)函數(shù)就可以引用改變后的字符串。5.4指向字符串的指針

5.4.3使用字符數(shù)組與字符指針變量的區(qū)別

用字符數(shù)組和字符指針變量都可實(shí)現(xiàn)對字符串的存儲和運(yùn)算。區(qū)別:1、存儲內(nèi)容不同

字符數(shù)組可存放整個(gè)字符串;而字符指針變量只能存放字符串某個(gè)字符的地址。2、賦值方式不同(1)對字符數(shù)組賦初值:

charst[]="CLanguage";(2)對字符指針變量賦初值:

char*ps="CLanguage";也可以寫成:

char*ps; ps="CLanguage";而不能寫成:

charst[20];st="CLanguage";

可見,使用指針變量處理字符串更加方便。但要注意:在使用指針變量時(shí),需要對指針變量賦予確定的地址?!纠?.17】用帶下標(biāo)的字符指針變量引用字符串中的字符。5.4指向字符串的指針

說明:可以用下標(biāo)方式引用指針變量所指向的字符串中的字符。5.4.3使用字符數(shù)組與字符指針變量的區(qū)別#include<stdio.h>intmain(void){inti;

char*p="IloveChina!";//定義字符指針變量p,并使其指向字符串的第1個(gè)字符for(i=0;p[i]!='\0';i++)printf("%c",

p[i]);

//通過下標(biāo)方式引用字符串中的字符printf("\n");}5.5指向函數(shù)的指針

(2)通過指針變量調(diào)用函數(shù)#include<stdio.h>intadd(intx,inty);

//函數(shù)聲明intmain(void){inta,b,sum;

int(*p)(int,

int);

//定義指向函數(shù)的指針變量

p=add;

//使指針變量p指向add函數(shù)printf("請輸入a、b的值:");scanf("%d%d",&a,&b);sum=(*p)(a,b);//通過指針變量調(diào)用add函數(shù)printf("a=%d,b=%d\n",a,b);printf("sum=%d\n",sum);}intadd(intx,inty){ return(x+y);}

編譯系統(tǒng)為函數(shù)代碼分配一段存儲空間,其起始地址稱為該函數(shù)的入口地址?!纠?.18】用函數(shù)求整數(shù)a、b的和。利用指針變量調(diào)用函數(shù)的步驟和方法:

(1)定義指向函數(shù)的指針變量

類型標(biāo)識符(*指針變量名)(函數(shù)參數(shù)列表);

(2)將函數(shù)的入口地址(函數(shù)名)賦給指針變量,使指針變量指向函數(shù)(3)通過“(*指針變量名)(函數(shù)參數(shù)列表)”調(diào)用函數(shù)C規(guī)定,函數(shù)名代表函數(shù)的入口地址,可定義一個(gè)指針變量存放函數(shù)的入口地址,則該指針稱為指向函數(shù)的指針,簡稱函數(shù)指針。(1)通過函數(shù)名調(diào)用函數(shù)#include<stdio.h>intadd(intx,inty);

//函數(shù)聲明intmain(void){ inta,b,sum;printf("請輸入a、b的值:");scanf("%d%d",&a,&b);sum=add(a,b);//通過函數(shù)名調(diào)用add函數(shù) printf("a=%d,b=%d\n",a,b);printf("sum=%d\n",sum);}intadd(intx,inty){return(x+y);}5.5指向函數(shù)的指針

練習(xí):

教材【思考與實(shí)驗(yàn)】用起來更復(fù)雜,又有何用?

1、用函數(shù)名調(diào)用函數(shù),只能調(diào)用所指定的一個(gè)函數(shù);而通過指針變量可以根據(jù)不同情況先后調(diào)用不同的函數(shù),使用靈活。【例5.19】輸入兩個(gè)整數(shù),然后讓用戶選擇1或2,選擇1時(shí)調(diào)用max函數(shù),輸出兩數(shù)中的大數(shù);選擇2時(shí)調(diào)用min函數(shù),輸出兩數(shù)中的小數(shù)。2、指向函數(shù)的指針變量可作為函數(shù)參數(shù)進(jìn)行信息傳遞。5.6返回指針值的函數(shù)(指針型函數(shù))

一個(gè)函數(shù)可以返回指針型的值,即返回一個(gè)地址。聲明返回指針值的函數(shù)(指針型函數(shù)),一般形式:

類型標(biāo)識符*函數(shù)名(形參列表);

()優(yōu)先級高于*,因此f先與()結(jié)合,表示這是f函數(shù)。調(diào)用該函數(shù)之后能得到一個(gè)int*型的指針(指向整型數(shù)據(jù)),即整型數(shù)據(jù)的地址。

例如:int*f(intx,inty);說明:

在后續(xù)的內(nèi)存動態(tài)分配、鏈表及其操作、文件讀寫操作等內(nèi)容將涉及指針型函數(shù)的應(yīng)用方法。下面通過幾個(gè)簡單實(shí)例理解指針型函數(shù)的基本概念。

5.6返回指針值的函數(shù)(指針型函數(shù))

【例5.20】利用指針型函數(shù)輸出靜態(tài)局部數(shù)組的元素值。

靜態(tài)局部數(shù)組的內(nèi)容在函數(shù)調(diào)用結(jié)束后仍被保留,因此在主函數(shù)中可通過指針變量p輸出數(shù)組中元素的值。

若將數(shù)組a定義為動態(tài)局部數(shù)組,結(jié)果又如何?

#include<stdio.h>int*fun();

//指針型函數(shù)聲明intmain(void){ inti;int*p;

//定義指針變量

p=fun();

//調(diào)用fun函數(shù),獲取一指向整型數(shù)據(jù)的地址for(i=0;i<5;i++,

p++)printf("%4d",

*p);printf("\n");}int*fun()

//指針型函數(shù),返回指向整型數(shù)據(jù)的指針變量{

staticinta[]={1,2,3,4,5};//定義靜態(tài)局部數(shù)組int*q=a;

//定義指針變量q,并指向數(shù)組a

return(q);

//返回?cái)?shù)組a的首地址

}5.6返回指針值的函數(shù)(指針型函數(shù))

【例5.21】利用指針型函數(shù)輸出字符串(位于常量區(qū))。若將此行代碼改為:charstr[]=''abcde'';結(jié)果又如何?#include<stdio.h>char*fun();

//函數(shù)聲明intmain(void){ char*ps;

//定義指針變量

ps=fun();

//調(diào)用fun函數(shù),獲取一指向字符型數(shù)據(jù)的地址printf("%s\n",ps);}char*fun()

//指針型函數(shù),返回指向字符型數(shù)據(jù)的指針變量{

char*str="abcde";//定義指針變量,并指向字符串return(str);

//返回字符串的起始地址

}5.7指針數(shù)組、指向指針的指針

5.7.1指針數(shù)組1、指針數(shù)組的概念

指針數(shù)組用來存放一批地址,每一個(gè)元素都存放一個(gè)地址。

定義一維指針數(shù)組的一般形式:

類型標(biāo)識符*數(shù)組名[數(shù)組長度];例如:int*p[3];

[]比*優(yōu)先級高,p先與[3]結(jié)合,構(gòu)成p[3]數(shù)組的形式,然后再與*結(jié)合,表示數(shù)組p的3個(gè)元素均為指向int型數(shù)據(jù)的指針變量。5.7指針數(shù)組、指向指針的指針

5.7.1指針數(shù)組1、指針數(shù)組的概念

【例5.23】利用指針數(shù)組指向多個(gè)整型變量,并輸出各整型變量的值。

#include<stdio.h>intmain(void){ inta=10,b=20,c=30,i;

int*p[3]={&a,

&b,

&c};

//定義指針數(shù)組并使3個(gè)元素分別指向3個(gè)整型變量for(i=0;i<3;i++)printf("%d\n",

*p[i]);

//利用指針數(shù)組引用整型變量

}5.7指針數(shù)組、指向指針的指針

5.7.1指針數(shù)組1、指針數(shù)組的概念

【例5.24】利用指針數(shù)組指向一維整型數(shù)組的各元素,并引用一維整型數(shù)組的各元素。#include<stdio.h>intmain(void){ inta[3]={10,20,30},i;

int*p[3]={&a[0],&a[1],&a[2]};

//定義指針數(shù)組,并初始化for(i=0;i<3;i++)printf("%d\n",

*p[i]);

//利用指針數(shù)組引用整型數(shù)組元素}5.7指針數(shù)組、指向指針的指針

(1)多個(gè)字符串的處理方法一個(gè)字符串可用一維數(shù)組來存放,而多個(gè)字符串可用二維數(shù)組存放。

若用字符型指針引用多個(gè)字符串,則需要多個(gè)指針,因此也可利用字符型指針數(shù)組處理多個(gè)字符串。【例5.25】分別用二維數(shù)組和字符型指針數(shù)組處理多個(gè)字符串。2、指針數(shù)組的實(shí)際應(yīng)用5.7.1指針數(shù)組#include<stdio.h>intmain(void){

charstr[3][5]={"ab","abc","abcd"};inti;for(i=0;i<3;i++)printf("%s\n",str[i]);}#include<stdio.h>intmain(void){

char*ps[3]={"ab","abc","abcd"};inti;for(i=0;i<3;i++)printf("%s\n",ps[i]);}5.7指針數(shù)組、指向指針的指針

(2)利用函數(shù)型指針數(shù)組實(shí)現(xiàn)對若干個(gè)函數(shù)的調(diào)用【例5.26】函數(shù)型指針數(shù)組的應(yīng)用:實(shí)現(xiàn)對若干個(gè)函數(shù)的調(diào)用。2、指針數(shù)組的實(shí)際應(yīng)用5.7.1指針數(shù)組#include<stdio.h>voidmax(intx,inty);

//函數(shù)聲明voidmin(intx,inty);

//函數(shù)聲明voidadd(intx,inty);

//函數(shù)聲明intmain(void){ inta,b,i;

void(*p[3])(int,int)={max,min,add};

//定義函數(shù)型指針數(shù)組,存放3個(gè)函數(shù)名printf("請輸入兩個(gè)整數(shù):");scanf("%d%d",&a,&b);printf("a=%d,b=%d\n",a,b);for(i=0;i<3;i++)

(*p[i])(a,b);

//利用函數(shù)型指針數(shù)組調(diào)用函數(shù)}5.7指針數(shù)組、指向指針的指針

(3)指針數(shù)組作main函數(shù)的形參

在一些人機(jī)交互應(yīng)用系統(tǒng)中,main函數(shù)是可以帶參數(shù)的。例如:

intmain(intargc,char*argv[])2、指針數(shù)組的實(shí)際應(yīng)用5.7.1指針數(shù)組

操作系統(tǒng)調(diào)用main函數(shù)時(shí),將實(shí)參傳遞給main函數(shù)。在操作系統(tǒng)命令狀態(tài)下,命令行的一般形式:命令字(可執(zhí)行文件名)參數(shù)1參數(shù)2

……

參數(shù)n

例如:可執(zhí)行文件名為SW.exe,現(xiàn)將兩個(gè)字符串“OPEN”、“CLOSE”作為參數(shù)傳遞給main函數(shù),則命令行可寫成:SWOPENCLOSE

說明:argc的值和argv[]各元素的值都是系統(tǒng)自動賦值的。其中,argc的值等于命令行中字符串的總個(gè)數(shù)(包括命令字);argv指針數(shù)組中的各個(gè)元素依次指向命令行中的各個(gè)字符串。

5.7指針數(shù)組、指向指針的指針

【例5.27】測試帶有參數(shù)的main函數(shù)。

在VC++2010開發(fā)環(huán)境中建立項(xiàng)目,項(xiàng)目名為test,保存路徑為E:\test。在此項(xiàng)目中,建立ex.c文件:(3)指針數(shù)組作main函數(shù)的形參2、指針數(shù)組的實(shí)際應(yīng)用5.7.1指針數(shù)組#include<stdio.h>intmain(intargc,char*argv[]){ while(argc>0){ printf("%s\n",

*argv);

//輸出命令行中的字符串

argv++;argc--;}}5.7指針數(shù)組、指向指針的指針

5.7.2指向指針的指針

inta=3; int*num=&a;//定義指針變量num,指向變量a printf("%d\n",*num);//通過指針變量num引用變量a

通過指針變量num間接訪問變量a:“單級間址”訪問方式。

若再定義一個(gè)指針變量p,存放指針變量num的地址,則可通過指針變量p訪問變量a:“二級間址”訪問方式。p是指向指針數(shù)據(jù)的指針變量,簡稱“指向指針的指針”。

定義指向指針的指針變量的一般形式:類型標(biāo)識符**指針變量名;例如:int**p;//指針變量p指向一個(gè)整型的指針變量5.7指針數(shù)組、指向指針的指針

【例5.28】分析程序,理解指向指針的指針。5.7.2指向指針的指針#include<stdio.h>intmain(void){ inta=3;

int*num=&a;

int**p=#printf("%x\n",

num);printf("%x\n",

*p);printf("%d\n",

**p);}5.7指針數(shù)組、指向指針的指針

在實(shí)際應(yīng)用中,指向指針的指針常與指針數(shù)組配合使用處理問題。【例5.29】有一指針數(shù)組num,其元素分別指向一維整型數(shù)組a的各元素?,F(xiàn)用指向指針的指針變量p,依次輸出整型數(shù)組a中各元素的值。5.7.2指向指針的指針#include<stdio.h>intmain(void){ inta[3]={10,20,30},i;

int*num[3]={&a[0],&a[1],&a[2]};

//定義指針數(shù)組num

int**p=num;

//定義指向指針的指針變量p,并指向指針數(shù)組num的首元素for(i=0;i<3;i++,

p++)

printf("%d\n",**p);//利用指向指針的指針變量p引用整型數(shù)組元素}5.7指針數(shù)組、指向指針的指針

5.7.2指向指針的指針【例5.30】有一指針數(shù)組ps,其元素分別指向3個(gè)字符串?,F(xiàn)用指向指針的指針變量p,依次輸出3個(gè)字符串。在實(shí)際應(yīng)用中,指向指針的指針常與指針數(shù)組配合使用處理問題。#include<stdio.h>intmain(void){ inti;

char*ps[3]={"ab","abc","abcd"};

//定義指針數(shù)組ps

char**p=ps;

//定義指向指針的指針變量p,并指向指針數(shù)組ps的首元素for(i=0;i<3;i++,p++)printf("%s\n",*p);

//利用指向指針的指針變量p輸出字符串}5.8內(nèi)存動態(tài)分配與指向動態(tài)內(nèi)存區(qū)的指針變量

5.8.1內(nèi)存動態(tài)分配的概念

在4.5節(jié)中介紹過全局變量和局部變量,全局變量分配在內(nèi)存中的靜態(tài)存儲區(qū),非靜態(tài)的局部變量(包括形參)分配在內(nèi)存中的動態(tài)存儲區(qū)。

除此之外,C語言還允許建立內(nèi)存動態(tài)分配區(qū)域,用來存放一些臨時(shí)用的數(shù)據(jù),這些數(shù)據(jù)不必在程序中的聲明部分定義,也不必等函數(shù)結(jié)束時(shí)才釋放,而是需要時(shí)隨時(shí)申請開辟,不需要時(shí)隨時(shí)釋放。在內(nèi)存中動態(tài)分配的數(shù)據(jù),只能通過指針來引用。5.8.2內(nèi)存動態(tài)分配的方法5.8內(nèi)存動態(tài)分配與指向動態(tài)內(nèi)存區(qū)的指針變量

對內(nèi)存的動態(tài)分配是通過庫函數(shù)來實(shí)現(xiàn)的,對應(yīng)的頭文件是stdlib.h。1、malloc函數(shù):void*malloc(unsignedsize);

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論