利用指针实现三个数从大到小输出_第8章 指针

第八  指针

8.1  指针变量的定义与引用

【学习目标】

(1)掌握指针的概念

(2)掌握指针变量的定义方法

(3)掌握指针变量的赋值方法及相关运算符的使用

(4)会区分指针变量的值和指针的地址值

(5)掌握指针变量的基本操作

实例34  指针变量的定义与引用——寻找变量在内存中的

【实例任务】

已经定义了字符型、整型、实型三个变量,试定义三个指针变量,然后将几个变量在内存中的地址赋值给指针变量,输出本个变量的在内存中的地址值和变量的值。程序运行结果如图8-1所示。

d6caff739c0ac7d5e05e78736e4c3788.png

                           图8-1  程序运行结果

【程序代码】

#include  "stdio.h"

main()

{    char  c='a';

    int n=10;

    float f=1.5;

    char *cp; /*定义一个指向字符型变量c的指针变量*/

    int *np;/*定义一个指向整型变量a的指针变量*/

    float *fp ;/*定义一个指向单精度类型变量n的指针变量*/

    char **cpp; /*定义一个指向字符型指针变量cp的指针变量*/

    int **npp; /*定义一个指向整型指针变量np的指针变量*/

    float **fpp; /*定义一个指向实型指针变量fp的指针变量*/

    /*让指针变量指向各个变量并输出值 */

    cp=&c;/*取变量c的地址值给指针变量cp,也就是cp指向c*/

    np=&n;/*np指向变量n*/ 

    fp=&f;/*fp指向变量f*/ 

     printf("变量的初值和指针变量的初值为:\n");

     printf("变量c的值为:%c,它在内存中的地址为:0x%x\n",c,cp);

       /*c为字符型变量,内存中的地址输出值为十六进制整型*/ 

     printf("变量n的值为:%d,它在内存中的地址为:%#x\n",n,np);

       /*c为字符型变量,内存中的地址输出值为十六进制整型*/ 

     printf("变量f的值为:%f,它在内存中的地址为:0x%x\n",f,fp);

      /*c为字符型变量,内存中的地址输出值为十六进制整型*/ 

     /*改变变量的值,看看指针变量的值是否改变*/ 

     c='b';

     n=20;

     f=2.5;

     printf("\n\n变量的初值和指针变量的初值为:\n");

     printf("变量c的地址值为:%#x,它所存储的内容为:%c\n",cp,*cp);

     printf("变量n的地址值为:%#x,它所存储的内容为:%d\n",np,*np);

     printf("变量f的地址值为:%#x,它所存储的内容为:%f\n",fp,*fp);

      /*"*"是运算符,表示引用指针变量所内存单元中的内容*/

      /*通过指针变量改变所指地址的值*/

     *cp='c';      

*np=30;

     *fp=3.5;

     printf("\n\n通过指针变量改变所指地址的内容\n");

     printf("变量c的值为:%c\n",c);

     printf("变量n的值为:%d\n",n);

     printf("变量f的值为:%f\n",f);

     /*通过指向指针的指针变量引用变量的值*/

     printf("\n\n通过指向指针的指针变量引用变量的内容\n");

     cpp=&cp;

     npp=&np;

     fpp=&fp;

     printf("变量c的值为:%c\n",**cpp);

     printf("变量n的值为:%d\n",**npp);

     printf("变量f的值为:%f\n",**fpp);

}

【相关知识】

1.变量在内存中的地址

在C语言的程序设计中,指针是一种非常重要的数据类型,借助它可以表达非常复杂的数据结构,因而得到了广泛的应用,也是C语言中一个重要的知识点。

要了解指针,先要了解内存空间是如何进行存储和访问的。计算机内存管理时,是以字节为单位来编号的存储单元,这个编号就是这个单元在内存中的地址,类似于楼房中按序号编排的各家各户的门牌号码。

当一个变量被定义后,就在内存中为之分配一个大小合适的存储空间,这个空间的大小由变量的类型而定。一个char类型变量就占1个字节的存储空间,一个int类型的变量就占2个字节的存储空间,一个float类型的变量就占4个字节的存储空间,一个float类型的数组a[10]就占10×4个字节的空间。对于占多个字节的变量,存储空间的起始地址被当作是这个变量的地址。

实例中,定义语句“char  c='a'; int n=10; float f=1.5;”定义的三个变量,假如地址分配如图8-2所示。

8ea875de57ddf9077b5e07c287c6f976.png

4e322dd87e8f6e7aef9815e2814893a1.png

                       图8-2 地址分配

在这里,我们称变量c的地址为1000,变量n的地址为2000,变量f的地址为3000,这样就可以通过变量的地址实现对变量的访问。以前各章节,使用变量时都是通过变量名对变量内容进行存取,无需知道变量在内存中的存储地址,这种对存储单元的访问过程由系统自动完成对地址的查找,这种方式也称为“直接访问”。

学习本章后,可以在定义变量后,先将变量在内存的地址赋给指针变量,然后通过指针变量来访问变量的内存单元,这种访问方式也称为“间接访问”。实例中,定义的指针变量np,取整型变量n的地址赋值给np,则np指向了变量n,它们之间的关系如图8-3所示。

                   指针变量np       整型变量n

c2022a8b5f87b355c8fd2d0d10d15c7f.png0a15ece18cd13095c7b59d00a1e5c1cd.png

                           4000          2000   2001

                图8-3  指针变量存放变量的起始地址

这样,我们再使用变量n的时候,就可通过指针变量p来引用。指针的知识在后续章节中被广泛使用,尤其链表的建立部分,使用指针是唯一选择。

2.指针的定义

指针变量用于存放变量的地址,所以定义类型要与所要存储变量的地址相一致,这对指针变量而言,称为指针变量的基类型。定义指针变量的基本形式是:

    基类型名   *指针变量1,*指针变量2,…

如实例中的如下定义语句:

char *cp;

int *np;

float *fp;

这里,变量名cp、np、fp前的*标识出这三个变量。cp只能存放字符型变量的地址,np只能存放整型变量的地址,fp只能存放单精度型变量的地址。

另外,还有如下的定义形式:

int (*a)[5];  /*定义一个整型数组的指针变量,这个数组有5个数组元素*/

int (*f)( );  /*定义指向函数的指针变量,该函数返回一个整型值*/

int  *(*f)( ); /*定义一个指向函数的指针变量,此函数返回一个地址值*/

还有下面两种情况,应区别看待,依据字符的优先级别,其定义的结果不属指针变量。

int *a[5] /*a是数组名,它有5个数组元素,每个数组元素都是指向整型的指针变量*/

int *f( ); /*f是一个函数名,它返回指向一个整型值的地址*/

3.指针变量的引用

C语言中,对指针变量的引用,可以通过取地址运算符“&”和间接访问运算符“*”来完成。有前面章节中,输入变量的值是使用scanf语句,就是使用&这个运算符将输入结果保存到系统指定的存储单元中。

如有如下程序段,我们可以灵活使用这两个运算符完成对变量的引用:

int n=10,*p,**np;

  p=&n;

  np=&p;

则输出变量n的值,可以用如下几种方法:

  printf("直接输出n的值为:%d\n",n);

  printf("使用n的地址值输出n的值为:%d\n",*(&n));

  printf("引用指针变量p输出n的值为:%d\n",*p);

  printf("引用指针变量np输出n的值为:%d\n",**np);

【课堂精练】

1. 通过指针变量,按由大到小输出两个整数。程序的运行结果如图8-4所示。

74e5c24668e25a89b4e165c0fdcd03c9.png

                   图8-4  程序运行结果

根据程序的运行结果,将程序补充完整并调试。

#include  "stdio.h"

main()

{ int a,b,*p,*p1,*p2;

  scanf("%d,%d",&a,&b);

  ________________;

  ________________;

  if(a

  {p=p1;___________;___________;}

  printf("\n输入的a=%d,b=%d\n",a,b);

  printf("排序后两个数为%d,%d",*p1,*p2); 

  getch();     }

2.通过指向指针的指针变量,改变整型变量和字符型变量中的值。

    程序的运行结果如图8-5所示。

d92d913d624ba056e6b1651b0000d0bd.png

               图8-5  程序的运行结果

根据程序的运行结果,请将如下程序补充完整并调试。

#include "stdio.h"

main()

{char c='a',*cp,**cpp;

 int  n=10,*np,**npp;

 cp=&c;

 __________________________;

__________________________;

 npp=&np;

 c=(*cp)+1;  

 c=(**cpp)+1;

 *np=(*np)+10;

 n=(**npp)+10;

 printf("通过引用指针变量运算后,c的值为:%c\n",c);

 printf("通过引用指针变量运算后,n的值为:%d\n",n);

 getch();         } 

8.2  一维数组与指针

【学习目标】

(1)掌握数组名中存放的值的内涵

(2)会区分数组元素的值和数组元素的地址值

(3)能通过数组名的运算实现指针的移动来引用数组元素

实例35  数组名的值和数组元素的地址——按序输出内存中各家地址

【实例任务】

定义一个有6个数组元素的一维整型数组,用于存放6户人家的房号。利用数组名的值和数组元素的地址值,分别输出1-6号家庭的编号和在内存中的地址。程序的运行结果如图8-6所示。

1ed8a9046db22dc4e1ad6cfb4acb71cb.png

                       图8-6  程序的运行结果

【程序代码】

#include "stdio.h"

main()

{int a[6]={1,2,3,4,5,6};/*为各个家庭编号*/

int i=0;

printf("\n通过引用各个数组元素输出各个房间号的值\n");

while(i<< span="">=5)

{printf("%d   ",a[i]);

i++;}

printf("\n");

printf("通过数组的首地址来输出各个房间号的值\n");

for(i=0;i<=5;i++)< span="">

{printf("%d   ",*(a+i));}

printf("\n"); 

printf("输出整型数组各元素在内存中的十六进制地址\n");

for(i=0;i<=5;i++)< span="">

printf("0x%x    ",&a[i]);

 getch();          }

【相关知识】

1.一维数组名的值

一维数组被定义后,数组名就有了一个恒定的值,即这个数组在内存所占一串连续存储单元的首地址,也就是第一个数组元素的地址。

实例中,定义的数组a,它的值是数组元素a[0]在内存中的地址值,这个值不可改变,因此“a++;”或“a=&p;”等这样的语句都是不成立的。

2.数组元素的地址

虽然我们不能改变数组名的值,但是可以通过对数组名的运算,来得到不同数组元素的地址。如数组元素a[3]的地址值为表达式a+3的值。这种指向关系如图8-7所示。

1d8c2c6bff571ebe22e40b0ca79404ca.png

2b997aec8b90062a98ed94c18944acff.png

                图8-7  数组名的运算

可见,我们要想得到数组元素的地址,除直接引用取地址运算符名,还可以通过数组名得到。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值