• C语言-指针初阶(6)


    目录

    思维导图:

    1. 指针是什么?

    2. 指针和指针类型 

    2.1 指针+-整数

    2.2 指针的解引用

    3. 野指针

    3.1 野指针成因

    3.2 如何规避野指针

    4. 指针运算

    4.1 指针+-整数

    4.2 指针-指针

    4.3 指针的关系运算

    5. 指针和数组

    6. 二级指针

    7. 指针数组

    写在最后:


    思维导图

    1. 指针是什么?

    想了解指针,必须先了解内存是什么?

    内存是计算机上的一种存储空间,程序运行时会载入内存,存储数据时也会申请内存。

    而一个内存单元的大小是一个字节,每个内存单元都有自己的编号,而内存单元的编号被称为地址

    在C语言中,地址也被称为指针。

    总结:内存单元的编号 = 地址 = 指针

    有关指针:

    关于指针的大小:

    2. 指针和指针类型 

    2.1 指针+-整数

    指针类型的意义:

    例:

    2.2 指针的解引用

    指针类型决定了,指针进行解引用操作的时候,一次性访问几个字节,访问权限的大小

    如果是char*的指针,解引用访问1个字节

    如果是int*的指针,解引用访问4个字节

     所以,指针的访问是可以灵活运用的:

    例:

    1. #include
    2. int main()
    3. {
    4. int a = 0x11223344;
    5. int* pa = &a;
    6. *pa = 0;//一次性将四个字节初始化成零
    7. char* pc = &a;
    8. *pc = 0;//一次只将一个字节初始化成零
    9. return 0;
    10. }

    3. 野指针

    野指针就是指针指向的位置是不可知的。

    3.1 野指针成因

    1. 指针未初始化

    例:

    1. int main()
    2. {
    3. int* p;//未初始化
    4. *p = 20;
    5. return 0;
    6. }

    2. 指针越界访问

    例:

    1. #include
    2. int main()
    3. {
    4. int arr[5] = { 1,2,3,4,5 };
    5. int* p = arr;
    6. int i = 0;
    7. for (i = 0; i <= 5; i++)
    8. {
    9. printf("%d ", arr[i]);//越界访问
    10. }
    11. return 0;
    12. }

    输出结果:

    输出:1 2 3 4 5 -858993460(随机值)

    3.2 如何规避野指针

    1. 指针初始化

    2. 小心指针越界

    3. 指针指向空间释放,及时置NULL

    4. 避免返回局部变量的地址

    5. 指针使用之前检查有效性

    例:

    1. #include
    2. int main()
    3. {
    4. int a = 10;
    5. int* pa = &a;//指针的初始化
    6. int* p = NULL;//NULL - 空指针,专门用来初始化指针
    7. if (p != NULL)//使用前检查指针的有效性
    8. {
    9. ;
    10. }
    11. return 0;
    12. }

    4. 指针运算

    4.1 指针+-整数

    例:

    1. int main()
    2. {
    3. int arr[n];
    4. int* p;
    5. for (p = &arr[0]; p < &arr[n];)
    6. {
    7. *p++ = 0;//先赋值再++,将数值arr中的值都初始化成0
    8. } //每一次++都想后移一个整形
    9. return 0;
    10. }

    4.2 指针-指针

    例:

    1. #include
    2. int main()
    3. {
    4. int arr[10] = { 0 };
    5. printf("%d\n", &arr[9] - &arr[0]);//指针相减的值是两个指针之间的元素个数
    6. return 0;
    7. }

    注:两个数组的指针之间是不能相加减的

    应用:

    模拟实现strlen函数:

    1. #include
    2. my_strlen(char* arr)
    3. {
    4. char* str = arr;
    5. while (* arr != '\0')
    6. {
    7. arr++;
    8. }
    9. return arr - str;//数组长度
    10. }
    11. int main()
    12. {
    13. char arr[] = "abcdef";
    14. int len = my_strlen(arr);
    15. printf("%d\n", len);
    16. return 0;
    17. }

    输出结果:

    输出:6

    4.3 指针的关系运算

    例:

    1. #include
    2. #define n 5
    3. int main()
    4. {
    5. int arr[n];
    6. int* p;
    7. for (p = &arr[0]; p < &arr[n];)//这个其实就是指针之间的关系运算//p < &arr[n]
    8. {
    9. *p++ = 0;//先赋值再++,将数值arr中的值都初始化成0
    10. } //每一次++都想后移一个整形
    11. return 0;
    12. }

    5. 指针和数组

    用指针打印数组:

    例:

    1. #include
    2. int main()
    3. {
    4. int arr[10] = {0};
    5. int* p = arr;
    6. int sz = sizeof(arr) / sizeof(arr[0]);
    7. int i = 0;
    8. //给数组赋值
    9. for (i = 0; i < sz; i++)
    10. {
    11. *(p + i) = i + 1;//通过指针访问数组的每一个元素
    12. }
    13. //打印数组
    14. for (i = 0; i < sz; i++)
    15. {
    16. //printf("%d ", arr[i]);
    17. printf("%d ", *(arr + i));//这两种打印方式是一模一样的
    18. }
    19. return 0;
    20. }

    输出结果:

    输出:1 2 3 4 5 6 7 8 9 10

    6. 二级指针

    例:

    1. #include
    2. int main()
    3. {
    4. int a = 0;
    5. int* pa = &a;//pa是一级指针变量
    6. int** ppa = &pa;//ppa是二级指针变量
    7. **ppa = 50;
    8. printf("%d\n", **ppa);
    9. printf("%d\n", a);
    10. return 0;
    11. }

    输出结果:

    1. 输出:
    2. 50
    3. 50

    当然如果你想创建三级指针变量,规则也是一样的。

    7. 指针数组

    指针数组是什么?

    指针数组是数组(数组是主语),就比如:好孩子是孩子(孩子是主语)(主语在后面)

    例:

    1. #include
    2. int main()
    3. { //我们可以使用一维数组,模拟一个二维数组
    4. int a[] = { 1,2,3,4 };
    5. int b[] = { 2,3,4,5 };
    6. int c[] = { 3,4,5,6 };
    7. int* arr[3] = { a,b,c };
    8. int i = 0;
    9. int j = 0;
    10. for (i = 0; i < 3; i++)
    11. { //通过i访问arr
    12. for (j = 0; j < 4; j++)
    13. { //通过j访问a b c
    14. printf("%d ", arr[i][j]);
    15. }
    16. printf("\n");
    17. }
    18. return 0;
    19. }

    输出结果:

    1. 输出:
    2. 1 2 3 4
    3. 2 3 4 5
    4. 3 4 5 6

    写在最后:

    以上就是本篇文章的内容了,感谢你的阅读。

    如果喜欢本文的话,欢迎点赞和评论,写下你的见解。

    如果想和我一起学习编程,不妨点个关注,我们一起学习,一同成长。

    之后我还会输出更多高质量内容,欢迎收看。

  • 相关阅读:
    [附源码]java毕业设计宠物商店管理系统
    vue打包耗时显示插件安装、遇到插件版本不兼容问题以及解决方案
    客户关系管理系统(CRM)开发的意义
    操作系统
    Flink+Doris 实时数仓
    windows bat 批处理常用命令
    postgresql 格式化查询树为图片 —— pgNodeGraph 与 pg_node2graph
    我的创作纪念日(三周年)
    【知识点随笔分析 | 第五篇】简单介绍什么是QUIC
    Ceph Iscsi GW
  • 原文地址:https://blog.csdn.net/Locky136/article/details/127948346