C语言----指针基础(进阶篇二十五)

 

  指针的作用

    ※处理大量数据:编写大型软件时,函数与函数之间经常会传送大批量的数据。比如一个班有50个学生,有一个子函数的作用就是将这50个学生的成绩进行排序,再返回给父函数。如果用之前学过的“参数复制”方式,我们就要定义一个有50个参数的子函数,并且子函数只能有一个返回值,不能实现这个功能。

    这时候父函数可以将第一个同学的座位号(指针)传给子函数,一个参数就能搞定。

    ※改变父函数中变量的值。

    ※高手用来提高程序运行速度。

  内存和地址

    ※许多馆子店在管理房间时,会给每个房间编号,同时会给房间取个名字,比如“水云阁”,“碧玉居”等等。那么名字就是我们平时所说的“变量名”,编号就是我们所说的“指针”,俗称“内存地址”。

    ※指针也是变量,它也要占用内存,它不存储“整数”,“实数”这种普通数据,它存的是其它变量的“地址”,占用4字节内存。

  指针的定义和使用

    普通变量定义时,前面加个*就是指针的定义。一般来说,我们都会在指针类型的变量名前面加p,表示pointer(指针)的意思。

    指针也是变量,它也要占用内存,只是它不是存“整数”,“实数”,它存的是其它同种类型变量的“地址”。就像一个抽屉A,里面什么也不放,只放着另一个抽屉B的钥匙,若想拿到抽屉B中的物品,必须先从抽屉A中取钥匙。

    下面我们来看一个指针的执行情况:

      int i=15,j=0;      /*定义2个普通变量*/

      int *pi,*pj=0;     /*这行定义2个指针,pj初始化为空指针*/

      pi=&i;              /*用&运算符将i的地址赋给指针pi*/

 

 

    注意:

      ※可以将地址0赋给指针,如pi=0时,系统会自动将0转成空地址赋给pi。

      ※等号左边只允许是容器,右边只允许是数值。如果右边是容器,它会自动取出容器里的数值。

      ※ * 在定义时出现表示定义指针,在表达式中出现表示取值。它还有个作用就是做乘号,这时它是个双目运算符。

      

      如:

        int i=5,j=0,*pi;     /*定义指针*/

        pi=&i;

        int *pj=pi;           /*定义指针*/

        j=*pi;                  /*取值*/

        *pi=50;

        j=i*5;                 /*作为乘号*/

 

    提问:

      int i;

      int *pi=&i;

      这个*是定义变量还是取值?

      实际上系统看见“变量定义”与“表达式”合成的语句,会自动分解。如上式会被分解为:

      int *pi;

      pi=&i;

 

      int *p1=&a,*p2=p1;会被分解为:

      int *p1,*p2;

      p1=&a;

      p2=p1;

 

      思考一下:int *p=p1;和*p=*p1;的含义各是什么?

 

 

    程序1

      用指针间接操作2个变量

// 25-1用指针操作两个变量.c

#include <stdio.h>

void fun1()
{
    int a = 0, b = 0;    //定义两个普通变量
    int *p;                 // 定义指针变量

    p = &a;                 //取变量a的内存地址,(&是取址运算符)赋值给指针p
    *p = 30;             //把30赋给指针p指向的变量中(*是取变量运算符,与&相反)
    // p 指向 a

    p = &b;                //取变量b的内存地址,(&是取址运算符)赋值给指针p
    *p = 50;            //把50赋给指针p指向的变量中
    // p 指向 b

    printf("a = %d,b = %d", a, b);

}

void fun2()
{
    int a = 10, b, *p1, *p2;  //定义普通变量  指针变量
    p1 = &a;                  //取变量a内存地址赋值给p1
    b = *p1;                  // *p1取值 赋值给 变量b
    //若b = p1的 值就是: p1里面存的a的内存地址 赋值给变量 b
    printf("%d,%d\n", a, b);   //result :  a = 10   b = 10

    p2 = p1;     //指针赋值 p2指针也指向变量a的内存地址
    //如果 p2 = *p1  相当于 *p1取值里面是:10 赋值给p2
    //如果 *p2 = p1  报错

    b = 20;
    p1 = &b;
    *p2 = *p1; //取p1的内容赋给p2指向的变量

    printf("a=%d,b= %d\n", a, b);
}

main()
{
    fun2();
}

    ※指针就相当于存放着各变量的钥匙,得到变量的钥匙用&i,从指针中拿钥匙取值就用*pi

    ※指针不能指向不同类型的变量。

      如:

        float f=3.14;

        int *pi=&f;        /*错误*/

 

    ※指针在定义时*号可以靠着类型,也可以靠着变量,但中间一定要有空格。通常定义函数返回值时靠着类型,定义变量时靠着变量。为什么呢?

 

      如:

 

        int*  pi,pj;

 

        /*此写法容易误认为定义了2个指针,实际上pj是整型变量*/

        int  *p,pj; /*立刻就看出第二个不是指针*/

 

        因为函数不可能定义多个返回值,所以*号可以靠着类型。

        int*  fun(){…}  /*表示此函数返回一个整型指针*/

        int  *fun(){…}

        /*此写法容易误认为定义了指向函数的指针*/

 

posted @ 2021-10-31 17:34  httpcc  阅读(140)  评论(0编辑  收藏  举报