




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第1單元:C語言程序設計入門第2單元:利用三種程序結構解決簡單問題第3單元:利用數組處理同類型的批量數據第4單元:利用函數實現模塊化程序設計第5單元:靈活使用指針處理問題第6單元:利用復雜的構造類型解決實際問題第7單元:利用文件進行數據管理第8單元:應用軟件設計
教學內容第5單元靈活使用指針處理問題【單元導讀】
單元學習目標:理解指針的概念;利用指針引用普通變量、數組元素和字符串;利用指針數組、指向指針的指針引用多個數據;利用指針調用函數;通過函數調用獲取指針值;利用內存動態分配函數建立動態數組。
通過指針,可對計算機的硬件地址直接操作,在嵌入式軟件設計中應用非常廣泛。利用指針編寫的程序具有精煉、高效的優點;另外,還可以利用指針構成表、樹、棧等復雜的數據結構。
對變量值的存、取都是通過變量的地址進行的。
例如,scanf("%d",&i);將鍵盤上輸入的數據送給變量i對應的地址單元中。
再如,
printf("%d",i);從變量i對應的地址單元中取出變量i的值。
直接按照變量名(對應一個內存地址)進行的訪問,稱為“直接訪問”方式。
除了采用“直接訪問”方式,還可以采用“間接訪問”方式。
可通過語句“p=&i;”將變量i的地址(2000)存放到變量p中(變量
p的值就是2000)。
要讀取變量i的值,可以先找到變量p,從中取出i的地址(2000),然后到地址為2000的內存單元取出i的值(3)。
通過變量p能夠找到變量i,可以說變量p指向了變量i,在C語言中,將地址形象地稱為“指針”。
一個變量的地址,稱為該變量的“指針”。例如,地址2000是變量i的指針,而變量p用來存放變量i的地址,稱為“指針變量”。任務5.1理解指針的基本概念任務5.2利用指針引用普通變量5.2.1定義指針變量的方法
定義指針變量的一般形式:
類型標識符
*變量名;
例如:
int
*p1;//p1是指向整型變量的指針變量
注意:一個指針變量只能指向同類型的變量,如p2只能指向實型變量,不能指向字符變量。float
*p2;
//p2是指向實型變量的指針變量char
*p3;
//p3是指向字符變量的指針變量
所謂普通變量,是指基本數據類型(整型、實型、字符型)的變量。
變量的指針就是變量的地址。存放變量地址的變量是指針變量,用來指向另一個變量。5.2.2指針變量的引用請牢記:指針變量中只能存放地址(指針)。
兩個有關的運算符:
(1)&:取地址運算符。
(2)*:指針運算符(或稱“間接訪問”運算符),
取其指向單元的內容。
例如:&i表示變量i的地址(2000),
*p表示指針變量p所指向的存儲單元的內容(即p所指向的變量i的值3)。任務5.2利用指針引用普通變量【例5.1】通過指針變量訪問整型變量。5.2.2指針變量的引用任務5.2利用指針引用普通變量#include
<stdio.h>intmain(void){
inta=10,b=20;
int*p1,*p2;
//定義兩個指針變量,均指向整型變量
p1
=
&a;
//取變量a的地址,賦給指針變量p1
p2
=
&b;
//取變量b的地址,賦給指針變量p2printf("a=%d,b=%d\n",a,
b);printf("a=%d,b=%d\n",
*p1,*p2);//輸出指針變量指向單元的內容printf("變量a的地址:%x\n",p1);//輸出變量a的地址printf("變量b的地址:%x\n",
p2);
//輸出變量b的地址}5.2.2指針變量的引用任務5.2利用指針引用普通變量inta;int*p;p=&a;inta;int*p=&a;
(1)等價。與說明:(2)不能直接將一個地址常數賦給一個指針變量,只有強制類型轉換后才能賦值:
int*p
=
0x12345600;
//錯誤
int*p
=
(int*)0x12345600;
//正確
(3)注意“*p”在定義和引用中的區別:定義時:*p的前面要有類型標識符,表示指針變量p是指向某種類型數據的;引用時:*p的前面沒有類型標識符,表示指針變量p所指向的存儲單元的內容。5.2.2指針變量的引用任務5.2利用指針引用普通變量(4)inta;
int*p=&a;則&*p和
*&a的含義分別是什么?②*&a:先執行&a,表示變量a的地址,也就是變量p,再執行*運算。
因此*&a與*p等價,即變量a。
根據附錄C,“&”和“*”優先級相同,并按“自右至左”的結合性。①&*p:先執行
*p,表示變量a,再執行&運算。因此
&*p與&a相同,
即變量a的地址(p)。說明:【例5.2】指針變量的應用:輸入兩個整數,按由大到小的順序輸出這兩個整數。5.2.2指針變量的引用任務5.2利用指針引用普通變量#include
<stdio.h>intmain(void){
inta,b;
int*p1,
*p2,
*p;printf("請輸入兩個整數(用空格間隔):");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-1:知識鞏固。【例5.3】指針變量(變量的地址)作為函數參數。5.2.3指針變量作為函數參數實參指針的指向
實參傳遞給形參
變量a和b的值都加1形參被釋放
指針變量作函數參數,其作用是將一個變量的地址傳遞到另一個函數中。任務5.2利用指針引用普通變量#include
<stdio.h>voidfun(int
*p1,int
*p2);
//函數聲明intmain(void){
inta=1,
b=5;
int*pa
=
&a,*pb
=
&b;
//定義指針變量printf("調用fun函數前:a=%d,b=%d\n",
a,
b);
fun(pa,pb);
//調用fun函數,指針變量作函數實參printf("調用fun函數后:a=%d,b=%d\n",
a,
b);}voidfun(int
*p1,int
*p2)
//指針變量作形參{
(*p1)++;
//使
p1指向的變量值加1
(*p2)++;
//使
p2指向的變量值加1
}【思考與總結】
函數調用時,傳遞的是變量的地址,使實參和形參指向同一個內存單元。當形參指向單元的值發生變化時,實參指向單元的值也隨之變化。
若想通過函數調用得到n個要改變的值:可在主調函數中設n個變量,將這n個變量的地址傳遞給被調函數的形參(指針變量)。
實際上,數組名作為函數參數,其本質也如此。5.2.3指針變量作為函數參數任務5.2利用指針引用普通變量【例5.4】變量的地址作為函數實參。5.2.3指針變量作為函數參數任務5.2利用指針引用普通變量#include
<stdio.h>voidfun(int
*p);
//函數聲明intmain(void){
inta;
fun(&a);
//調用fun函數,變量的地址作實參printf("a=%d\n",a);}voidfun(int
*p)
//指針變量作形參{
*p=3;
//使指針變量p所指向單元的內容為3}【課后作業】(1)【例5.5】對輸入的兩個整數進行交換并輸出。(2)同步練習5-2:活學活用。5.3.1指向數組元素的指針任務5.3利用指針引用數組元素
p=
&a[0];//使p指向a[0]元素
指針變量既然可以指向變量,當然也可以指向數組元素(把某一元素的地址放到一個指針變量中)。
inta[10];
//定義a為包含10個整型數據的數組
int*p;
//定義p為指向整型數據的指針變量
下面兩個語句等價:
int
*p=&a[0];
int
*p=a;
p、a、&a[0]均代表數組a的首地址(a[0]的地址)。5.3.2通過指針引用一維數組元素任務5.3利用指針引用數組元素
如果指針變量p已指向一維數組中的一個元素,則p+1指向同一數組中的下一個元素,p-1指向同一數組中的上一個元素。
(1)p+i和
a+i就是a[i]的地址,即&a[i]。或者說它們指向數組a的第i個元素。
(2)*(p+i)
或
*(a+i)就是p+i或a+i所指向的數組元素,即a[i]。例如,*(p+5)或*(a+5)就是a[5]。即*(p+5)、*(a+5)、a[5]三者等價。(3)指向數組的指針變量也可以帶下標,如p[i]與*(p+i)等價。
實際上,在編譯時,對數組元素a[i]就是按*(a+i)處理的,因此[]實際上是變址運算符。
如果p的初值為&a[0],則:
【例5.6】輸出數組中的全部元素。任務5.3利用指針引用數組元素
引用一個數組元素有兩種方法:下標法:a[i]。指針法:*(a+i)或*(p+i)
順序訪問數組元素時:第(3)種方法比第(1)、(2)種方法快,用指針變量直接指向元素,不必每次都重新計算地址。這種有規律地改變地址值(p++)能大大提高執行效率。(1)下標法#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)通過數組名計算元素
的地址,找出元素的值#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)用指針變量
引用數組元素
#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.2通過指針引用一維數組元素
(1)可以通過改變指針變量的值(如p++)而指向不同的元素。而a++是錯誤的,因為a是數組名(數組的首地址),是常量。(2)要注意指針變量的當前值。
在使用指針變量引用數組元素時,要特別注意:
從運行結果看,沒有實現要求。如何改正?任務5.3利用指針引用數組元素#include<stdio.h>intmain(void){
inti,
a[5];
int*p=a;printf("請輸入5個整數:");for(i=0;i<5;i++)scanf("%d",p++);for(i=0;i<5;i++,
p++)printf("%d",
*p);printf("\n");}【例5.7】通過指針變量輸入和輸出a數組的5個元素。for(p=a,i=0;i<5;i++,p++)for(p=a;
p<a+5;p++)5.3.2通過指針引用一維數組元素【例5.8】通過指針變量找出數組元素的最大值和最小值。任務5.3利用指針引用數組元素#include<stdio.h>intmain(void){
inta[5]
=
{23,
12,
34,
78,
55};
int*p,
*max,
*min;
//定義3個指針變量
p=max=min=a;
//將3個指針變量同時指向數組首元素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.2通過指針引用一維數組元素【課后思考與實踐】畫圖分析例5.8程序的設計思路,上機編程并運行程序。(1)自學例5.8程序下面的說明。(2)同步練習5-3:知識鞏固。【課后作業】5.3.3用數組的首地址作函數參數的應用形式
在4.4.2節曾介紹過數組名可以作函數的實參和形參。
實際上,C語言編譯系統都是將形參數組名作為指針變量(存放地址)來處理的,并非真正開辟一個新的數組空間。voidf(intb[
],intn)相當于:
void
f(int*b,intn)任務5.3利用指針引用數組元素
普通變量、數組元素,普通變量的地址、指針變量、數組名都可以作為函數參數:任務5.3利用指針引用數組元素5.3.3用數組的首地址作函數參數的應用形式在主調函數中若有一實參數組,則主調函數的實參和被調函數的形參,有4種形式:任務5.3利用指針引用數組元素5.3.3用數組的首地址作函數參數的應用形式【例5.9】用指針變量作函數形參,改寫例4.8給出的程序。任務5.3利用指針引用數組元素#include<stdio.h>voidchange(int
b[],intn);
//函數聲明intmain(void){
inta[5]={1,
3,
5,
7,
9},i;printf("函數調用前:");for(i=0;i<5;i++)printf("a[%d]=%d",
i,
a[i]);printf("\n");
change(a,5);//調用change函數,實參:數組名a、數值5printf("函數調用后:");for(i=0;i<5;i++)printf("a[%d]=%d",i,
a[i]);printf("\n");}voidchange(intb[],
intn)
//形參:數組名
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.3用數組的首地址作函數參數的應用形式(2)【例5.10】用指針變量作為函數的參數,改寫例4.9給出的冒泡法排序程序。(1)同步練習5-4:知識鞏固與應用。【課后作業】1、二維數組元素的地址C語言中,二維數組a又可看作是一個特殊的一維數組。有3個行元素:a[0]、a[1]、a[2],而每個行元素又是一個包含4個列元素的一維數組,此時把a[0]、a[1]、a[2]看作一維數組名。
根據一維數組的指針知識,a+i代表元素a[i]的地址&a[i],而在二維數組中,元素a[i]是包含4個元素的一維數組,因此a+i代表第i行的首地址(起始地址)。aa+1a+2a[0]、a[1]、a[2]既然是一維數組名,而數組名代表數組首元素的地址,因此a[0]代表一維數組a[0]中第0列元素的地址,即&a[0][0]。同理,a[1]代表&a[1][0],a[2]代表&a[2][0]。據此,a[i][j]的地址&a[i][j]可用a[i]+j表示。a[0]+0a[0]+1a[0]+2a[0]+3*5.3.4通過指針引用多維數組任務5.3利用指針引用數組元素a[i]與*(a+i)等價!1、二維數組元素的地址*5.3.4通過指針引用多維數組
(1)a與a[0]指向同一個地址,區別:a指向一維數組,而a[0]指向a[0][0]元素。a+1中的“1”代表一行中全部整型元素所占的字節數(VC中為16字節),而a[0]+1中的“1”代表一個整型元素所占的字節數(VC中為4字節)。
(2)在行指針(a+i)的前面加一個*,就轉換為列指針(指向第i行第0列元素)。例如,而*a、*(a+1)分別指向數組第0行第0列的元素、第1行第0列的元素。
在列指針a[i]前面加&,就成為指向第i行的行指針。例如,&a[0]是指向第0行的行指針。任務5.3利用指針引用數組元素【課堂練習】同步練習5-5:概念理解。2、指向二維數組的指針變量(1)指向二維數組元素的指針變量【例5.11】用指向數組元素的指針變量輸出3×4二維數組各元素的值。*5.3.4通過指針引用多維數組任務5.3利用指針引用數組元素
分析:二維數組的元素在內存中是按行順序存放的,12個元素的地址依次為a[0]~a[0]+11,因此可以用一個指向二維數組元素的指針,依次指向各個元素。#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個值換行printf("%4d",
*p); }printf("\n");}(2)指向由n個元素組成的一維數組的指針變量:(*p)[n]
指針變量p先指向第0行a[0](即p=&a[0]),則p+1指向第1行a[1],p的增值以一維數組中n個元素的長度為單位。*5.3.4通過指針引用多維數組2、指向二維數組的指針變量
p是指向由4個元素組成的一維數組的指針,p的值是該一維數組的起始地址。p不能指向一維數組中的某一個元素。任務5.3利用指針引用數組元素【例5.12】用指向由n個元素組成的一維數組的指針變量輸出3×4二維數組各元素值。(2)指向由n個元素組成的一維數組的指針變量:(*p)[n]*5.3.4通過指針引用多維數組2、指向二維數組的指針變量任務5.3利用指針引用數組元素#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個元素組成的一維數組的指針變量p
for(p=a;p<a+3;
p++){for(j=0;j<4;j++)printf("%4d",
*(*p+j)); printf("\n"); }}【課后作業】同步練習5-6:概念理解。3、用指向二維數組的指針變量作函數參數*5.3.4通過指針引用多維數組
用指針變量作形參,以接收實參數組名傳遞來的地址時,可有兩種方法:(1)用指向二維數組元素的指針變量(列指針);(2)用指向由n個元素組成的一維數組的指針變量(行指針)。【例5.13】某測控系統,在上午、下午和夜間3個時間段內各檢測4次溫度,利用指向二維數組的指針,計算室內一天內的平均溫度,并輸出夜間檢測到的4次溫度值。任務5.3利用指針引用數組元素intmain(void){
floatt[3][4]
={{18,20,22,25},{26,24,21,19},{16,14,12,15}}//上午、下午、夜間溫度
average(*t,
12);//計算平均溫度,實參:指向t[0][0]元素的指針變量(列指針)
print(t,2);
//輸出夜間溫度值,實參:二維數組名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("一天內的平均溫度:%5.1f\n",
aver);}voidprint(float
(*p)[4],intn)//形參p是指向具有4個元素的一維數組的指針{
intj;printf("夜間內溫度檢測值:");for(j=0;j<4;j++)printf("%5.1f",
*(*(p+n)+j));printf("\n");}
字符串廣泛應用于嵌入式系統與物聯網軟件設計中,本節主要介紹字符串的引用方式和字符串在函數間的傳遞方式。5.4.1字符串的引用方式1、字符數組法【例5.14】用字符數組存放一個字符串,然后輸出該字符串和第4個字符。任務5.4利用指針引用字符串#include<stdio.h>intmain(void){
char
str[]
=
"IloveChina!";//定義字符數組strprintf("%s\n",
str);
//用%s格式輸出str整個字符串printf("%c\n",
str[3]);
//用%c格式輸出一個字符數組元素}【例5.15】用字符指針變量輸出一個字符串和該串的第4個字符。2、字符指針法
在C語言中,用字符數組用來存放字符串常量。因此可將字符串首元素(第1個字符)的地址賦給一個指針變量,通過指針變量來訪問字符串,該指針就是指向字符串的指針。5.4.1字符串的引用方式任務5.4利用指針引用字符串
使用%s輸出時,先輸出指針變量p所指向的一個字符,然后自動使p加1,使之指向下一個字符,再輸出一個字符,…,直到遇到字符串結束標志'\0'為止。#include<stdio.h>intmain(void){
char*p
=
"IloveChina!";
//定義字符指針變量p,并使其指向字符串的第1個字符printf("%s\n",
p);
//輸出整個字符串printf("%c\n",
*(p+3));
//輸出第4個字符}【例5.16】輸出字符串中n個字符后的所有字符。2、字符指針法5.4.1字符串的引用方式任務5.4利用指針引用字符串#include<stdio.h>intmain(void){
intn=10;
char
*ps
=
"thisisabook";
//定義字符型指針變量,并使其指向字符串的第1個字符
ps
=
ps+n;printf("%s\n",
ps);}5.4.2使用字符數組與字符指針變量的區別
用字符數組和字符指針變量都可實現對字符串的存儲和運算。區別:1、存儲內容不同
字符數組可存放整個字符串;而字符指針變量只能存放字符串某個字符的地址。2、賦值方式不同(1)對字符數組賦初值:
charst[]="CLanguage";(2)對字符指針變量賦初值:
char*ps="CLanguage";也可以寫成:
char*ps; ps="CLanguage";而不能寫成:
charst[20];st="CLanguage";
可見,使用指針變量處理字符串更加方便。但要注意:在使用指針變量時,需要對指針變量賦予確定的地址。任務5.4利用指針引用字符串【例5.17】用帶下標的字符指針變量引用字符串中的字符。
說明:可以用下標方式引用指針變量所指向的字符串中的字符。任務5.4利用指針引用字符串5.4.2使用字符數組與字符指針變量的區別#include<stdio.h>intmain(void){
inti;
char*p
=
"IloveChina!";//定義字符指針變量p,并使其指向字符串的第1個字符for(i=0;p[i]
!=
'\0';i++)printf("%c",
p[i]);
//通過下標方式引用字符串中的字符printf("\n");}【課后作業】同步練習5-7:知識鞏固與應用。5.4.3字符串在函數間的傳遞方式任務5.4利用指針引用字符串
在字符串處理運算中,將一個字符串從一個函數傳遞給另一個函數時,可用字符數組名或字符指針變量作函數參數,傳遞字符串的起始地址。(1)用字符數組名作函數參數#include<stdio.h>voidstring_out1(charb[
]){
inti;
for(i=0;b[i]
!=
'\0';i++)
printf("%c",b[i]);}voidstring_out2(charb[
]){
printf("%s",b);}intmain(void){
char
str[
]
=
"abcde\n";
string_out1(str);
string_out2(str);}(2)用字符指針變量作函數參數#include<stdio.h>voidstring_out1(char*b){
for(;*b
!=
'\0';b++)
printf("%c",*b);}voidstring_out2(char*b){
printf("%s",b);}intmain(void){
char
*str
=
"abcde\n";
string_out1(str);
string_out2(str);}【例5.18】字符串的輸出。(1)【例5.19】自編字符串復制的函數。(2)同步練習5-8:活學活用。【課后作業】任務5.5利用指針數組、指向指針的指針引用多個數據5.5.1指針數組1、指針數組的概念
指針數組用來存放一批地址,每一個元素都存放一個地址。
定義一維指針數組的一般形式:
類型標識符
*數組名[數組長度];例如:int
*p[3];
[]比
*
優先級高,p先與[3]結合,構成p[3]數組的形式,然后再與*結合,表示數組p的3個元素均為指向int型數據的指針變量。【例5.20】利用指針數組指向多個整型變量,并輸出各整型變量的值。
5.5.1指針數組任務5.5利用指針數組、指向指針的指針引用多個數據#include<stdio.h>intmain(void){
inta=10,
b=20,
c=30,
i;
int*p[3]
=
{&a,
&b,
&c};
//定義指針數組并使3個元素分別指向3個整型變量for(i=0;i<3;i++)printf("%d\n",
*p[i]);
//利用指針數組引用整型變量
}1、指針數組的概念
【例5.21】利用指針數組指向一維整型數組的各元素,并引用一維整型數組的各元素。5.5.1指針數組任務5.5利用指針數組、指向指針的指針引用多個數據#include<stdio.h>intmain(void){
inta[3]
=
{10,
20,
30},
i;
int*p[3]
=
{
&a[0],
&a[1],
&a[2]
};
//定義指針數組,并初始化for(i=0;i<3;i++)printf("%d\n",
*p[i]);
//利用指針數組引用整型數組元素}1、指針數組的概念
一個字符串可用一維數組來存放,而多個字符串可用二維數組存放。
若用字符型指針引用多個字符串,則需要多個指針,因此也可利用字符型指針數組處理多個字符串。【例5.22】分別用二維數組和字符型指針數組處理多個字符串。5.5.1指針數組任務5.5利用指針數組、指向指針的指針引用多個數據2、利用指針數組處理多個字符串#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-9:知識鞏固及應用。5.5.2指向指針的指針
inta=3;
int
*num=&a;//定義指針變量num,指向變量a printf("%d\n",*num);//通過指針變量num引用變量a
通過指針變量num間接訪問變量a:“單級間址”訪問方式。
若再定義一個指針變量p,存放指針變量num的地址,則可通過指針變量p訪問變量a:“二級間址”訪問方式。p是指向指針數據的指針變量,簡稱“指向指針的指針”。
定義指向指針的指針變量的一般形式:類型標識符
**指針變量名;例如:int
**p;
//指針變量p指向一個整型的指針變量任務5.5利用指針數組、指向指針的指針引用多個數據相當于:
int
*(*p);
//指針運算符的結合性是從右到左5.5.2指向指針的指針任務5.5利用指針數組、指向指針的指針引用多個數據【例5.23】分析程序,理解指向指針的指針。#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.24】有一指針數組num,其元素分別指向一維整型數組a的各元素。現用指向指針的指針變量p,依次輸出整型數組a中各元素的值。5.5.2指向指針的指針任務5.5利用指針數組、指向指針的指針引用多個數據#include<stdio.h>intmain(void){
inta[3]
=
{10,20,30},i;
int*num[3]
=
{&a[0],&a[1],&a[2]};
//定義指針數組num
int**p
=
num;
//定義指向指針的指針變量p,并指向指針數組num的首元素for(i=0;i<3;i++,
p++)
printf("%d\n",**p);//利用指向指針的指針變量p引用整型數組元素}【例5.25】有一指針數組ps,其元素分別指向3個字符串。現用指向指針的指針變量p,依次輸出3個字符串。5.5.2指向指針的指針在實際應用中,指向指針的指針常與指針數組配合使用處理問題。任務5.5利用指針數組、指向指針的指針引用多個數據#include<stdio.h>intmain(void){
inti;
char*ps[3]=
{"ab","abc","abcd"};
//定義指針數組ps
char**p
=
ps;
//定義指向指針的指針變量p,并指向指針數組ps的首元素for(i=0;i<3;i++,p++)printf("%s\n",*p);
//利用指向指針的指針變量p輸出字符串}【課后作業】同步練習5-10:活學活用。任務5.6利用指針調用函數(2)通過指針變量調用函數#include<stdio.h>intadd(intx,inty);
//函數聲明intmain(void){
inta,
b,
sum;int(*p)(int,
int);
//定義指向函數的指針變量
p
=
add;
//使指針變量p指向add函數printf("請輸入a、b的值:");scanf("%d%d",
&a,
&b);sum
=
(*p)(a,
b);//通過指針變量調用add函數printf("a=%d,b=%d\n",
a,
b);printf("sum=%d\n",sum);}intadd(intx,inty){ return(x+y);}
編譯系統為函數代碼分配一段存儲空間,其起始地址稱為該函數的入口地址。【例5.26】用函數求整數a、b的和。利用指針變量調用函數的步驟和方法:
(1)定義指向函數的指針變量
類型標識符(*指針變量名)(函數參數類型列表);
(2)將函數的入口地址(函數名)賦給指針變量,使指針變量指向函數(3)通過“(*指針變量名)(函數參數列表)”調用函數C規定,函數名代表函數的入口地址,可定義一個指針變量存放函數的入口地址,則該指針稱為指向函數的指針,簡稱函數指針。(1)通過函數名調用函數#include<stdio.h>intadd(intx,inty);
//函數聲明intmain(void){
inta,
b,
sum;
printf("請輸入a、b的值:");scanf("%d%d",
&a,
&b);sum
=
add(a,
b);//通過函數名調用add函數printf("a=%d,b=%d\n",
a,
b);printf("sum=%d\n",sum);}intadd(intx,inty){return(x+y);}任務5.6利用指針調用函數用起來更復雜,又有何用?
用函數名調用函數,只能調用所指定的一個函數;而通過指針變量可以根據不同情況先后調用不同的函數,使用靈活。【例5.27】利用指針調用不同的函數。
#include<stdio.h>intmax(intx,inty){return(x>y?x:y);}intmin(intx,inty)
{return(x<y?x:y);}intmain(void){
int(*p)(int,int);//定義函數指針變量
inta=3,b=2,n;printf("請選擇功能號:1-獲取最大值;2-獲取最小值\n");scanf("%d",&n);//輸入功能號printf("a=%d,b=%d\n",a,b);switch(n){case1:p=max;printf("max=%d\n",(*p)(a,b));break;case2:p=min;printf("min=%d\n",(*p)(a,b));break;}}【課后作業】
同步練習5-11:知識鞏固與應用。任務5.7通過函數調用獲取指針值
一個函數可以返回指針型的值,即返回一個地址。聲明返回指針值的函數(指針型函數),一般形式:
類型標識符*函數名(形參列表);
()優先級高于*,因此f先與()結合,表示這是f函數。調用該函數之后能得到一個int
*型的指針(指向整型數據),即整型數據的地址。
例如:int
*f(intx,inty);說明:
在后續的內存動態分配、文件讀寫操作等內容將涉及指針型函數。
【例5.28】利用指針型函數輸出字符串。任務5.7通過函數調用獲取指針值【思考與實踐】
將fun2函數中的static去掉,重新編譯和運行程序,查看結果并分析原因。【課后作業】
同步練習5-12:知識鞏固、程序分析。#include<stdio.h>char*fun1(void)
//指針型函數,返回指向字符型數據的指針{
char
*str="abcde";//定義指針變量,并指向字符串常量(位于常量區)
returnstr;
//返回字符串的起始地址
}char*fun2(void)
//指針型函數,返回指向字符型數據的指針{
static
chars[]="12345";//定義靜態局部數組
returns;
//返回靜態數組的首地址
}intmain(void){
char
*ps;//定義指針變量
ps=fun1();
//調用fun1函數,獲取一指向字符型數據的地址printf("%s\n",ps);//輸出字符串
ps=fun2();
//調用fun2函數,獲取一指向字符型數據的地址printf("%s\n",ps);//輸出字符串
}任務5.8利用內存動態分配函數建立動態數組5.8.1內存動態分配的概念
在4.5節中介紹過全局變量和局部變量,全局變量分配在內存中的靜態存儲區,非靜態的局部變量(包括形參)分配在內存中的動態存儲區。
除此之外,C語言還允許建立內存動態分配區域,用來存放一些臨時用的數據,這些數據不必在程序中的聲明部分定義,也不必等函數結束時才釋放,而是需要時隨時申請開辟,不需要時隨時釋放。在內存中動態分配的數據,只能通過指針來引用。5.8.2內存動態分配的方法任務5.8利用內存動態分配函數建立動態數組
對內存的動態分配是通過庫函數來實現的,對應的頭文件是stdlib.h。1、malloc函數:
void
*malloc(unsignedsize);動態申請分配一個長度為size的連續空間。如果分配成功,返回一個指向所分配內存首字節地址的指針;否則返回空指針NULL。2
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 四個合伙人合同協議書
- 脫離債務協議書
- 男子生育協議書
- 竹鼠引種協議書
- 快遞簽合同轉租協議書
- 熟食店轉讓合同協議書
- 莫衡相親協議書
- 外包電氣工程師協議書
- 租山合伙協議書
- 自然死亡協議書
- 2025年中國冷庫用叉車數據監測研究報告
- 2025年高考第二次模擬考試物理(浙江卷)(參考答案)-20250416-113627
- 2025年化妝師職業技能考試試題及答案
- GA 1812.1-2024銀行系統反恐怖防范要求第1部分:人民幣發行庫
- 2025中信建投證券股份限公司校園招聘易考易錯模擬試題(共500題)試卷后附參考答案
- 2025年山東省泰安市新泰市中考二模化學試題(原卷版+解析版)
- 2025年雞蛋市場調查報告
- 2025年職業技能競賽(計算機程序員賽項)參考試題(附答案)
- 湖北省武漢市2025屆高中畢業生四月調研考試語文試卷及答案(武漢四調)
- 2025年全國中小學生百科知識競賽題庫及答案(480題)
- 測控技術培訓課件
評論
0/150
提交評論