• 指针变量和指针变量符号 & *


    指针和普通变量的一样,本质没有区别,指针的本质就是变量。指针全名就是指针变量。

    1.什么是指针?

    #include<stdio.h>
    int main(void)
    {
        int   a = 0;
        float b = 3.14;
        char  c = 'a'; 
    }

    分析:

    变量 a 的数据类型是int,a存放整形数据
    变量 b 的数据类型是float,b存放浮点数
    变量 c 的数据类型是char,c存放字符型

    思考1:我们发现一个变量的存放什么样的数据取决于他的数据类型,对于一个变量,我们想让它是什么类型就定义成什么类型,我要整型变量b,int b这样就能得到了。思考:我要指针类型的p,怎么办?肯定得有一个”指针类型“吧?

    int * p;//定义一个指针p

    这样我们就得到一个指针p,类型是int*,其实是指针p指向int的地址。指针本身没有类型。就好比一块地本身不是商场也不是居住房,就看我们怎么规划这块土地。

    思考2:整型变量存放整形数据,浮点类型数据存放浮点数据,那指针存放什么数据?

    指针存放的都是地址,指针的类型只代表指针存放什么类型数据的地址。
    int * p1 //指针p1存放int类型数据的地址
    float *p2 //指针p2存放float类型数据的地址
    char *p3 //指针p3存放char类型数据的地址

    由此来看指针只能存放地址。关键取决于存放什么类型数据的地址
    int a = 10; //int类型的a
    int pa = &a; //所以要存放a的地址,指针pa只能是int类型的

    思考3:如何让定义一个指针,指向浮点数?(所谓指向就是保存被指向的变量的地址)

    float b = 3.14; //定义一个浮点数b
    float *pb =&b; //定义一个指针指向b

    2.为什么使用指针

    (1)为了间接访问,cpu通过寄存器间接访问一个物理地址,cpu直接访问地址叫做直接访问。
    (2)需要注意的是:指针是必然出现的。因为cpu需要间接访问地址。
    3.指针如何使用?
    (1)三部曲:定义,赋值,解引用。这三步缺一不可,

    #include<stdio.h>
    int main(void)
    {
        int a = 10;             //第一步:定义一个int数据
        int *pa = &a;           //第二步:定义一个指针并赋值
        *pa = 20;               //第三步:解引用
        printf("*pa = %d",*pa); //*pa = 20
        printf("a = %d",a);     //a = 20
    
    }

    思考4:为什么a也变成了20?
    当第二步中,把a的地址赋值给指针pa以后,相当于给了指针pa一个可以进入a家里的钥匙,可以随意进出,一旦把钥匙给了pa,当a回家一看,完了,家里被盗了。。

    (2)指针和地址
    pa 存放的是a的地址
    *pa 就等价于寻访pa存放的地址所对应的变量。也就是pa 是等于a的

    & 表示取出一个变量的地址
    * 表示访问一个地址存放的变量是谁
    (3)来看看 * 用在不同地方的区别

    int * p = &a; //定义指针时,*表示该变量是一个指针类型
    * p = 250; //解引用时,*表示访问该地址的变量

    (4)再来看一个细节

    int * p1,p2;

    p1、p2分别是什么类型?先假装思考一下~~~~

    p1是int*,而p2是int类型,所以当我们需要连续定义两个指针变量时需要这么定义

    int * p1,*p2;

    (5)指针定义并初始化,与指针先定义后赋值的区别
    (1)指针的初始化就是给它赋初值,
    (2)指针定义初始化: int a = 1; int *p=&a;
    (3)再定义之后赋值:int a = 1; int *p; p = &a;

    (6)左值和右值
    我们来看一下下面这句代码
    int a = 10,b = 20;
    a = b;

    有没有想过执行完这一句编译器做了什么?
    一步一步分析:

    第一步:编译器看到要定义变量,先找类型,找到是int类型

    第二步:编译器在内存中分配一个int类型大小的字节地址(0x12345678),并标记和变量a绑定。再找到一个地址0x12345679和b绑定

    第三步:给a赋值,a = 10:编译器自动找到变量a对应的地址(0x12345678),把10写入地址0x12345678
    编译器自动找到变量b对应的地址(0x12345679),把20写入地址0x12345679

    第四步:编译器一看要要执行a = b;于是找到变量b对应的地址0x12345679里面的值(20)写入变量a对应的地址0x12345678

    第五步:思考左值和右值的区别:a = b; 把b的值写入a对应的地址,

    总节:

    左值和右值时一大重点,后面我们还会再来研究的,这里只开一个头。

  • 相关阅读:
    Cookies 和 Session的区别
    List接口、Set接口和Map接口
    Java NIO:IO与NIO的区别
    NIO与传统IO的区别
    Java中堆内存和栈内存详解
    Java序列化与反序列化
    maven搭建
    深入研究java.lang.ThreadLocal类
    SQL 优化经验总结34条
    数据库事务的四大特性以及事务的隔离级别
  • 原文地址:https://www.cnblogs.com/1024E/p/13209628.html
Copyright © 2020-2023  润新知