《汽车计算机基础》 课件 5- 灵活使用指针处理问题_第1页
《汽车计算机基础》 课件 5- 灵活使用指针处理问题_第2页
《汽车计算机基础》 课件 5- 灵活使用指针处理问题_第3页
《汽车计算机基础》 课件 5- 灵活使用指针处理问题_第4页
《汽车计算机基础》 课件 5- 灵活使用指针处理问题_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第1单元:C语言程序设计入门第2单元:利用三种程序结构解决简单问题第3单元:利用数组处理同类型的批量数据第4单元:利用函数实现模块化程序设计第5单元:灵活使用指针处理问题第6单元:利用复杂的构造类型解决实际问题汽车程序设计基础篇

第5单元灵活使用指针处理问题【单元导读】

单元学习目标:理解指针的概念;利用指针引用普通变量、数组元素和字符串;利用指针数组引用多个数据。

通过指针,可对计算机的硬件地址直接操作,在嵌入式软件设计中应用非常广泛。利用指针编写的程序具有精炼、高效的优点;另外,还可以利用指针构成表、树、栈等复杂的数据结构。任务5.1理解指针的基本概念

对变量值的存、取都是通过变量的地址进行的。

例如,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.2利用指针引用普通变量5.2.1定义指针变量的方法

定义指针变量的一般形式:

类型标识符

*变量名;

例如:

int

*p1;//p1是指向整型变量的指针变量

注意:一个指针变量只能指向同类型的变量,如p2只能指向实型变量,不能指向字符变量。float

*p2;

//p2是指向实型变量的指针变量char

*p3;

//p3是指向字符变量的指针变量

所谓普通变量,是指基本数据类型(整型、实型、字符型)的变量。

变量的指针就是变量的地址。存放变量地址的变量是指针变量,用来指向另一个变量。5.2.2指针变量的引用任务5.2利用指针引用普通变量请牢记:指针变量中只能存放地址(指针)。

两个有关的运算符:

(1)&:取地址运算符。

(2)*:指针运算符(或称“间接访问”运算符),

取其指向单元的内容。

例如:&i表示变量i的地址(2000),

*p表示指针变量p所指向的存储单元的内容(即p所指向的变量i的值3)。任务5.2利用指针引用普通变量【例5.1】通过指针变量访问整型变量。5.2.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.2指针变量的引用任务5.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.2.3指针变量作为函数参数任务5.2利用指针引用普通变量【例5.3】指针变量(变量的地址)作为函数参数。实参指针的指向

实参传递给形参

变量a和b的值都加1形参被释放

指针变量作函数参数,其作用是将一个变量的地址传递到另一个函数中。#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

}5.2.3指针变量作为函数参数任务5.2利用指针引用普通变量【思考与总结】

函数调用时,传递的是变量的地址,使实参和形参指向同一个内存单元。当形参指向单元的值发生变化时,实参指向单元的值也随之变化。

若想通过函数调用得到n个要改变的值:可在主调函数中设n个变量,将这n个变量的地址传递给被调函数的形参(指针变量)。

实际上,数组名作为函数参数,其本质也如此。5.2.3指针变量作为函数参数任务5.2利用指针引用普通变量【简单例题】变量的地址作为函数实参。【课后作业】(1)【例5.4】对输入的两个整数进行交换并输出。(2)同步练习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}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.3.2通过指针引用一维数组元素任务5.3利用指针引用数组元素

【例5.5】输出数组中的全部元素。

引用一个数组元素有两种方法:下标法:a[i]。指针法:*(p+i)

顺序访问数组元素时:第(2)种方法比第(1)种方法快,用指针变量直接指向元素,不必每次都重新计算地址。这种有规律地改变地址值(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,*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通过指针引用一维数组元素任务5.3利用指针引用数组元素

(1)可以通过改变指针变量的值(如p++)而指向不同的元素。而a++是错误的,因为a是数组名(数组的首地址),是常量。(2)要注意指针变量的当前值。

在使用指针变量引用数组元素时,要特别注意:

从运行结果看,没有实现要求。如何改正?#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.6】通过指针变量输入和输出a数组的5个元素。for(p=a,i=0;i<5;i++,p++)for(p=a;

p<a+5;p++)5.3.2通过指针引用一维数组元素任务5.3利用指针引用数组元素【例5.7】通过指针变量找出数组元素的最大值和最小值。#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.7程序的设计思路,上机编程并运行程序。(1)自学例5.7程序下面的说明。(2)同步练习5-3:知识巩固。【课后作业】任务5.3利用指针引用数组元素

在4.4.2节曾介绍过数组名可以作函数的实参和形参。

实际上,C语言编译系统都是将形参数组名作为指针变量(存放地址)来处理的,并非真正开辟一个新的数组空间。voidf(intb[

],intn)相当于:

void

f(int*b,intn)5.3.3用数组的首地址作函数参数的应用形式任务5.3利用指针引用数组元素

普通变量、数组元素,普通变量的地址、指针变量、数组名都可以作为函数参数:5.3.3用数组的首地址作函数参数的应用形式任务5.3利用指针引用数组元素在主调函数中若有一实参数组,则主调函数的实参和被调函数的形参,有4种形式:5.3.3用数组的首地址作函数参数的应用形式【例5.8】用指针变量作函数形参,改写例4.5给出的程序。任务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-4:知识巩固与应用。【课后作业】5.3.3用数组的首地址作函数参数的应用形式任务5.4利用指针引用字符串

字符串广泛应用于嵌入式系统与物联网软件设计中,本节主要介绍字符串的引用方式和字符串在函数间的传递方式。5.4.1字符串的引用方式1、字符数组法【例5.9】用字符数组存放一个字符串,然后输出该字符串和第4个字符。#include<stdio.h>intmain(void){

char

str[]

=

"IloveChina!";//定义字符数组strprintf("%s\n",

str);

//用%s格式输出str整个字符串printf("%c\n",

str[3]);

//用%c格式输出一个字符数组元素}5.4.1字符串的引用方式任务5.4利用指针引用字符串【课后作业】同步练习5-5:理解概念、解决实际问题。【例5.10】用字符指针变量输出一个字符串和该串的第4个字符。2、字符指针法

在C语言中,用字符数组用来存放字符串常量。因此可将字符串首元素(第1个字符)的地址赋给一个指针变量,通过指针变量来访问字符串,该指针就是指向字符串的指针。

使用%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.4.2使用字符数组与字符指针变量的区别任务5.4利用指针引用字符串

用字符数组和字符指针变量都可实现对字符串的存储和运算。区别:1、存储内容不同

字符数组可存放整个字符串;而字符指针变量只能存放字符串某个字符的地址。2、赋值方式不同(1)对字符数组赋初值:

charst[]="CLanguage";(2)对字符指针变量赋初值:

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

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

charst[20];st="CLanguage";

可见,使用指针变量处理字符串更加方便。但要注意:在使用指针变量时,需要对指针变量赋予确定的地址。任务5.4利用指针引用字符串5.4.2使用字符数组与字符指针变量的区别【例5.12】用带下标的字符指针变量引用字符串中的字符。

说明:可以用下标方式引用指针变量所指向的字符串中的字符。#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-6:理解概念、分析程序。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.11】字符串的输出。5.5.1指针数组的概念

指针数组用来存放一批地址,每一个元素都存放一个地址。

定义一维指针数组的一般形式:

类型标识符

*数组名[数组长度];例如:int

*p[3];

[]比

*

优先级高,p先与[3]结合,构成p[3]数组的形式,然后再与*结合,表示数组p的3个元素均为指向int型数据的指针变量。任务5.5利用指针数组引用多个数据5.5.1指针数组的概念通过两个简单实例,理解

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论