C語言程序設(shè)計(jì)(八)-指針及宏定義_第1頁
C語言程序設(shè)計(jì)(八)-指針及宏定義_第2頁
C語言程序設(shè)計(jì)(八)-指針及宏定義_第3頁
C語言程序設(shè)計(jì)(八)-指針及宏定義_第4頁
C語言程序設(shè)計(jì)(八)-指針及宏定義_第5頁
已閱讀5頁,還剩70頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第八章指針及宏定義

主要內(nèi)容

8.1地址和指針的概念

8.2變量的指針和指向變量的指針變量

8.3數(shù)組與指針

8.4字符串與指針

8.5指向函數(shù)的指針

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

8.7指針數(shù)組和指向指針的指針

8.8有關(guān)指針的數(shù)據(jù)類型和指針運(yùn)算的小結(jié)

8.1地址和指針的概念內(nèi)存區(qū)的每一個字節(jié)有一個編號,這就是“地址”。如果在程序中定義了一個變量,在對程序進(jìn)行編譯時(shí),系統(tǒng)就會給這個變量分配內(nèi)存單元?!?1234…nn-2注:地址實(shí)際上使用8個16進(jìn)制數(shù)表示:如:0x00000010,0x0F00FF921.按變量名存取變量值的方式稱為“直接訪問”方式

shorti,j;

shortk=i+j;

printf(“%d”,k);

8.1.2直接訪問與間接訪問2.另一種存取變量值的方式稱為“間接訪問”的方式。即,將變量i的地址存放在另一個變量j中,通過j訪問i。由于j存放的是i的地址,在C語言中,j稱為指針。指針是一種特殊的變量,它是存放地址的。

8.1.2直接訪問與間接訪問一個變量的地址稱為該變量的“指針”。例如,地址2000是變量i的指針。如果有一個變量專門用來存放另一變量的地址(即指針),則它稱為“指針變量”。上述的i_pointer就是一個指針變量。8.1.3指針和指針變量的定義:int*i_pointer=&i;8.2

定義一個指針變量定義指針變量的一般形式為

基類型*

指針變量名;提示:書上的形式一般為:基類型*指針變量名。下面都是合法的定義:

float*

pointer_3;

char*

pointer_4;由于指針變量代表的是地址,所以應(yīng)該用賦值語句使一個指針變量得到另一個變量的地址,從而使它指向一個該變量。取某個變量的地址,應(yīng)該用&變量名的方式例如:

inti,j;int*pointer_1=&i;int*pointer_2=&j;其中&稱為“取地址符”在定義指針變量時(shí)要注意兩點(diǎn):(1)指針變量前面的“*”,表示該變量的類型為指針型變量。

例:float*

pointer_1;

指針變量名是pointer_1,而不是*pointer_1

(2)在定義指針變量時(shí)必須指定基類型。需要特別注意的是,只有整型變量的地址才能放到指向整型變量的指針變量中。下面的賦值是錯誤的∶

floata;int*pointer_1;pointer_1=&a;即:同類型變量的地址應(yīng)該放入同類型的指針中。8.2.2指針變量的使用

定義好一個指針,指向某個變量地址后,可以通過該指針直接訪問變量。5i的地址ii_pointer例:inti=5;int*i_pointer=&i;問題:怎么通過i_pointer來訪問i呢?i_pointer=10;//不行,修改的是i_pointer的內(nèi)容*i_pointer=10;通過指針訪問所指向的變量的時(shí)候,應(yīng)該通過*指針變量名的方式。printf(“%d”,*i_pointer);8.2.2指針變量的引用

例8.1

通過指針變量訪問整型變量#include<stdio.h>voidmain(){

inta,b;

int*pointer_1,*pointer_2;

a=100;b=10;pointer_1=&a;

pointer_2=&b;

printf(″%d,%d\n″,a,b);

printf(″%d,%d\n″,*pointer_1,*pointer_2);}8.2.3對“&”和“*”運(yùn)算符說明:&取地址運(yùn)算符。&a是變量a的地址*指針(間接)運(yùn)算符,*p代表指針變量p指向的變量假設(shè):如果已執(zhí)行了語句pointer_1=&a;(1)&*pointer_1的含義是什么?“&”和“*”兩個運(yùn)算符的優(yōu)先級別相同,但按自右而左方向結(jié)合。因此,&*pointer_1與&a相同,即變量a的地址&*pointer_1=>&(*pointer_1)

(2)如果

pointer_2=&*pointer_18.2.3對“&”和“*”運(yùn)算符說明:point_2=&(*pointer_1)(3)

*&a的含義是什么?

*&a=>*(&a)

先進(jìn)行&a運(yùn)算,得a的地址,再進(jìn)行*運(yùn)算。*&a和*pointer_1的作用是一樣的,它們都等價(jià)于變量a。即*&a與a等價(jià)。(4)(*pointer_1)++相當(dāng)于a++。8.2.3對“&”和“*”運(yùn)算符說明:提示:*pointer_1++不等價(jià)于*(pointer_1)++練習(xí):請分別定義整形變量、浮點(diǎn)型變量、字符型變量,以及指向這3個變量的指針,并通過指針輸出變量的值。8.3指針變量作為函數(shù)參數(shù)指針可以作為函數(shù)形參,這時(shí)候?qū)崊?yīng)該傳地址,而不是值。voidfunc(int*p)

{

(*p)++;}voidmain(){

inta=10;

func();

}&aprintf(“%d”,a);問題:這里a的值是什么?int*p=&a;(*p)++;翻譯為a的地址ap*p1011提示:當(dāng)指針作為形參的時(shí)候,會“改變”實(shí)參到形參單向值傳遞的概念。8.3指針變量作為函數(shù)參數(shù)例8.2

對輸入的兩個整數(shù)按大小順序輸出

//voidswap(intp1,intp2)voidswap(int*p1,int*p2)voidmain(){

inta=5,b=9;int*pointer_1=&a;

int*pointer_2

=&b;

if(a<b)

swap(pointer_1

,pointer_2);printf(″\n%d,%d\n″,a,b);}

voidswap(int*p1,int*p2){inttemp;temp=*p1;*p1=*p2;*p2=temp;

}例8.3

輸入a、b、c3個整數(shù),按大小順序輸出。#include<stdio.h>voidswap(int*p1,int*p2);voidexchange(int*q1,int*q2,int*q3);voidmain(){

inta,b,c;

int*p1,*p2,*p3;

scanf(″%d,%d,%d″,

&a,&b,&c);

p1=&a;p2=&b;p3=&c;exchange(p1,p2,p3);

}voidexchange(int*q1,int*q2,int*q3){if(*q1<*q2)

swap(q1,q2);

if(*q1<*q3)

swap(q1,q3);

if(*q2<*q3)

swap(q2,q3);}voidswap(int*pt1,int*pt2){inttemp;temp=*pt1;

*pt1=*pt2;

*pt2=temp;}8.3數(shù)組與指針

一個變量有地址,一個數(shù)組包含若干元素,每個數(shù)組元素都在內(nèi)存中占用存儲單元,它們都有相應(yīng)的地址。指針變量既然可以指向變量,當(dāng)然也可以指向數(shù)組元素(把某一元素的地址放到一個指針變量中)。數(shù)組元素的指針就是數(shù)組元素的地址。123456inta[6]:a[0]a[1]……a[5]例:如何定義一個指針指向數(shù)組a中的某個元素?int*p;p=&a[0];p=&a[5];即:定義一個指向數(shù)組某個元素的指針,和定義指向同類型變量的指針一致

8.3.1

指針的實(shí)質(zhì)與指針運(yùn)算指針的實(shí)質(zhì)inta=10;int*p=&a;10ap類型名*指針名printf(“%d”,a);(*p)++;總結(jié):

指針永遠(yuǎn)指向的是內(nèi)存區(qū)塊的首地址,而指針類型決定了指針從該地址向前訪問多少空間。short*m=&a;printf(“%d”,*m);m限定了訪問多少字節(jié)(short*)

8.3.1

指針的實(shí)質(zhì)與指針運(yùn)算關(guān)于指針運(yùn)算假設(shè)定義了一個數(shù)組:inta[5]a[0]a[1]a[2]a[3]a[4]int*p=&a[0];pp=&a[1];20002004200820122016p=&a[n];….問題:怎么讓p指向數(shù)組a的下一個元素實(shí)際上可以通過p++(或p+1)的形式,讓p訪問數(shù)組的下一個單元疑惑:假設(shè)數(shù)組a的首地址為2000,p指向a[0],即p也指向2000錯誤的思路:p++=>2000+1=2001?正確的計(jì)算:p++=>2000+p所指的變量類型大小

錯誤:2000+int類型所占字節(jié)數(shù)=2000+4=2004總結(jié):關(guān)于指針:p+n的計(jì)算方式等價(jià)于

p地址+n*p所指的變量類型大小

8.3.1

指針的實(shí)質(zhì)與指針運(yùn)算練習(xí)1:假設(shè)目前有一個指針p指向一個浮點(diǎn)型數(shù)組的a[1]元素,該數(shù)組的首地址為2000,p+2的值為?練習(xí)2:假設(shè)目前有一個指針p指向一個短整型數(shù)組的a[3]元素,該數(shù)組的首地址為2000,p+7的值為?練習(xí)3:假設(shè)目前有一個指針p指向一個字符串s的第5個字符,該字符串的首地址為2000,p-2的值為?a[1]的地址為2004p+2=2004+2*sizeof(float)=2012a[3]的地址為2006p+7=2006+7*sizeof(short)=2020s[5]的地址為2005p-2=2005+(-2*sizeof(char))=2003

8.3.2

指針與數(shù)組的關(guān)系a[0]a[1]a[2]a[3]a[4]p20002004200820122016假設(shè)定義了一個數(shù)組:inta[5],p=&a[0];printf(“%d,%d”,a[0],*p);應(yīng)該是同一個值簡單結(jié)論:a[0]等價(jià)于*(p+0)問題:那a[0]本身到底在做什么呢?a定義一個數(shù)組等價(jià)于定義一個連續(xù)的空間和一個指向該空間首地址的指針:即數(shù)組名!a[0]等價(jià)于一個指針操作,即:*(a+0)重要結(jié)論1:數(shù)組名[n]的操作等價(jià)于指針操作,即:

a[n]等價(jià)于*(a+n)重要結(jié)論2:引用一個數(shù)組元素,可以用:(1)下標(biāo)法,如a[i]形式;(2)指針法,如*(a+i)或*(p+i)。其中a是數(shù)組名,p是指向數(shù)組元素的指針變量,其初值p=a。例8.4

輸出數(shù)組中的全部元素。

假設(shè)有一個a數(shù)組,整型,有10個元素。要輸出各元素的值有三種方法:

8.3.2

指針與數(shù)組的關(guān)系(1)下標(biāo)法。#include<stdio.h>voidmain(){

inta[10];

inti;

for(i=0;i<10;i++)

scanf(″%d″,&a[i]);printf(″\n″);

for(i=0;i<10;i++)

printf(″%d″,a[i]);

}(2)通過數(shù)組名計(jì)算數(shù)組元素地址,找出元素的值。#include<stdio.h>voidmain(){inta[10];inti;

for(i=0;i<10;i++)

scanf(″%d″,&a[i]);

printf(″\n″);for(i=0;i<10;i++)

printf(″%d″,*(a+i));

}scanf接受的是地址,因此這里可以寫a+i(3)

用指針變量指向數(shù)組元素。#include<stdio.h>voidmain(){inta[10];int*p,i;for(i=0;i<10;i++)scanf(″%d″,&a[i]);printf(″\n″);for(p=a;p<(a+10);p++)

printf(″%d″,*p);

}8.3.3

用數(shù)組名作函數(shù)參數(shù)回顧:若要一個函數(shù)接受數(shù)組作為參數(shù),則該函數(shù)的形參表可以為:voidfunc(inta[],intn);voidfunc(inta[/*數(shù)組大小*/]);而由于數(shù)組名實(shí)際上等價(jià)于指針,即,假設(shè)inta[10]等價(jià)于定義了一個指針int*a指向一個包含10個整形變量的空間的首地址。因此,當(dāng)一個函數(shù)的形參表為數(shù)組時(shí),其存在第三個寫法:voidfunc(int*a,intn);調(diào)用該函數(shù)時(shí)候,依然傳數(shù)組名和數(shù)組大?。?/p>

func(a,10);例8.5

將數(shù)組a中n個整數(shù)按相反順序存放。#include<stdio.h>voidinv(intx[],intn);voidmain(){inti,a[10]={3,7,9,11,0,6,7,5,4,2};

inv(a,10);

//輸出}voidinv(intx[],intn)/*形參x是數(shù)組名*/

{inttemp,i,j,m=(n-1)/2;for(i=0;i<=m;i++)

j=n-1-i;

temp=x[i];

x[i]=x[j];

x[j]=temp;

}}voidinv(int*x,intn)/*形參x為指針變量*/{

intp,temp;

int*i,*j,m=(n-1)/2;

i=x;j=x+n-1;p=x+m;

for(;i<=p;i++,j--)

{temp=*i;*i=*j;*j=temp;}}解惑:數(shù)組作為參數(shù)時(shí),實(shí)參到形參的“值”傳遞,傳遞的是什么?8.3.3

用數(shù)組名作函數(shù)參數(shù)從數(shù)組和指針的關(guān)系中可以看出,定義數(shù)組實(shí)際上是定義的指針,因此,當(dāng)數(shù)組作為參數(shù)時(shí),無論哪種形式,實(shí)參到形參傳遞的都是該指針的地址。voidf(intp[],intn)voidf(intp[10])voidf(int*p,intn)inta[10];f(a);//f(a,10)ap拷貝結(jié)論:數(shù)組作為參數(shù)時(shí),形參和實(shí)參實(shí)際指向同一個數(shù)組例8.6

用選擇法對10個整數(shù)按由大到小順序排序。

voidsort(int*x,intn){inti,j,k,t

for(i=0;i<n-1;i++)

{k=i;for(j=i+1;j<n;j++)

if(*(x+j)>*(x+k))k=j;

if(k?。剑?

{

t=*(x+i);

*(x+i)=*(x+k);

*(x+k)=t;}}}拓展:指針和數(shù)組關(guān)系的用法a=10int*p=&a;p除了通過*p獲取a的值外,還有別的方法嗎?n=10m=9可以通過p來獲取m和n的值嗎?p[0]p[-1]獲取mp[1]獲取n8.3.3

用數(shù)組名作函數(shù)參數(shù)總結(jié):定義一個普通變量,等價(jià)定義一個包含1個元素的數(shù)組。即:inta[1]等價(jià)于inta。只不過使用方式不一樣。8.3.3

一維數(shù)組與指針總結(jié)

總結(jié):一維數(shù)組與指針的關(guān)系定義一個一維數(shù)組typea[m],等價(jià)于定義了一個大小為m個sizeof(type)大小的內(nèi)存空間,以及一個指向該空間首地址的指針type*a;chara[5]={…};a即:typea[m]等價(jià)于type*a,但a只能從首地址開始訪問m*sizeof(type)大小的空間而a[n]這種操作,等價(jià)于*(a+n)但注意:這里+n實(shí)際上加的是sizeof(type)*n定義一個指針指向數(shù)組a[m]或定義一個函數(shù),形參表接受a[m]的方法:指針:type*p=a;函數(shù)形參表:(type*p,int/*m*/)提示1:C語言存在一個操作sizeof(變量),將得到該變量所占內(nèi)存空間大小8.3.4多維數(shù)組與指針

用指針變量可以指向一維數(shù)組中的元素,也可以指向多維數(shù)組中的元素。但在概念上和使用上,多維數(shù)組的指針比一維數(shù)組的指針要復(fù)雜一些。1、二維數(shù)組的實(shí)質(zhì):

以inta[3][3]為例a[0][0]a[0][1]a[1][0]a[1][1]a[2][0]a[2][1]a[0][2]a[1][2]a[2][2]一維數(shù)組一維數(shù)組一維數(shù)組aa[0]a[1]a[2]換句話說a[0],a[1]和a[2]是3個一維數(shù)組的名字,即本身是一個指針,分別指向3個一維數(shù)組的首地址,而a指向由a[0],a[1],a[2]構(gòu)成的一維數(shù)組。8.3.4多維數(shù)組與指針

2、二維數(shù)組與指針的聯(lián)系:假設(shè)inta[3][3]數(shù)組的首地址為2000a[0][0]a[0][1]a[1][0]a[1][1]a[2][0]a[2][1]a[0][2]a[1][2]a[2][2]20122024aa[0]a[1]a[2]200020042000201220242008回顧:在一維數(shù)組里面:a[n]等價(jià)于*(a+n)問題:二維數(shù)組里面a[m][n]的指針等價(jià)形式是什么呢?a[0][2]*(a[0]+2)a[0]等價(jià)于*(a+0)*(*(a+0)+2)總結(jié):二維數(shù)組a[m][n]等價(jià)于*(*(a+m)+n)8.3.4多維數(shù)組與指針

3、二維數(shù)組的地址a[0][0]a[0][1]a[1][0]a[1][1]a[2][0]a[2][1]a[0][2]a[1][2]a[2][2]20122024aa[0]a[1]a[2]200020042000201220242008問題1:a[0]和*(a+0)的值是什么?注意:a[0]是指向一個一維數(shù)組的指針(即一維數(shù)組名),C語言規(guī)定,一維數(shù)組名的值就是該數(shù)組的首地址。a[0]的值為第一行元素構(gòu)成的數(shù)組的首地址,即2000而根據(jù)一維數(shù)組等價(jià)形式:a[0]和*(a+0)等價(jià),所以均為2000且與&a[0][0]等價(jià)8.3.4多維數(shù)組與指針

a[0][0]a[0][1]a[1][0]a[1][1]a[2][0]a[2][1]a[0][2]a[1][2]a[2][2]20122024aa[0]a[1]a[2]200020042000201220242008問題2:a+1和*(a+1)的值是什么?答案:a+1和*(a+1)的值均為2012原因:a所指向的那個一維數(shù)組實(shí)際上并不存在于內(nèi)存單元中,僅僅是一種計(jì)算的方式。拓展:aa+0,*a的值分別是什么?均為20008.3.4多維數(shù)組與指針

問題3:a[1]+2,*(a+1)+2,&a[1][2]的值是什么?a[0][0]a[0][1]a[1][0]a[1][1]a[2][0]a[2][1]a[0][2]a[1][2]a[2][2]20122024aa[0]a[1]a[2]200020042000201220242008實(shí)際上均為a[1][2]的地址,即2020問題4:*(a[0]+2),(*(a+0)+2)的值是什么?實(shí)際上均為a[0][2]的值表示形式含義a

二維數(shù)組名,指向一維數(shù)組a[0],即0行首地址a[0],*(a+0),*a0行0列元素地址a+1,&a[1]1行首地址a[1],*(a+1)1行0列元素a[1][0]的地址a[1]+2,*(a+1)+2,&a[1][2]1行2列元素a[1][2]的地址*(a[1]+2),*(*(a+1)+2),a[1][2]1行2列元素a[1][2]的值練習(xí):假設(shè)定義了一個短整型數(shù)組a[2][3],起始地址為3000,存放的數(shù)據(jù)為1,2,3,4,5,6,請寫出下表的值10.3.4多維數(shù)組與指針

4、怎么定義一個指向二維數(shù)組的指針:指向數(shù)組的指針a[0][0]a[0][1]a[1][0]a[1][1]a[2][0]a[2][1]a[0][2]a[1][2]a[2][2]a[0]a[1]a[2]a分析一下a的指向:a指向了一個數(shù)組,其數(shù)組里的每個元素都是一個指向包含3個整形變量的數(shù)組的指針,因此需要一個這樣的指針int[3](*p)=ap解惑:假設(shè)a起始地址為2000,a+1的地址為什么為2012a+1=2000+1*a的類型

=2000+1*4*3=2012總結(jié):如何定義一個指向二維數(shù)組的指針(指向數(shù)組的指針)

數(shù)組類型(*指針名)

[列數(shù)]8.3.4多維數(shù)組與指針

4、定義一個指向二維數(shù)組的指針:第二種方法a[0][0]a[0][1]a[1][0]a[1][1]a[2][0]a[2][1]a[0][2]a[1][2]a[2][2]a[0]a[1]a[2]a由于a[0],a[1],a[2]相當(dāng)于指向一個整形數(shù)組的指針(即數(shù)組名),即數(shù)組名,根據(jù)一維數(shù)組和指針的關(guān)系,還可以這么定義指針指向二維數(shù)組:int*p=a[0];while(p<=a[0]+9){

printf(“%d”,*p);

p++}或者*a提示:由于a[M][N]是連續(xù)存放的,因此二維數(shù)組還能看成是定義了一個M*N的一維數(shù)組,但此一維數(shù)組的數(shù)組名是a[0]或者*a,而不是a。例10.11用指針變量輸出二維數(shù)組元素的值

#include<stdio.h>voidmain(){inta[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};int*p;for(p=a[0];p<a[0]+12;p++)

{if((p-a[0])%4==0)printf(″\n″);printf(″%4d″,*p);

}}8.3.4多維數(shù)組與指針

(2)指向由m個元素組成的一維數(shù)組的指針變量例8.7

出二維數(shù)組任一行任一列元素的值#include<stdio.h>voidmain(){inta[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};

int(*p)[4],i,j;

p=a;

scanf(″i=%d,j=%d″,&i,&j);

printf(″a[%d,%d]=%d\n″,i,

j,*(*(p+i)+j));}8.3.4多維數(shù)組與指針

擴(kuò)展:指針數(shù)組(注意和指向數(shù)組的指針區(qū)別)先從簡單的開始:指向指針的指針(即指向地址的指針)。20003p問題:怎么通過p獲取變量a的值。intaq假設(shè)p所指向的地址變量為q通過q訪問a,明顯是*qq的定義方式明顯是int*q=&a由于p是指向q的指針*p就是q,而*q能訪問a*(*p)即**p能訪問a因此:p是個指針,只不過其類型是int**p,即一個指向指針(地址)的指針,也稱間接指針??偨Y(jié):定義一個指向指針的指針type**變量名示例:int*q=&a;int**p=&q;8.3.4多維數(shù)組與指針

a[0]a[1]a[2]a怎么定義這樣數(shù)組呢?type*name[N]總結(jié):定義一個數(shù)組中有N個元素,每個元素都為type類型指針的指針數(shù)組擴(kuò)展:指針數(shù)組(注意和指向數(shù)組的指針區(qū)別)假設(shè)我們需要定義一個數(shù)組,其數(shù)組里面的每個元素都是一個指向同一類型的變量的指針。1045a[3]int*8.3.4多維數(shù)組與指針

擴(kuò)展:指針數(shù)組(注意和指向數(shù)組的指針區(qū)別)a[0]a[1]a[2]a1045怎么定義一個指針指向該指針數(shù)組a呢?a其實(shí)是一個指向指針的指針*a*而定義一個指向數(shù)組a的指針的類型和數(shù)組名的類型相同:簡化問題:a[0]a10int**aint**p=a;8.3.4多維數(shù)組與指針

擴(kuò)展:指針數(shù)組(注意和指向數(shù)組的指針區(qū)別)a[0]a[1]a[2]a1045繼續(xù)糾結(jié):int**p=a;p通過指針p訪問4所在的空間(p+1)**()考慮一下p+1的值的計(jì)算方式:p+1=數(shù)組a的首地址+1*數(shù)組元素的大小數(shù)組元素為指針指針即地址,占多大的內(nèi)存空間呢?任意類型的指針大小均為4個字節(jié)提示:指針數(shù)組的使用8.3.4多維數(shù)組與指針

假設(shè)存在3個整形變量i,j,k,怎么定義一個指針數(shù)組存放這3個整形變量的地址呢?int*p[3];p[0]=&i;p[1]=&j;p[2]=&k;1、申明后初始化2、申明時(shí)初始化int*p[3]={&i,&j,&k};3、通過p訪問jprintf(“%d”,*p[1]);提示:使用方式和普通數(shù)組類似,但請注意指針數(shù)組的每個元素都是指針10.3.4多維數(shù)組與指針

總結(jié):指針數(shù)組(指向指針的指針)和指向數(shù)組的指針的區(qū)別1、如何定義一個指向數(shù)組的指針以及一個指針數(shù)組類型名(*p)[數(shù)組大小]指向數(shù)組的指針:指針數(shù)組:類型名*p[數(shù)組大小]2、指向數(shù)組的指針,實(shí)際上代表了一個二維數(shù)組,而指針數(shù)組是一個一維數(shù)組,其每個元素都是一個指針。3、定義一個指向二維數(shù)組的指針時(shí),需要使用指向數(shù)組的指針。而定義一個指向指針數(shù)組的指針時(shí),需要使用指向指針的指針。inta[3][4]int(*p)[4]=a;int*a[4]int**p=a;練習(xí):假設(shè)存在以下兩個數(shù)組floatb[4][2],short*c[15],請分別定義兩個指針p和q指向b和c,并通過p訪問b[3][1],通過q訪問c[12]指向的變量;8.3.5.用指向數(shù)組的指針作函數(shù)參數(shù)回顧1:由于定義一個二維數(shù)組a[M][N],等價(jià)于定義了一個指針:TYPE(*a)[N],因此,當(dāng)二維數(shù)組作為參數(shù)傳遞時(shí),形參表可以以一個同樣的類型(指向數(shù)組的指針)作為接受類型。接受二維數(shù)組的函數(shù)申明形式3:返回類型函數(shù)名(TYPE(*p)[N],intM)例:假設(shè)有個浮點(diǎn)型數(shù)組floatb[3][4],需要傳給函數(shù)func,則func的申明方式為:voidfunc()float(*b)[4],intsize調(diào)用時(shí),可寫為:func(b,3);8.3.5.用指向數(shù)組的指針作函數(shù)參數(shù)回顧2:由于定義一個二維數(shù)組a[M][N],等價(jià)于定義了一個包含MxN個元素的一維數(shù)組,但數(shù)組名為*a或者a[0],接受二維數(shù)組的形參可以是type*p,傳參為*a或者a[0]接受二維數(shù)組的函數(shù)申明形式4:返回類型函數(shù)名(TYPE*p,int/*M*N*/)例:假設(shè)有個浮點(diǎn)型數(shù)組floatb[3][4],需要傳給函數(shù)func,則func的申明方式為:voidfunc()float*p,intsize調(diào)用時(shí),可寫為:func(b,3*4);voidaverage(float*p,intn);voidsearch(float(*p)[4],intn);voidmain(){floatscore[3][4]={{65,67,70,60},{80,87,90,81},{90,99,100,98}};

average(*score,12);/*求12個分?jǐn)?shù)的平均分*/

search(score,2);

/*求序號為2的學(xué)生的成績*/}例8.8

有一個班,3個學(xué)生,各學(xué)4門課,計(jì)算總平均分?jǐn)?shù)以及第n個學(xué)生的成績。這個題目是很簡單的。只是為了說明用指向數(shù)組的指針作函數(shù)參數(shù)而舉的例子。用函數(shù)average求總平均成績,用函數(shù)search找出并輸出第i個學(xué)生的成績。voidaverage(float*p,intn){

float*p_end;

floatsum=0,aver;

p_end=p+n-1;

//找到數(shù)組的最后一個位置

for(;p<=p_end;p++)

sum=sum+(*p);

aver=sum/n;

printf(″average=%5.2f\n″,aver);}voidsearch(float(*p)[4],intn)

/*p是指向具有4個元素的一維數(shù)組的指針*/{inti;printf(″thescoreofNo.%dare:\n″,n);for(i=0;i<4;i++)

printf(″%5.2f″,*(*(p+n)+i));}例8.9

在上題基礎(chǔ)上,查找有一門以上課程不及格的學(xué)生,打印出他們的全部課程的成績。

#include<stdio.h>voidmain(){voidsearch(float(*p)[4],intn);/*函數(shù)聲明*/floatscore[3][4]={{65,57,70,60},{58,87,90,81},{90,99,100,98}};

search(score,3);}voidsearch(float(*p)[4],intn){inti,j,flag;for(j=0;j<n;j++){flag=0;for(i=0;i<4;i++)

if(*(*(p+j)+i)<60)flag=1;if(flag==1){printf("No.%dfails,hisscoresare:\n",j+1);for(i=0;i<4;i++)printf(″%5.1f″,*(*(p+j)+i));printf(″\n″);}}}

總結(jié):多維數(shù)組與指針的關(guān)系(以二維數(shù)組為例)1、定義一個M行N列的二維數(shù)組a,等價(jià)于定義了a指向一個一維數(shù)組,該一維數(shù)組存放的了M個指向包含N個元素的一維數(shù)組的指針(指向數(shù)組的指針)。inta[3][4]int(*)[4]定義一個指針指向該數(shù)組:int(*p)[4]=a;函數(shù)形參表:(int

(*p)[N],int/*M*/);2、定義一個M行N列的二維數(shù)組a,等價(jià)于定義了一個一維數(shù)組,該一維數(shù)組擁有M*N個元素,但此一維數(shù)組的數(shù)組名為a[0]或*ainta[3][4]intb[3*4]b=*a定義一個指針指向該數(shù)組:int*p=*a或a[0];函數(shù)形參表:(int*p,int/*M*N*/);8.4多維數(shù)組與指針總結(jié)

3、多維數(shù)組與指針的運(yùn)算關(guān)系當(dāng)定義一個二維數(shù)組typea[m][n],a[1][2]=3等價(jià)于*(*(a+1)+2))即:a[x][y]等價(jià)于*(*(a+x)+y))注意:這里的+x等價(jià)于

+x*sizeof(type)*n注意:這里的+y等價(jià)于

+y*sizeof(type)例:假設(shè)inta[3][4],起始地址為2000a[2][1]等價(jià)于*(*(a+2)+1),其地址計(jì)算方式為2000+2*sizeof(int)*4+1*sizeof(int)=20368.4多維數(shù)組與指針總結(jié)

4、指針數(shù)組和指向數(shù)組的指針的區(qū)別type(*p)[m]:定義一個指針,指向一個類型為type,包含m

個元素的數(shù)組type*p[m]:p是一個包含m個元素的數(shù)組,其每個元素都是一

個type*指針如何定義一個指向“指針數(shù)組”的指針type**m=p;由于指針數(shù)組的數(shù)組名依然是個指針,而其數(shù)組元素也是指針,因此其實(shí)際為指向指針的指針。要訪問m指向的元素需要兩次解引用,即**m8.4多維數(shù)組與指針總結(jié)

8.4多維數(shù)組與指針總結(jié)

綜合練習(xí):(作業(yè))inta[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};1、現(xiàn)假設(shè)存在一個二維數(shù)組如下:請問以下一些操作的值分別是什么:(假設(shè)數(shù)組的啟始地址是1000)a、*a、a[0]、*(a+0)、

a[1]、a+1、&a[1][0]、

*(a+2)、&a[2]a[1][0]、

*(*(a+2)+1)綜合練習(xí):(作業(yè))8.4多維數(shù)組與指針總結(jié)

2、假設(shè)存在數(shù)組inta[3][4],請用兩種不同的方式,定義指針指向該數(shù)組,并通過該指針訪問a[2][3]元素。3、假設(shè)目前需要一個數(shù)組,存放4個浮點(diǎn)型變量的地址,請定義這樣一個數(shù)組,并定義一個指向該數(shù)組的指針p,通過該指針訪問第3個元素所指向的浮點(diǎn)型變量的值。例:floata,b,c,d;

//定義數(shù)組,并賦值a,b,c,d的地址

//定義指針指向數(shù)組,并訪問第三個元素4、假設(shè)一個不需要返回值的函數(shù)func,接受一個二維數(shù)組floata[2][3]為參數(shù),請寫出4種不同的func申明方式。8.5字符串與指針8.5.1字符串的指針表示形式

#include<stdio.h>voidmain(){

charstring[]=″IloveChina!″;

printf(″%s\n″,string);}回顧:用字符數(shù)組存放一個字符串,然后輸出該字符串。string其實(shí)是一個char*因此:可以不定義字符數(shù)組,而定義一個字符指針。用字符指針指向字符串中的字符。char*string=″IloveChina!″;提示1:字符串(字符數(shù)組)名其實(shí)就是個char*,可以通過其方便的操作字符串提示2:字符串(字符數(shù)組)滿足一維數(shù)組與指針的關(guān)系例8.10

將字符串a復(fù)制為字符串b。

#include<stdio.h>voidmain(){chara[]=″Iamaboy.″,b[20];inti;

for(i=0;*(a+i)?。健洌埽啊?;i++)*(b+i)=*(a+i);

*(b+i)=′\0′;printf(″stringais:%s\n″,a);printf(″stringbis:″);for(i=0;b[i]?。健洌埽啊?;i++)

printf(″%c″,b[i]);printf(″\n″);}也可以設(shè)指針變量,用它的值的改變來指向字符串中的不同的字符。例8.11

用指針變量來處理例8.9問題。#include<stdio.h>voidmain(){chara[]=″Iamaboy.″,b[20],*p1,*p2;inti;

p1=a;p2=b;

for(;*p1?。健洌埽啊?;p1++,p2++)

*p2=*p1;

*p2=′\0′;

printf(″stringais:%s\n″,a);

printf(″string

is:″);

for(i=0;b[i]?。健洌埽啊洌唬椋?/p>

printf(″%c″,b[i]);}8.5字符串與指針8.5.1

字符指針作函數(shù)參數(shù)例8.12

用函數(shù)調(diào)用實(shí)現(xiàn)字符串的復(fù)制

#include<stdio.h>voidcopy_string(char*from,char*to);voidmain(){

chara[]=″Iamateacher.″;charb[]=″youareastudent.″;

copy_string(a,b);printf("\nstringa=%s\nstringb=%s\n",a,b);}用字符串作參數(shù):由于字符串就是字符數(shù)組,所以定義指針指向字符串,或傳遞給函數(shù)的方式和普通一維數(shù)組一致。voidcopy_string(char*from,char*to){inti=0;while(from[i]?。健洌埽啊洌?/p>

{to[i]=from[i];i++;}

to[i]=′\0′;}這里的形參還可以是charfrom[],charto[]對copystring

函數(shù)的幾種簡化寫法

voidcopy_string(char*from,char*to){while((*to=*from)?。健洌埽啊洌?/p>

{to++;from++;}}?copy_string函數(shù)的函數(shù)體還可改為{

while((*to++=*from++)!=’\0’);}while(*from?。健洌埽啊洌?/p>

*to++=*from++;*to=′\0′;思考:如果copy_string函數(shù)返回值為實(shí)際拷貝的字符數(shù)量,代碼應(yīng)該怎么修改?8.5.1

字符指針作函數(shù)參數(shù)例8.13

用函數(shù)實(shí)現(xiàn)計(jì)算字符串長度以及兩個字符串的連接

intstringLen(char*

str)

{inti=0;

while(from[i]?。健洌埽啊洌?/p>

{i++;}

returni+1;}voidstringCat(char*

dest,char*from)

{inti=

stringLen(dest);

intj=0;while(*(from+j)!=‘\0’)

{dest[i++]=from[j++];

}}字符數(shù)組由若干個字符元素組成,而字符指針變量中存放的是地址(字符串第1個字符的地址),決不是將字符串放到字符指針變量中。賦值方式。對字符數(shù)組只能對各個元素賦值,不能用以下辦法對字符數(shù)組賦值。

charstr[14];

str=″IloveChina!″;而對字符指針變量,可以采用下面方法賦值:

char*a;

a=″IloveChina!″;8.5.2

對使用字符指針變量和字符數(shù)組的討論字符數(shù)組和字符指針變量二者之間的區(qū)別:(3)對字符指針變量賦初值:

char*a=″IloveChina!″;8.5.2

對使用字符指針變量和字符數(shù)組的討論char*a;a=″IloveChian!″;等價(jià)于

charstr[14];str[]=″IloveChina!″;而對數(shù)組的初始化:

charstr[14]={″IloveChina!″};不能等價(jià)于(4)字符指針變量的值是可以改變的,計(jì)算方式和普通指針類似,例如:char*a=″IloveChina!″;a=a+7;printf(“%s”,a);相當(dāng)于將a向前移動了7個字符,即輸出為China函數(shù)與指針,函數(shù)名到底是什么?floatSub(floata,floatb){returna–b;}因此:函數(shù)名實(shí)際上也是個指針!關(guān)鍵問題,指向什么類型?本例中,指向了一個返回值為float,且接受兩個float參數(shù)的函數(shù)。=Sub;float(float,float)怎么定義一個指向本例函數(shù)的指針*p()總結(jié):函數(shù)名實(shí)際上是一個指針,其類型為:返回類型(*)(形參表)8.6指向函數(shù)的指針

溫馨提示

  • 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

提交評論