C语言-指针

一. 指针的概念

指针的用途: 高效的访问数据
特征:

高效,简洁(相对于普通变量而言)。

指针可以直接访问物理内存,或者直接操作硬件。(单片机开发)。

内存地址: 计算机需要对物理内存进行管理。因为内存空间大,给每个**存储单元(1byte)**分配一个编号。这个标号就被称为内存地址。

**指针:**就是指针变量。专门用来存储内存地址的变量。在32位系统中,任意类型的指针大小为4byte (0-0xffffffff)。64位系统中任意类型的指针大小为8byte.(0-0xffffffffffffffff).

指针的类型是多种多样:int*(整形的),char*(字符指针),double*(浮点类型指针)。任意类型的指针大小都是一致。 用指针可以表示任意的数据。

相关的运算符:

&:取地址运算符。获得变量在内存空间中的地址编号。

单目运算符,从右向左结合。

被操作对象,只能是变量。不能是常量,或这表达式。

int a =20;

&a; //获得a变量在内存中的地址。需要输出时应使用%p打印地址。

*:解引用操作符。对地址进行解引用操作。

cpp 复制代码
int main()
{
    int a = 66;
    char c = 'z';

    printf("&a is %p,&a size is %lu\n",&a,sizeof(&a));//整形指针
    printf("&c is %p,&c size is %lu\n",&c,sizeof(&c));//字符指针

    printf("a = %d\n",*&a);//解引用操作,对象必须是指针
    printf("c = %c\n",*&c);

    return 0;
}

二. 指针的定义与初始化

cpp 复制代码
int main()
{
    int* pi;//只能指向整形变量的地址
    char *pc;//野指针
    double *pd = 0;//空指针
    float *pf = NULL;//空指针,逻辑上先指向地址为0处的空间,稍后给一个合理的
                     //地址

    int a = 10;
    pi = &a;//正常初始化

    return 0;
}

注意:1、指针也是有类型的

2、在定义指针时,同时初始化为NULL或者0,防止野指针。

**野指针:成因:**1、指针未初始化,指向的内存地址随机

2、指针指向的变量内存空间被释放

三. 指针的访问

直接访问变量的内容称为直接访问。

使用指针访问变量的内容称为间接访问。

cpp 复制代码
int main()
{
    int a = 0, b = 0, ret = 0;
    int *pa = &a, *pb = &b;
    printf("input two number:");
    scanf("%d %d",pa,pb);
    //使用指针完成加减乘除
    ret = *pa + *pb;
    printf("a + b = %d\n",ret);
    ret = *pa - *pb;
    printf("a - b = %d\n",ret);
    ret = *pa * *pb;
    printf("a * b = %d\n",ret);
    ret = *pa / *pb;
    printf("a / b = %d\n",ret);

    return 0;
}

四. 指针的运算操作

cpp 复制代码
int main()
{
    int a = 0, b = 0;
    int *pa = &a, *pb = &b;
    printf("&a = %p,&b = %p\n",pa,pb);
    printf("&a - 1 = %p\n",pa-1);
    
    //pb - pa 指向两个不同变量的指针,相减无意义
    //pa = pa * 2, pa = pa / 2 指针的相乘相除都无意义
    //

    int arr[10] = { 0 };
    int *p1 = &arr[0], *p2 = &arr[9];
    int ret = p2 - p1;//在同一数组中,指针减指针得到的是两个指针之间的元
                      //素个数
    printf("p2 - p1 = %d\n",ret);

    return 0;
}

对于同一数组来说,指针减指针得到的是两个指针之间的元素个数:

相当于:(p1 - p2) / sizeof(基类型)

4.1 不同类型的指针的解引用操作

指针的类型决定了在使用解引用操作时访问几个字节的大小。比如 int* 类型的指针解引用时可访问4个字节,char* 类型的指针在进行解引用操作时可访问1个字节

如果执行*解引用操作话。假设指针存储的地址是0x2000,则不同类型的指针的解引用有如下操作结果:

char*,取0x2000 开始的1个字节空间的数据

int*,取0x2000 开始的4个字节空间的数据

short*,取0x2000开始的2个字节空间的数据

f1oat*,取0x2000 开始的4个字节空间的数据

double*,取0x2000 开始的8个字节空间的数据

4.2 不同类型的指针的++,--

如果执行++。假设指针存储的地址是0x2000,则不同类型的指针的解引用有如下操作结果:

char*,偏移量 1byte -> 0x2001

int*,偏移量 4byte -> 0x2004

short*,偏移量 2byte -> 0x2002

f1oat*,偏移量 4byte -> 0x2004

double*,偏移量 8byte -> 0x2008

五. 大小端存储方式

**大端存储方式:**数据的低字节存储在高地址,高字节存储在低地址

**小端存储方式:**数据的低字节存储在低地址,高字节存储在高地址

大小段存储方式,是由CPU 决定。 51单片机,网络设备,都使用大端方式储存数据。

AMD,intel,ARM,都是采取小端存储。

cpp 复制代码
int main()
{
    int a = 1;
    char *p = (char*)&a;//强制类型转换

    if(*p == 1)
        printf("小端存储\n");
    else
        printf("大端存储\n");

    return 0;
}
相关推荐
郑州光合科技余经理2 小时前
同城外卖小程序开发:下单成功后,后台导出能不能对上用户端状态
开发语言·前端·git·后端·uni-app·php·ai编程
知识分享小能手2 小时前
C++ 学习教程,从入门到精通,C++ 入门知识 — 完整知识点(1)
开发语言·c++·学习
+VX:Fegn08953 小时前
计算机毕业设计|基于springboot + vue旅游管理系统(源码+数据库+文档)
java·开发语言·vue.js·spring boot·课程设计
阿里嘎多学长3 小时前
2026-09-20 GitHub 热点项目精选
开发语言·程序员·github·代码托管
Escalating_xu4 小时前
【C 语言项目】数组和函数综合实践:从零实现控制台扫雷游戏
c语言
weixin_307779135 小时前
C++代码实现MATLAB中的ode23tb函数功能
开发语言·c++·算法·matlab
2601_966949655 小时前
为什么量化回测中 for 循环比 DataFrame 慢三个数量级?从向量化原理讲起
开发语言·python·pandas·股票数据·quantdash
边境悍匪7 小时前
蜗牛学苑 Java 智能体学习 Day45|Knife4j+SpringBoot3、书城项目整合 MyBatis 思维导图复盘
java·开发语言·vue.js·学习·spring
我的xiaodoujiao7 小时前
Django 基础知识详细图文教程 9-Django 模板引擎 2
开发语言·数据库·后端·django
菜鸟~noob2337 小时前
【太空电子战】从CCS到Meadowlands:反通信系统的二十年演进史【含matlab代码】
开发语言·matlab