




版權(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
b
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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025海南省安全員B證考試題庫附答案
- 武漢設(shè)計(jì)工程學(xué)院《火電廠煙氣凈化Ⅰ》2023-2024學(xué)年第二學(xué)期期末試卷
- 湖北科技學(xué)院《生物技術(shù)制藥B》2023-2024學(xué)年第二學(xué)期期末試卷
- 四川科技職業(yè)學(xué)院《房屋建筑與實(shí)務(wù)》2023-2024學(xué)年第二學(xué)期期末試卷
- 荊門職業(yè)學(xué)院《雷達(dá)信號分析》2023-2024學(xué)年第二學(xué)期期末試卷
- 黑龍江三江美術(shù)職業(yè)學(xué)院《BIM技術(shù)與軟件應(yīng)用》2023-2024學(xué)年第二學(xué)期期末試卷
- 長春早期教育職業(yè)學(xué)院《紡織品實(shí)驗(yàn)與設(shè)計(jì)》2023-2024學(xué)年第二學(xué)期期末試卷
- 2024-2025學(xué)年河北省部分重點(diǎn)中學(xué)高三上學(xué)期12月聯(lián)考?xì)v史試卷
- 廣西民族師范學(xué)院《連鎖經(jīng)營管理》2023-2024學(xué)年第二學(xué)期期末試卷
- 青島求實(shí)職業(yè)技術(shù)學(xué)院《商務(wù)禮儀E》2023-2024學(xué)年第二學(xué)期期末試卷
- 潔凈空調(diào)負(fù)荷計(jì)算表格
- 瀘州食品安全承諾書
- 《機(jī)械基礎(chǔ)》課程標(biāo)準(zhǔn)
- 大理市房地產(chǎn)市場調(diào)研報(bào)告
- 倉庫固定資產(chǎn)管理規(guī)范
- 企業(yè)關(guān)停方案
- 陰道分泌物檢驗(yàn)
- 企業(yè)安全文化建設(shè)導(dǎo)則
- 職業(yè)技能等級認(rèn)定管理制度匯編
- 八年級語文上冊第六單元作業(yè)設(shè)計(jì) 品格與志趣
- C++面向?qū)ο蟪绦蛟O(shè)計(jì)雙語教程(第3版)課件全套 ch01Introduction-ch08Templates
評論
0/150
提交評論