• C primer plus学习笔记 —— 5、指针


    什么是指针

    指针是一个值为内存地址的变量。
    类比一下:int类型变量的值是个整数。 指针类型变量的值是个地址。

    int a = 4;// 变量a是一个整数值
    int * p = 0x3434523; //变量p是一个地址值
    
    • 1
    • 2

    但是这个地址的值一般我们肯定不能显示的知道,一般交给系统分配完之后,然后我们使用

    int a = 4;
    int *p = &a; //因为系统已经给变量a分配地址了,所以我们可以取到a的地址然后赋值给p
    
    • 1
    • 2

    这里指针是p,我们也可以说是指针p指向变量a。

    * 运算符

    运算符* 我们也管他叫解引用运算符。

    声明一个指针:

    int *p; //p是指向int类型变量的指针。
    char *pc; //pc是一个指向char类型的指针
    
    • 1
    • 2

    这里,星号 * 表示声明的意思,声明的变量是一个指针。也就是声明p是一个指针,这个指针指向int类型变量。换句话说存储在p地址上的数据类型为int
    pc指向的值也就是(*pc)是char类型。

    int a = 4;
    int *p = &a; 
    printf(%d, *p); //*会找出地址p上存在的值
    
    • 1
    • 2
    • 3

    指针类型

    指针实际上是一个新的类型,他不是整数类型,他就是指针类型。比如p,他的类型就是指针。
    int*pchar*pc中p和pc都是指针类型,但是他们地址上存储的值类型不同,一个存储的是int类型,一个存储的是char类型。
    不是说这个指针的类型是char,另一个指针类型是int。而应该说他们都是指针类型,而指向的值的类型不同。

    int main(void)
    {
        int a = 1000;
        int *p = &a; 
        printf("%p \n", p); //打印地址 0x7ffeba874aac
        printf("%d \n", *p);  // 1000
        char *pc = &a;
        printf("%p \n", pc); //打印地址 0x7ffeba874aac
        printf("%d \n", *pc); // -24
    
        printf("%p \n", p+1); //0x7ffeba874ab0
        printf("%p \n", pc+1); //0x7ffeba874aad
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    体现就是以什么为单位:比如上例中如果以int为单位,我们打印p的地址,并取到p处的值,以int类型去取,就是4字节去取得到1000。
    当我们以pc指针取到a的地址的时候,还是取这个位置的值,但这时我们是以char类型为单位去取的,那么得到的值就是其中一个字节的值-24.

    再来看地址+1,比如p+1在内存地址中会以int为移动最小的单位,移动4字节,也就是地址值会增加4,而pc+1则只移动1个字节地址值只增加1。

    个人理解

    书中并没有说指针类型不同,但是我觉得可以理解为不同类型的指针,比如int类型的指针,和char类型的指针,这两个属于不同类型的指针,他们在移动的时候就是以各自为单位,并且指向的值是不同类型。也没有什么不妥。

    地址的值强转

    地址由一个无符号的整数表示。我们可以用uint_64t
    我觉得一个例子能更好的理解指针,就是把一个uint_64类型的数给强转成指针类型。

    
    int main(void)
    {
        int a = 1000;
        int *p = &a; 
        printf("%p \n", p); //打印地址 0x7ffeba874aac
    
        uint64_t val_p = (uint64_t)p; //p是一个指针类型,我们给他强转
        printf("%lx \n", val_p); // 7ffeba874aac
       
        // &a 就是一个地址的值,我们可以把它强转成一个指针类型
        
        printf("%lx \n", &a); // &a 的值为7ffeba874aac
        int *ip;
        ip = (int *) &a; //这样ip就是该地址了
        printf("%p \n",  ip); //0x7ffeba874aac
        printf("%d \n", *ip); // 1000 我们可以取到该地址
    
        int *ip2;
        ip2 = (void *) &a; //z这个地址我们可以强转成任意指针类型
        printf("%p \n",  ip2); //0x7ffeba874aac
        printf("%d \n", *ip2); // 1000 但是打印时候我们要指明这个打印的变量是什么类型
    
    	printf("%zd \n", sizeof(int*)); //8
        printf("%zd \n", sizeof(ip)); //8
        printf("%zd \n", sizeof(void *));//8
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    指针类型所占大小都是8字节。

  • 相关阅读:
    jmeter性能测试步骤实战教程
    Jmeter调用Python脚本实现参数互相传递的实现
    浅谈菊风实时音视频 (RTC)与实时操作系统 (RTOS) 在智能硬件领域应用
    卷妹带你回顾Java基础(一)每日更新Day2
    DRF 学习
    基于事件触发机制的孤岛微电网二次电压与频率协同控制MATLAB仿真模型
    MoeCTF2022 部分Crypto 复现
    C++/C关于#define的那些奇奇怪怪的用法
    LeetCode75——Day18
    Bug记录:【com.fasterxml.jackson.databind.exc.InvalidDefinitionException】
  • 原文地址:https://blog.csdn.net/chongbin007/article/details/125902394