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;
}
相关推荐
zhangzhi19798155921 小时前
Agent Skills
开发语言·python
故事和你912 小时前
洛谷-【图论2-1】树4
开发语言·数据结构·c++·算法·动态规划·图论
故事和你912 小时前
洛谷-【图论2-1】树1
开发语言·数据结构·c++·算法·深度优先·动态规划·图论
段ヤシ.2 小时前
回顾Java知识点,面试题汇总Day5(持续更新)
java·开发语言
不会C语言的男孩2 小时前
C++ SLTL编程
java·开发语言·c++
java修仙传2 小时前
Java 实习日记:从业务表关系到节点价格分析接口改造
java·开发语言·实习
qq_452396232 小时前
第十四篇:《JMeter插件扩展:自定义函数与第三方插件》
开发语言·python·jmeter
敲代码的嘎仔2 小时前
力扣高频SQL基础50题详解
开发语言·数据库·笔记·sql·算法·leetcode·后端开发
码农-阿杰2 小时前
Java 线程等待唤醒机制深度解析:synchronized、ReentrantLock、LockSupport 底层实现对比
java·开发语言·c++