




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第十章指針第十章指針
主要內(nèi)容10.1地址和指針的概念
10.2變量的指針和指向變量的指針變量
10.3數(shù)組與指針
10.4字符串與指針
10.5指向函數(shù)的指針
10.6返回指針值的函數(shù)
10.7指針數(shù)組和指向指針的指針
10.8有關(guān)指針的數(shù)據(jù)類型和指針運算的小結(jié)主要內(nèi)容10.1地址和指針的概念10.1地址和指針的概念內(nèi)存區(qū)的每一個字節(jié)有一個編號,這就是“地址”。如果在程序中定義了一個變量,在對程序進行編譯時,系統(tǒng)就會給這個變量分配內(nèi)存單元。1.按變量地址存取變量值的方式稱為“直接訪問”方式printf(″%d″,i);scanf(″%d″,&i);k=i+j;10.1地址和指針的概念內(nèi)存區(qū)的每一個字節(jié)有一個編號,這就C語言入門學(xué)習(xí)-C第10章-指針課件2.另一種存取變量值的方式稱為“間接訪問”的方式。即,將變量i的地址存放在另一個變量中。在C語言中,指針是一種特殊的變量,它是存放地址的。2.另一種存取變量值的方式稱為“間接訪問”的方式。即,將變一個變量的地址稱為該變量的“指針”。例如,地址2000是變量i的指針-----計算機給變量i分配存儲空間的中的第一個字節(jié)的字節(jié)編號。
如果有一個變量(計算機也給這個變量分配了存儲空間)專門用來存放另一變量的地址(即指針),則它稱為“指針變量”。上述的i_pointer就是一個指針變量。指針和指針變量的定義:一個變量的地址稱為該變量的“指針”。指針和指針變量的定義:
10.2變量的指針和指向變量的指
針變量10.2.1定義一個指針變量定義指針變量的一般形式為基類型*指針變量名;這里的*不是運算10.2變量的指針和指向變量的指
針變量10下面都是合法的定義:float*pointer_3;
char*pointer_4;可以用賦值語句使一個指針變量得到另一個變量的地址,從而使它指向一個該變量。例如:pointer_1=&i;pointer_2=&j;下面都是合法的定義:指針變量前面的“*”,表示該變量的類型為指針型變量。例:float*pointer_1;指針變量名是pointer_1
,而不是*pointer_1
。(2)在定義指針變量時必須指定基類型?;愋筒皇侵羔樧兞康念愋?。
基類型:指針變量里面存放的是內(nèi)存中的一個字節(jié)編號,在這個編號所對應(yīng)的存儲空間里面存放的數(shù)據(jù)類型。在定義指針變量時要注意兩點:指針變量前面的“*”,表示該變量的類型為指針型變量。(2)int*a指針變量a的基類型是intfloat*b指針變量b的基類型是float下面的賦值是錯誤的∶
floata;int*pointer_1;基類型為intpointer_1=&a;變量a的類型為float
需要特別注意的是,只有整型變量的地址才能放到指向整型變量的指針變量中。
int*a指針變量a的基類型是int下面的賦值是錯10.2.2指針變量的引用
注意:指針變量中只能存放地址(指針),不要將一個整數(shù)(或任何其他非地址類型的數(shù)據(jù))賦給一個指針變量。
例10.1通過指針變量訪問整型變量#include<stdio.h>voidmain(){inta,b;int*pointer_1,*pointer_2;a=100;b=10;pointer_1=&a;/*把變量a的地址賦給
pointer_1*/10.2.2指針變量的引用注意:指針變量中只能存放地址(pointer_2=&b;/*把變量b的地址賦給
pointer_2*/printf("%d,%d\n",a,b);printf("%d,%d\n",*pointer_1,*pointer_2);}pointer_2=&b;/*把對“&”和“*”運算符說明:如果已執(zhí)行了語句pointer_1=&a;(1)&*pointer_1的含義是什么?“&”和“*”兩個運算符的優(yōu)先級別相同,但按自右而左方向結(jié)合。因此,&*pointer_1與&a相同,即變量a的地址。如果有pointer_2=&*pointer_1;它的作用是將&a(a的地址)賦給pointer_2,如果pointer_2原來指向b,經(jīng)過重新賦值后它已不再指向b了,而指向了a。注:指針變量的值為某個變量的地址,則是指針變量指向某個變量。后面圖示上用了一個符號來表示。對“&”和“*”運算符說明:C語言入門學(xué)習(xí)-C第10章-指針課件(2)
*&a的含義是什么?
先進行&a運算,得a的地址,再進行*運算。*&a和*pointer_1的作用是一樣的,它們都等價于變量a。即*&a與a等價。(3)(*pointer_1)++相當(dāng)于a++。(2)*&a的含義是什么?(3)(*pointer_1)例10.2輸入a和b兩個整數(shù),按先大后小的順序輸出a和b。#include<stdio.h>voidmain(){int*p1,*p2,*p,a,b;scanf("%d,%d",&a,&b);p1=&a;p2=&b;if(a<b){p=p1;p1=p2;p2=p;}printf("a=%d,b=%d\n",a,b);printf("max=%d,min=%d\n",*p1,*p2);}例10.2輸入a和b兩個整數(shù),按先大后小的順序輸運行情況如下:5,9↙a=5,b=9max=9,min=5當(dāng)輸入a=5,b=9時,由于a<b,將p1和p2交換。交換前的情況見圖(a),交換后見圖(b)。運行情況如下:10.2.3指針變量作為函數(shù)參數(shù)例10.3對輸入的兩個整數(shù)按大小順序輸出
#include<stdio.h>voidmain(){voidswap(int*p1,int*p2);inta,b;int*pointer_1,*pointer_2;scanf("%d,%d",&a,&b);pointer_1=&a;pointer_2=&b;if(a<b)swap(pointer_1,pointer_2);printf("\n%d,%d\n",a,b);}10.2.3指針變量作為函數(shù)參數(shù)例10.3對輸入的voidswap(int*p1,int*p2){inttemp;temp=*p1;*p1=*p2;*p2=temp;}voidswap(int*p1,int*p2)C語言入門學(xué)習(xí)-C第10章-指針課件
10.3數(shù)組與指針
一個變量有地址,一個數(shù)組包含若干元素,每個數(shù)組元素都在內(nèi)存中占用存儲單元,它們都有相應(yīng)的地址。指針變量既然可以指向變量,當(dāng)然也可以指向數(shù)組元素(把某一元素的地址放到一個指針變量中)。所謂數(shù)組元素的指針就是數(shù)組元素的地址。10.3數(shù)組與指針一個變量有地址,一個數(shù)組包含若干元素定義一個指向數(shù)組元素的指針變量的方法,與以前介紹的指向變量的指針變量相同。例如:inta[10];
(定義a為包含10個整型數(shù)據(jù)的數(shù)組)int*p;
(定義p為指向整型變量的指針變量)應(yīng)當(dāng)注意,如果數(shù)組里存放的數(shù)據(jù)為int型,則指針變量的基類型亦應(yīng)為int型。
10.3.1指向數(shù)組元素的指針定義一個指向數(shù)組元素的指針變量的方法,與以前介紹的指向變量的對該指針變量賦值:p=&a[0];把a[0]元素的地址賦給指針變量p。也就是使p指向a數(shù)組的第0位置上的元素,如圖:對該指針變量賦值:10.3.2通過指針引用數(shù)組元素引用一個數(shù)組元素,可以用:
(1)下標(biāo)法,如a[i]形式;以前學(xué)的內(nèi)容(2)指針法,如*(a+i)或*(p+i)。其中a是數(shù)組名(數(shù)據(jù)在計算機中存儲的地址),p是指向數(shù)組元素的指針變量,其初值p=a。例10.5輸出數(shù)組中的全部元素。
假設(shè)有一個a數(shù)組,整型,有10個元素。要輸出各元素的值有三種方法:10.3.2通過指針引用數(shù)組元素引用一個數(shù)組元素,可以用:例(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]);}(1)下標(biāo)法。(2)通過數(shù)組名計算數(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));}(2)通過數(shù)組名計算數(shù)組元素地址,找出元素的值。(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);}(3)用指針變量指向數(shù)組元素。例10.6通過指針變量輸出a數(shù)組的10個元素。
#include<stdio.h>voidmain(){
int*p,i,a[10];p=a;
for(i=0;i<10;i++)
scanf(″%d″,p++);
printf(″\n″);
for(i=0;i<10;i++,p++)
printf(″%d″,*p);}程序運行情況:1234567890↙22153234003003625202116318259823728483顯然輸出的數(shù)值并不是a數(shù)組中各元素的值通過調(diào)試程序找出程序的問題?例10.6通過指針變量輸出a數(shù)組的10個元素。#incl*和++運算符仔細理解,*和++是同級運算符,結(jié)合方向為自右而左*p++等同于*(p++),先執(zhí)行*p,然后p=p+1*++p等同與*(++p),先執(zhí)行p=p+1,然后執(zhí)行*p(*p)++,先執(zhí)行*p,然后使得*p的值加1++(*p),先使得*p的值加1,然后執(zhí)行*p通過程序10-6-1.c加深理解*和++運算符仔細理解,*和++是同級運算符,結(jié)合方向為自右10.3.3用數(shù)組名作函數(shù)參數(shù)在第8章8.7節(jié)中介紹過可以用數(shù)組名作函數(shù)的參數(shù)如:voidmain()
{f(intarr[],intn);intarray[10];┇f(array,10);┇}
voidf(intarr[],intn){┇}10.3.3用數(shù)組名作函數(shù)參數(shù)在第8章8.7節(jié)中介紹過可例10.7將數(shù)組a中n個整數(shù)按相反順序存放。例10.7將數(shù)組a中n個整數(shù)按相反順序存放。#include<stdio.h>voidmain(){voidinv(intx[],intn);inti,a[10]={3,7,9,11,0,6,7,5,4,2};printf("Theoriginalarray:\n");for(i=0;i<0;i++)printf("%d,",a[i]);printf("\n");inv(a,10);printf("Thearrayhasbeeninverted:\n");for(i=0;i<10;i++)printf("%d,",a[i]);printf("\n");}#include<stdio.h>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;
}
return;
}運行情況如下:Theoriginalarray:3,7,9,11,0,6,7,5,4,2Thearrayhasbeeninverted:2,4,5,7,6,0,11,9,7,3voidinv(intx[],intn)/#include<stdio.h>voidmain(){voidinv(int*x,intn);inti,a[10]={3,7,9,11,0,6,7,5,4,2};
printf(″Theoriginalarray:\n″);
for(i=0;i<10;i++)
printf(″%d,″,a[i]);
printf(″\n″);
inv(a,10);
printf(″Thearrayhasbeeninverted:\n″);
for(i=0;i<10;i++)
printf(″%d,″,a[i]);
printf(″\n″);}對剛才的程序可以作一些改動。將函數(shù)inv中的形參x改成指針變量。
#include<stdio.h>對剛才的程序可以作一些改voidinv(int*x,intn)/*形參x為指針變量*/{int*p,temp,*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;}
return;}voidinv(int*x,intn)/*形如果有一個實參數(shù)組,想在函數(shù)中改變此數(shù)組中的元素的值,實參與形參的對應(yīng)關(guān)系有以下4種情況:(1)形參和實參都用數(shù)組名,如:voidmain()voidf(intx[],intn){inta[10];{……
f(a,10);}
}形參和實參都用數(shù)組名在例10.7程序已實現(xiàn)如果有一個實參數(shù)組,想在函數(shù)中改變此數(shù)組中的元素的值,實參與(2)實參用數(shù)組名,形參用指針變量。如:voidmain()voidf(int*x,intn){inta[10];{……
f(a,10);}
}實參用數(shù)組名,形參用指針變量在10-7-2.c程序中實現(xiàn)(3)實參形參都用指針變量。例如:voidmain()voidf(int*x,intn){inta[10],*p=a;{┇┇
f(p,10);}
}10.7程序改寫為例10.8實現(xiàn)實參形參都用指針變量(2)實參用數(shù)組名,形參用指針變量。如:(3)實參形參都用(4)實參為指針變量,形參為數(shù)組名。如:
voidmain()voidf(intx[],intn){inta[10],*p=a;{┇┇
f(p,10);}
}將例10.7程序中的函數(shù)inv替代10.8中的inv函數(shù),編寫程序10-7-4.c,實現(xiàn)實參為指針變量,形參為數(shù)組名(4)實參為指針變量,形參為數(shù)組名。如:例10.9用選擇法對10個整數(shù)按由大到小順序排序。
函數(shù)sort的功能為用選擇法對10個整數(shù)按由大到小順序排序本程序?qū)崿F(xiàn)實參為指向一維數(shù)組的指針變量,形參為一維數(shù)組名在理解程序的基礎(chǔ)上,改寫程序?qū)崿F(xiàn)實參形參都用指針變量實參用數(shù)組名,形參用指針變量
例10.9用選擇法對10個整數(shù)按由大到小順序排序。10.3.4多維數(shù)組與指針
用指針變量可以指向一維數(shù)組中的元素,前面的知識可知地址+整數(shù)仍然為一個地址值*(地址+整數(shù))等價地址[整數(shù)]1.多維數(shù)組元素的地址例:定義二維數(shù)組inta[3][4]則二維數(shù)組名a的值是第一個元素存儲空間的字節(jié)編號(第一個元素的地址)指針變量也可以指向多維數(shù)組中的元素。但在概念上和使用上,多維數(shù)組的指針比一維數(shù)組的指針要復(fù)雜一些。10.3.4多維數(shù)組與指針用指針變量可以指向一維數(shù)組中的定義二維數(shù)組為inta[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
調(diào)試程序在watch窗口理解a[0],a[1],a[2],a+1的數(shù)值二維數(shù)組是“數(shù)組的數(shù)組”,集合中的元素為一個集合。因此,可以理解二維數(shù)組由3個元素組成,每個元素是一個一維數(shù)組,即{a[0],a[1],a[2]}。
地址值+1表示下一個數(shù)據(jù)的地址值概念可知,a+1就是下一個元素的地址,即a[1]這個元素的地址,得出a+1的值就是二維數(shù)組第二行數(shù)據(jù)在計算機中的存儲地址。定義二維數(shù)組為inta[3][4]={{1,2,3,4},*(地址+整數(shù))地址[整數(shù)]a[0]和*(a+0)等價,都是相同的數(shù)據(jù)值因為a+0等于a,所以*(a+0)等于*a因此,a[0],*(a+0),*a都是相同的數(shù)值
,即0行首地址a[0]+2為地址值+整數(shù),表示從a[0]這個地址值開始往后第二個元素的地址*(a[0]+2)等價a[0][2],并且a[0]等價*(a+0)因此,*(a[0]+2)等價*(*(a+0)+2)等價定義二維數(shù)組為inta[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
在watch窗口理解*a[0],a[0]+2,*(*(a+0)+2)的數(shù)值參見書上表10-2,和例10.10加深對這部分知識的理解。*(地址+整數(shù))地址[整數(shù)]2.指向多維數(shù)組元素的指針變量(1)指向數(shù)組元素的指針變量例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);}}運行結(jié)果如下:135791113151921232.指向多維數(shù)組元素的指針變量(1)指向數(shù)組元素的指針
(2)指向由m個元素組成的一維數(shù)組的指針變量例10.12輸出二維數(shù)組任一行任一列元素的值int(*p)[4],表示p是一個指針變量,他指向包含4個整型元素的一維數(shù)組。p的使用就和二維數(shù)組名類似。給定p一個數(shù)值后,p+1就表示4個整型數(shù)據(jù)后接下來4個整數(shù)的起始地址。
給定p一具體數(shù)據(jù)值后,包括該地址空間后的數(shù)據(jù)就形成了4個數(shù)據(jù)為一行的超長二位數(shù)組。[]運算級別高,(*p)如果不寫(),則p先與[4]結(jié)合,int*p[4]與int(*p)[4]意義完全不同,表示一個一維數(shù)組,里面有4個元素,每個元素為地址值。(2)指向由m個元素組成的一維數(shù)組的指針變量例10.12
10.4字符串與指針10.4.1字符串的表示形式
例10.15定義一個字符數(shù)組,對它初始化,然后輸出該字符串
實質(zhì):指針變量的基類型為char(1)用字符數(shù)組存放一個字符串,然后輸出該字符串。10.4字符串與指針10.4.1字符串的表示形式例1(2)用字符指針指向一個字符串??梢圆欢x字符數(shù)組,而定義一個字符指針。用字符指針指向字符串中的字符。例10.16定義字符指針#include<stdio.h>voidmain(){char*string=″IloveChina!″;
printf(″%s\n″,string);}(2)用字符指針指向一個字符串。例10.16定義字符指針string的值是字符串第一個字符的地址。等價于char*string;string=″IloveChina!″改成以下程序是錯誤的
#include<stdio.h>voidmain(){char*string;*string=″IloveChina!″;
printf(″%s\n″,string);}string的值是字符串第一個字符的地址。#include例10.17將字符串a復(fù)制為字符串b。
#include<stdio.h>voidmain(){chara[]=″Iamaboy.″,b[20];
inti;
for(i=0;*(a+i)!=′\0′;i++)*(b+i)=*(a+i);*(b+i)=′\0′;
printf(″stringais:%s\n″,a);
printf(″stringbis:″);
for(i=0;b[i]?。健洌埽啊洌唬椋?/p>
printf(″%c″,b[i]);
printf(″\n″);}例10.17將字符串a復(fù)制為字符串b。#include也可以設(shè)指針變量,用它的值的改變來指向字符串中的不同的字符。例10.18用指針變量來處理例10.17問題。#include<stdio.h>voidmain(){chara[]=″Iamaboy.″,b[20],*p1,*p2;
inti;p1=a;p2=b;
for(;*p1!=′\0′;p1++,p2++)也可以設(shè)指針變量,用它的值的改變來指向字符串中的不同的字符*p2=*p1;*p2=′\0′;printf(″stringais:%s\n″,a);
printf(″stringbis:″);for(i=0;b[i]!=′\0′;i++)
printf(″%c″,b[i]);
printf(″\n″);}程序必須保證使p1和p2同步移動
*p2=*p1;程序必須保證使p1和p2同步移動10.4.2字符指針作函數(shù)參數(shù)例10.19用函數(shù)調(diào)用實現(xiàn)字符串的復(fù)制
#include<stdio.h>voidmain(){voidcopy_string(charfrom[],charto[]);chara[]=″Iamateacher.″;
charb[]=″youareastudent.″;
printf(“stringa=%s\nstringb=%s\n″,a,b);
printf(“copystringatostringb:\n”);
copy_string(a,b);
printf("\nstringa=%s\nstringb=%s\n",a,b);
}(1)用字符數(shù)組作參數(shù)10.4.2字符指針作函數(shù)參數(shù)例10.19用函數(shù)調(diào)用voidcopy_string(charfrom[],charto[]){inti=0;
while(from[i]?。健洌埽啊洌鹴o[i]=from[i];i++;}
to[i]=′\0′;}程序運行結(jié)果如下:
stringa=Iamateacher.
stringb
=y(tǒng)ouareastudent.
copystringatostringb:stringa=Iamateacher.stringb=Iamateacher.voidcopy_string(charfrom[](2)形參用字符指針變量
#include<stdio.h>voidmain(){voidcopy_string(char*from,char*to);char*a=″Iamateacher.″;
char*b=″youareastudent.″;
printf("stringa=%s\nstringb=%s\n″,a,b);
printf("copystringatostringb:\n");
copy_string(a,b);
printf("\nstringa=%s\nstringb=%s\n",a,b);
}(2)形參用字符指針變量#include<stdio.voidcopy_string(char*from,char*to){for(;*from!=′\0′;from++,to++)*to=from;*to=′\0′;}(3)對copy_string
函數(shù)還可作簡化參見書上內(nèi)容
voidcopy_string(char*from,c(1)字符數(shù)組由若干個元素組成,每個元素中放一個字符,而字符指針變量中存放的是地址(字符串第1個字符的地址),決不是將字符串放到字符指針變量中。(2)賦值方式。對字符數(shù)組只能對各個元素賦值,不能用以下辦法對字符數(shù)組賦值。
charstr[14];
str=″IloveChina!″;而對字符指針變量,可以采用下面方法賦值:
char*a;a=″IloveChina!″;10.4.3對使用字符指針變量和字符數(shù)組的討論字符數(shù)組和字符指針變量二者之間的區(qū)別:(1)字符數(shù)組由若干個元素組成,每個元素中放一個字符,而字(3)對字符指針變量賦初值:
char*a=″IloveChina!″;等價于
char*a;a=″IloveChian!″;而對數(shù)組的初始化:
charstr[14]={″IloveChina!″};
不能等價于
charstr[14];
str[]=″IloveChina!″;(3)對字符指針變量賦初值:(4)定義了一個字符數(shù)組,在編譯時為它分配內(nèi)存單元,它有確定的地址。而定義一個字符指針變量時,給指針變量分配內(nèi)存單元,在其中可以放一個字符變量的地址。例如:
charstr[10];
scanf(″%s″,str);(4)定義了一個字符數(shù)組,在編譯時為它分配內(nèi)存單元,它有確(5)指針變量的值是可以改變的,例如:例10.20改變指針變量的值#include<stdio.h>voidmain(){char*a=″IloveChina!″;a=a+7;//地址值
printf(″%s″,a);}(5)指針變量的值是可以改變的,例如:例10.20改變指#include<stdio.h>main(){char*a="IloveChina!";a=a+7;printf("%c",a[0]);}可參考書上例10.21加深理解。
若定義了一個指針變量,并使它指向一個字符串,就可以用下標(biāo)形式引用指針變量所指的字符串中的字符。*(地址+整數(shù))等價地址[整數(shù)]例如:#include<stdio.h>若定義了一個指針變量10.5指向函數(shù)的指針10.5.1用函數(shù)指針變量調(diào)用函數(shù)用指針變量可以指向一個函數(shù)。函數(shù)在編譯時被分配給一個入口地址。這個函數(shù)的入口地址就稱為函數(shù)的指針。10.5指向函數(shù)的指針10.5.1用函數(shù)指針變量調(diào)用函數(shù)例10.22#include<stdio.h>void
main(){intmax(int,int);
inta,b,c;
scanf(″%d,%d″,&a,&b);c=max(a,b);
printf(″a=%d,b=%d,max=%d
″,a,b,c);}
intmax(intx,inty){intz;
if(x>y)z=x;
elsez=y;
return(z);}例10.22將main函數(shù)改寫為#include<stdio.h>void
main(){intmax(int,int);
int(*p)();
inta,b,c;p=max;
scanf(″%d,%d″,&a,&b);c=(*p)(a,b);
printf(″a=%d,b=%d,max=%d″,a,b,c);}將main函數(shù)改寫為10.5.2用指向函數(shù)的指針作函數(shù)參數(shù)
函數(shù)指針變量常用的用途之一是把指針作為參數(shù)傳遞到其他函數(shù)。指向函數(shù)的指針也可以作為參數(shù),以實現(xiàn)函數(shù)地址的傳遞,這樣就能夠在被調(diào)用的函數(shù)中使用實參函數(shù)。
通過書例10.23自己學(xué)習(xí)。10.5.2用指向函數(shù)的指針作函數(shù)參數(shù)函數(shù)指針變10.6返回指針值的函數(shù)一個函數(shù)可以帶回一個整型值、字符值、實型值等,也可以帶回指針型的數(shù)據(jù),即地址。其概念與以前類似,只是帶回的值的類型是指針類型而已。這種帶回指針值的函數(shù),一般定義形式為類型名*函數(shù)名(參數(shù)表列);例如:int*a(intx,inty);10.6返回指針值的函數(shù)一個函數(shù)可以帶回一個整型值、字符值例10.24有若干個學(xué)生的成績(每個學(xué)生有4門課程),要求在用戶輸入學(xué)生序號以后,能輸出該學(xué)生的全部成績。用指針函數(shù)來實現(xiàn)。
#include<stdio.h>voidmain(){floatscore[][4]={{60,70,80,90},
{56,89,67,88},{34,78,90,66}};float*search(float(*pointer)[4],intn);
float*p;
inti,m;
printf(″enterthenumberofstudent:″);
scanf(″%d″,&m);
printf(″ThescoresofNo.%dare:\n″,m);
例10.24有若干個學(xué)生的成績(每個學(xué)生有4門課程),要求
p=search(score,m);
for(i=0;i<4;i++)
printf(″%5.2f\t″,*(p+i));}float*search(float(*pointer)[4],intn){float*pt;pt=*(pointer+n);
return(pt);}
運行情況如下:enterthenumberofstudent:1↙ThescoresofNo.1are:56.0089.0067.0088.00p=search(score,m);運行情況如下:10.7指針數(shù)組和指向指針的指針10.7.1指針數(shù)組的概念一個數(shù)組,若其元素均為指針類型數(shù)據(jù),稱為指針數(shù)組,也就是說,指針數(shù)組中的每一個元素都相當(dāng)于一個指針變量。一維指針數(shù)組的定義形式為:類型名*數(shù)組名[數(shù)組長度];例如:int*p[4];10.7指針數(shù)組和指向指針的指針10.7.1指針數(shù)組的概二維數(shù)組存放字符串,每一行均為一個字符串,各字符串的長度一般不相等,如果按最長的字符串來定義列數(shù),會浪費許多存儲單元。二維數(shù)組存放字符串,每一行均為一個字符串,各char*name[]={"Followme","BASIC","GreatWall″,"FORTRAN","Computerdesign"};指針數(shù)組比較適合用來指向若干個字符串,節(jié)約了存儲空間,如果想對字符串排序,不必改動字符串的位置,只需改動指針數(shù)組中各元素的指向(即改變各素元素的值,這些值是個字符串的首地址)。例10.26將若干字符串按字母順序(由小到大)輸出。char*name[]={"Followme","BA10.7.2指向指針的指針定義一個指向指針數(shù)據(jù)的指針變量:char**p;p的前面有兩個*號。*運算符的結(jié)合性是從右到左,因此**p相當(dāng)于*(*p),顯然*p是指針變量的定義形式。如果沒有最前面的*,那就是定義了一個指向字符數(shù)據(jù)的指針變量?,F(xiàn)在它前面又有一個*號,表示指針變量p是指向一個字符指針變量的。*p就是p所指向的另一個指針變量。10.7.2指向指針的指針定義一個指向指針數(shù)據(jù)的指針變量例10.27使用指向指針的指針。
#include<stdio.h>voidmain(){char*name[]={"Followme","BASIC","GreatWall″,"FORTRAN","Computerdesign"};char**p;
inti;
for(i=0;i<5;i++){p=name+i;
printf(″%s\n″,*p);}}例10.27使用指向指針的指針。#include<例10.28一個指針數(shù)組的元素指向整型數(shù)據(jù)的簡單例子。#include<stdio.h>voidmain(){inta[5]={1,3,5,7,9};
int*num[5]={&a[0],&a[1],
&a[2],&a[3],&a[4]};
int**p,i;p=num;
for(i=0;i<5;i++){printf(″%d″,**p);p++;}}例10.28一個指針數(shù)組的元素指向整型數(shù)據(jù)的簡單例子。10.7.3指針數(shù)組作main函數(shù)的形參指針數(shù)組的一個重要應(yīng)用是作為main函數(shù)的形參。在以往的程序中,main函數(shù)的第一行一般寫成以下形式:voidmain()括弧中是空的。
main函數(shù)可以有參數(shù),例如:voidmain(intargc,char*argv[])。命令行的一般形式為命令名參數(shù)1參數(shù)2……參數(shù)n10.7.3指針數(shù)組作main函數(shù)的形參指針數(shù)組的一個例如一個文件,它包含以下的main函數(shù):voidmain(intargc,char*argv[]){while(argc>1){++argv;
printf(″%s\n″,*argv);--argc;}}例如一個文件,它包含以下的main函數(shù):voidmain10.8有關(guān)指針的數(shù)據(jù)類型和指針運算的小結(jié)10.8.1有關(guān)指針的數(shù)據(jù)類型的小結(jié)10.8有關(guān)指針的數(shù)據(jù)類型和10.8.1有關(guān)指針的數(shù)據(jù)類型的定義含義inti;定義整型變量iint*p;p為指向整型數(shù)據(jù)的指針變量inta[n];定義整型數(shù)組a,它有n個元素int*p[n];定義指針數(shù)組p,它由n個指向整型數(shù)據(jù)的指針元素組成int(*p)[n];p為指向含n個元素的一維數(shù)組的指針變量intf();f為帶回整型函數(shù)值的函數(shù)int*p();p為帶回一個指針的函數(shù),該指針指向整型數(shù)據(jù)int(*p)();p為指向函數(shù)的指針,該函數(shù)返回一個整型值int**p;p是一個指針變量,它指向一個指向整型數(shù)據(jù)的指針變量定義含義inti;定義整型變量iint*p;p為指向整型10.8.2指針運算小結(jié)(1)指針變量加(減)一個整數(shù)例如:p++、p--、p+i、p-i、p+=i、p-=i等。10.8.2指針運算小結(jié)(1)指針變量加(減)一個整數(shù)(2)指針變量賦值將一個變量地址賦給一個指針變量。如:p=&a;(將變量a的地址賦給p)p=array;(將數(shù)組array首元素地址賦給p)p=&array[i];(將數(shù)組array第i個元素的地址賦給p)p=max;(max為已定義的函數(shù),將max的入口地址賦給p)p1=p2;(p1和p2都是指針變量,將p2的值賦給p1)(2)指針變量賦值(3)指針變量可以有空值,即該指針變量不指向任何變量。(4)兩個指針變量可以相減如果兩個指針變量都指向同一個數(shù)組中的元素,則兩個指針變量值之差是兩個指針之間的元素個數(shù)。
兩個指針變量的值相加就為無意義的數(shù)據(jù)。(3)指針變量可以有空值,即該指針變量不指向任何變量。(4(5)兩個指針變量比較若兩個指針指向同一個數(shù)組的元素,則可以進行比較。指向前面的元素的指針變量“小于”指向后面元素的指針變量。(5)兩個指針變量比較10.8.3void指針類型ANSIC新標(biāo)準(zhǔn)增加了一種“void”指針類型,即可定義一個指針變量,但不指定它是指向哪一種類型數(shù)據(jù)的。ANSIC標(biāo)準(zhǔn)規(guī)定用動態(tài)存儲分配函數(shù)時返回void指針,它可以用來指向一個抽象的類型的數(shù)據(jù),在將它的值賦給另一指針變量時要進行強制類型轉(zhuǎn)換使之適合于被賦值的變量的類型。10.8.3void指針類型ANSIC新標(biāo)準(zhǔn)增加了一種“第十章指針第十章指針
主要內(nèi)容10.1地址和指針的概念
10.2變量的指針和指向變量的指針變量
10.3數(shù)組與指針
10.4字符串與指針
10.5指向函數(shù)的指針
10.6返回指針值的函數(shù)
10.7指針數(shù)組和指向指針的指針
10.8有關(guān)指針的數(shù)據(jù)類型和指針運算的小結(jié)主要內(nèi)容10.1地址和指針的概念10.1地址和指針的概念內(nèi)存區(qū)的每一個字節(jié)有一個編號,這就是“地址”。如果在程序中定義了一個變量,在對程序進行編譯時,系統(tǒng)就會給這個變量分配內(nèi)存單元。1.按變量地址存取變量值的方式稱為“直接訪問”方式printf(″%d″,i);scanf(″%d″,&i);k=i+j;10.1地址和指針的概念內(nèi)存區(qū)的每一個字節(jié)有一個編號,這就C語言入門學(xué)習(xí)-C第10章-指針課件2.另一種存取變量值的方式稱為“間接訪問”的方式。即,將變量i的地址存放在另一個變量中。在C語言中,指針是一種特殊的變量,它是存放地址的。2.另一種存取變量值的方式稱為“間接訪問”的方式。即,將變一個變量的地址稱為該變量的“指針”。例如,地址2000是變量i的指針-----計算機給變量i分配存儲空間的中的第一個字節(jié)的字節(jié)編號。
如果有一個變量(計算機也給這個變量分配了存儲空間)專門用來存放另一變量的地址(即指針),則它稱為“指針變量”。上述的i_pointer就是一個指針變量。指針和指針變量的定義:一個變量的地址稱為該變量的“指針”。指針和指針變量的定義:
10.2變量的指針和指向變量的指
針變量10.2.1定義一個指針變量定義指針變量的一般形式為基類型*指針變量名;這里的*不是運算10.2變量的指針和指向變量的指
針變量10下面都是合法的定義:float*pointer_3;
char*pointer_4;可以用賦值語句使一個指針變量得到另一個變量的地址,從而使它指向一個該變量。例如:pointer_1=&i;pointer_2=&j;下面都是合法的定義:指針變量前面的“*”,表示該變量的類型為指針型變量。例:float*pointer_1;指針變量名是pointer_1
,而不是*pointer_1
。(2)在定義指針變量時必須指定基類型?;愋筒皇侵羔樧兞康念愋?。
基類型:指針變量里面存放的是內(nèi)存中的一個字節(jié)編號,在這個編號所對應(yīng)的存儲空間里面存放的數(shù)據(jù)類型。在定義指針變量時要注意兩點:指針變量前面的“*”,表示該變量的類型為指針型變量。(2)int*a指針變量a的基類型是intfloat*b指針變量b的基類型是float下面的賦值是錯誤的∶
floata;int*pointer_1;基類型為intpointer_1=&a;變量a的類型為float
需要特別注意的是,只有整型變量的地址才能放到指向整型變量的指針變量中。
int*a指針變量a的基類型是int下面的賦值是錯10.2.2指針變量的引用
注意:指針變量中只能存放地址(指針),不要將一個整數(shù)(或任何其他非地址類型的數(shù)據(jù))賦給一個指針變量。
例10.1通過指針變量訪問整型變量#include<stdio.h>voidmain(){inta,b;int*pointer_1,*pointer_2;a=100;b=10;pointer_1=&a;/*把變量a的地址賦給
pointer_1*/10.2.2指針變量的引用注意:指針變量中只能存放地址(pointer_2=&b;/*把變量b的地址賦給
pointer_2*/printf("%d,%d\n",a,b);printf("%d,%d\n",*pointer_1,*pointer_2);}pointer_2=&b;/*把對“&”和“*”運算符說明:如果已執(zhí)行了語句pointer_1=&a;(1)&*pointer_1的含義是什么?“&”和“*”兩個運算符的優(yōu)先級別相同,但按自右而左方向結(jié)合。因此,&*pointer_1與&a相同,即變量a的地址。如果有pointer_2=&*pointer_1;它的作用是將&a(a的地址)賦給pointer_2,如果pointer_2原來指向b,經(jīng)過重新賦值后它已不再指向b了,而指向了a。注:指針變量的值為某個變量的地址,則是指針變量指向某個變量。后面圖示上用了一個符號來表示。對“&”和“*”運算符說明:C語言入門學(xué)習(xí)-C第10章-指針課件(2)
*&a的含義是什么?
先進行&a運算,得a的地址,再進行*運算。*&a和*pointer_1的作用是一樣的,它們都等價于變量a。即*&a與a等價。(3)(*pointer_1)++相當(dāng)于a++。(2)*&a的含義是什么?(3)(*pointer_1)例10.2輸入a和b兩個整數(shù),按先大后小的順序輸出a和b。#include<stdio.h>voidmain(){int*p1,*p2,*p,a,b;scanf("%d,%d",&a,&b);p1=&a;p2=&b;if(a<b){p=p1;p1=p2;p2=p;}printf("a=%d,b=%d\n",a,b);printf("max=%d,min=%d\n",*p1,*p2);}例10.2輸入a和b兩個整數(shù),按先大后小的順序輸運行情況如下:5,9↙a=5,b=9max=9,min=5當(dāng)輸入a=5,b=9時,由于a<b,將p1和p2交換。交換前的情況見圖(a),交換后見圖(b)。運行情況如下:10.2.3指針變量作為函數(shù)參數(shù)例10.3對輸入的兩個整數(shù)按大小順序輸出
#include<stdio.h>voidmain(){voidswap(int*p1,int*p2);inta,b;int*pointer_1,*pointer_2;scanf("%d,%d",&a,&b);pointer_1=&a;pointer_2=&b;if(a<b)swap(pointer_1,pointer_2);printf("\n%d,%d\n",a,b);}10.2.3指針變量作為函數(shù)參數(shù)例10.3對輸入的voidswap(int*p1,int*p2){inttemp;temp=*p1;*p1=*p2;*p2=temp;}voidswap(int*p1,int*p2)C語言入門學(xué)習(xí)-C第10章-指針課件
10.3數(shù)組與指針
一個變量有地址,一個數(shù)組包含若干元素,每個數(shù)組元素都在內(nèi)存中占用存儲單元,它們都有相應(yīng)的地址。指針變量既然可以指向變量,當(dāng)然也可以指向數(shù)組元素(把某一元素的地址放到一個指針變量中)。所謂數(shù)組元素的指針就是數(shù)組元素的地址。10.3數(shù)組與指針一個變量有地址,一個數(shù)組包含若干元素定義一個指向數(shù)組元素的指針變量的方法,與以前介紹的指向變量的指針變量相同。例如:inta[10];
(定義a為包含10個整型數(shù)據(jù)的數(shù)組)int*p;
(定義p為指向整型變量的指針變量)應(yīng)當(dāng)注意,如果數(shù)組里存放的數(shù)據(jù)為int型,則指針變量的基類型亦應(yīng)為int型。
10.3.1指向數(shù)組元素的指針定義一個指向數(shù)組元素的指針變量的方法,與以前介紹的指向變量的對該指針變量賦值:p=&a[0];把a[0]元素的地址賦給指針變量p。也就是使p指向a數(shù)組的第0位置上的元素,如圖:對該指針變量賦值:10.3.2通過指針引用數(shù)組元素引用一個數(shù)組元素,可以用:
(1)下標(biāo)法,如a[i]形式;以前學(xué)的內(nèi)容(2)指針法,如*(a+i)或*(p+i)。其中a是數(shù)組名(數(shù)據(jù)在計算機中存儲的地址),p是指向數(shù)組元素的指針變量,其初值p=a。例10.5輸出數(shù)組中的全部元素。
假設(shè)有一個a數(shù)組,整型,有10個元素。要輸出各元素的值有三種方法:10.3.2通過指針引用數(shù)組元素引用一個數(shù)組元素,可以用:例(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]);}(1)下標(biāo)法。(2)通過數(shù)組名計算數(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));}(2)通過數(shù)組名計算數(shù)組元素地址,找出元素的值。(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);}(3)用指針變量指向數(shù)組元素。例10.6通過指針變量輸出a數(shù)組的10個元素。
#include<stdio.h>voidmain(){
int*p,i,a[10];p=a;
for(i=0;i<10;i++)
scanf(″%d″,p++);
printf(″\n″);
for(i=0;i<10;i++,p++)
printf(″%d″,*p);}程序運行情況:1234567890↙22153234003003625202116318259823728483顯然輸出的數(shù)值并不是a數(shù)組中各元素的值通過調(diào)試程序找出程序的問題?例10.6通過指針變量輸出a數(shù)組的10個元素。#incl*和++運算符仔細理解,*和++是同級運算符,結(jié)合方向為自右而左*p++等同于*(p++),先執(zhí)行*p,然后p=p+1*++p等同與*(++p),先執(zhí)行p=p+1,然后執(zhí)行*p(*p)++,先執(zhí)行*p,然后使得*p的值加1++(*p),先使得*p的值加1,然后執(zhí)行*p通過程序10-6-1.c加深理解*和++運算符仔細理解,*和++是同級運算符,結(jié)合方向為自右10.3.3用數(shù)組名作函數(shù)參數(shù)在第8章8.7節(jié)中介紹過可以用數(shù)組名作函數(shù)的參數(shù)如:voidmain()
{f(intarr[],intn);intarray[10];┇f(array,10);┇}
voidf(intarr[],intn){┇}10.3.3用數(shù)組名作函數(shù)參數(shù)在第8章8.7節(jié)中介紹過可例10.7將數(shù)組a中n個整數(shù)按相反順序存放。例10.7將數(shù)組a中n個整數(shù)按相反順序存放。#include<stdio.h>voidmain(){voidinv(intx[],intn);inti,a[10]={3,7,9,11,0,6,7,5,4,2};printf("Theoriginalarray:\n");for(i=0;i<0;i++)printf("%d,",a[i]);printf("\n");inv(a,10);printf("Thearrayhasbeeninverted:\n");for(i=0;i<10;i++)printf("%d,",a[i]);printf("\n");}#include<stdio.h>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;
}
return;
}運行情況如下:Theoriginalarray:3,7,9,11,0,6,7,5,4,2Thearrayhasbeeninverted:2,4,5,7,6,0,11,9,7,3voidinv(intx[],intn)/#include<stdio.h>voidmain(){voidinv(int*x,intn);inti,a[10]={3,7,9,11,0,6,7,5,4,2};
printf(″Theoriginalarray:\n″);
for(i=0;i<10;i++)
printf(″%d,″,a[i]);
printf(″\n″);
inv(a,10);
printf(″Thearrayhasbeeninverted:\n″);
for(i=0;i<10;i++)
printf(″%d,″,a[i]);
printf(″\n″);}對剛才的程序可以作一些改動。將函數(shù)inv中的形參x改成指針變量。
#include<stdio.h>對剛才的程序可以作一些改voidinv(int*x,intn)/*形參x為指針變量*/{int*p,temp,*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;}
return;}voidinv(int*x,intn)/*形如果有一個實參數(shù)組,想在函數(shù)中改變此數(shù)組中的元素的值,實參與形參的對應(yīng)關(guān)系有以下4種情況:(1)形參和實參都用數(shù)組名,如:voidmain()voidf(intx[],intn){inta[10];{……
f(a,10);}
}形參和實參都用數(shù)組名在例10.7程序已實現(xiàn)如果有一個實參數(shù)組,想在函數(shù)中改變此數(shù)組中的元素的值,實參與(2)實參用數(shù)組名,形參用指針變量。如:voidmain()voidf(int*x,intn){inta[10];{……
f(a,10);}
}實參用數(shù)組名,形參用指針變量在10-7-2.c程序中實現(xiàn)(3)實參形參都用指針變量。例如:voidmain()voidf(int*x,intn){inta[10],*p=a;{┇┇
f(p,10);}
}10.7程序改寫為例10.8實現(xiàn)實參形參都用指針變量(2)實參用數(shù)組名,形參用指針變量。如:(3)實參形參都用(4)實參為指針變量,形參為數(shù)組名。如:
voidmain()voidf(intx[],intn){inta[10],*p=a;{┇┇
f(p,10);}
}將例10.7程序中的函數(shù)inv替代10.8中的inv函數(shù),編寫程序10-7-4.c,實現(xiàn)實參為指針變量,形參為數(shù)組名(4)實參為指針變量,形參為數(shù)組名。如:例10.9用選擇法對10個整數(shù)按由大到小順序排序。
函數(shù)sort的功能為用選擇法對10個整數(shù)按由大到小順序排序本程序?qū)崿F(xiàn)實參為指向一維數(shù)組的指針變量,形參為一維數(shù)組名在理解程序的基礎(chǔ)上,改寫程序?qū)崿F(xiàn)實參形參都用指針變量實參用數(shù)組名,形參用指針變量
例10.9用選擇法對10個整數(shù)按由大到小順序排序。10.3.4多維數(shù)組與指針
用指針變量可以指向一維數(shù)組中的元素,前面的知識可知地址+整數(shù)仍然為一個地址值*(地址+整數(shù))等價地址[整數(shù)]1.
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 【正版授權(quán)】 ISO/IEC 15415:2024 EN Automatic identification and data capture techniques - Bar code symbol print quality test specification - Two-dimensional symbols
- 2025年度化工生產(chǎn)工廠技術(shù)許可合同協(xié)議
- 2025年城市管道天然氣項目建議書
- 設(shè)備管理科設(shè)備維護與更新計劃
- 提升倉庫服務(wù)質(zhì)量的個人策略計劃
- 社區(qū)個人工作計劃改善社區(qū)供水設(shè)施
- 2025年特種大型鋁合金型材合作協(xié)議書
- 新聞媒體安全管理的必要性計劃
- 社團交流合作的網(wǎng)絡(luò)平臺計劃
- 2025年中大型重載軸承項目建議書
- 兒科護理學(xué)試題及答案解析-神經(jīng)系統(tǒng)疾病患兒的護理(二)
- 二年級下冊計算小能手帶答案
- 《石油產(chǎn)品分析》課件-車用汽油
- 2024年臨滄市工業(yè)產(chǎn)業(yè)發(fā)展集團限公司招聘2名公開引進高層次人才和急需緊缺人才筆試參考題庫(共500題)答案詳解版
- 2023年3月云南專升本大??肌堵糜螌W(xué)概論》試題及答案
- 一年級趣味數(shù)學(xué)幾和第幾
- 《你為什么不開花》兒童故事繪本
- 方案優(yōu)缺點對比表模板
- 數(shù)據(jù)真實性承諾書
- 湖北省普通高中2022-2023學(xué)年高一下學(xué)期學(xué)業(yè)水平合格性考試模擬化學(xué)(八)含解析
- 保潔班長演講稿
評論
0/150
提交評論